#ifndef wasm_wasm_type_printing_h
#define wasm_wasm_type_printing_h
#include <cstddef>
#include <iostream>
#include <unordered_map>
#include "support/name.h"
#include "support/utilities.h"
#include "wasm-type.h"
#include "wasm.h"
namespace wasm {
template<typename Subclass> struct TypeNameGeneratorBase {
TypeNames getNames(HeapType type) {
static_assert(&TypeNameGeneratorBase<Subclass>::getNames !=
&Subclass::getNames,
"Derived class must implement getNames");
WASM_UNREACHABLE("Derived class must implement getNames");
}
HeapType::Printed operator()(HeapType type) {
return type.print(
[&](HeapType 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); });
}
};
struct DefaultTypeNameGenerator
: TypeNameGeneratorBase<DefaultTypeNameGenerator> {
size_t funcCount = 0;
size_t contCount = 0;
size_t structCount = 0;
size_t arrayCount = 0;
std::unordered_map<HeapType, TypeNames> nameCache;
TypeNames getNames(HeapType type);
};
template<typename FallbackGenerator = DefaultTypeNameGenerator>
struct IndexedTypeNameGenerator
: TypeNameGeneratorBase<IndexedTypeNameGenerator<FallbackGenerator>> {
DefaultTypeNameGenerator defaultGenerator;
FallbackGenerator& fallback;
std::unordered_map<HeapType, TypeNames> names;
template<typename T>
IndexedTypeNameGenerator(T& types,
FallbackGenerator& fallback,
const std::string& prefix = "")
: fallback(fallback) {
for (size_t i = 0; i < types.size(); ++i) {
names.insert({types[i], {prefix + std::to_string(i), {}}});
}
}
template<typename T>
IndexedTypeNameGenerator(T& types, const std::string& prefix = "")
: IndexedTypeNameGenerator(types, defaultGenerator, prefix) {}
TypeNames getNames(HeapType type) {
if (auto it = names.find(type); it != names.end()) {
return it->second;
} else {
return fallback.getNames(type);
}
}
};
template<typename T> IndexedTypeNameGenerator(T&) -> IndexedTypeNameGenerator<>;
template<typename FallbackGenerator = DefaultTypeNameGenerator>
struct ModuleTypeNameGenerator
: TypeNameGeneratorBase<ModuleTypeNameGenerator<FallbackGenerator>> {
const Module& wasm;
DefaultTypeNameGenerator defaultGenerator;
FallbackGenerator& fallback;
ModuleTypeNameGenerator(const Module& wasm, FallbackGenerator& fallback)
: wasm(wasm), fallback(fallback) {}
template<class T = FallbackGenerator>
ModuleTypeNameGenerator(
const Module& wasm,
std::enable_if_t<std::is_same_v<T, DefaultTypeNameGenerator>>* = nullptr)
: ModuleTypeNameGenerator(wasm, defaultGenerator) {}
TypeNames getNames(HeapType type) {
if (auto it = wasm.typeNames.find(type); it != wasm.typeNames.end()) {
return it->second;
}
return fallback.getNames(type);
}
};
ModuleTypeNameGenerator(const Module&) -> ModuleTypeNameGenerator<>;
}
#endif