Commit 2a2d82fd authored by Kenton Varda's avatar Kenton Varda

Fix 32-bit build.

parent fd669b11
...@@ -190,16 +190,31 @@ private: ...@@ -190,16 +190,31 @@ private:
const _::RawSchema* schema, const _::RawSchema* schema,
kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> bindings); kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> bindings);
_::RawBrandedSchema::Binding makeDep( void makeDep(_::RawBrandedSchema::Binding& result,
schema::Type::Reader type, kj::StringPtr scopeName, schema::Type::Reader type, kj::StringPtr scopeName,
kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings); kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings);
_::RawBrandedSchema::Binding makeDep( void makeDep(_::RawBrandedSchema::Binding& result,
uint64_t typeId, schema::Type::Which whichType, schema::Node::Which expectedKind, uint64_t typeId, schema::Type::Which whichType, schema::Node::Which expectedKind,
schema::Brand::Reader brand, kj::StringPtr scopeName, schema::Brand::Reader brand, kj::StringPtr scopeName,
kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings); kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings);
// Looks up the schema and brand for a dependency, or creates lazily-evaluated placeholders if // Looks up the schema and brand for a dependency, or creates lazily-evaluated placeholders if
// they don't already exist. `scopeName` is a human-readable name of the place where the type // they don't already exist, and fills in `result`. `scopeName` is a human-readable name of the
// appeared. // place where the type appeared.
//
// Note that we don't simply return a Binding because we need to be careful about initialization
// to ensure that our byte-based de-duplification works. If we constructed a Binding on the stack
// and returned it, padding bytes in that Binding could go uninitialized, causing it to appear
// unique when it's not. It is expected that `result` has been zero'd via memset() before these
// methods are called.
const _::RawBrandedSchema* makeDepSchema(
schema::Type::Reader type, kj::StringPtr scopeName,
kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings);
const _::RawBrandedSchema* makeDepSchema(
uint64_t typeId, schema::Type::Which whichType, schema::Node::Which expectedKind,
schema::Brand::Reader brand, kj::StringPtr scopeName,
kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings);
// Invoke makeDep() then return the result's schema, or nullptr if it's a primitive type.
template <typename T> template <typename T>
kj::ArrayPtr<const T> copyDeduped(kj::ArrayPtr<const T> values); kj::ArrayPtr<const T> copyDeduped(kj::ArrayPtr<const T> values);
...@@ -1436,7 +1451,7 @@ const _::RawBrandedSchema* SchemaLoader::Impl::makeBranded( ...@@ -1436,7 +1451,7 @@ const _::RawBrandedSchema* SchemaLoader::Impl::makeBranded(
case schema::Brand::Binding::UNBOUND: case schema::Brand::Binding::UNBOUND:
break; break;
case schema::Brand::Binding::TYPE: { case schema::Brand::Binding::TYPE: {
dstBinding = makeDep(srcBinding.getType(), scopeName, clientBrand); makeDep(dstBinding, srcBinding.getType(), scopeName, clientBrand);
break; break;
} }
} }
...@@ -1535,8 +1550,8 @@ SchemaLoader::Impl::makeBrandedDependencies( ...@@ -1535,8 +1550,8 @@ SchemaLoader::Impl::makeBrandedDependencies(
break; break;
case schema::Node::CONST: case schema::Node::CONST:
ADD_ENTRY(CONST_TYPE, 0, makeDep( ADD_ENTRY(CONST_TYPE, 0, makeDepSchema(
node.getConst().getType(), scopeName, bindings).schema); node.getConst().getType(), scopeName, bindings));
break; break;
case schema::Node::STRUCT: { case schema::Node::STRUCT: {
...@@ -1545,8 +1560,8 @@ SchemaLoader::Impl::makeBrandedDependencies( ...@@ -1545,8 +1560,8 @@ SchemaLoader::Impl::makeBrandedDependencies(
auto field = fields[i]; auto field = fields[i];
switch (field.which()) { switch (field.which()) {
case schema::Field::SLOT: case schema::Field::SLOT:
ADD_ENTRY(FIELD, i, makeDep( ADD_ENTRY(FIELD, i, makeDepSchema(
field.getSlot().getType(), scopeName, bindings).schema) field.getSlot().getType(), scopeName, bindings))
break; break;
case schema::Field::GROUP: { case schema::Field::GROUP: {
const _::RawSchema* group = loadEmpty( const _::RawSchema* group = loadEmpty(
...@@ -1570,21 +1585,21 @@ SchemaLoader::Impl::makeBrandedDependencies( ...@@ -1570,21 +1585,21 @@ SchemaLoader::Impl::makeBrandedDependencies(
auto superclasses = interface.getSuperclasses(); auto superclasses = interface.getSuperclasses();
for (auto i: kj::indices(superclasses)) { for (auto i: kj::indices(superclasses)) {
auto superclass = superclasses[i]; auto superclass = superclasses[i];
ADD_ENTRY(SUPERCLASS, i, makeDep( ADD_ENTRY(SUPERCLASS, i, makeDepSchema(
superclass.getId(), schema::Type::INTERFACE, schema::Node::INTERFACE, superclass.getId(), schema::Type::INTERFACE, schema::Node::INTERFACE,
superclass.getBrand(), scopeName, bindings).schema) superclass.getBrand(), scopeName, bindings))
} }
} }
{ {
auto methods = interface.getMethods(); auto methods = interface.getMethods();
for (auto i: kj::indices(methods)) { for (auto i: kj::indices(methods)) {
auto method = methods[i]; auto method = methods[i];
ADD_ENTRY(METHOD_PARAMS, i, makeDep( ADD_ENTRY(METHOD_PARAMS, i, makeDepSchema(
method.getParamStructType(), schema::Type::STRUCT, schema::Node::STRUCT, method.getParamStructType(), schema::Type::STRUCT, schema::Node::STRUCT,
method.getParamBrand(), scopeName, bindings).schema) method.getParamBrand(), scopeName, bindings))
ADD_ENTRY(METHOD_RESULTS, i, makeDep( ADD_ENTRY(METHOD_RESULTS, i, makeDepSchema(
method.getResultStructType(), schema::Type::STRUCT, schema::Node::STRUCT, method.getResultStructType(), schema::Type::STRUCT, schema::Node::STRUCT,
method.getResultBrand(), scopeName, bindings).schema) method.getResultBrand(), scopeName, bindings))
} }
} }
break; break;
...@@ -1601,7 +1616,7 @@ SchemaLoader::Impl::makeBrandedDependencies( ...@@ -1601,7 +1616,7 @@ SchemaLoader::Impl::makeBrandedDependencies(
return copyDeduped(deps.asPtr()); return copyDeduped(deps.asPtr());
} }
_::RawBrandedSchema::Binding SchemaLoader::Impl::makeDep( void SchemaLoader::Impl::makeDep(_::RawBrandedSchema::Binding& result,
schema::Type::Reader type, kj::StringPtr scopeName, schema::Type::Reader type, kj::StringPtr scopeName,
kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings) { kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings) {
switch (type.which()) { switch (type.which()) {
...@@ -1619,35 +1634,40 @@ _::RawBrandedSchema::Binding SchemaLoader::Impl::makeDep( ...@@ -1619,35 +1634,40 @@ _::RawBrandedSchema::Binding SchemaLoader::Impl::makeDep(
case schema::Type::FLOAT64: case schema::Type::FLOAT64:
case schema::Type::TEXT: case schema::Type::TEXT:
case schema::Type::DATA: case schema::Type::DATA:
return { static_cast<uint8_t>(type.which()), 0, nullptr }; result.which = static_cast<uint8_t>(type.which());
return;
case schema::Type::STRUCT: { case schema::Type::STRUCT: {
auto structType = type.getStruct(); auto structType = type.getStruct();
return makeDep(structType.getTypeId(), schema::Type::STRUCT, schema::Node::STRUCT, makeDep(result, structType.getTypeId(), schema::Type::STRUCT, schema::Node::STRUCT,
structType.getBrand(), scopeName, brandBindings); structType.getBrand(), scopeName, brandBindings);
return;
} }
case schema::Type::ENUM: { case schema::Type::ENUM: {
auto enumType = type.getEnum(); auto enumType = type.getEnum();
return makeDep(enumType.getTypeId(), schema::Type::ENUM, schema::Node::ENUM, makeDep(result, enumType.getTypeId(), schema::Type::ENUM, schema::Node::ENUM,
enumType.getBrand(), scopeName, brandBindings); enumType.getBrand(), scopeName, brandBindings);
return;
} }
case schema::Type::INTERFACE: { case schema::Type::INTERFACE: {
auto interfaceType = type.getInterface(); auto interfaceType = type.getInterface();
return makeDep(interfaceType.getTypeId(), schema::Type::INTERFACE, schema::Node::INTERFACE, makeDep(result, interfaceType.getTypeId(), schema::Type::INTERFACE, schema::Node::INTERFACE,
interfaceType.getBrand(), scopeName, brandBindings); interfaceType.getBrand(), scopeName, brandBindings);
return;
} }
case schema::Type::LIST: { case schema::Type::LIST: {
auto result = makeDep(type.getList().getElementType(), scopeName, brandBindings); makeDep(result, type.getList().getElementType(), scopeName, brandBindings);
++result.listDepth; ++result.listDepth;
return result; return;
} }
case schema::Type::ANY_POINTER: { case schema::Type::ANY_POINTER: {
result.which = static_cast<uint8_t>(schema::Type::ANY_POINTER);
auto anyPointer = type.getAnyPointer(); auto anyPointer = type.getAnyPointer();
switch (anyPointer.which()) { switch (anyPointer.which()) {
case schema::Type::AnyPointer::UNCONSTRAINED: case schema::Type::AnyPointer::UNCONSTRAINED:
return { static_cast<uint8_t>(type.which()), 0, nullptr }; return;
case schema::Type::AnyPointer::PARAMETER: { case schema::Type::AnyPointer::PARAMETER: {
auto param = anyPointer.getParameter(); auto param = anyPointer.getParameter();
uint64_t id = param.getScopeId(); uint64_t id = param.getScopeId();
...@@ -1659,26 +1679,32 @@ _::RawBrandedSchema::Binding SchemaLoader::Impl::makeDep( ...@@ -1659,26 +1679,32 @@ _::RawBrandedSchema::Binding SchemaLoader::Impl::makeDep(
if (scope.typeId == id) { if (scope.typeId == id) {
if (scope.isUnbound) { if (scope.isUnbound) {
// Unbound brand parameter. // Unbound brand parameter.
return { static_cast<uint8_t>(schema::Type::ANY_POINTER), 0, id, index }; result.scopeId = id;
result.paramIndex = index;
return;
} else if (index >= scope.bindingCount) { } else if (index >= scope.bindingCount) {
// Binding index out-of-range. Treat as AnyPointer. This is important to allow // Binding index out-of-range. Treat as AnyPointer. This is important to allow
// new type parameters to be added to existing types without breaking dependent // new type parameters to be added to existing types without breaking dependent
// schemas. // schemas.
break; return;
} else { } else {
return scope.bindings[index]; result = scope.bindings[index];
return;
} }
} }
} }
return { static_cast<uint8_t>(schema::Type::ANY_POINTER), 0, 0, 0 }; return;
} else { } else {
// Unbound brand parameter. // Unbound brand parameter.
return { static_cast<uint8_t>(schema::Type::ANY_POINTER), 0, id, index }; result.scopeId = id;
result.paramIndex = index;
return;
} }
} }
case schema::Type::AnyPointer::IMPLICIT_METHOD_PARAMETER: case schema::Type::AnyPointer::IMPLICIT_METHOD_PARAMETER:
return { static_cast<uint8_t>(schema::Type::ANY_POINTER), 0, result.isImplicitParameter = true;
anyPointer.getImplicitMethodParameter().getParameterIndex() }; result.paramIndex = anyPointer.getImplicitMethodParameter().getParameterIndex();
return;
} }
KJ_UNREACHABLE; KJ_UNREACHABLE;
} }
...@@ -1687,17 +1713,34 @@ _::RawBrandedSchema::Binding SchemaLoader::Impl::makeDep( ...@@ -1687,17 +1713,34 @@ _::RawBrandedSchema::Binding SchemaLoader::Impl::makeDep(
KJ_UNREACHABLE; KJ_UNREACHABLE;
} }
_::RawBrandedSchema::Binding SchemaLoader::Impl::makeDep( void SchemaLoader::Impl::makeDep(_::RawBrandedSchema::Binding& result,
uint64_t typeId, schema::Type::Which whichType, schema::Node::Which expectedKind, uint64_t typeId, schema::Type::Which whichType, schema::Node::Which expectedKind,
schema::Brand::Reader brand, kj::StringPtr scopeName, schema::Brand::Reader brand, kj::StringPtr scopeName,
kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings) { kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings) {
const _::RawSchema* schema = loadEmpty(typeId, const _::RawSchema* schema = loadEmpty(typeId,
kj::str("(unknown type; seen as dependency of ", scopeName, ")"), kj::str("(unknown type; seen as dependency of ", scopeName, ")"),
expectedKind, true); expectedKind, true);
return _::RawBrandedSchema::Binding { result.which = static_cast<uint8_t>(whichType);
static_cast<uint8_t>(whichType), 0, result.schema = makeBranded(schema, brand, brandBindings);
makeBranded(schema, brand, brandBindings) }
};
const _::RawBrandedSchema* SchemaLoader::Impl::makeDepSchema(
schema::Type::Reader type, kj::StringPtr scopeName,
kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings) {
_::RawBrandedSchema::Binding binding;
memset(&binding, 0, sizeof(binding));
makeDep(binding, type, scopeName, brandBindings);
return binding.schema;
}
const _::RawBrandedSchema* SchemaLoader::Impl::makeDepSchema(
uint64_t typeId, schema::Type::Which whichType, schema::Node::Which expectedKind,
schema::Brand::Reader brand, kj::StringPtr scopeName,
kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings) {
_::RawBrandedSchema::Binding binding;
memset(&binding, 0, sizeof(binding));
makeDep(binding, typeId, whichType, expectedKind, brand, scopeName, brandBindings);
return binding.schema;
} }
template <typename T> template <typename T>
...@@ -1899,7 +1942,7 @@ Schema SchemaLoader::get(uint64_t id, schema::Brand::Reader brand, Schema scope) ...@@ -1899,7 +1942,7 @@ Schema SchemaLoader::get(uint64_t id, schema::Brand::Reader brand, Schema scope)
KJ_IF_MAYBE(result, tryGet(id, brand, scope)) { KJ_IF_MAYBE(result, tryGet(id, brand, scope)) {
return *result; return *result;
} else { } else {
KJ_FAIL_REQUIRE("no schema node loaded for id", id); KJ_FAIL_REQUIRE("no schema node loaded for id", kj::hex(id));
} }
} }
......
...@@ -402,21 +402,24 @@ Type Schema::BrandArgumentList::operator[](uint index) const { ...@@ -402,21 +402,24 @@ Type Schema::BrandArgumentList::operator[](uint index) const {
} }
auto& binding = bindings[index]; auto& binding = bindings[index];
Type result;
if (binding.which == (uint)schema::Type::ANY_POINTER) { if (binding.which == (uint)schema::Type::ANY_POINTER) {
if (binding.scopeId != 0) { if (binding.scopeId != 0) {
return Type::BrandParameter { binding.scopeId, binding.paramIndex }; result = Type::BrandParameter { binding.scopeId, binding.paramIndex };
} else if (binding.isImplicitParameter) { } else if (binding.isImplicitParameter) {
return Type::ImplicitParameter { binding.paramIndex }; result = Type::ImplicitParameter { binding.paramIndex };
} else { } else {
return Type(schema::Type::ANY_POINTER, binding.listDepth, nullptr); result = schema::Type::ANY_POINTER;
} }
} else if (binding.schema == nullptr) { } else if (binding.schema == nullptr) {
// Builtin / primitive type. // Builtin / primitive type.
return Type(static_cast<schema::Type::Which>(binding.which), binding.listDepth, nullptr); result = static_cast<schema::Type::Which>(binding.which);
} else { } else {
binding.schema->ensureInitialized(); binding.schema->ensureInitialized();
return Type(static_cast<schema::Type::Which>(binding.which), binding.listDepth, binding.schema); result = Type(static_cast<schema::Type::Which>(binding.which), binding.schema);
} }
return result.wrapInList(binding.listDepth);
} }
// ======================================================================================= // =======================================================================================
......
...@@ -633,6 +633,12 @@ public: ...@@ -633,6 +633,12 @@ public:
bool operator==(const Type& other) const; bool operator==(const Type& other) const;
inline bool operator!=(const Type& other) const { return !(*this == other); } inline bool operator!=(const Type& other) const { return !(*this == other); }
inline Type wrapInList(uint depth = 1) const;
// Return the Type formed by wrapping this type in List() `depth` times.
inline Type(schema::Type::Which derived, const _::RawBrandedSchema* schema);
// For internal use.
private: private:
schema::Type::Which baseType; // type not including applications of List() schema::Type::Which baseType; // type not including applications of List()
uint8_t listDepth; // 0 for T, 1 for List(T), 2 for List(List(T)), ... uint8_t listDepth; // 0 for T, 1 for List(T), 2 for List(List(T)), ...
...@@ -652,11 +658,12 @@ private: ...@@ -652,11 +658,12 @@ private:
}; };
Type(schema::Type::Which baseType, uint8_t listDepth, const _::RawBrandedSchema* schema) Type(schema::Type::Which baseType, uint8_t listDepth, const _::RawBrandedSchema* schema)
: baseType(baseType), listDepth(listDepth), schema(schema) {} : baseType(baseType), listDepth(listDepth), schema(schema) {
KJ_IREQUIRE(baseType != schema::Type::ANY_POINTER);
}
void requireUsableAs(Type expected) const; void requireUsableAs(Type expected) const;
friend class Schema;
friend class ListSchema; friend class ListSchema;
}; };
...@@ -826,11 +833,22 @@ struct ListSchema::FromImpl<List<T>> { ...@@ -826,11 +833,22 @@ struct ListSchema::FromImpl<List<T>> {
inline Type::Type(): baseType(schema::Type::VOID), listDepth(0), schema(nullptr) {} inline Type::Type(): baseType(schema::Type::VOID), listDepth(0), schema(nullptr) {}
inline Type::Type(schema::Type::Which primitive) inline Type::Type(schema::Type::Which primitive)
: baseType(primitive), listDepth(0), isImplicitParam(false), scopeId(0) { : baseType(primitive), listDepth(0), isImplicitParam(false) {
KJ_IREQUIRE(primitive != schema::Type::STRUCT && KJ_IREQUIRE(primitive != schema::Type::STRUCT &&
primitive != schema::Type::ENUM && primitive != schema::Type::ENUM &&
primitive != schema::Type::INTERFACE && primitive != schema::Type::INTERFACE &&
primitive != schema::Type::LIST); primitive != schema::Type::LIST);
if (primitive == schema::Type::ANY_POINTER) {
scopeId = 0;
} else {
schema = nullptr;
}
}
inline Type::Type(schema::Type::Which derived, const _::RawBrandedSchema* schema)
: baseType(derived), listDepth(0), isImplicitParam(false), schema(schema) {
KJ_IREQUIRE(derived == schema::Type::STRUCT ||
derived == schema::Type::ENUM ||
derived == schema::Type::INTERFACE);
} }
inline Type::Type(StructSchema schema) inline Type::Type(StructSchema schema)
...@@ -879,6 +897,12 @@ inline bool Type::isAnyPointer() const { ...@@ -879,6 +897,12 @@ inline bool Type::isAnyPointer() const {
return baseType == schema::Type::ANY_POINTER && listDepth == 0; return baseType == schema::Type::ANY_POINTER && listDepth == 0;
} }
inline Type Type::wrapInList(uint depth) const {
Type result = *this;
result.listDepth += depth;
return result;
}
} // namespace capnp } // namespace capnp
#endif // CAPNP_SCHEMA_H_ #endif // CAPNP_SCHEMA_H_
...@@ -32,10 +32,10 @@ namespace _ { // private ...@@ -32,10 +32,10 @@ namespace _ { // private
void inlineRequireFailure(const char* file, int line, const char* expectation, void inlineRequireFailure(const char* file, int line, const char* expectation,
const char* macroArgs, const char* message) { const char* macroArgs, const char* message) {
if (message == nullptr) { if (message == nullptr) {
Debug::Fault f(file, line, 0, expectation, macroArgs); Debug::Fault f(file, line, kj::Exception::Type::FAILED, expectation, macroArgs);
f.fatal(); f.fatal();
} else { } else {
Debug::Fault f(file, line, 0, expectation, macroArgs, message); Debug::Fault f(file, line, kj::Exception::Type::FAILED, expectation, macroArgs, message);
f.fatal(); f.fatal();
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment