diff options
Diffstat (limited to 'src/binaryen-c.cpp')
-rw-r--r-- | src/binaryen-c.cpp | 115 |
1 files changed, 92 insertions, 23 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 84612d0e4..2ea4bd87f 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -128,6 +128,7 @@ void traceNameOrNULL(const char* name, std::ostream& out = std::cout) { } } +std::map<BinaryenType, size_t> types; std::map<BinaryenExpressionRef, size_t> expressions; std::map<BinaryenFunctionRef, size_t> functions; std::map<BinaryenGlobalRef, size_t> globals; @@ -135,6 +136,71 @@ std::map<BinaryenEventRef, size_t> events; std::map<BinaryenExportRef, size_t> exports; std::map<RelooperBlockRef, size_t> relooperBlocks; +static bool isBasicAPIType(BinaryenType type) { + return type == BinaryenTypeAuto() || type <= Type::_last_value_type; +} + +static const char* basicAPITypeFunction(BinaryenType type) { + if (type == BinaryenTypeAuto()) { + return "BinaryenTypeAuto()"; + } + switch (type) { + case Type::none: + return "BinaryenTypeNone()"; + case Type::i32: + return "BinaryenTypeInt32()"; + case Type::i64: + return "BinaryenTypeInt64()"; + case Type::f32: + return "BinaryenTypeFloat32()"; + case Type::f64: + return "BinaryenTypeFloat64()"; + case Type::v128: + return "BinaryenTypeVec128()"; + case Type::funcref: + return "BinaryenTypeFuncref()"; + case Type::anyref: + return "BinaryenTypeAnyref()"; + case Type::nullref: + return "BinaryenTypeNullref()"; + case Type::exnref: + return "BinaryenTypeExnref()"; + case Type::unreachable: + return "BinaryenTypeUnreachable()"; + default: + WASM_UNREACHABLE("unexpected type"); + } +} + +struct TypeArg { + BinaryenType type; + TypeArg(BinaryenType type) : type(type){}; +}; + +std::ostream& operator<<(std::ostream& os, TypeArg t) { + if (isBasicAPIType(t.type)) { + return os << basicAPITypeFunction(t.type); + } else { + auto it = types.find(t.type); + assert(it != types.end()); + return os << "types[" << it->second << "]"; + } +} + +size_t noteType(BinaryenType type) { + // Basic types can be trivially rematerialized at every use + assert(!isBasicAPIType(type)); + // Unlike expressions, the same type can be created multiple times + auto it = types.find(type); + if (it != types.end()) { + return it->second; + } else { + auto id = types.size(); + types[type] = id; + return id; + } +} + size_t noteExpression(BinaryenExpressionRef expression) { auto id = expressions.size(); assert(expressions.find(expression) == expressions.end()); @@ -153,6 +219,11 @@ void printArg(std::ostream& setup, std::ostream& out, T arg) { } template<> +void printArg(std::ostream& setup, std::ostream& out, BinaryenType arg) { + out << TypeArg(arg); +} + +template<> void printArg(std::ostream& setup, std::ostream& out, BinaryenExpressionRef arg) { @@ -170,15 +241,6 @@ void printArg(std::ostream& setup, std::ostream& out, StringLit arg) { } template<> -void printArg(std::ostream& setup, std::ostream& out, BinaryenType arg) { - if (arg == BinaryenTypeAuto()) { - out << "BinaryenTypeAuto()"; - } else { - out << arg; - } -} - -template<> void printArg(std::ostream& setup, std::ostream& out, BinaryenLiteral arg) { switch (arg.type) { case Type::i32: @@ -308,7 +370,7 @@ BinaryenType BinaryenTypeAnyref(void) { return Type::anyref; } BinaryenType BinaryenTypeNullref(void) { return Type::nullref; } BinaryenType BinaryenTypeExnref(void) { return Type::exnref; } BinaryenType BinaryenTypeUnreachable(void) { return Type::unreachable; } -BinaryenType BinaryenTypeAuto(void) { return uint32_t(-1); } +BinaryenType BinaryenTypeAuto(void) { return uintptr_t(-1); } BinaryenType BinaryenTypeCreate(BinaryenType* types, uint32_t numTypes) { std::vector<Type> typeVec; @@ -318,19 +380,20 @@ BinaryenType BinaryenTypeCreate(BinaryenType* types, uint32_t numTypes) { } Type result(typeVec); - if (tracing) { + if (tracing && !isBasicAPIType(result.getID())) { + auto id = noteType(result.getID()); std::string array = getTemp(); std::cout << " {\n"; std::cout << " BinaryenType " << array << "[] = {"; for (size_t i = 0; i < numTypes; ++i) { - std::cout << uint32_t(types[i]); + std::cout << basicAPITypeFunction(types[i]); if (i < numTypes - 1) { std::cout << ", "; } } std::cout << "};\n"; - std::cout << " BinaryenTypeCreate(" << array << ", " << numTypes - << "); // " << result.getID() << "\n"; + std::cout << " types[" << id << "] = BinaryenTypeCreate(" << array + << ", " << numTypes << ");\n"; std::cout << " }\n"; } @@ -534,12 +597,14 @@ BinaryenModuleRef BinaryenModuleCreate(void) { void BinaryenModuleDispose(BinaryenModuleRef module) { if (tracing) { std::cout << " BinaryenModuleDispose(the_module);\n"; + std::cout << " types.clear();\n"; std::cout << " expressions.clear();\n"; std::cout << " functions.clear();\n"; std::cout << " globals.clear();\n"; std::cout << " events.clear();\n"; std::cout << " exports.clear();\n"; std::cout << " relooperBlocks.clear();\n"; + types.clear(); expressions.clear(); functions.clear(); globals.clear(); @@ -3230,7 +3295,7 @@ BinaryenFunctionRef BinaryenAddFunction(BinaryenModuleRef module, if (i > 0) { std::cout << ", "; } - std::cout << varTypes[i]; + std::cout << TypeArg(varTypes[i]); } if (numVarTypes == 0) { // ensure the array is not empty, otherwise a compiler error on VS @@ -3241,8 +3306,9 @@ BinaryenFunctionRef BinaryenAddFunction(BinaryenModuleRef module, functions[ret] = id; std::cout << " functions[" << id << "] = BinaryenAddFunction(the_module, \"" << name << "\", " - << params << ", " << results << ", varTypes, " << numVarTypes - << ", expressions[" << expressions[body] << "]);\n"; + << TypeArg(params) << ", " << TypeArg(results) << ", varTypes, " + << numVarTypes << ", expressions[" << expressions[body] + << "]);\n"; std::cout << " }\n"; } @@ -3314,7 +3380,7 @@ BinaryenGlobalRef BinaryenAddGlobal(BinaryenModuleRef module, auto id = globals.size(); globals[ret] = id; std::cout << " globals[" << id << "] = BinaryenAddGlobal(the_module, \"" - << name << "\", " << type << ", " << int(mutable_) + << name << "\", " << TypeArg(type) << ", " << int(mutable_) << ", expressions[" << expressions[init] << "]);\n"; } @@ -3352,7 +3418,8 @@ BinaryenEventRef BinaryenAddEvent(BinaryenModuleRef module, BinaryenType results) { if (tracing) { std::cout << " BinaryenAddEvent(the_module, \"" << name << "\", " - << attribute << ", " << params << ", " << results << ");\n"; + << attribute << ", " << TypeArg(params) << ", " + << TypeArg(results) << ");\n"; } auto* wasm = (Module*)module; @@ -3395,7 +3462,8 @@ void BinaryenAddFunctionImport(BinaryenModuleRef module, if (tracing) { std::cout << " BinaryenAddFunctionImport(the_module, \"" << internalName << "\", \"" << externalModuleName << "\", \"" << externalBaseName - << "\", " << params << ", " << results << ");\n"; + << "\", " << TypeArg(params) << ", " << TypeArg(results) + << ");\n"; } ret->name = internalName; @@ -3448,7 +3516,7 @@ void BinaryenAddGlobalImport(BinaryenModuleRef module, if (tracing) { std::cout << " BinaryenAddGlobalImport(the_module, \"" << internalName << "\", \"" << externalModuleName << "\", \"" << externalBaseName - << "\", " << globalType << ", " << mutable_ << ");\n"; + << "\", " << TypeArg(globalType) << ", " << mutable_ << ");\n"; } ret->name = internalName; @@ -3471,8 +3539,8 @@ void BinaryenAddEventImport(BinaryenModuleRef module, if (tracing) { std::cout << " BinaryenAddEventImport(the_module, \"" << internalName << "\", \"" << externalModuleName << "\", \"" << externalBaseName - << "\", " << attribute << ", " << params << ", " << results - << ");\n"; + << "\", " << attribute << ", " << TypeArg(params) << ", " + << TypeArg(results) << ");\n"; } ret->name = internalName; @@ -4895,6 +4963,7 @@ void BinaryenSetAPITracing(int on) { "#include <map>\n" "#include \"binaryen-c.h\"\n" "int main() {\n" + " std::map<size_t, BinaryenType> types;\n" " std::map<size_t, BinaryenExpressionRef> expressions;\n" " std::map<size_t, BinaryenFunctionRef> functions;\n" " std::map<size_t, BinaryenGlobalRef> globals;\n" |