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