Mercurial > hg > sv-dependency-builds
view win64-msvc/include/capnp/raw-schema.h @ 148:b4bfdf10c4b3
Update Win64 capnp builds to v0.6
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Mon, 22 May 2017 18:56:49 +0100 (2017-05-22) |
parents | |
children |
line wrap: on
line source
// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors // Licensed under the MIT License: // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #ifndef CAPNP_RAW_SCHEMA_H_ #define CAPNP_RAW_SCHEMA_H_ #if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) #pragma GCC system_header #endif #include "common.h" // for uint and friends #if _MSC_VER #include <atomic> #endif namespace capnp { namespace _ { // private struct RawSchema; struct RawBrandedSchema { // Represents a combination of a schema and bindings for its generic parameters. // // Note that while we generate one `RawSchema` per type, we generate a `RawBrandedSchema` for // every _instance_ of a generic type -- or, at least, every instance that is actually used. For // generated-code types, we use template magic to initialize these. const RawSchema* generic; // Generic type which we're branding. struct Binding { uint8_t which; // Numeric value of one of schema::Type::Which. bool isImplicitParameter; // For AnyPointer, true if it's an implicit method parameter. uint16_t listDepth; // Number of times to wrap the base type in List(). uint16_t paramIndex; // For AnyPointer. If it's a type parameter (scopeId is non-zero) or it's an implicit parameter // (isImplicitParameter is true), then this is the parameter index. Otherwise this is a numeric // value of one of schema::Type::AnyPointer::Unconstrained::Which. union { const RawBrandedSchema* schema; // for struct, enum, interface uint64_t scopeId; // for AnyPointer, if it's a type parameter }; Binding() = default; inline constexpr Binding(uint8_t which, uint16_t listDepth, const RawBrandedSchema* schema) : which(which), isImplicitParameter(false), listDepth(listDepth), paramIndex(0), schema(schema) {} inline constexpr Binding(uint8_t which, uint16_t listDepth, uint64_t scopeId, uint16_t paramIndex) : which(which), isImplicitParameter(false), listDepth(listDepth), paramIndex(paramIndex), scopeId(scopeId) {} inline constexpr Binding(uint8_t which, uint16_t listDepth, uint16_t implicitParamIndex) : which(which), isImplicitParameter(true), listDepth(listDepth), paramIndex(implicitParamIndex), scopeId(0) {} }; struct Scope { uint64_t typeId; // Type ID whose parameters are being bound. const Binding* bindings; uint bindingCount; // Bindings for those parameters. bool isUnbound; // This scope is unbound, in the sense of SchemaLoader::getUnbound(). }; const Scope* scopes; // Array of enclosing scopes for which generic variables have been bound, sorted by type ID. struct Dependency { uint location; const RawBrandedSchema* schema; }; const Dependency* dependencies; // Map of branded schemas for dependencies of this type, given our brand. Only dependencies that // are branded are included in this map; if a dependency is missing, use its `defaultBrand`. uint32_t scopeCount; uint32_t dependencyCount; enum class DepKind { // Component of a Dependency::location. Specifies what sort of dependency this is. INVALID, // Mostly defined to ensure that zero is not a valid location. FIELD, // Binding needed for a field's type. The index is the field index (NOT ordinal!). METHOD_PARAMS, // Bindings needed for a method's params type. The index is the method number. METHOD_RESULTS, // Bindings needed for a method's results type. The index is the method ordinal. SUPERCLASS, // Bindings needed for a superclass type. The index is the superclass's index in the // "extends" list. CONST_TYPE // Bindings needed for the type of a constant. The index is zero. }; static inline uint makeDepLocation(DepKind kind, uint index) { // Make a number representing the location of a particular dependency within its parent // schema. return (static_cast<uint>(kind) << 24) | index; } class Initializer { public: virtual void init(const RawBrandedSchema* generic) const = 0; }; const Initializer* lazyInitializer; // Lazy initializer, invoked by ensureInitialized(). inline void ensureInitialized() const { // Lazy initialization support. Invoke to ensure that initialization has taken place. This // is required in particular when traversing the dependency list. RawSchemas for compiled-in // types are always initialized; only dynamically-loaded schemas may be lazy. #if __GNUC__ const Initializer* i = __atomic_load_n(&lazyInitializer, __ATOMIC_ACQUIRE); #elif _MSC_VER const Initializer* i = *static_cast<Initializer const* const volatile*>(&lazyInitializer); std::atomic_thread_fence(std::memory_order_acquire); #else #error "Platform not supported" #endif if (i != nullptr) i->init(this); } inline bool isUnbound() const; // Checks if this schema is the result of calling SchemaLoader::getUnbound(), in which case // binding lookups need to be handled specially. }; struct RawSchema { // The generated code defines a constant RawSchema for every compiled declaration. // // This is an internal structure which could change in the future. uint64_t id; const word* encodedNode; // Encoded SchemaNode, readable via readMessageUnchecked<schema::Node>(encodedNode). uint32_t encodedSize; // Size of encodedNode, in words. const RawSchema* const* dependencies; // Pointers to other types on which this one depends, sorted by ID. The schemas in this table // may be uninitialized -- you must call ensureInitialized() on the one you wish to use before // using it. // // TODO(someday): Make this a hashtable. const uint16_t* membersByName; // Indexes of members sorted by name. Used to implement name lookup. // TODO(someday): Make this a hashtable. uint32_t dependencyCount; uint32_t memberCount; // Sizes of above tables. const uint16_t* membersByDiscriminant; // List of all member indexes ordered by discriminant value. Those which don't have a // discriminant value are listed at the end, in order by ordinal. const RawSchema* canCastTo; // Points to the RawSchema of a compiled-in type to which it is safe to cast any DynamicValue // with this schema. This is null for all compiled-in types; it is only set by SchemaLoader on // dynamically-loaded types. class Initializer { public: virtual void init(const RawSchema* schema) const = 0; }; const Initializer* lazyInitializer; // Lazy initializer, invoked by ensureInitialized(). inline void ensureInitialized() const { // Lazy initialization support. Invoke to ensure that initialization has taken place. This // is required in particular when traversing the dependency list. RawSchemas for compiled-in // types are always initialized; only dynamically-loaded schemas may be lazy. #if __GNUC__ const Initializer* i = __atomic_load_n(&lazyInitializer, __ATOMIC_ACQUIRE); #elif _MSC_VER const Initializer* i = *static_cast<Initializer const* const volatile*>(&lazyInitializer); std::atomic_thread_fence(std::memory_order_acquire); #else #error "Platform not supported" #endif if (i != nullptr) i->init(this); } RawBrandedSchema defaultBrand; // Specifies the brand to use for this schema if no generic parameters have been bound to // anything. Generally, in the default brand, all generic parameters are treated as if they were // bound to `AnyPointer`. }; inline bool RawBrandedSchema::isUnbound() const { // The unbound schema is the only one that has no scopes but is not the default schema. return scopeCount == 0 && this != &generic->defaultBrand; } } // namespace _ (private) } // namespace capnp #endif // CAPNP_RAW_SCHEMA_H_