Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/passes/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> {
}
}

TypeNames getNames(HeapType type) {
TypeNames getNames(HeapTypeDef type) {
if (parent.currModule) {
if (auto it = parent.currModule->typeNames.find(type);
it != parent.currModule->typeNames.end()) {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/wasm-fuzz-types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ void Fuzzer::printTypes(const std::vector<HeapType>& types) {
std::cout << "Built " << types.size() << " types:\n";
struct FatalTypeNameGenerator
: TypeNameGeneratorBase<FatalTypeNameGenerator> {
TypeNames getNames(HeapType type) {
TypeNames getNames(HeapTypeDef type) {
Fatal() << "trying to print unknown heap type";
}
} fatalGenerator;
Expand Down
39 changes: 26 additions & 13 deletions src/wasm-type-printing.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,32 @@ namespace wasm {
// ability to use the generator as a function to print Types and HeapTypes to
// streams.
template<typename Subclass> struct TypeNameGeneratorBase {
TypeNames getNames(HeapType type) {
static_assert(&TypeNameGeneratorBase<Subclass>::getNames !=
&Subclass::getNames,
"Derived class must implement getNames");
TypeNameGeneratorBase() { assertValidUsage(); }

TypeNames getNames(HeapTypeDef type) {
WASM_UNREACHABLE("Derived class must implement getNames");
}
HeapType::Printed operator()(HeapType type) {
return type.print(
[&](HeapType ht) { return static_cast<Subclass*>(this)->getNames(ht); });
HeapType::Printed operator()(HeapTypeDef type) {
return type.print([&](HeapTypeDef ht) {
return static_cast<Subclass*>(this)->getNames(ht);
});
}
Type::Printed operator()(Type type) {
return type.print(
[&](HeapType ht) { return static_cast<Subclass*>(this)->getNames(ht); });
return type.print([&](HeapTypeDef ht) {
return static_cast<Subclass*>(this)->getNames(ht);
});
}

private:
constexpr void assertValidUsage() {
#if !defined(__GNUC__) || __GNUC__ >= 14
// Check that the subclass provides `getNames` with the correct type.
using Self = TypeNameGeneratorBase<Subclass>;
static_assert(
static_cast<TypeNames (Self::*)(HeapTypeDef)>(&Self::getNames) !=
static_cast<TypeNames (Self::*)(HeapTypeDef)>(&Subclass::getNames),
"Derived class must implement getNames");
#endif
}
};

Expand All @@ -60,7 +73,7 @@ struct DefaultTypeNameGenerator
// Cached names for types that have already been seen.
std::unordered_map<HeapType, TypeNames> nameCache;

TypeNames getNames(HeapType type);
TypeNames getNames(HeapTypeDef type);
};

// Generates names based on the indices of types in some collection, falling
Expand All @@ -71,7 +84,7 @@ struct IndexedTypeNameGenerator
: TypeNameGeneratorBase<IndexedTypeNameGenerator<FallbackGenerator>> {
DefaultTypeNameGenerator defaultGenerator;
FallbackGenerator& fallback;
std::unordered_map<HeapType, TypeNames> names;
std::unordered_map<HeapTypeDef, TypeNames> names;

template<typename T>
IndexedTypeNameGenerator(T& types,
Expand All @@ -86,7 +99,7 @@ struct IndexedTypeNameGenerator
IndexedTypeNameGenerator(T& types, const std::string& prefix = "")
: IndexedTypeNameGenerator(types, defaultGenerator, prefix) {}

TypeNames getNames(HeapType type) {
TypeNames getNames(HeapTypeDef type) {
if (auto it = names.find(type); it != names.end()) {
return it->second;
} else {
Expand Down Expand Up @@ -117,7 +130,7 @@ struct ModuleTypeNameGenerator
std::enable_if_t<std::is_same_v<T, DefaultTypeNameGenerator>>* = nullptr)
: ModuleTypeNameGenerator(wasm, defaultGenerator) {}

TypeNames getNames(HeapType type) {
TypeNames getNames(HeapTypeDef type) {
if (auto it = wasm.typeNames.find(type); it != wasm.typeNames.end()) {
return it->second;
}
Expand Down
17 changes: 16 additions & 1 deletion src/wasm-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ void destroyAllTypesForTestingPurposesOnly();
// data.
class Type;
class HeapType;
class HeapTypeDef;
class RecGroup;
struct Signature;
struct Continuation;
Expand All @@ -73,7 +74,7 @@ struct TypeNames {
};

// Used to generate HeapType names.
using HeapTypeNameGenerator = std::function<TypeNames(HeapType)>;
using HeapTypeNameGenerator = std::function<TypeNames(HeapTypeDef)>;

// The type used for interning IDs in the public interfaces of Type and
// HeapType.
Expand Down Expand Up @@ -294,6 +295,16 @@ class HeapType {
std::string toString() const;
};

// Like `HeapType`, but used to represent heap type definitions and abstract
// heap types rather than arbitrary heap types. Use this whenever it would be a
// category error to use an exact heap type.
class HeapTypeDef : public HeapType {
public:
// Allow implicit conversions from HeapType.
constexpr HeapTypeDef(HeapType type) : HeapType(type.with(Inexact)) {}
constexpr HeapTypeDef() = default;
};

class Type {
// The `id` uniquely represents each type, so type equality is just a
// comparison of the ids. The basic types are packed at the bottom of the
Expand Down Expand Up @@ -1007,6 +1018,10 @@ template<> class hash<wasm::HeapType> {
public:
size_t operator()(const wasm::HeapType&) const;
};
template<> class hash<wasm::HeapTypeDef> {
public:
size_t operator()(const wasm::HeapTypeDef&) const;
};
template<> class hash<wasm::RecGroup> {
public:
size_t operator()(const wasm::RecGroup&) const;
Expand Down
4 changes: 2 additions & 2 deletions src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -2415,8 +2415,8 @@ class Module {
// Module name, if specified. Serves a documentary role only.
Name name;

std::unordered_map<HeapType, TypeNames> typeNames;
std::unordered_map<HeapType, Index> typeIndices;
std::unordered_map<HeapTypeDef, TypeNames> typeNames;
std::unordered_map<HeapTypeDef, Index> typeIndices;

MixedArena allocator;

Expand Down
6 changes: 5 additions & 1 deletion src/wasm/wasm-type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1369,7 +1369,7 @@ size_t RecGroup::size() const {
}
}

TypeNames DefaultTypeNameGenerator::getNames(HeapType type) {
TypeNames DefaultTypeNameGenerator::getNames(HeapTypeDef type) {
auto [it, inserted] = nameCache.insert({type, {}});
if (inserted) {
// Generate a new name for this type we have not previously seen.
Expand Down Expand Up @@ -2768,6 +2768,10 @@ size_t hash<wasm::HeapType>::operator()(const wasm::HeapType& heapType) const {
return wasm::hash(heapType.getID());
}

size_t hash<wasm::HeapTypeDef>::operator()(const wasm::HeapTypeDef& def) const {
return wasm::hash(def.getID());
}

size_t hash<wasm::RecGroup>::operator()(const wasm::RecGroup& group) const {
return wasm::hash(group.getID());
}
Expand Down