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

Fix 32-bit build.

parent fd669b11
......@@ -190,16 +190,31 @@ private:
const _::RawSchema* schema,
kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> bindings);
_::RawBrandedSchema::Binding makeDep(
void makeDep(_::RawBrandedSchema::Binding& result,
schema::Type::Reader type, kj::StringPtr scopeName,
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,
schema::Brand::Reader brand, kj::StringPtr scopeName,
kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings);
// 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
// appeared.
// they don't already exist, and fills in `result`. `scopeName` is a human-readable name of the
// 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>
kj::ArrayPtr<const T> copyDeduped(kj::ArrayPtr<const T> values);
......@@ -1436,7 +1451,7 @@ const _::RawBrandedSchema* SchemaLoader::Impl::makeBranded(
case schema::Brand::Binding::UNBOUND:
break;
case schema::Brand::Binding::TYPE: {
dstBinding = makeDep(srcBinding.getType(), scopeName, clientBrand);
makeDep(dstBinding, srcBinding.getType(), scopeName, clientBrand);
break;
}
}
......@@ -1535,8 +1550,8 @@ SchemaLoader::Impl::makeBrandedDependencies(
break;
case schema::Node::CONST:
ADD_ENTRY(CONST_TYPE, 0, makeDep(
node.getConst().getType(), scopeName, bindings).schema);
ADD_ENTRY(CONST_TYPE, 0, makeDepSchema(
node.getConst().getType(), scopeName, bindings));
break;
case schema::Node::STRUCT: {
......@@ -1545,8 +1560,8 @@ SchemaLoader::Impl::makeBrandedDependencies(
auto field = fields[i];
switch (field.which()) {
case schema::Field::SLOT:
ADD_ENTRY(FIELD, i, makeDep(
field.getSlot().getType(), scopeName, bindings).schema)
ADD_ENTRY(FIELD, i, makeDepSchema(
field.getSlot().getType(), scopeName, bindings))
break;
case schema::Field::GROUP: {
const _::RawSchema* group = loadEmpty(
......@@ -1570,21 +1585,21 @@ SchemaLoader::Impl::makeBrandedDependencies(
auto superclasses = interface.getSuperclasses();
for (auto i: kj::indices(superclasses)) {
auto superclass = superclasses[i];
ADD_ENTRY(SUPERCLASS, i, makeDep(
ADD_ENTRY(SUPERCLASS, i, makeDepSchema(
superclass.getId(), schema::Type::INTERFACE, schema::Node::INTERFACE,
superclass.getBrand(), scopeName, bindings).schema)
superclass.getBrand(), scopeName, bindings))
}
}
{
auto methods = interface.getMethods();
for (auto i: kj::indices(methods)) {
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.getParamBrand(), scopeName, bindings).schema)
ADD_ENTRY(METHOD_RESULTS, i, makeDep(
method.getParamBrand(), scopeName, bindings))
ADD_ENTRY(METHOD_RESULTS, i, makeDepSchema(
method.getResultStructType(), schema::Type::STRUCT, schema::Node::STRUCT,
method.getResultBrand(), scopeName, bindings).schema)
method.getResultBrand(), scopeName, bindings))
}
}
break;
......@@ -1601,7 +1616,7 @@ SchemaLoader::Impl::makeBrandedDependencies(
return copyDeduped(deps.asPtr());
}
_::RawBrandedSchema::Binding SchemaLoader::Impl::makeDep(
void SchemaLoader::Impl::makeDep(_::RawBrandedSchema::Binding& result,
schema::Type::Reader type, kj::StringPtr scopeName,
kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings) {
switch (type.which()) {
......@@ -1619,35 +1634,40 @@ _::RawBrandedSchema::Binding SchemaLoader::Impl::makeDep(
case schema::Type::FLOAT64:
case schema::Type::TEXT:
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: {
auto structType = type.getStruct();
return makeDep(structType.getTypeId(), schema::Type::STRUCT, schema::Node::STRUCT,
structType.getBrand(), scopeName, brandBindings);
makeDep(result, structType.getTypeId(), schema::Type::STRUCT, schema::Node::STRUCT,
structType.getBrand(), scopeName, brandBindings);
return;
}
case schema::Type::ENUM: {
auto enumType = type.getEnum();
return makeDep(enumType.getTypeId(), schema::Type::ENUM, schema::Node::ENUM,
enumType.getBrand(), scopeName, brandBindings);
makeDep(result, enumType.getTypeId(), schema::Type::ENUM, schema::Node::ENUM,
enumType.getBrand(), scopeName, brandBindings);
return;
}
case schema::Type::INTERFACE: {
auto interfaceType = type.getInterface();
return makeDep(interfaceType.getTypeId(), schema::Type::INTERFACE, schema::Node::INTERFACE,
interfaceType.getBrand(), scopeName, brandBindings);
makeDep(result, interfaceType.getTypeId(), schema::Type::INTERFACE, schema::Node::INTERFACE,
interfaceType.getBrand(), scopeName, brandBindings);
return;
}
case schema::Type::LIST: {
auto result = makeDep(type.getList().getElementType(), scopeName, brandBindings);
makeDep(result, type.getList().getElementType(), scopeName, brandBindings);
++result.listDepth;
return result;
return;
}
case schema::Type::ANY_POINTER: {
result.which = static_cast<uint8_t>(schema::Type::ANY_POINTER);
auto anyPointer = type.getAnyPointer();
switch (anyPointer.which()) {
case schema::Type::AnyPointer::UNCONSTRAINED:
return { static_cast<uint8_t>(type.which()), 0, nullptr };
return;
case schema::Type::AnyPointer::PARAMETER: {
auto param = anyPointer.getParameter();
uint64_t id = param.getScopeId();
......@@ -1659,26 +1679,32 @@ _::RawBrandedSchema::Binding SchemaLoader::Impl::makeDep(
if (scope.typeId == id) {
if (scope.isUnbound) {
// 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) {
// 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
// schemas.
break;
return;
} else {
return scope.bindings[index];
result = scope.bindings[index];
return;
}
}
}
return { static_cast<uint8_t>(schema::Type::ANY_POINTER), 0, 0, 0 };
return;
} else {
// 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:
return { static_cast<uint8_t>(schema::Type::ANY_POINTER), 0,
anyPointer.getImplicitMethodParameter().getParameterIndex() };
result.isImplicitParameter = true;
result.paramIndex = anyPointer.getImplicitMethodParameter().getParameterIndex();
return;
}
KJ_UNREACHABLE;
}
......@@ -1687,17 +1713,34 @@ _::RawBrandedSchema::Binding SchemaLoader::Impl::makeDep(
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,
schema::Brand::Reader brand, kj::StringPtr scopeName,
kj::Maybe<kj::ArrayPtr<const _::RawBrandedSchema::Scope>> brandBindings) {
const _::RawSchema* schema = loadEmpty(typeId,
kj::str("(unknown type; seen as dependency of ", scopeName, ")"),
expectedKind, true);
return _::RawBrandedSchema::Binding {
static_cast<uint8_t>(whichType), 0,
makeBranded(schema, brand, brandBindings)
};
result.which = static_cast<uint8_t>(whichType);
result.schema = 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>
......@@ -1899,7 +1942,7 @@ Schema SchemaLoader::get(uint64_t id, schema::Brand::Reader brand, Schema scope)
KJ_IF_MAYBE(result, tryGet(id, brand, scope)) {
return *result;
} 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 {
}
auto& binding = bindings[index];
Type result;
if (binding.which == (uint)schema::Type::ANY_POINTER) {
if (binding.scopeId != 0) {
return Type::BrandParameter { binding.scopeId, binding.paramIndex };
result = Type::BrandParameter { binding.scopeId, binding.paramIndex };
} else if (binding.isImplicitParameter) {
return Type::ImplicitParameter { binding.paramIndex };
result = Type::ImplicitParameter { binding.paramIndex };
} else {
return Type(schema::Type::ANY_POINTER, binding.listDepth, nullptr);
result = schema::Type::ANY_POINTER;
}
} else if (binding.schema == nullptr) {
// Builtin / primitive type.
return Type(static_cast<schema::Type::Which>(binding.which), binding.listDepth, nullptr);
result = static_cast<schema::Type::Which>(binding.which);
} else {
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:
bool operator==(const Type& other) const;
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:
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)), ...
......@@ -652,11 +658,12 @@ private:
};
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;
friend class Schema;
friend class ListSchema;
};
......@@ -826,11 +833,22 @@ struct ListSchema::FromImpl<List<T>> {
inline Type::Type(): baseType(schema::Type::VOID), listDepth(0), schema(nullptr) {}
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 &&
primitive != schema::Type::ENUM &&
primitive != schema::Type::INTERFACE &&
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)
......@@ -879,6 +897,12 @@ inline bool Type::isAnyPointer() const {
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
#endif // CAPNP_SCHEMA_H_
......@@ -32,10 +32,10 @@ namespace _ { // private
void inlineRequireFailure(const char* file, int line, const char* expectation,
const char* macroArgs, const char* message) {
if (message == nullptr) {
Debug::Fault f(file, line, 0, expectation, macroArgs);
Debug::Fault f(file, line, kj::Exception::Type::FAILED, expectation, macroArgs);
f.fatal();
} else {
Debug::Fault f(file, line, 0, expectation, macroArgs, message);
Debug::Fault f(file, line, kj::Exception::Type::FAILED, expectation, macroArgs, message);
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