annotate win32-mingw/include/capnp/raw-schema.h @ 64:eccd51b72864

Update Win32 capnp builds to v0.6
author Chris Cannam
date Tue, 23 May 2017 09:16:54 +0100
parents
children
rev   line source
Chris@64 1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
Chris@64 2 // Licensed under the MIT License:
Chris@64 3 //
Chris@64 4 // Permission is hereby granted, free of charge, to any person obtaining a copy
Chris@64 5 // of this software and associated documentation files (the "Software"), to deal
Chris@64 6 // in the Software without restriction, including without limitation the rights
Chris@64 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
Chris@64 8 // copies of the Software, and to permit persons to whom the Software is
Chris@64 9 // furnished to do so, subject to the following conditions:
Chris@64 10 //
Chris@64 11 // The above copyright notice and this permission notice shall be included in
Chris@64 12 // all copies or substantial portions of the Software.
Chris@64 13 //
Chris@64 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Chris@64 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Chris@64 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Chris@64 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Chris@64 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Chris@64 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
Chris@64 20 // THE SOFTWARE.
Chris@64 21
Chris@64 22 #ifndef CAPNP_RAW_SCHEMA_H_
Chris@64 23 #define CAPNP_RAW_SCHEMA_H_
Chris@64 24
Chris@64 25 #if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS)
Chris@64 26 #pragma GCC system_header
Chris@64 27 #endif
Chris@64 28
Chris@64 29 #include "common.h" // for uint and friends
Chris@64 30
Chris@64 31 #if _MSC_VER
Chris@64 32 #include <atomic>
Chris@64 33 #endif
Chris@64 34
Chris@64 35 namespace capnp {
Chris@64 36 namespace _ { // private
Chris@64 37
Chris@64 38 struct RawSchema;
Chris@64 39
Chris@64 40 struct RawBrandedSchema {
Chris@64 41 // Represents a combination of a schema and bindings for its generic parameters.
Chris@64 42 //
Chris@64 43 // Note that while we generate one `RawSchema` per type, we generate a `RawBrandedSchema` for
Chris@64 44 // every _instance_ of a generic type -- or, at least, every instance that is actually used. For
Chris@64 45 // generated-code types, we use template magic to initialize these.
Chris@64 46
Chris@64 47 const RawSchema* generic;
Chris@64 48 // Generic type which we're branding.
Chris@64 49
Chris@64 50 struct Binding {
Chris@64 51 uint8_t which; // Numeric value of one of schema::Type::Which.
Chris@64 52
Chris@64 53 bool isImplicitParameter;
Chris@64 54 // For AnyPointer, true if it's an implicit method parameter.
Chris@64 55
Chris@64 56 uint16_t listDepth; // Number of times to wrap the base type in List().
Chris@64 57
Chris@64 58 uint16_t paramIndex;
Chris@64 59 // For AnyPointer. If it's a type parameter (scopeId is non-zero) or it's an implicit parameter
Chris@64 60 // (isImplicitParameter is true), then this is the parameter index. Otherwise this is a numeric
Chris@64 61 // value of one of schema::Type::AnyPointer::Unconstrained::Which.
Chris@64 62
Chris@64 63 union {
Chris@64 64 const RawBrandedSchema* schema; // for struct, enum, interface
Chris@64 65 uint64_t scopeId; // for AnyPointer, if it's a type parameter
Chris@64 66 };
Chris@64 67
Chris@64 68 Binding() = default;
Chris@64 69 inline constexpr Binding(uint8_t which, uint16_t listDepth, const RawBrandedSchema* schema)
Chris@64 70 : which(which), isImplicitParameter(false), listDepth(listDepth), paramIndex(0),
Chris@64 71 schema(schema) {}
Chris@64 72 inline constexpr Binding(uint8_t which, uint16_t listDepth,
Chris@64 73 uint64_t scopeId, uint16_t paramIndex)
Chris@64 74 : which(which), isImplicitParameter(false), listDepth(listDepth), paramIndex(paramIndex),
Chris@64 75 scopeId(scopeId) {}
Chris@64 76 inline constexpr Binding(uint8_t which, uint16_t listDepth, uint16_t implicitParamIndex)
Chris@64 77 : which(which), isImplicitParameter(true), listDepth(listDepth),
Chris@64 78 paramIndex(implicitParamIndex), scopeId(0) {}
Chris@64 79 };
Chris@64 80
Chris@64 81 struct Scope {
Chris@64 82 uint64_t typeId;
Chris@64 83 // Type ID whose parameters are being bound.
Chris@64 84
Chris@64 85 const Binding* bindings;
Chris@64 86 uint bindingCount;
Chris@64 87 // Bindings for those parameters.
Chris@64 88
Chris@64 89 bool isUnbound;
Chris@64 90 // This scope is unbound, in the sense of SchemaLoader::getUnbound().
Chris@64 91 };
Chris@64 92
Chris@64 93 const Scope* scopes;
Chris@64 94 // Array of enclosing scopes for which generic variables have been bound, sorted by type ID.
Chris@64 95
Chris@64 96 struct Dependency {
Chris@64 97 uint location;
Chris@64 98 const RawBrandedSchema* schema;
Chris@64 99 };
Chris@64 100
Chris@64 101 const Dependency* dependencies;
Chris@64 102 // Map of branded schemas for dependencies of this type, given our brand. Only dependencies that
Chris@64 103 // are branded are included in this map; if a dependency is missing, use its `defaultBrand`.
Chris@64 104
Chris@64 105 uint32_t scopeCount;
Chris@64 106 uint32_t dependencyCount;
Chris@64 107
Chris@64 108 enum class DepKind {
Chris@64 109 // Component of a Dependency::location. Specifies what sort of dependency this is.
Chris@64 110
Chris@64 111 INVALID,
Chris@64 112 // Mostly defined to ensure that zero is not a valid location.
Chris@64 113
Chris@64 114 FIELD,
Chris@64 115 // Binding needed for a field's type. The index is the field index (NOT ordinal!).
Chris@64 116
Chris@64 117 METHOD_PARAMS,
Chris@64 118 // Bindings needed for a method's params type. The index is the method number.
Chris@64 119
Chris@64 120 METHOD_RESULTS,
Chris@64 121 // Bindings needed for a method's results type. The index is the method ordinal.
Chris@64 122
Chris@64 123 SUPERCLASS,
Chris@64 124 // Bindings needed for a superclass type. The index is the superclass's index in the
Chris@64 125 // "extends" list.
Chris@64 126
Chris@64 127 CONST_TYPE
Chris@64 128 // Bindings needed for the type of a constant. The index is zero.
Chris@64 129 };
Chris@64 130
Chris@64 131 static inline uint makeDepLocation(DepKind kind, uint index) {
Chris@64 132 // Make a number representing the location of a particular dependency within its parent
Chris@64 133 // schema.
Chris@64 134
Chris@64 135 return (static_cast<uint>(kind) << 24) | index;
Chris@64 136 }
Chris@64 137
Chris@64 138 class Initializer {
Chris@64 139 public:
Chris@64 140 virtual void init(const RawBrandedSchema* generic) const = 0;
Chris@64 141 };
Chris@64 142
Chris@64 143 const Initializer* lazyInitializer;
Chris@64 144 // Lazy initializer, invoked by ensureInitialized().
Chris@64 145
Chris@64 146 inline void ensureInitialized() const {
Chris@64 147 // Lazy initialization support. Invoke to ensure that initialization has taken place. This
Chris@64 148 // is required in particular when traversing the dependency list. RawSchemas for compiled-in
Chris@64 149 // types are always initialized; only dynamically-loaded schemas may be lazy.
Chris@64 150
Chris@64 151 #if __GNUC__
Chris@64 152 const Initializer* i = __atomic_load_n(&lazyInitializer, __ATOMIC_ACQUIRE);
Chris@64 153 #elif _MSC_VER
Chris@64 154 const Initializer* i = *static_cast<Initializer const* const volatile*>(&lazyInitializer);
Chris@64 155 std::atomic_thread_fence(std::memory_order_acquire);
Chris@64 156 #else
Chris@64 157 #error "Platform not supported"
Chris@64 158 #endif
Chris@64 159 if (i != nullptr) i->init(this);
Chris@64 160 }
Chris@64 161
Chris@64 162 inline bool isUnbound() const;
Chris@64 163 // Checks if this schema is the result of calling SchemaLoader::getUnbound(), in which case
Chris@64 164 // binding lookups need to be handled specially.
Chris@64 165 };
Chris@64 166
Chris@64 167 struct RawSchema {
Chris@64 168 // The generated code defines a constant RawSchema for every compiled declaration.
Chris@64 169 //
Chris@64 170 // This is an internal structure which could change in the future.
Chris@64 171
Chris@64 172 uint64_t id;
Chris@64 173
Chris@64 174 const word* encodedNode;
Chris@64 175 // Encoded SchemaNode, readable via readMessageUnchecked<schema::Node>(encodedNode).
Chris@64 176
Chris@64 177 uint32_t encodedSize;
Chris@64 178 // Size of encodedNode, in words.
Chris@64 179
Chris@64 180 const RawSchema* const* dependencies;
Chris@64 181 // Pointers to other types on which this one depends, sorted by ID. The schemas in this table
Chris@64 182 // may be uninitialized -- you must call ensureInitialized() on the one you wish to use before
Chris@64 183 // using it.
Chris@64 184 //
Chris@64 185 // TODO(someday): Make this a hashtable.
Chris@64 186
Chris@64 187 const uint16_t* membersByName;
Chris@64 188 // Indexes of members sorted by name. Used to implement name lookup.
Chris@64 189 // TODO(someday): Make this a hashtable.
Chris@64 190
Chris@64 191 uint32_t dependencyCount;
Chris@64 192 uint32_t memberCount;
Chris@64 193 // Sizes of above tables.
Chris@64 194
Chris@64 195 const uint16_t* membersByDiscriminant;
Chris@64 196 // List of all member indexes ordered by discriminant value. Those which don't have a
Chris@64 197 // discriminant value are listed at the end, in order by ordinal.
Chris@64 198
Chris@64 199 const RawSchema* canCastTo;
Chris@64 200 // Points to the RawSchema of a compiled-in type to which it is safe to cast any DynamicValue
Chris@64 201 // with this schema. This is null for all compiled-in types; it is only set by SchemaLoader on
Chris@64 202 // dynamically-loaded types.
Chris@64 203
Chris@64 204 class Initializer {
Chris@64 205 public:
Chris@64 206 virtual void init(const RawSchema* schema) const = 0;
Chris@64 207 };
Chris@64 208
Chris@64 209 const Initializer* lazyInitializer;
Chris@64 210 // Lazy initializer, invoked by ensureInitialized().
Chris@64 211
Chris@64 212 inline void ensureInitialized() const {
Chris@64 213 // Lazy initialization support. Invoke to ensure that initialization has taken place. This
Chris@64 214 // is required in particular when traversing the dependency list. RawSchemas for compiled-in
Chris@64 215 // types are always initialized; only dynamically-loaded schemas may be lazy.
Chris@64 216
Chris@64 217 #if __GNUC__
Chris@64 218 const Initializer* i = __atomic_load_n(&lazyInitializer, __ATOMIC_ACQUIRE);
Chris@64 219 #elif _MSC_VER
Chris@64 220 const Initializer* i = *static_cast<Initializer const* const volatile*>(&lazyInitializer);
Chris@64 221 std::atomic_thread_fence(std::memory_order_acquire);
Chris@64 222 #else
Chris@64 223 #error "Platform not supported"
Chris@64 224 #endif
Chris@64 225 if (i != nullptr) i->init(this);
Chris@64 226 }
Chris@64 227
Chris@64 228 RawBrandedSchema defaultBrand;
Chris@64 229 // Specifies the brand to use for this schema if no generic parameters have been bound to
Chris@64 230 // anything. Generally, in the default brand, all generic parameters are treated as if they were
Chris@64 231 // bound to `AnyPointer`.
Chris@64 232 };
Chris@64 233
Chris@64 234 inline bool RawBrandedSchema::isUnbound() const {
Chris@64 235 // The unbound schema is the only one that has no scopes but is not the default schema.
Chris@64 236 return scopeCount == 0 && this != &generic->defaultBrand;
Chris@64 237 }
Chris@64 238
Chris@64 239 } // namespace _ (private)
Chris@64 240 } // namespace capnp
Chris@64 241
Chris@64 242 #endif // CAPNP_RAW_SCHEMA_H_