diff options
-rwxr-xr-x | auto_update_tests.py | 37 | ||||
-rwxr-xr-x | check.py | 34 | ||||
-rwxr-xr-x | scripts/clean_c_api_trace.py | 23 | ||||
-rw-r--r-- | src/binaryen-c.cpp | 438 | ||||
-rw-r--r-- | src/binaryen-c.h | 15 | ||||
-rw-r--r-- | test/example/c-api-hello-world.c | 2 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.c | 9 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.txt | 696 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.txt.txt | 363 |
9 files changed, 1583 insertions, 34 deletions
diff --git a/auto_update_tests.py b/auto_update_tests.py index 0a42d8357..8e33e1517 100755 --- a/auto_update_tests.py +++ b/auto_update_tests.py @@ -96,32 +96,47 @@ print '\n[ checking example testcases... ]\n' for t in sorted(os.listdir(os.path.join('test', 'example'))): output_file = os.path.join('bin', 'example') cmd = ['-Isrc', '-g', '-lasmjs', '-lsupport', '-Llib/.', '-pthread', '-o', output_file] - if t.endswith('.cpp'): - cmd = [os.path.join('test', 'example', t), - os.path.join('src', 'passes', 'pass.cpp'), - os.path.join('src', 'wasm.cpp'), - os.path.join('src', 'passes', 'Print.cpp')] + cmd - elif t.endswith('.c'): + if t.endswith('.txt'): + # check if there is a trace in the file, if so, we should build it + out = subprocess.Popen([os.path.join('scripts', 'clean_c_api_trace.py'), os.path.join('test', 'example', t)], stdout=subprocess.PIPE).communicate()[0] + if len(out) == 0: + print ' (no trace in ', t, ')' + continue + print ' (will check trace in ', t, ')' + src = 'trace.cpp' + open(src, 'w').write(out) + expected = os.path.join('test', 'example', t + '.txt') + else: + src = os.path.join('test', 'example', t) + expected = os.path.join('test', 'example', '.'.join(t.split('.')[:-1]) + '.txt') + if src.endswith(('.c', '.cpp')): # build the C file separately extra = [os.environ.get('CC') or 'gcc', - os.path.join('test', 'example', t), '-c', '-o', 'example.o', + src, '-c', '-o', 'example.o', '-Isrc', '-g', '-Llib/.', '-pthread'] - print ' '.join(extra) + print 'build: ', ' '.join(extra) subprocess.check_call(extra) # Link against the binaryen C library DSO, using an executable-relative rpath cmd = ['example.o', '-lbinaryen'] + cmd + ['-Wl,-rpath=$ORIGIN/../lib'] else: continue + print ' ', t, src, expected if os.environ.get('COMPILER_FLAGS'): for f in os.environ.get('COMPILER_FLAGS').split(' '): cmd.append(f) cmd = [os.environ.get('CXX') or 'g++', '-std=c++11'] + cmd - print ' '.join(cmd) try: + print 'link: ', ' '.join(cmd) subprocess.check_call(cmd) - actual = subprocess.Popen([output_file], stdout=subprocess.PIPE).communicate()[0] - open(os.path.join('test', 'example', '.'.join(t.split('.')[:-1]) + '.txt'), 'w').write(actual) + print 'run...', output_file + proc = subprocess.Popen([output_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + actual, err = proc.communicate() + assert proc.returncode == 0, [proc.returncode, actual, err] + open(expected, 'w').write(actual) finally: os.remove(output_file) + if sys.platform == 'darwin': + # Also removes debug directory produced on Mac OS + shutil.rmtree(output_file + '.dSYM') print '\n[ success! ]' @@ -665,33 +665,49 @@ print '\n[ checking example testcases... ]\n' for t in sorted(os.listdir(os.path.join('test', 'example'))): output_file = os.path.join('bin', 'example') cmd = ['-Isrc', '-g', '-lasmjs', '-lsupport', '-Llib/.', '-pthread', '-o', output_file] - if t.endswith('.c'): + if t.endswith('.txt'): + # check if there is a trace in the file, if so, we should build it + out = subprocess.Popen([os.path.join('scripts', 'clean_c_api_trace.py'), os.path.join('test', 'example', t)], stdout=subprocess.PIPE).communicate()[0] + if len(out) == 0: + print ' (no trace in ', t, ')' + continue + print ' (will check trace in ', t, ')' + src = 'trace.cpp' + open(src, 'w').write(out) + expected = os.path.join('test', 'example', t + '.txt') + else: + src = os.path.join('test', 'example', t) + expected = os.path.join('test', 'example', '.'.join(t.split('.')[:-1]) + '.txt') + if src.endswith(('.c', '.cpp')): # build the C file separately extra = [os.environ.get('CC') or 'gcc', - os.path.join('test', 'example', t), '-c', '-o', 'example.o', + src, '-c', '-o', 'example.o', '-Isrc', '-g', '-Llib/.', '-pthread'] - print ' '.join(extra) + print 'build: ', ' '.join(extra) subprocess.check_call(extra) # Link against the binaryen C library DSO, using an executable-relative rpath - cmd = ['example.o', '-lbinaryen'] + cmd - if sys.platform == 'linux' or sys.platform == 'linux2': - cmd = cmd + ['-Wl,-rpath=$ORIGIN/../lib'] + cmd = ['example.o', '-lbinaryen'] + cmd + ['-Wl,-rpath=$ORIGIN/../lib'] else: continue + print ' ', t, src, expected if os.environ.get('COMPILER_FLAGS'): for f in os.environ.get('COMPILER_FLAGS').split(' '): cmd.append(f) cmd = [os.environ.get('CXX') or 'g++', '-std=c++11'] + cmd - print ' '.join(cmd) try: + print 'link: ', ' '.join(cmd) subprocess.check_call(cmd) - actual = subprocess.Popen([output_file], stdout=subprocess.PIPE).communicate()[0] - expected = open(os.path.join('test', 'example', '.'.join(t.split('.')[:-1]) + '.txt')).read() + print 'run...', output_file + proc = subprocess.Popen([output_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + actual, err = proc.communicate() + assert proc.returncode == 0, [proc.returncode, actual, err] finally: os.remove(output_file) if sys.platform == 'darwin': # Also removes debug directory produced on Mac OS shutil.rmtree(output_file + '.dSYM') + + expected = open(expected).read() if actual != expected: fail(actual, expected) diff --git a/scripts/clean_c_api_trace.py b/scripts/clean_c_api_trace.py new file mode 100755 index 000000000..efe8baa43 --- /dev/null +++ b/scripts/clean_c_api_trace.py @@ -0,0 +1,23 @@ +#! /usr/bin/env python + +''' +Cleans up output from the C api, makes a runnable C file +''' + +import sys + +trace = open(sys.argv[1]).read() + +start = trace.find('// beginning a Binaryen API trace') +if start >= 0: + trace = trace[start:] + + while 1: + start = trace.find('\n(') + if start < 0: + break + end = trace.find('\n)', start + 1) + assert end > 0 + trace = trace[:start] + trace[end + 2:] + + print trace diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index abc89c88e..20fefece0 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -60,6 +60,21 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) { } } +// Tracing support + +static int tracing = 0; + +void traceNameOrNULL(const char *name) { + if (name) std::cout << "\"" << name << "\""; + else std::cout << "NULL"; +} + +std::map<BinaryenFunctionTypeRef, size_t> functionTypes; +std::map<BinaryenExpressionRef, size_t> expressions; +std::map<BinaryenFunctionRef, size_t> functions; +std::map<RelooperBlockRef, size_t> relooperBlocks; + + extern "C" { // @@ -76,8 +91,34 @@ BinaryenType BinaryenFloat64(void) { return f64; } // Modules -BinaryenModuleRef BinaryenModuleCreate(void) { return new Module(); } -void BinaryenModuleDispose(BinaryenModuleRef module) { delete (Module*)module; } +BinaryenModuleRef BinaryenModuleCreate(void) { + if (tracing) { + std::cout << "// beginning a Binaryen API trace\n"; + std::cout << "#include <math.h>\n"; + std::cout << "#include <map>\n"; + std::cout << "#include \"src/binaryen-c.h\"\n"; + std::cout << "int main() {\n"; + std::cout << " std::map<size_t, BinaryenFunctionTypeRef> functionTypes;\n"; + std::cout << " std::map<size_t, BinaryenExpressionRef> expressions;\n"; + std::cout << " expressions[size_t(NULL)] = BinaryenExpressionRef(NULL);\n"; + std::cout << " std::map<size_t, BinaryenFunctionRef> functions;\n"; + std::cout << " std::map<size_t, RelooperBlockRef> relooperBlocks;\n"; + std::cout << " BinaryenModuleRef the_module = BinaryenModuleCreate();\n"; + std::cout << " RelooperRef the_relooper = NULL;\n"; + expressions[NULL] = 0; + } + + return new Module(); +} +void BinaryenModuleDispose(BinaryenModuleRef module) { + if (tracing) { + std::cout << " BinaryenModuleDispose(the_module);\n"; + std::cout << " return 0;\n"; + std::cout << "}\n"; + } + + delete (Module*)module; +} // Function types @@ -98,6 +139,22 @@ BinaryenFunctionTypeRef BinaryenAddFunctionType(BinaryenModuleRef module, const wasm->addFunctionType(ret); } + if (tracing) { + std::cout << " {\n"; + std::cout << " BinaryenIndex paramTypes[] = { "; + for (BinaryenIndex i = 0; i < numParams; i++) { + if (i > 0) std::cout << ", "; + std::cout << paramTypes[i]; + } + std::cout << " };\n"; + size_t id = functionTypes.size(); + std::cout << " functionTypes[" << id << "] = BinaryenAddFunctionType(the_module, "; + functionTypes[ret] = id; + traceNameOrNULL(name); + std::cout << ", " << result << ", paramTypes, sizeof(paramTypes) / sizeof(BinaryenIndex));\n"; + std::cout << " }\n"; + } + return ret; } @@ -245,6 +302,23 @@ BinaryenExpressionRef BinaryenBlock(BinaryenModuleRef module, const char* name, ret->list.push_back((Expression*)children[i]); } ret->finalize(); + + if (tracing) { + std::cout << " {\n"; + std::cout << " BinaryenExpressionRef children[] = { "; + for (BinaryenIndex i = 0; i < numChildren; i++) { + if (i > 0) std::cout << ", "; + std::cout << "expressions[" << expressions[children[i]] << "]"; + } + std::cout << " };\n"; + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenBlock(the_module, "; + traceNameOrNULL(name); + std::cout << ", children, sizeof(children) / sizeof(BinaryenExpressionRef));\n"; + std::cout << " }\n"; + } + return static_cast<Expression*>(ret); } BinaryenExpressionRef BinaryenIf(BinaryenModuleRef module, BinaryenExpressionRef condition, BinaryenExpressionRef ifTrue, BinaryenExpressionRef ifFalse) { @@ -253,17 +327,59 @@ BinaryenExpressionRef BinaryenIf(BinaryenModuleRef module, BinaryenExpressionRef ret->ifTrue = (Expression*)ifTrue; ret->ifFalse = (Expression*)ifFalse; ret->finalize(); + + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenIf(the_module, expressions[" << expressions[condition] << "], expressions[" << expressions[ifTrue] << "], expressions[" << expressions[ifFalse] << "]);\n"; + } + return static_cast<Expression*>(ret); } BinaryenExpressionRef BinaryenLoop(BinaryenModuleRef module, const char* out, const char* in, BinaryenExpressionRef body) { if (out && !in) abort(); - return static_cast<Expression*>(Builder(*((Module*)module)).makeLoop(out ? Name(out) : Name(), in ? Name(in) : Name(), (Expression*)body)); + auto* ret = Builder(*((Module*)module)).makeLoop(out ? Name(out) : Name(), in ? Name(in) : Name(), (Expression*)body); + + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenLoop(the_module, "; + traceNameOrNULL(out); + std::cout << ", "; + traceNameOrNULL(in); + std::cout << ", expressions[" << expressions[body] << "]);\n"; + } + + return static_cast<Expression*>(ret); } BinaryenExpressionRef BinaryenBreak(BinaryenModuleRef module, const char* name, BinaryenExpressionRef condition, BinaryenExpressionRef value) { - return static_cast<Expression*>(Builder(*((Module*)module)).makeBreak(name, (Expression*)value, (Expression*)condition)); + auto* ret = Builder(*((Module*)module)).makeBreak(name, (Expression*)value, (Expression*)condition); + + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenBreak(the_module, \"" << name << "\", expressions[" << expressions[condition] << "], expressions[" << expressions[value] << "]);\n"; + } + + return static_cast<Expression*>(ret); } BinaryenExpressionRef BinaryenSwitch(BinaryenModuleRef module, const char **names, BinaryenIndex numNames, const char* defaultName, BinaryenExpressionRef condition, BinaryenExpressionRef value) { auto* ret = ((Module*)module)->allocator.alloc<Switch>(); + + if (tracing) { + std::cout << " {\n"; + std::cout << " const char* names[] = { "; + for (BinaryenIndex i = 0; i < numNames; i++) { + if (i > 0) std::cout << ", "; + std::cout << "\"" << names[i] << "\""; + } + std::cout << " };\n"; + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenSwitch(the_module, names, sizeof(names) / sizeof(const char *), \"" << defaultName << "\", expressions[" << expressions[condition] << "], expressions[" << expressions[value] << "]);\n"; + std::cout << " }\n"; + } + for (BinaryenIndex i = 0; i < numNames; i++) { ret->targets.push_back(names[i]); } @@ -275,6 +391,21 @@ BinaryenExpressionRef BinaryenSwitch(BinaryenModuleRef module, const char **name } BinaryenExpressionRef BinaryenCall(BinaryenModuleRef module, const char *target, BinaryenExpressionRef* operands, BinaryenIndex numOperands, BinaryenType returnType) { auto* ret = ((Module*)module)->allocator.alloc<Call>(); + + if (tracing) { + std::cout << " {\n"; + std::cout << " BinaryenExpressionRef operands[] = { "; + for (BinaryenIndex i = 0; i < numOperands; i++) { + if (i > 0) std::cout << ", "; + std::cout << "expressions[" << expressions[operands[i]] << "]"; + } + std::cout << " };\n"; + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenCall(the_module, \"" << target << "\", operands, " << numOperands << ", " << returnType << ");\n"; + std::cout << " }\n"; + } + ret->target = target; for (BinaryenIndex i = 0; i < numOperands; i++) { ret->operands.push_back((Expression*)operands[i]); @@ -285,6 +416,21 @@ BinaryenExpressionRef BinaryenCall(BinaryenModuleRef module, const char *target, } BinaryenExpressionRef BinaryenCallImport(BinaryenModuleRef module, const char *target, BinaryenExpressionRef* operands, BinaryenIndex numOperands, BinaryenType returnType) { auto* ret = ((Module*)module)->allocator.alloc<CallImport>(); + + if (tracing) { + std::cout << " {\n"; + std::cout << " BinaryenExpressionRef operands[] = { "; + for (BinaryenIndex i = 0; i < numOperands; i++) { + if (i > 0) std::cout << ", "; + std::cout << "expressions[" << expressions[operands[i]] << "]"; + } + std::cout << " };\n"; + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenCallImport(the_module, \"" << target << "\", operands, " << numOperands << ", " << returnType << ");\n"; + std::cout << " }\n"; + } + ret->target = target; for (BinaryenIndex i = 0; i < numOperands; i++) { ret->operands.push_back((Expression*)operands[i]); @@ -296,6 +442,21 @@ BinaryenExpressionRef BinaryenCallImport(BinaryenModuleRef module, const char *t BinaryenExpressionRef BinaryenCallIndirect(BinaryenModuleRef module, BinaryenExpressionRef target, BinaryenExpressionRef* operands, BinaryenIndex numOperands, const char* type) { auto* wasm = (Module*)module; auto* ret = wasm->allocator.alloc<CallIndirect>(); + + if (tracing) { + std::cout << " {\n"; + std::cout << " BinaryenExpressionRef operands[] = { "; + for (BinaryenIndex i = 0; i < numOperands; i++) { + if (i > 0) std::cout << ", "; + std::cout << "expressions[" << expressions[operands[i]] << "]"; + } + std::cout << " };\n"; + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenCallIndirect(the_module, expressions[" << expressions[target] << "], operands, " << numOperands << ", \"" << type << "\");\n"; + std::cout << " }\n"; + } + ret->target = (Expression*)target; for (BinaryenIndex i = 0; i < numOperands; i++) { ret->operands.push_back((Expression*)operands[i]); @@ -306,6 +467,13 @@ BinaryenExpressionRef BinaryenCallIndirect(BinaryenModuleRef module, BinaryenExp } BinaryenExpressionRef BinaryenGetLocal(BinaryenModuleRef module, BinaryenIndex index, BinaryenType type) { auto* ret = ((Module*)module)->allocator.alloc<GetLocal>(); + + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenGetLocal(the_module, " << index << ", " << type << ");\n"; + } + ret->index = index; ret->type = WasmType(type); ret->finalize(); @@ -313,6 +481,13 @@ BinaryenExpressionRef BinaryenGetLocal(BinaryenModuleRef module, BinaryenIndex i } BinaryenExpressionRef BinaryenSetLocal(BinaryenModuleRef module, BinaryenIndex index, BinaryenExpressionRef value) { auto* ret = ((Module*)module)->allocator.alloc<SetLocal>(); + + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenSetLocal(the_module, " << index << ", expressions[" << expressions[value] << "]);\n"; + } + ret->index = index; ret->value = (Expression*)value; ret->finalize(); @@ -320,6 +495,13 @@ BinaryenExpressionRef BinaryenSetLocal(BinaryenModuleRef module, BinaryenIndex i } BinaryenExpressionRef BinaryenLoad(BinaryenModuleRef module, uint32_t bytes, int8_t signed_, uint32_t offset, uint32_t align, BinaryenType type, BinaryenExpressionRef ptr) { auto* ret = ((Module*)module)->allocator.alloc<Load>(); + + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenLoad(the_module, " << bytes << ", " << int(signed_) << ", " << offset << ", " << align << ", " << type << ", expressions[" << expressions[ptr] << "]);\n"; + } + ret->bytes = bytes; ret->signed_ = !!signed_; ret->offset = offset; @@ -331,6 +513,13 @@ BinaryenExpressionRef BinaryenLoad(BinaryenModuleRef module, uint32_t bytes, int } BinaryenExpressionRef BinaryenStore(BinaryenModuleRef module, uint32_t bytes, uint32_t offset, uint32_t align, BinaryenExpressionRef ptr, BinaryenExpressionRef value) { auto* ret = ((Module*)module)->allocator.alloc<Store>(); + + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenStore(the_module, " << bytes << ", " << offset << ", " << align << ", expressions[" << expressions[ptr] << "], expressions[" << expressions[value] << "]);\n"; + } + ret->bytes = bytes; ret->offset = offset; ret->align = align ? align : bytes; @@ -340,16 +529,63 @@ BinaryenExpressionRef BinaryenStore(BinaryenModuleRef module, uint32_t bytes, ui return static_cast<Expression*>(ret); } BinaryenExpressionRef BinaryenConst(BinaryenModuleRef module, BinaryenLiteral value) { - return static_cast<Expression*>(Builder(*((Module*)module)).makeConst(fromBinaryenLiteral(value))); + auto* ret = Builder(*((Module*)module)).makeConst(fromBinaryenLiteral(value)); + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + switch (value.type) { + case WasmType::i32: std::cout << " expressions[" << id << "] = BinaryenConst(the_module, BinaryenLiteralInt32(" << value.i32 << "));\n"; break; + case WasmType::i64: std::cout << " expressions[" << id << "] = BinaryenConst(the_module, BinaryenLiteralInt64(" << value.i64 << "));\n"; break; + case WasmType::f32: { + std::cout << " expressions[" << id << "] = BinaryenConst(the_module, BinaryenLiteralFloat32("; + if (std::isnan(value.f32)) std::cout << "NAN"; + else std::cout << value.f32; + std::cout << "));\n"; + break; + } + case WasmType::f64: { + std::cout << " expressions[" << id << "] = BinaryenConst(the_module, BinaryenLiteralFloat64("; + if (std::isnan(value.f64)) std::cout << "NAN"; + else std::cout << value.f64; + std::cout << "));\n"; + break; + } + default: WASM_UNREACHABLE(); + } + } + return static_cast<Expression*>(ret); } BinaryenExpressionRef BinaryenUnary(BinaryenModuleRef module, BinaryenOp op, BinaryenExpressionRef value) { - return static_cast<Expression*>(Builder(*((Module*)module)).makeUnary(UnaryOp(op), (Expression*)value)); + auto* ret = Builder(*((Module*)module)).makeUnary(UnaryOp(op), (Expression*)value); + + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenUnary(the_module, " << op << ", expressions[" << expressions[value] << "]);\n"; + } + + return static_cast<Expression*>(ret); } BinaryenExpressionRef BinaryenBinary(BinaryenModuleRef module, BinaryenOp op, BinaryenExpressionRef left, BinaryenExpressionRef right) { - return static_cast<Expression*>(Builder(*((Module*)module)).makeBinary(BinaryOp(op), (Expression*)left, (Expression*)right)); + auto* ret = Builder(*((Module*)module)).makeBinary(BinaryOp(op), (Expression*)left, (Expression*)right); + + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenBinary(the_module, " << op << ", expressions[" << expressions[left] << "], expressions[" << expressions[right] << "]);\n"; + } + + return static_cast<Expression*>(ret); } BinaryenExpressionRef BinaryenSelect(BinaryenModuleRef module, BinaryenExpressionRef condition, BinaryenExpressionRef ifTrue, BinaryenExpressionRef ifFalse) { auto* ret = ((Module*)module)->allocator.alloc<Select>(); + + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenSelect(the_module, expressions[" << expressions[condition] << "], expressions[" << expressions[ifTrue] << "], expressions[" << expressions[ifFalse] << "]);\n"; + } + ret->condition = (Expression*)condition; ret->ifTrue = (Expression*)ifTrue; ret->ifFalse = (Expression*)ifFalse; @@ -357,9 +593,21 @@ BinaryenExpressionRef BinaryenSelect(BinaryenModuleRef module, BinaryenExpressio return static_cast<Expression*>(ret); } BinaryenExpressionRef BinaryenReturn(BinaryenModuleRef module, BinaryenExpressionRef value) { - return static_cast<Expression*>(Builder(*((Module*)module)).makeReturn((Expression*)value)); + auto* ret = Builder(*((Module*)module)).makeReturn((Expression*)value); + + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenReturn(the_module, expressions[" << expressions[value] << "]);\n"; + } + + return static_cast<Expression*>(ret); } BinaryenExpressionRef BinaryenHost(BinaryenModuleRef module, BinaryenOp op, const char* name, BinaryenExpressionRef* operands, BinaryenIndex numOperands) { + if (tracing) { + std::cout << " TODO: host...\n"; + } + auto* ret = ((Module*)module)->allocator.alloc<Host>(); ret->op = HostOp(op); if (name) ret->nameOperand = name; @@ -370,13 +618,33 @@ BinaryenExpressionRef BinaryenHost(BinaryenModuleRef module, BinaryenOp op, cons return static_cast<Expression*>(ret); } BinaryenExpressionRef BinaryenNop(BinaryenModuleRef module) { - return static_cast<Expression*>(((Module*)module)->allocator.alloc<Nop>()); + auto* ret = ((Module*)module)->allocator.alloc<Nop>(); + + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenNop(the_module);\n"; + } + + return static_cast<Expression*>(ret); } BinaryenExpressionRef BinaryenUnreachable(BinaryenModuleRef module) { - return static_cast<Expression*>(((Module*)module)->allocator.alloc<Unreachable>()); + auto* ret = ((Module*)module)->allocator.alloc<Unreachable>(); + + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = BinaryenUnreachable(the_module);\n"; + } + + return static_cast<Expression*>(ret); } void BinaryenExpressionPrint(BinaryenExpressionRef expr) { + if (tracing) { + std::cout << " BinaryenExpressionPrint(expressions[" << expressions[expr] << "]);\n"; + } + WasmPrinter::printExpression((Expression*)expr, std::cout); std::cout << '\n'; } @@ -386,6 +654,21 @@ void BinaryenExpressionPrint(BinaryenExpressionRef expr) { BinaryenFunctionRef BinaryenAddFunction(BinaryenModuleRef module, const char* name, BinaryenFunctionTypeRef type, BinaryenType* varTypes, BinaryenIndex numVarTypes, BinaryenExpressionRef body) { auto* wasm = (Module*)module; auto* ret = new Function; + + if (tracing) { + std::cout << " {\n"; + std::cout << " BinaryenType varTypes[] = { "; + for (BinaryenIndex i = 0; i < numVarTypes; i++) { + if (i > 0) std::cout << ", "; + std::cout << varTypes[i]; + } + std::cout << " };\n"; + auto id = functions.size(); + functions[ret] = id; + std::cout << " functions[" << id << "] = BinaryenAddFunction(the_module, \"" << name << "\", functionTypes[" << functionTypes[type] << "], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[" << expressions[body] << "]);\n"; + std::cout << " }\n"; + } + ret->name = name; ret->type = ((FunctionType*)type)->name; auto* functionType = wasm->getFunctionType(ret->type); @@ -410,6 +693,10 @@ BinaryenFunctionRef BinaryenAddFunction(BinaryenModuleRef module, const char* na // Imports BinaryenImportRef BinaryenAddImport(BinaryenModuleRef module, const char* internalName, const char* externalModuleName, const char *externalBaseName, BinaryenFunctionTypeRef type) { + if (tracing) { + std::cout << " BinaryenAddImport(the_module, \"" << internalName << "\", \"" << externalModuleName << "\", \"" << externalBaseName << "\", functionTypes[" << functionTypes[type] << "]);\n"; + } + auto* wasm = (Module*)module; auto* ret = new Import(); ret->name = internalName; @@ -423,6 +710,10 @@ BinaryenImportRef BinaryenAddImport(BinaryenModuleRef module, const char* intern // Exports BinaryenExportRef BinaryenAddExport(BinaryenModuleRef module, const char* internalName, const char* externalName) { + if (tracing) { + std::cout << " BinaryenAddExport(the_module, \"" << internalName << "\", \"" << externalName << "\");\n"; + } + auto* wasm = (Module*)module; auto* ret = new Export(); ret->value = internalName; @@ -433,16 +724,62 @@ BinaryenExportRef BinaryenAddExport(BinaryenModuleRef module, const char* intern // Function table. One per module -void BinaryenSetFunctionTable(BinaryenModuleRef module, BinaryenFunctionRef* functions, BinaryenIndex numFunctions) { +void BinaryenSetFunctionTable(BinaryenModuleRef module, BinaryenFunctionRef* funcs, BinaryenIndex numFuncs) { + if (tracing) { + std::cout << " {\n"; + std::cout << " BinaryenFunctionRef funcs[] = { "; + for (BinaryenIndex i = 0; i < numFuncs; i++) { + if (i > 0) std::cout << ", "; + std::cout << "functions[" << functions[funcs[i]] << "]"; + } + std::cout << " };\n"; + std::cout << " BinaryenSetFunctionTable(the_module, funcs, sizeof(funcs) / sizeof(BinaryenFunctionRef));\n"; + std::cout << " }\n"; + } + auto* wasm = (Module*)module; - for (BinaryenIndex i = 0; i < numFunctions; i++) { - wasm->table.names.push_back(((Function*)functions[i])->name); + for (BinaryenIndex i = 0; i < numFuncs; i++) { + wasm->table.names.push_back(((Function*)funcs[i])->name); } } // Memory. One per module void BinaryenSetMemory(BinaryenModuleRef module, BinaryenIndex initial, BinaryenIndex maximum, const char* exportName, const char **segments, BinaryenIndex* segmentOffsets, BinaryenIndex* segmentSizes, BinaryenIndex numSegments) { + if (tracing) { + std::cout << " {\n"; + for (BinaryenIndex i = 0; i < numSegments; i++) { + std::cout << " const char segment" << i << "[] = { "; + for (BinaryenIndex j = 0; j < segmentSizes[i]; j++) { + if (j > 0) std::cout << ", "; + std::cout << int(segments[i][j]); + } + std::cout << " };\n"; + } + std::cout << " const char* segments[] = { "; + for (BinaryenIndex i = 0; i < numSegments; i++) { + if (i > 0) std::cout << ", "; + std::cout << "segment" << i; + } + std::cout << " };\n"; + std::cout << " BinaryenIndex segmentOffsets[] = { "; + for (BinaryenIndex i = 0; i < numSegments; i++) { + if (i > 0) std::cout << ", "; + std::cout << segmentOffsets[i]; + } + std::cout << " };\n"; + std::cout << " BinaryenIndex segmentSizes[] = { "; + for (BinaryenIndex i = 0; i < numSegments; i++) { + if (i > 0) std::cout << ", "; + std::cout << segmentSizes[i]; + } + std::cout << " };\n"; + std::cout << " BinaryenSetMemory(the_module, " << initial << ", " << maximum << ", "; + traceNameOrNULL(exportName); + std::cout << ", segments, segmentOffsets, segmentSizes, sizeof(segments) / sizeof(const char*));\n"; + std::cout << " }\n"; + } + auto* wasm = (Module*)module; wasm->memory.initial = initial; wasm->memory.max = maximum; @@ -455,6 +792,10 @@ void BinaryenSetMemory(BinaryenModuleRef module, BinaryenIndex initial, Binaryen // Start function. One per module void BinaryenSetStart(BinaryenModuleRef module, BinaryenFunctionRef start) { + if (tracing) { + std::cout << " BinaryenSetStart(the_module, functions[" << functions[start] << "]);\n"; + } + auto* wasm = (Module*)module; wasm->addStart(((Function*)start)->name); } @@ -464,15 +805,27 @@ void BinaryenSetStart(BinaryenModuleRef module, BinaryenFunctionRef start) { // void BinaryenModulePrint(BinaryenModuleRef module) { + if (tracing) { + std::cout << " BinaryenModulePrint(the_module);\n"; + } + WasmPrinter::printModule((Module*)module); } int BinaryenModuleValidate(BinaryenModuleRef module) { + if (tracing) { + std::cout << " BinaryenModuleValidate(the_module);\n"; + } + Module* wasm = (Module*)module; return WasmValidator().validate(*wasm) ? 1 : 0; } void BinaryenModuleOptimize(BinaryenModuleRef module) { + if (tracing) { + std::cout << " BinaryenModuleOptimize(the_module);\n"; + } + Module* wasm = (Module*)module; PassRunner passRunner(wasm); passRunner.addDefaultOptimizationPasses(); @@ -480,6 +833,10 @@ void BinaryenModuleOptimize(BinaryenModuleRef module) { } size_t BinaryenModuleWrite(BinaryenModuleRef module, char* output, size_t outputSize) { + if (tracing) { + std::cout << " // BinaryenModuleWrite\n"; + } + Module* wasm = (Module*)module; BufferWithRandomAccess buffer(false); WasmBinaryWriter writer(wasm, buffer, false); @@ -490,6 +847,10 @@ size_t BinaryenModuleWrite(BinaryenModuleRef module, char* output, size_t output } BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize) { + if (tracing) { + std::cout << " // BinaryenModuleRead\n"; + } + auto* wasm = new Module; std::vector<char> buffer(false); buffer.resize(inputSize); @@ -505,6 +866,10 @@ BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize) { } void BinaryenModuleInterpret(BinaryenModuleRef module) { + if (tracing) { + std::cout << " BinaryenModuleInterpret(the_module);\n"; + } + Module* wasm = (Module*)module; ShellExternalInterface interface; ModuleInstance instance(*wasm, &interface); @@ -515,17 +880,32 @@ void BinaryenModuleInterpret(BinaryenModuleRef module) { // RelooperRef RelooperCreate(void) { + if (tracing) { + std::cout << " RelooperRef the_relooper = RelooperCreate();\n"; + } + return RelooperRef(new CFG::Relooper()); } RelooperBlockRef RelooperAddBlock(RelooperRef relooper, BinaryenExpressionRef code) { auto* R = (CFG::Relooper*)relooper; auto* ret = new CFG::Block((Expression*)code); + + if (tracing) { + auto id = relooperBlocks.size(); + relooperBlocks[ret] = id; + std::cout << " relooperBlocks[" << id << "] = RelooperAddBlock(the_relooper, expressions[" << expressions[code] << "]);\n"; + } + R->AddBlock(ret); return RelooperRef(ret); } void RelooperAddBranch(RelooperBlockRef from, RelooperBlockRef to, BinaryenExpressionRef condition, BinaryenExpressionRef code) { + if (tracing) { + std::cout << " RelooperAddBranch(relooperBlocks[" << relooperBlocks[from] << "], relooperBlocks[" << relooperBlocks[to] << "], expressions[" << expressions[condition] << "], expressions[" << expressions[code] << "]);\n"; + } + auto* fromBlock = (CFG::Block*)from; auto* toBlock = (CFG::Block*)to; fromBlock->AddBranchTo(toBlock, (Expression*)condition, (Expression*)code); @@ -534,11 +914,28 @@ void RelooperAddBranch(RelooperBlockRef from, RelooperBlockRef to, BinaryenExpre RelooperBlockRef RelooperAddBlockWithSwitch(RelooperRef relooper, BinaryenExpressionRef code, BinaryenExpressionRef condition) { auto* R = (CFG::Relooper*)relooper; auto* ret = new CFG::Block((Expression*)code, (Expression*)condition); + + if (tracing) { + std::cout << " relooperBlocks[" << relooperBlocks[ret] << "] = RelooperAddBlockWithSwitch(the_relooper, expressions[" << expressions[code] << "], expressions[" << expressions[condition] << "]);\n"; + } + R->AddBlock(ret); return RelooperRef(ret); } void RelooperAddBranchForSwitch(RelooperBlockRef from, RelooperBlockRef to, BinaryenIndex* indexes, BinaryenIndex numIndexes, BinaryenExpressionRef code) { + if (tracing) { + std::cout << " {\n"; + std::cout << " BinaryenIndex indexes[] = { "; + for (BinaryenIndex i = 0; i < numIndexes; i++) { + if (i > 0) std::cout << ", "; + std::cout << indexes[i]; + } + std::cout << " };\n"; + std::cout << " RelooperAddBranchForSwitch(relooperBlocks[" << relooperBlocks[from] << "], relooperBlocks[" << relooperBlocks[to] << "], indexes, " << numIndexes << ");\n"; + std::cout << " }\n"; + } + auto* fromBlock = (CFG::Block*)from; auto* toBlock = (CFG::Block*)to; std::vector<Index> values; @@ -553,8 +950,23 @@ BinaryenExpressionRef RelooperRenderAndDispose(RelooperRef relooper, RelooperBlo R->Calculate((CFG::Block*)entry); CFG::RelooperBuilder builder(*(Module*)module, labelHelper); auto* ret = R->Render(builder); + + if (tracing) { + auto id = expressions.size(); + expressions[ret] = id; + std::cout << " expressions[" << id << "] = RelooperRenderAndDispose(the_relooper, relooperBlocks[" << relooperBlocks[entry] << "], " << labelHelper << ", the_module);\n"; + } + delete R; return BinaryenExpressionRef(ret); } +// +// ========= Other APIs ========= +// + +void BinaryenSetAPITracing(int on) { + tracing = on; +} + } // extern "C" diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 3f940c0cc..706bc4a1a 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -24,6 +24,9 @@ // The third part of the API lets you provide a general control-flow // graph (CFG) as input. // +// The final part of the API contains miscellaneous utilities like +// debugging/tracing for the API itself. +// // --------------- // // Thread safety: You can create Expressions in parallel, as they do not @@ -337,7 +340,7 @@ BinaryenExportRef BinaryenAddExport(BinaryenModuleRef module, const char* intern // Function table. One per module -void BinaryenSetFunctionTable(BinaryenModuleRef module, BinaryenFunctionRef* functions, BinaryenIndex numFunctions); +void BinaryenSetFunctionTable(BinaryenModuleRef module, BinaryenFunctionRef* funcs, BinaryenIndex numFuncs); // Memory. One per module @@ -410,6 +413,16 @@ void RelooperAddBranchForSwitch(RelooperBlockRef from, RelooperBlockRef to, Bina // an i32 local variable that is free for us to use. BinaryenExpressionRef RelooperRenderAndDispose(RelooperRef relooper, RelooperBlockRef entry, BinaryenIndex labelHelper, BinaryenModuleRef module); +// +// ========= Other APIs ========= +// + +// Sets whether API tracing is on or off. It is off by default. When on, each call +// to an API method will print out C code equivalent to it, which is useful for +// auto-generating standalone testcases from projects using the API. +// TODO: compile-time option to enable/disable this feature entirely at build time. +void BinaryenSetAPITracing(int on); + #ifdef __cplusplus } // extern "C" #endif diff --git a/test/example/c-api-hello-world.c b/test/example/c-api-hello-world.c index e4a8a1cad..9117c5762 100644 --- a/test/example/c-api-hello-world.c +++ b/test/example/c-api-hello-world.c @@ -25,5 +25,7 @@ int main() { // Clean up the module, which owns all the objects we created above BinaryenModuleDispose(module); + + return 0; } diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index 6fb095d20..4f1d839c0 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -500,10 +500,19 @@ void test_nonvalid() { BinaryenModuleDispose(module); } +void test_tracing() { + BinaryenSetAPITracing(1); + test_core(); + BinaryenSetAPITracing(0); +} + int main() { test_core(); test_relooper(); test_binaries(); test_interpret(); test_nonvalid(); + test_tracing(); + + return 0; } diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 7076622c5..e6e266f02 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -817,3 +817,699 @@ module loaded from binary form: ) ) validation: 0 +BinaryenNone: 0 +BinaryenInt32: 1 +BinaryenInt64: 2 +BinaryenFloat32: 3 +BinaryenFloat64: 4 +// beginning a Binaryen API trace +#include <math.h> +#include <map> +#include "src/binaryen-c.h" +int main() { + std::map<size_t, BinaryenFunctionTypeRef> functionTypes; + std::map<size_t, BinaryenExpressionRef> expressions; + expressions[size_t(NULL)] = BinaryenExpressionRef(NULL); + std::map<size_t, BinaryenFunctionRef> functions; + std::map<size_t, RelooperBlockRef> relooperBlocks; + BinaryenModuleRef the_module = BinaryenModuleCreate(); + RelooperRef the_relooper = NULL; + expressions[1] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); + expressions[2] = BinaryenConst(the_module, BinaryenLiteralInt64(2)); + expressions[3] = BinaryenConst(the_module, BinaryenLiteralFloat32(3.14)); + expressions[4] = BinaryenConst(the_module, BinaryenLiteralFloat64(2.1828)); + expressions[5] = BinaryenConst(the_module, BinaryenLiteralFloat32(NAN)); + expressions[6] = BinaryenConst(the_module, BinaryenLiteralFloat64(NAN)); + expressions[7] = BinaryenConst(the_module, BinaryenLiteralInt32(13)); + expressions[8] = BinaryenConst(the_module, BinaryenLiteralFloat64(3.7)); + expressions[9] = BinaryenConst(the_module, BinaryenLiteralInt32(13)); + expressions[10] = BinaryenConst(the_module, BinaryenLiteralInt64(37)); + expressions[11] = BinaryenConst(the_module, BinaryenLiteralFloat32(1.3)); + expressions[12] = BinaryenConst(the_module, BinaryenLiteralFloat64(3.7)); + { + BinaryenIndex paramTypes[] = { 1, 2, 3, 4 }; + functionTypes[0] = BinaryenAddFunctionType(the_module, "iiIfF", 1, paramTypes, sizeof(paramTypes) / sizeof(BinaryenIndex)); + } + expressions[13] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[14] = BinaryenUnary(the_module, 0, expressions[13]); + expressions[15] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[16] = BinaryenUnary(the_module, 3, expressions[15]); + expressions[17] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[18] = BinaryenUnary(the_module, 4, expressions[17]); + expressions[19] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[20] = BinaryenUnary(the_module, 6, expressions[19]); + expressions[21] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84)); + expressions[22] = BinaryenUnary(the_module, 9, expressions[21]); + expressions[23] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[24] = BinaryenUnary(the_module, 10, expressions[23]); + expressions[25] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84)); + expressions[26] = BinaryenUnary(the_module, 13, expressions[25]); + expressions[27] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[28] = BinaryenUnary(the_module, 14, expressions[27]); + expressions[29] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[30] = BinaryenUnary(the_module, 16, expressions[29]); + expressions[31] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84)); + expressions[32] = BinaryenUnary(the_module, 19, expressions[31]); + expressions[33] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[34] = BinaryenUnary(the_module, 20, expressions[33]); + expressions[35] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[36] = BinaryenUnary(the_module, 22, expressions[35]); + expressions[37] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[38] = BinaryenUnary(the_module, 23, expressions[37]); + expressions[39] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[40] = BinaryenUnary(the_module, 24, expressions[39]); + expressions[41] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[42] = BinaryenUnary(the_module, 25, expressions[41]); + expressions[43] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[44] = BinaryenUnary(the_module, 26, expressions[43]); + expressions[45] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[46] = BinaryenUnary(the_module, 27, expressions[45]); + expressions[47] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[48] = BinaryenUnary(the_module, 28, expressions[47]); + expressions[49] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84)); + expressions[50] = BinaryenUnary(the_module, 29, expressions[49]); + expressions[51] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84)); + expressions[52] = BinaryenUnary(the_module, 30, expressions[51]); + expressions[53] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84)); + expressions[54] = BinaryenUnary(the_module, 31, expressions[53]); + expressions[55] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84)); + expressions[56] = BinaryenUnary(the_module, 32, expressions[55]); + expressions[57] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[58] = BinaryenUnary(the_module, 33, expressions[57]); + expressions[59] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84)); + expressions[60] = BinaryenUnary(the_module, 34, expressions[59]); + expressions[61] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[62] = BinaryenUnary(the_module, 35, expressions[61]); + expressions[63] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[64] = BinaryenUnary(the_module, 36, expressions[63]); + expressions[65] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[66] = BinaryenUnary(the_module, 37, expressions[65]); + expressions[67] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[68] = BinaryenUnary(the_module, 38, expressions[67]); + expressions[69] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[70] = BinaryenUnary(the_module, 39, expressions[69]); + expressions[71] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[72] = BinaryenUnary(the_module, 40, expressions[71]); + expressions[73] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[74] = BinaryenUnary(the_module, 41, expressions[73]); + expressions[75] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[76] = BinaryenUnary(the_module, 42, expressions[75]); + expressions[77] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[78] = BinaryenUnary(the_module, 43, expressions[77]); + expressions[79] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84)); + expressions[80] = BinaryenUnary(the_module, 44, expressions[79]); + expressions[81] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[82] = BinaryenUnary(the_module, 45, expressions[81]); + expressions[83] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[84] = BinaryenUnary(the_module, 46, expressions[83]); + expressions[85] = BinaryenConst(the_module, BinaryenLiteralInt32(-11)); + expressions[86] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[87] = BinaryenBinary(the_module, 0, expressions[86], expressions[85]); + expressions[88] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9007.33)); + expressions[89] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84)); + expressions[90] = BinaryenBinary(the_module, 64, expressions[89], expressions[88]); + expressions[91] = BinaryenConst(the_module, BinaryenLiteralInt32(-11)); + expressions[92] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[93] = BinaryenBinary(the_module, 3, expressions[92], expressions[91]); + expressions[94] = BinaryenConst(the_module, BinaryenLiteralInt64(-23)); + expressions[95] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[96] = BinaryenBinary(the_module, 29, expressions[95], expressions[94]); + expressions[97] = BinaryenConst(the_module, BinaryenLiteralInt64(-23)); + expressions[98] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[99] = BinaryenBinary(the_module, 30, expressions[98], expressions[97]); + expressions[100] = BinaryenConst(the_module, BinaryenLiteralInt32(-11)); + expressions[101] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[102] = BinaryenBinary(the_module, 6, expressions[101], expressions[100]); + expressions[103] = BinaryenConst(the_module, BinaryenLiteralInt32(-11)); + expressions[104] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[105] = BinaryenBinary(the_module, 7, expressions[104], expressions[103]); + expressions[106] = BinaryenConst(the_module, BinaryenLiteralInt64(-23)); + expressions[107] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[108] = BinaryenBinary(the_module, 33, expressions[107], expressions[106]); + expressions[109] = BinaryenConst(the_module, BinaryenLiteralInt32(-11)); + expressions[110] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[111] = BinaryenBinary(the_module, 9, expressions[110], expressions[109]); + expressions[112] = BinaryenConst(the_module, BinaryenLiteralInt64(-23)); + expressions[113] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[114] = BinaryenBinary(the_module, 35, expressions[113], expressions[112]); + expressions[115] = BinaryenConst(the_module, BinaryenLiteralInt64(-23)); + expressions[116] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[117] = BinaryenBinary(the_module, 36, expressions[116], expressions[115]); + expressions[118] = BinaryenConst(the_module, BinaryenLiteralInt32(-11)); + expressions[119] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[120] = BinaryenBinary(the_module, 12, expressions[119], expressions[118]); + expressions[121] = BinaryenConst(the_module, BinaryenLiteralInt32(-11)); + expressions[122] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[123] = BinaryenBinary(the_module, 13, expressions[122], expressions[121]); + expressions[124] = BinaryenConst(the_module, BinaryenLiteralInt64(-23)); + expressions[125] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[126] = BinaryenBinary(the_module, 39, expressions[125], expressions[124]); + expressions[127] = BinaryenConst(the_module, BinaryenLiteralFloat32(-62.5)); + expressions[128] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[129] = BinaryenBinary(the_module, 53, expressions[128], expressions[127]); + expressions[130] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9007.33)); + expressions[131] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84)); + expressions[132] = BinaryenBinary(the_module, 67, expressions[131], expressions[130]); + expressions[133] = BinaryenConst(the_module, BinaryenLiteralFloat32(-62.5)); + expressions[134] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[135] = BinaryenBinary(the_module, 55, expressions[134], expressions[133]); + expressions[136] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9007.33)); + expressions[137] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84)); + expressions[138] = BinaryenBinary(the_module, 69, expressions[137], expressions[136]); + expressions[139] = BinaryenConst(the_module, BinaryenLiteralInt32(-11)); + expressions[140] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[141] = BinaryenBinary(the_module, 15, expressions[140], expressions[139]); + expressions[142] = BinaryenConst(the_module, BinaryenLiteralFloat32(-62.5)); + expressions[143] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[144] = BinaryenBinary(the_module, 58, expressions[143], expressions[142]); + expressions[145] = BinaryenConst(the_module, BinaryenLiteralInt32(-11)); + expressions[146] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[147] = BinaryenBinary(the_module, 17, expressions[146], expressions[145]); + expressions[148] = BinaryenConst(the_module, BinaryenLiteralInt64(-23)); + expressions[149] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[150] = BinaryenBinary(the_module, 43, expressions[149], expressions[148]); + expressions[151] = BinaryenConst(the_module, BinaryenLiteralInt64(-23)); + expressions[152] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[153] = BinaryenBinary(the_module, 44, expressions[152], expressions[151]); + expressions[154] = BinaryenConst(the_module, BinaryenLiteralInt32(-11)); + expressions[155] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[156] = BinaryenBinary(the_module, 20, expressions[155], expressions[154]); + expressions[157] = BinaryenConst(the_module, BinaryenLiteralInt64(-23)); + expressions[158] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[159] = BinaryenBinary(the_module, 46, expressions[158], expressions[157]); + expressions[160] = BinaryenConst(the_module, BinaryenLiteralInt32(-11)); + expressions[161] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[162] = BinaryenBinary(the_module, 22, expressions[161], expressions[160]); + expressions[163] = BinaryenConst(the_module, BinaryenLiteralInt32(-11)); + expressions[164] = BinaryenConst(the_module, BinaryenLiteralInt32(-10)); + expressions[165] = BinaryenBinary(the_module, 23, expressions[164], expressions[163]); + expressions[166] = BinaryenConst(the_module, BinaryenLiteralInt64(-23)); + expressions[167] = BinaryenConst(the_module, BinaryenLiteralInt64(-22)); + expressions[168] = BinaryenBinary(the_module, 49, expressions[167], expressions[166]); + expressions[169] = BinaryenConst(the_module, BinaryenLiteralFloat32(-62.5)); + expressions[170] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[171] = BinaryenBinary(the_module, 59, expressions[170], expressions[169]); + expressions[172] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9007.33)); + expressions[173] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84)); + expressions[174] = BinaryenBinary(the_module, 73, expressions[173], expressions[172]); + expressions[175] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9007.33)); + expressions[176] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84)); + expressions[177] = BinaryenBinary(the_module, 74, expressions[176], expressions[175]); + expressions[178] = BinaryenConst(the_module, BinaryenLiteralFloat32(-62.5)); + expressions[179] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612)); + expressions[180] = BinaryenBinary(the_module, 62, expressions[179], expressions[178]); + { + BinaryenExpressionRef children[] = { }; + expressions[181] = BinaryenBlock(the_module, NULL, children, sizeof(children) / sizeof(BinaryenExpressionRef)); + } + expressions[182] = BinaryenConst(the_module, BinaryenLiteralInt32(3)); + expressions[183] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); + expressions[184] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); + expressions[185] = BinaryenIf(the_module, expressions[184], expressions[183], expressions[182]); + expressions[186] = BinaryenConst(the_module, BinaryenLiteralInt32(5)); + expressions[187] = BinaryenConst(the_module, BinaryenLiteralInt32(4)); + expressions[188] = BinaryenIf(the_module, expressions[187], expressions[186], expressions[0]); + expressions[189] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[190] = BinaryenLoop(the_module, "out", "in", expressions[189]); + expressions[191] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[192] = BinaryenLoop(the_module, NULL, "in2", expressions[191]); + expressions[193] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[194] = BinaryenLoop(the_module, NULL, NULL, expressions[193]); + expressions[195] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); + expressions[196] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[197] = BinaryenBreak(the_module, "the-value", expressions[196], expressions[195]); + expressions[198] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); + expressions[199] = BinaryenBreak(the_module, "the-nothing", expressions[198], expressions[0]); + expressions[200] = BinaryenConst(the_module, BinaryenLiteralInt32(3)); + expressions[201] = BinaryenBreak(the_module, "the-value", expressions[0], expressions[200]); + expressions[202] = BinaryenBreak(the_module, "the-nothing", expressions[0], expressions[0]); + expressions[203] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); + expressions[204] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + { + const char* names[] = { "the-value" }; + expressions[205] = BinaryenSwitch(the_module, names, sizeof(names) / sizeof(const char *), "the-value", expressions[204], expressions[203]); + } + expressions[206] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); + { + const char* names[] = { "the-nothing" }; + expressions[207] = BinaryenSwitch(the_module, names, sizeof(names) / sizeof(const char *), "the-nothing", expressions[206], expressions[0]); + } + { + BinaryenExpressionRef operands[] = { expressions[9], expressions[10], expressions[11], expressions[12] }; + expressions[208] = BinaryenCall(the_module, "kitchen()sinker", operands, 4, 1); + } + expressions[209] = BinaryenUnary(the_module, 20, expressions[208]); + { + BinaryenExpressionRef operands[] = { expressions[7], expressions[8] }; + expressions[210] = BinaryenCallImport(the_module, "an-imported", operands, 2, 3); + } + expressions[211] = BinaryenUnary(the_module, 25, expressions[210]); + expressions[212] = BinaryenUnary(the_module, 20, expressions[211]); + expressions[213] = BinaryenConst(the_module, BinaryenLiteralInt32(2449)); + { + BinaryenExpressionRef operands[] = { expressions[9], expressions[10], expressions[11], expressions[12] }; + expressions[214] = BinaryenCallIndirect(the_module, expressions[213], operands, 4, "iiIfF"); + } + expressions[215] = BinaryenUnary(the_module, 20, expressions[214]); + expressions[216] = BinaryenGetLocal(the_module, 0, 1); + expressions[217] = BinaryenConst(the_module, BinaryenLiteralInt32(101)); + expressions[218] = BinaryenSetLocal(the_module, 0, expressions[217]); + expressions[219] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); + expressions[220] = BinaryenLoad(the_module, 4, 0, 0, 0, 1, expressions[219]); + expressions[221] = BinaryenConst(the_module, BinaryenLiteralInt32(8)); + expressions[222] = BinaryenLoad(the_module, 1, 1, 2, 4, 2, expressions[221]); + expressions[223] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); + expressions[224] = BinaryenLoad(the_module, 4, 0, 0, 0, 3, expressions[223]); + expressions[225] = BinaryenConst(the_module, BinaryenLiteralInt32(9)); + expressions[226] = BinaryenLoad(the_module, 8, 0, 2, 8, 4, expressions[225]); + expressions[227] = BinaryenConst(the_module, BinaryenLiteralInt32(11)); + expressions[228] = BinaryenConst(the_module, BinaryenLiteralInt32(10)); + expressions[229] = BinaryenStore(the_module, 4, 0, 0, expressions[228], expressions[227]); + expressions[230] = BinaryenConst(the_module, BinaryenLiteralInt64(111)); + expressions[231] = BinaryenConst(the_module, BinaryenLiteralInt32(110)); + expressions[232] = BinaryenStore(the_module, 8, 2, 4, expressions[231], expressions[230]); + expressions[233] = BinaryenConst(the_module, BinaryenLiteralInt32(5)); + expressions[234] = BinaryenConst(the_module, BinaryenLiteralInt32(3)); + expressions[235] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); + expressions[236] = BinaryenSelect(the_module, expressions[235], expressions[234], expressions[233]); + expressions[237] = BinaryenConst(the_module, BinaryenLiteralInt32(1337)); + expressions[238] = BinaryenReturn(the_module, expressions[237]); + expressions[239] = BinaryenNop(the_module); + expressions[240] = BinaryenUnreachable(the_module); + BinaryenExpressionPrint(expressions[20]); +(f32.neg + (f32.const -33.61199951171875) +) + { + BinaryenExpressionRef children[] = { expressions[14], expressions[16], expressions[18], expressions[20], expressions[22], expressions[24], expressions[26], expressions[28], expressions[30], expressions[32], expressions[34], expressions[36], expressions[38], expressions[40], expressions[42], expressions[44], expressions[46], expressions[48], expressions[50], expressions[52], expressions[54], expressions[56], expressions[58], expressions[60], expressions[62], expressions[64], expressions[66], expressions[68], expressions[70], expressions[72], expressions[74], expressions[76], expressions[78], expressions[80], expressions[82], expressions[84], expressions[87], expressions[90], expressions[93], expressions[96], expressions[99], expressions[102], expressions[105], expressions[108], expressions[111], expressions[114], expressions[117], expressions[120], expressions[123], expressions[126], expressions[129], expressions[132], expressions[135], expressions[138], expressions[141], expressions[144], expressions[147], expressions[150], expressions[153], expressions[156], expressions[159], expressions[162], expressions[165], expressions[168], expressions[171], expressions[174], expressions[177], expressions[180], expressions[181], expressions[185], expressions[188], expressions[190], expressions[192], expressions[194], expressions[197], expressions[199], expressions[201], expressions[202], expressions[205], expressions[207], expressions[209], expressions[212], expressions[215], expressions[216], expressions[218], expressions[220], expressions[222], expressions[224], expressions[226], expressions[229], expressions[232], expressions[236], expressions[238], expressions[239], expressions[240] }; + expressions[241] = BinaryenBlock(the_module, "the-value", children, sizeof(children) / sizeof(BinaryenExpressionRef)); + } + { + BinaryenExpressionRef children[] = { expressions[241] }; + expressions[242] = BinaryenBlock(the_module, "the-nothing", children, sizeof(children) / sizeof(BinaryenExpressionRef)); + } + expressions[243] = BinaryenConst(the_module, BinaryenLiteralInt32(42)); + { + BinaryenExpressionRef children[] = { expressions[242], expressions[243] }; + expressions[244] = BinaryenBlock(the_module, "the-body", children, sizeof(children) / sizeof(BinaryenExpressionRef)); + } + { + BinaryenType varTypes[] = { 1 }; + functions[0] = BinaryenAddFunction(the_module, "kitchen()sinker", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[244]); + } + { + BinaryenIndex paramTypes[] = { 1, 4 }; + functionTypes[1] = BinaryenAddFunctionType(the_module, "fiF", 3, paramTypes, sizeof(paramTypes) / sizeof(BinaryenIndex)); + } + BinaryenAddImport(the_module, "an-imported", "module", "base", functionTypes[1]); + BinaryenAddExport(the_module, "kitchen()sinker", "kitchen_sinker"); + { + BinaryenFunctionRef funcs[] = { functions[0] }; + BinaryenSetFunctionTable(the_module, funcs, sizeof(funcs) / sizeof(BinaryenFunctionRef)); + } + { + const char segment0[] = { 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100 }; + const char* segments[] = { segment0 }; + BinaryenIndex segmentOffsets[] = { 10 }; + BinaryenIndex segmentSizes[] = { 12 }; + BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentOffsets, segmentSizes, sizeof(segments) / sizeof(const char*)); + } + { + BinaryenIndex paramTypes[] = { }; + functionTypes[2] = BinaryenAddFunctionType(the_module, "v", 0, paramTypes, sizeof(paramTypes) / sizeof(BinaryenIndex)); + } + expressions[245] = BinaryenNop(the_module); + { + BinaryenType varTypes[] = { }; + functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[2], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[245]); + } + BinaryenSetStart(the_module, functions[1]); + { + BinaryenIndex paramTypes[] = { }; + functionTypes[3] = BinaryenAddFunctionType(the_module, NULL, 0, paramTypes, sizeof(paramTypes) / sizeof(BinaryenIndex)); + } + BinaryenModuleValidate(the_module); + BinaryenModulePrint(the_module); +(module + (memory 1 256 + (segment 10 "hello, world") + ) + (export "mem" memory) + (start $starter) + (type $iiIfF (func (param i32 i64 f32 f64) (result i32))) + (type $fiF (func (param i32 f64) (result f32))) + (type $v (func)) + (type $3 (func)) + (import $an-imported "module" "base" (param i32 f64) (result f32)) + (export "kitchen_sinker" "$kitchen()sinker") + (table "$kitchen()sinker") + (func "$kitchen()sinker" (type $iiIfF) (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64) (result i32) + (local $4 i32) + (block $the-body + (block $the-nothing + (block $the-value + (i32.clz + (i32.const -10) + ) + (i64.ctz + (i64.const -22) + ) + (i32.popcnt + (i32.const -10) + ) + (f32.neg + (f32.const -33.61199951171875) + ) + (f64.abs + (f64.const -9005.841) + ) + (f32.ceil + (f32.const -33.61199951171875) + ) + (f64.floor + (f64.const -9005.841) + ) + (f32.trunc + (f32.const -33.61199951171875) + ) + (f32.nearest + (f32.const -33.61199951171875) + ) + (f64.sqrt + (f64.const -9005.841) + ) + (i32.eqz + (i32.const -10) + ) + (i64.extend_s/i32 + (i32.const -10) + ) + (i64.extend_u/i32 + (i32.const -10) + ) + (i32.wrap/i64 + (i64.const -22) + ) + (i32.trunc_s/f32 + (f32.const -33.61199951171875) + ) + (i64.trunc_s/f32 + (f32.const -33.61199951171875) + ) + (i32.trunc_u/f32 + (f32.const -33.61199951171875) + ) + (i64.trunc_u/f32 + (f32.const -33.61199951171875) + ) + (i32.trunc_s/f64 + (f64.const -9005.841) + ) + (i64.trunc_s/f64 + (f64.const -9005.841) + ) + (i32.trunc_u/f64 + (f64.const -9005.841) + ) + (i64.trunc_u/f64 + (f64.const -9005.841) + ) + (i32.reinterpret/f32 + (f32.const -33.61199951171875) + ) + (i64.reinterpret/f64 + (f64.const -9005.841) + ) + (f32.convert_s/i32 + (i32.const -10) + ) + (f64.convert_s/i32 + (i32.const -10) + ) + (f32.convert_u/i32 + (i32.const -10) + ) + (f64.convert_u/i32 + (i32.const -10) + ) + (f32.convert_s/i64 + (i64.const -22) + ) + (f64.convert_s/i64 + (i64.const -22) + ) + (f32.convert_u/i64 + (i64.const -22) + ) + (f64.convert_u/i64 + (i64.const -22) + ) + (f64.promote/f32 + (f32.const -33.61199951171875) + ) + (f32.demote/f64 + (f64.const -9005.841) + ) + (f32.reinterpret/i32 + (i32.const -10) + ) + (f64.reinterpret/i64 + (i64.const -22) + ) + (i32.add + (i32.const -10) + (i32.const -11) + ) + (f64.sub + (f64.const -9005.841) + (f64.const -9007.333) + ) + (i32.div_s + (i32.const -10) + (i32.const -11) + ) + (i64.div_u + (i64.const -22) + (i64.const -23) + ) + (i64.rem_s + (i64.const -22) + (i64.const -23) + ) + (i32.rem_u + (i32.const -10) + (i32.const -11) + ) + (i32.and + (i32.const -10) + (i32.const -11) + ) + (i64.or + (i64.const -22) + (i64.const -23) + ) + (i32.xor + (i32.const -10) + (i32.const -11) + ) + (i64.shl + (i64.const -22) + (i64.const -23) + ) + (i64.shr_u + (i64.const -22) + (i64.const -23) + ) + (i32.shr_s + (i32.const -10) + (i32.const -11) + ) + (i32.rotl + (i32.const -10) + (i32.const -11) + ) + (i64.rotr + (i64.const -22) + (i64.const -23) + ) + (f32.div + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (f64.copysign + (f64.const -9005.841) + (f64.const -9007.333) + ) + (f32.min + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (f64.max + (f64.const -9005.841) + (f64.const -9007.333) + ) + (i32.eq + (i32.const -10) + (i32.const -11) + ) + (f32.ne + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (i32.lt_s + (i32.const -10) + (i32.const -11) + ) + (i64.lt_u + (i64.const -22) + (i64.const -23) + ) + (i64.le_s + (i64.const -22) + (i64.const -23) + ) + (i32.le_u + (i32.const -10) + (i32.const -11) + ) + (i64.gt_s + (i64.const -22) + (i64.const -23) + ) + (i32.gt_u + (i32.const -10) + (i32.const -11) + ) + (i32.ge_s + (i32.const -10) + (i32.const -11) + ) + (i64.ge_u + (i64.const -22) + (i64.const -23) + ) + (f32.lt + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (f64.le + (f64.const -9005.841) + (f64.const -9007.333) + ) + (f64.gt + (f64.const -9005.841) + (f64.const -9007.333) + ) + (f32.ge + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (block + ) + (if + (i32.const 1) + (i32.const 2) + (i32.const 3) + ) + (if + (i32.const 4) + (i32.const 5) + ) + (loop $out $in + (i32.const 0) + ) + (loop $in2 + (i32.const 0) + ) + (loop + (i32.const 0) + ) + (br_if $the-value + (i32.const 1) + (i32.const 0) + ) + (br_if $the-nothing + (i32.const 2) + ) + (br $the-value + (i32.const 3) + ) + (br $the-nothing) + (br_table $the-value $the-value + (i32.const 1) + (i32.const 0) + ) + (br_table $the-nothing $the-nothing + (i32.const 2) + ) + (i32.eqz + (call "$kitchen()sinker" + (i32.const 13) + (i64.const 37) + (f32.const 1.2999999523162842) + (f64.const 3.7) + ) + ) + (i32.eqz + (i32.trunc_s/f32 + (call_import $an-imported + (i32.const 13) + (f64.const 3.7) + ) + ) + ) + (i32.eqz + (call_indirect $iiIfF + (i32.const 2449) + (i32.const 13) + (i64.const 37) + (f32.const 1.2999999523162842) + (f64.const 3.7) + ) + ) + (get_local $0) + (set_local $0 + (i32.const 101) + ) + (i32.load + (i32.const 1) + ) + (i64.load8_s offset=2 align=4 + (i32.const 8) + ) + (f32.load + (i32.const 2) + ) + (f64.load offset=2 + (i32.const 9) + ) + (i32.store + (i32.const 10) + (i32.const 11) + ) + (i64.store offset=2 align=4 + (i32.const 110) + (i64.const 111) + ) + (select + (i32.const 3) + (i32.const 5) + (i32.const 1) + ) + (return + (i32.const 1337) + ) + (nop) + (unreachable) + ) + ) + (i32.const 42) + ) + ) + (func $starter (type $v) + (nop) + ) +) + BinaryenModuleDispose(the_module); + return 0; +} diff --git a/test/example/c-api-kitchen-sink.txt.txt b/test/example/c-api-kitchen-sink.txt.txt new file mode 100644 index 000000000..d7556413d --- /dev/null +++ b/test/example/c-api-kitchen-sink.txt.txt @@ -0,0 +1,363 @@ +(f32.neg + (f32.const -33.61199951171875) +) +(module + (memory 1 256 + (segment 10 "hello, world") + ) + (export "mem" memory) + (start $starter) + (type $iiIfF (func (param i32 i64 f32 f64) (result i32))) + (type $fiF (func (param i32 f64) (result f32))) + (type $v (func)) + (type $3 (func)) + (import $an-imported "module" "base" (param i32 f64) (result f32)) + (export "kitchen_sinker" "$kitchen()sinker") + (table "$kitchen()sinker") + (func "$kitchen()sinker" (type $iiIfF) (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64) (result i32) + (local $4 i32) + (block $the-body + (block $the-nothing + (block $the-value + (i32.clz + (i32.const -10) + ) + (i64.ctz + (i64.const -22) + ) + (i32.popcnt + (i32.const -10) + ) + (f32.neg + (f32.const -33.61199951171875) + ) + (f64.abs + (f64.const -9005.84) + ) + (f32.ceil + (f32.const -33.61199951171875) + ) + (f64.floor + (f64.const -9005.84) + ) + (f32.trunc + (f32.const -33.61199951171875) + ) + (f32.nearest + (f32.const -33.61199951171875) + ) + (f64.sqrt + (f64.const -9005.84) + ) + (i32.eqz + (i32.const -10) + ) + (i64.extend_s/i32 + (i32.const -10) + ) + (i64.extend_u/i32 + (i32.const -10) + ) + (i32.wrap/i64 + (i64.const -22) + ) + (i32.trunc_s/f32 + (f32.const -33.61199951171875) + ) + (i64.trunc_s/f32 + (f32.const -33.61199951171875) + ) + (i32.trunc_u/f32 + (f32.const -33.61199951171875) + ) + (i64.trunc_u/f32 + (f32.const -33.61199951171875) + ) + (i32.trunc_s/f64 + (f64.const -9005.84) + ) + (i64.trunc_s/f64 + (f64.const -9005.84) + ) + (i32.trunc_u/f64 + (f64.const -9005.84) + ) + (i64.trunc_u/f64 + (f64.const -9005.84) + ) + (i32.reinterpret/f32 + (f32.const -33.61199951171875) + ) + (i64.reinterpret/f64 + (f64.const -9005.84) + ) + (f32.convert_s/i32 + (i32.const -10) + ) + (f64.convert_s/i32 + (i32.const -10) + ) + (f32.convert_u/i32 + (i32.const -10) + ) + (f64.convert_u/i32 + (i32.const -10) + ) + (f32.convert_s/i64 + (i64.const -22) + ) + (f64.convert_s/i64 + (i64.const -22) + ) + (f32.convert_u/i64 + (i64.const -22) + ) + (f64.convert_u/i64 + (i64.const -22) + ) + (f64.promote/f32 + (f32.const -33.61199951171875) + ) + (f32.demote/f64 + (f64.const -9005.84) + ) + (f32.reinterpret/i32 + (i32.const -10) + ) + (f64.reinterpret/i64 + (i64.const -22) + ) + (i32.add + (i32.const -10) + (i32.const -11) + ) + (f64.sub + (f64.const -9005.84) + (f64.const -9007.33) + ) + (i32.div_s + (i32.const -10) + (i32.const -11) + ) + (i64.div_u + (i64.const -22) + (i64.const -23) + ) + (i64.rem_s + (i64.const -22) + (i64.const -23) + ) + (i32.rem_u + (i32.const -10) + (i32.const -11) + ) + (i32.and + (i32.const -10) + (i32.const -11) + ) + (i64.or + (i64.const -22) + (i64.const -23) + ) + (i32.xor + (i32.const -10) + (i32.const -11) + ) + (i64.shl + (i64.const -22) + (i64.const -23) + ) + (i64.shr_u + (i64.const -22) + (i64.const -23) + ) + (i32.shr_s + (i32.const -10) + (i32.const -11) + ) + (i32.rotl + (i32.const -10) + (i32.const -11) + ) + (i64.rotr + (i64.const -22) + (i64.const -23) + ) + (f32.div + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (f64.copysign + (f64.const -9005.84) + (f64.const -9007.33) + ) + (f32.min + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (f64.max + (f64.const -9005.84) + (f64.const -9007.33) + ) + (i32.eq + (i32.const -10) + (i32.const -11) + ) + (f32.ne + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (i32.lt_s + (i32.const -10) + (i32.const -11) + ) + (i64.lt_u + (i64.const -22) + (i64.const -23) + ) + (i64.le_s + (i64.const -22) + (i64.const -23) + ) + (i32.le_u + (i32.const -10) + (i32.const -11) + ) + (i64.gt_s + (i64.const -22) + (i64.const -23) + ) + (i32.gt_u + (i32.const -10) + (i32.const -11) + ) + (i32.ge_s + (i32.const -10) + (i32.const -11) + ) + (i64.ge_u + (i64.const -22) + (i64.const -23) + ) + (f32.lt + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (f64.le + (f64.const -9005.84) + (f64.const -9007.33) + ) + (f64.gt + (f64.const -9005.84) + (f64.const -9007.33) + ) + (f32.ge + (f32.const -33.61199951171875) + (f32.const -62.5) + ) + (block + ) + (if + (i32.const 1) + (i32.const 2) + (i32.const 3) + ) + (if + (i32.const 4) + (i32.const 5) + ) + (loop $out $in + (i32.const 0) + ) + (loop $in2 + (i32.const 0) + ) + (loop + (i32.const 0) + ) + (br_if $the-value + (i32.const 1) + (i32.const 0) + ) + (br_if $the-nothing + (i32.const 2) + ) + (br $the-value + (i32.const 3) + ) + (br $the-nothing) + (br_table $the-value $the-value + (i32.const 1) + (i32.const 0) + ) + (br_table $the-nothing $the-nothing + (i32.const 2) + ) + (i32.eqz + (call "$kitchen()sinker" + (i32.const 13) + (i64.const 37) + (f32.const 1.2999999523162842) + (f64.const 3.7) + ) + ) + (i32.eqz + (i32.trunc_s/f32 + (call_import $an-imported + (i32.const 13) + (f64.const 3.7) + ) + ) + ) + (i32.eqz + (call_indirect $iiIfF + (i32.const 2449) + (i32.const 13) + (i64.const 37) + (f32.const 1.2999999523162842) + (f64.const 3.7) + ) + ) + (get_local $0) + (set_local $0 + (i32.const 101) + ) + (i32.load + (i32.const 1) + ) + (i64.load8_s offset=2 align=4 + (i32.const 8) + ) + (f32.load + (i32.const 2) + ) + (f64.load offset=2 + (i32.const 9) + ) + (i32.store + (i32.const 10) + (i32.const 11) + ) + (i64.store offset=2 align=4 + (i32.const 110) + (i64.const 111) + ) + (select + (i32.const 3) + (i32.const 5) + (i32.const 1) + ) + (return + (i32.const 1337) + ) + (nop) + (unreachable) + ) + ) + (i32.const 42) + ) + ) + (func $starter (type $v) + (nop) + ) +) |