summaryrefslogtreecommitdiff
path: root/src/binaryen-c.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/binaryen-c.cpp')
-rw-r--r--src/binaryen-c.cpp115
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"