summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-07-12 15:00:26 -0700
committerGitHub <noreply@github.com>2016-07-12 15:00:26 -0700
commitcd707e8ef504cca1e1a6a73580672af14bc40d38 (patch)
treecb45aaaaeb8754d5d14dd7ddf74c719264606901
parent8e936ce0635b66a3b2754292bab7c6c262b0bb1f (diff)
parent43ae9d622a33ca6ede829524a99bdec9f6b2bfc6 (diff)
downloadbinaryen-cd707e8ef504cca1e1a6a73580672af14bc40d38.tar.gz
binaryen-cd707e8ef504cca1e1a6a73580672af14bc40d38.tar.bz2
binaryen-cd707e8ef504cca1e1a6a73580672af14bc40d38.zip
Merge pull request #627 from WebAssembly/trace-c-api-nice
Add a tracing option to the c api
-rwxr-xr-xauto_update_tests.py37
-rwxr-xr-xcheck.py36
-rwxr-xr-xscripts/clean_c_api_trace.py23
-rw-r--r--src/binaryen-c.cpp438
-rw-r--r--src/binaryen-c.h18
-rw-r--r--src/cfg/Relooper.cpp3
-rw-r--r--test/example/c-api-hello-world.c2
-rw-r--r--test/example/c-api-kitchen-sink.c71
-rw-r--r--test/example/c-api-kitchen-sink.txt1386
-rw-r--r--test/example/c-api-kitchen-sink.txt.txt777
10 files changed, 2738 insertions, 53 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! ]'
diff --git a/check.py b/check.py
index 622989006..658746dff 100755
--- a/check.py
+++ b/check.py
@@ -164,7 +164,7 @@ def run_command(cmd, expected_status=0, stderr=None):
def fail(actual, expected):
raise Exception("incorrect output, diff:\n\n%s" % (
- ''.join([a.rstrip()+'\n' for a in difflib.unified_diff(expected.split('\n'), actual.split('\n'), fromfile='expected', tofile='actual')])[-1000:]
+ ''.join([a.rstrip()+'\n' for a in difflib.unified_diff(expected.split('\n'), actual.split('\n'), fromfile='expected', tofile='actual')])[:]
))
def fail_if_not_identical(actual, expected):
@@ -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..cdc1d6612 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -60,6 +60,27 @@ 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;
+
+size_t noteExpression(BinaryenExpressionRef expression) {
+ auto id = expressions.size();
+ assert(expressions.find(expression) == expressions.end());
+ expressions[expression] = id;
+ return id;
+}
+
extern "C" {
//
@@ -76,8 +97,30 @@ 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 << " the_module = BinaryenModuleCreate();\n";
+ std::cout << " expressions[size_t(NULL)] = BinaryenExpressionRef(NULL);\n";
+ expressions[NULL] = 0;
+ }
+
+ return new Module();
+}
+void BinaryenModuleDispose(BinaryenModuleRef module) {
+ if (tracing) {
+ std::cout << " BinaryenModuleDispose(the_module);\n";
+ std::cout << " functionTypes.clear();\n";
+ std::cout << " expressions.clear();\n";
+ std::cout << " functions.clear();\n";
+ std::cout << " relooperBlocks.clear();\n";
+ functionTypes.clear();
+ expressions.clear();
+ functions.clear();
+ relooperBlocks.clear();
+ }
+
+ delete (Module*)module;
+}
// Function types
@@ -98,6 +141,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 +304,22 @@ 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 = noteExpression(ret);
+ 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 +328,55 @@ BinaryenExpressionRef BinaryenIf(BinaryenModuleRef module, BinaryenExpressionRef
ret->ifTrue = (Expression*)ifTrue;
ret->ifFalse = (Expression*)ifFalse;
ret->finalize();
+
+ if (tracing) {
+ auto id = noteExpression(ret);
+ 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 = noteExpression(ret);
+ 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 = noteExpression(ret);
+ 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 = noteExpression(ret);
+ 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 +388,20 @@ 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 = noteExpression(ret);
+ 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 +412,20 @@ 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 = noteExpression(ret);
+ 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 +437,20 @@ 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 = noteExpression(ret);
+ 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 +461,12 @@ BinaryenExpressionRef BinaryenCallIndirect(BinaryenModuleRef module, BinaryenExp
}
BinaryenExpressionRef BinaryenGetLocal(BinaryenModuleRef module, BinaryenIndex index, BinaryenType type) {
auto* ret = ((Module*)module)->allocator.alloc<GetLocal>();
+
+ if (tracing) {
+ auto id = noteExpression(ret);
+ std::cout << " expressions[" << id << "] = BinaryenGetLocal(the_module, " << index << ", " << type << ");\n";
+ }
+
ret->index = index;
ret->type = WasmType(type);
ret->finalize();
@@ -313,6 +474,12 @@ 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 = noteExpression(ret);
+ std::cout << " expressions[" << id << "] = BinaryenSetLocal(the_module, " << index << ", expressions[" << expressions[value] << "]);\n";
+ }
+
ret->index = index;
ret->value = (Expression*)value;
ret->finalize();
@@ -320,6 +487,12 @@ 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 = noteExpression(ret);
+ 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 +504,12 @@ 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 = noteExpression(ret);
+ 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 +519,59 @@ 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 = noteExpression(ret);
+ 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 = noteExpression(ret);
+ 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 = noteExpression(ret);
+ 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 = noteExpression(ret);
+ 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 +579,20 @@ 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 = noteExpression(ret);
+ 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 +603,31 @@ 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 = noteExpression(ret);
+ 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 = noteExpression(ret);
+ 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 +637,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 +676,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 +693,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 +707,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 +775,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 +788,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 +816,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 +830,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 +849,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 +863,32 @@ void BinaryenModuleInterpret(BinaryenModuleRef module) {
//
RelooperRef RelooperCreate(void) {
+ if (tracing) {
+ std::cout << " 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 +897,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 << ", expressions[" << expressions[code] << "]);\n";
+ std::cout << " }\n";
+ }
+
auto* fromBlock = (CFG::Block*)from;
auto* toBlock = (CFG::Block*)to;
std::vector<Index> values;
@@ -553,8 +933,40 @@ 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 = noteExpression(ret);
+ std::cout << " expressions[" << id << "] = RelooperRenderAndDispose(the_relooper, relooperBlocks[" << relooperBlocks[entry] << "], " << labelHelper << ", the_module);\n";
+ relooperBlocks.clear();
+ }
+
delete R;
return BinaryenExpressionRef(ret);
}
+//
+// ========= Other APIs =========
+//
+
+void BinaryenSetAPITracing(int on) {
+ tracing = on;
+
+ 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 << " std::map<size_t, BinaryenFunctionRef> functions;\n";
+ std::cout << " std::map<size_t, RelooperBlockRef> relooperBlocks;\n";
+ std::cout << " BinaryenModuleRef the_module = NULL;\n";
+ std::cout << " RelooperRef the_relooper = NULL;\n";
+ } else {
+ std::cout << " return 0;\n";
+ std::cout << "}\n";
+ }
+}
+
} // extern "C"
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index 3f940c0cc..3ed5f167f 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,19 @@ 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.
+// When calling this to turn on tracing, the prelude of the full program is printed,
+// and when calling it to turn it off, the ending of the program is printed, giving
+// you the full compilable testcase.
+// 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/src/cfg/Relooper.cpp b/src/cfg/Relooper.cpp
index 4151f7885..9330be718 100644
--- a/src/cfg/Relooper.cpp
+++ b/src/cfg/Relooper.cpp
@@ -72,6 +72,9 @@ Block::~Block() {
for (BlockBranchMap::iterator iter = ProcessedBranchesOut.begin(); iter != ProcessedBranchesOut.end(); iter++) {
delete iter->second;
}
+ for (BlockBranchMap::iterator iter = BranchesOut.begin(); iter != BranchesOut.end(); iter++) {
+ delete iter->second;
+ }
}
void Block::AddBranchTo(Block *Target, wasm::Expression* Condition, wasm::Expression* Code) {
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..568492659 100644
--- a/test/example/c-api-kitchen-sink.c
+++ b/test/example/c-api-kitchen-sink.c
@@ -24,10 +24,23 @@ BinaryenExpressionRef makeUnary(BinaryenModuleRef module, BinaryenOp op, Binarye
}
BinaryenExpressionRef makeBinary(BinaryenModuleRef module, BinaryenOp op, BinaryenType type) {
- if (type == BinaryenInt32()) return BinaryenBinary(module, op, BinaryenConst(module, BinaryenLiteralInt32(-10)), BinaryenConst(module, BinaryenLiteralInt32(-11)));
- if (type == BinaryenInt64()) return BinaryenBinary(module, op, BinaryenConst(module, BinaryenLiteralInt64(-22)), BinaryenConst(module, BinaryenLiteralInt64(-23)));
- if (type == BinaryenFloat32()) return BinaryenBinary(module, op, BinaryenConst(module, BinaryenLiteralFloat32(-33.612f)), BinaryenConst(module, BinaryenLiteralFloat32(-62.5f)));
- if (type == BinaryenFloat64()) return BinaryenBinary(module, op, BinaryenConst(module, BinaryenLiteralFloat64(-9005.841)), BinaryenConst(module, BinaryenLiteralFloat64(-9007.333)));
+ if (type == BinaryenInt32()) {
+ // use temp vars to ensure optimization doesn't change the order of operation in our trace recording
+ BinaryenExpressionRef temp = BinaryenConst(module, BinaryenLiteralInt32(-11));
+ return BinaryenBinary(module, op, BinaryenConst(module, BinaryenLiteralInt32(-10)), temp);
+ }
+ if (type == BinaryenInt64()) {
+ BinaryenExpressionRef temp = BinaryenConst(module, BinaryenLiteralInt64(-23));
+ return BinaryenBinary(module, op, BinaryenConst(module, BinaryenLiteralInt64(-22)), temp);
+ }
+ if (type == BinaryenFloat32()) {
+ BinaryenExpressionRef temp = BinaryenConst(module, BinaryenLiteralFloat32(-62.5f));
+ return BinaryenBinary(module, op, BinaryenConst(module, BinaryenLiteralFloat32(-33.612f)), temp);
+ }
+ if (type == BinaryenFloat64()) {
+ BinaryenExpressionRef temp = BinaryenConst(module, BinaryenLiteralFloat64(-9007.333));
+ return BinaryenBinary(module, op, BinaryenConst(module, BinaryenLiteralFloat64(-9005.841)), temp);
+ }
abort();
}
@@ -53,15 +66,15 @@ BinaryenExpressionRef makeSomething(BinaryenModuleRef module) {
// tests
-void test_core() {
-
- // Core types
-
+void test_types() {
printf("BinaryenNone: %d\n", BinaryenNone());
printf("BinaryenInt32: %d\n", BinaryenInt32());
printf("BinaryenInt64: %d\n", BinaryenInt64());
printf("BinaryenFloat32: %d\n", BinaryenFloat32());
printf("BinaryenFloat64: %d\n", BinaryenFloat64());
+}
+
+void test_core() {
// Module creation
@@ -85,6 +98,14 @@ void test_core() {
BinaryenType params[4] = { BinaryenInt32(), BinaryenInt64(), BinaryenFloat32(), BinaryenFloat64() };
BinaryenFunctionTypeRef iiIfF = BinaryenAddFunctionType(module, "iiIfF", BinaryenInt32(), params, 4);
+ BinaryenExpressionRef temp1 = makeInt32(module, 1), temp2 = makeInt32(module, 2), temp3 = makeInt32(module, 3),
+ temp4 = makeInt32(module, 4), temp5 = makeInt32(module, 5),
+ temp6 = makeInt32(module, 0), temp7 = makeInt32(module, 1),
+ temp8 = makeInt32(module, 0), temp9 = makeInt32(module, 1),
+ temp10 = makeInt32(module, 1), temp11 = makeInt32(module, 3), temp12 = makeInt32(module, 5),
+ temp13 = makeInt32(module, 10), temp14 = makeInt32(module, 11),
+ temp15 = makeInt32(module, 110), temp16 = makeInt64(module, 111);
+
BinaryenExpressionRef valueList[] = {
// Unary
makeUnary(module, BinaryenClzInt32(), 1),
@@ -158,16 +179,16 @@ void test_core() {
makeBinary(module, BinaryenGeFloat32(), 3),
// All the rest
BinaryenBlock(module, NULL, NULL, 0), // block with no name
- BinaryenIf(module, makeInt32(module, 1), makeInt32(module, 2), makeInt32(module, 3)),
- BinaryenIf(module, makeInt32(module, 4), makeInt32(module, 5), NULL),
+ BinaryenIf(module, temp1, temp2, temp3),
+ BinaryenIf(module, temp4, temp5, NULL),
BinaryenLoop(module, "out", "in", makeInt32(module, 0)),
BinaryenLoop(module, NULL, "in2", makeInt32(module, 0)),
BinaryenLoop(module, NULL, NULL, makeInt32(module, 0)),
- BinaryenBreak(module, "the-value", makeInt32(module, 0), makeInt32(module, 1)),
+ BinaryenBreak(module, "the-value", temp6, temp7),
BinaryenBreak(module, "the-nothing", makeInt32(module, 2), NULL),
BinaryenBreak(module, "the-value", NULL, makeInt32(module, 3)),
BinaryenBreak(module, "the-nothing", NULL, NULL),
- BinaryenSwitch(module, switchValueNames, 1, "the-value", makeInt32(module, 0), makeInt32(module, 1)),
+ BinaryenSwitch(module, switchValueNames, 1, "the-value", temp8, temp9),
BinaryenSwitch(module, switchBodyNames, 1, "the-nothing", makeInt32(module, 2), NULL),
BinaryenUnary(module, BinaryenEqZInt32(), // check the output type of the call node
BinaryenCall(module, "kitchen()sinker", callOperands4, 4, BinaryenInt32())
@@ -187,9 +208,9 @@ void test_core() {
BinaryenLoad(module, 1, 1, 2, 4, BinaryenInt64(), makeInt32(module, 8)),
BinaryenLoad(module, 4, 0, 0, 0, BinaryenFloat32(), makeInt32(module, 2)),
BinaryenLoad(module, 8, 0, 2, 8, BinaryenFloat64(), makeInt32(module, 9)),
- BinaryenStore(module, 4, 0, 0, makeInt32(module, 10), makeInt32(module, 11)),
- BinaryenStore(module, 8, 2, 4, makeInt32(module, 110), makeInt64(module, 111)),
- BinaryenSelect(module, makeInt32(module, 1), makeInt32(module, 3), makeInt32(module, 5)),
+ BinaryenStore(module, 4, 0, 0, temp13, temp14),
+ BinaryenStore(module, 8, 2, 4, temp15, temp16),
+ BinaryenSelect(module, temp10, temp11, temp12),
BinaryenReturn(module, makeInt32(module, 1337)),
// TODO: Host
BinaryenNop(module),
@@ -309,7 +330,8 @@ void test_relooper() {
RelooperBlockRef block0 = RelooperAddBlock(relooper, makeInt32(module, 0));
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeInt32(module, 1));
RelooperBlockRef block2 = RelooperAddBlock(relooper, makeInt32(module, 2));
- RelooperAddBranch(block0, block1, makeInt32(module, 55), makeInt32(module, 10));
+ BinaryenExpressionRef temp = makeInt32(module, 10);
+ RelooperAddBranch(block0, block1, makeInt32(module, 55), temp);
RelooperAddBranch(block0, block2, NULL, makeInt32(module, 20));
BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0, module);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "split-plus-code", v, localTypes, 1, body);
@@ -330,7 +352,8 @@ void test_relooper() {
RelooperBlockRef block0 = RelooperAddBlock(relooper, makeInt32(module, 0));
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeInt32(module, 1));
RelooperBlockRef block2 = RelooperAddBlock(relooper, makeInt32(module, 2));
- RelooperAddBranch(block0, block1, makeInt32(module, 55), makeInt32(module, -1));
+ BinaryenExpressionRef temp = makeInt32(module, -1);
+ RelooperAddBranch(block0, block1, makeInt32(module, 55), temp);
RelooperAddBranch(block0, block2, NULL, makeInt32(module, -2));
RelooperAddBranch(block1, block2, NULL, makeInt32(module, -3));
BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0, module);
@@ -383,7 +406,8 @@ void test_relooper() {
}
{ // switch
RelooperRef relooper = RelooperCreate();
- RelooperBlockRef block0 = RelooperAddBlockWithSwitch(relooper, makeInt32(module, 0), makeInt32(module, -99));
+ BinaryenExpressionRef temp = makeInt32(module, -99);
+ RelooperBlockRef block0 = RelooperAddBlockWithSwitch(relooper, makeInt32(module, 0), temp);
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeInt32(module, 1));
RelooperBlockRef block2 = RelooperAddBlock(relooper, makeInt32(module, 2));
RelooperBlockRef block3 = RelooperAddBlock(relooper, makeInt32(module, 3));
@@ -500,10 +524,21 @@ void test_nonvalid() {
BinaryenModuleDispose(module);
}
+void test_tracing() {
+ BinaryenSetAPITracing(1);
+ test_core();
+ test_relooper();
+ BinaryenSetAPITracing(0);
+}
+
int main() {
+ test_types();
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..279c0d84c 100644
--- a/test/example/c-api-kitchen-sink.txt
+++ b/test/example/c-api-kitchen-sink.txt
@@ -817,3 +817,1389 @@ module loaded from binary form:
)
)
validation: 0
+// 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;
+ std::map<size_t, BinaryenFunctionRef> functions;
+ std::map<size_t, RelooperBlockRef> relooperBlocks;
+ BinaryenModuleRef the_module = NULL;
+ RelooperRef the_relooper = NULL;
+ the_module = BinaryenModuleCreate();
+ expressions[size_t(NULL)] = BinaryenExpressionRef(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(1));
+ expressions[14] = BinaryenConst(the_module, BinaryenLiteralInt32(2));
+ expressions[15] = BinaryenConst(the_module, BinaryenLiteralInt32(3));
+ expressions[16] = BinaryenConst(the_module, BinaryenLiteralInt32(4));
+ expressions[17] = BinaryenConst(the_module, BinaryenLiteralInt32(5));
+ expressions[18] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ expressions[19] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ expressions[20] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ expressions[21] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ expressions[22] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ expressions[23] = BinaryenConst(the_module, BinaryenLiteralInt32(3));
+ expressions[24] = BinaryenConst(the_module, BinaryenLiteralInt32(5));
+ expressions[25] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
+ expressions[26] = BinaryenConst(the_module, BinaryenLiteralInt32(11));
+ expressions[27] = BinaryenConst(the_module, BinaryenLiteralInt32(110));
+ expressions[28] = BinaryenConst(the_module, BinaryenLiteralInt64(111));
+ expressions[29] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[30] = BinaryenUnary(the_module, 0, expressions[29]);
+ expressions[31] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[32] = BinaryenUnary(the_module, 3, expressions[31]);
+ expressions[33] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[34] = BinaryenUnary(the_module, 4, expressions[33]);
+ expressions[35] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[36] = BinaryenUnary(the_module, 6, expressions[35]);
+ expressions[37] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84));
+ expressions[38] = BinaryenUnary(the_module, 9, expressions[37]);
+ expressions[39] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[40] = BinaryenUnary(the_module, 10, expressions[39]);
+ expressions[41] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84));
+ expressions[42] = BinaryenUnary(the_module, 13, expressions[41]);
+ expressions[43] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[44] = BinaryenUnary(the_module, 14, expressions[43]);
+ expressions[45] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[46] = BinaryenUnary(the_module, 16, expressions[45]);
+ expressions[47] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84));
+ expressions[48] = BinaryenUnary(the_module, 19, expressions[47]);
+ expressions[49] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[50] = BinaryenUnary(the_module, 20, expressions[49]);
+ expressions[51] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[52] = BinaryenUnary(the_module, 22, expressions[51]);
+ expressions[53] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[54] = BinaryenUnary(the_module, 23, expressions[53]);
+ expressions[55] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[56] = BinaryenUnary(the_module, 24, expressions[55]);
+ expressions[57] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[58] = BinaryenUnary(the_module, 25, expressions[57]);
+ expressions[59] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[60] = BinaryenUnary(the_module, 26, expressions[59]);
+ expressions[61] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[62] = BinaryenUnary(the_module, 27, expressions[61]);
+ expressions[63] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[64] = BinaryenUnary(the_module, 28, expressions[63]);
+ expressions[65] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84));
+ expressions[66] = BinaryenUnary(the_module, 29, expressions[65]);
+ expressions[67] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84));
+ expressions[68] = BinaryenUnary(the_module, 30, expressions[67]);
+ expressions[69] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84));
+ expressions[70] = BinaryenUnary(the_module, 31, expressions[69]);
+ expressions[71] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84));
+ expressions[72] = BinaryenUnary(the_module, 32, expressions[71]);
+ expressions[73] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[74] = BinaryenUnary(the_module, 33, expressions[73]);
+ expressions[75] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84));
+ expressions[76] = BinaryenUnary(the_module, 34, expressions[75]);
+ expressions[77] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[78] = BinaryenUnary(the_module, 35, expressions[77]);
+ expressions[79] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[80] = BinaryenUnary(the_module, 36, expressions[79]);
+ expressions[81] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[82] = BinaryenUnary(the_module, 37, expressions[81]);
+ expressions[83] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[84] = BinaryenUnary(the_module, 38, expressions[83]);
+ expressions[85] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[86] = BinaryenUnary(the_module, 39, expressions[85]);
+ expressions[87] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[88] = BinaryenUnary(the_module, 40, expressions[87]);
+ expressions[89] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[90] = BinaryenUnary(the_module, 41, expressions[89]);
+ expressions[91] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[92] = BinaryenUnary(the_module, 42, expressions[91]);
+ expressions[93] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[94] = BinaryenUnary(the_module, 43, expressions[93]);
+ expressions[95] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84));
+ expressions[96] = BinaryenUnary(the_module, 44, expressions[95]);
+ expressions[97] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[98] = BinaryenUnary(the_module, 45, expressions[97]);
+ expressions[99] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[100] = BinaryenUnary(the_module, 46, expressions[99]);
+ expressions[101] = BinaryenConst(the_module, BinaryenLiteralInt32(-11));
+ expressions[102] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[103] = BinaryenBinary(the_module, 0, expressions[102], expressions[101]);
+ expressions[104] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9007.33));
+ expressions[105] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84));
+ expressions[106] = BinaryenBinary(the_module, 64, expressions[105], expressions[104]);
+ expressions[107] = BinaryenConst(the_module, BinaryenLiteralInt32(-11));
+ expressions[108] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[109] = BinaryenBinary(the_module, 3, expressions[108], expressions[107]);
+ expressions[110] = BinaryenConst(the_module, BinaryenLiteralInt64(-23));
+ expressions[111] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[112] = BinaryenBinary(the_module, 29, expressions[111], expressions[110]);
+ expressions[113] = BinaryenConst(the_module, BinaryenLiteralInt64(-23));
+ expressions[114] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[115] = BinaryenBinary(the_module, 30, expressions[114], expressions[113]);
+ expressions[116] = BinaryenConst(the_module, BinaryenLiteralInt32(-11));
+ expressions[117] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[118] = BinaryenBinary(the_module, 6, expressions[117], expressions[116]);
+ expressions[119] = BinaryenConst(the_module, BinaryenLiteralInt32(-11));
+ expressions[120] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[121] = BinaryenBinary(the_module, 7, expressions[120], expressions[119]);
+ expressions[122] = BinaryenConst(the_module, BinaryenLiteralInt64(-23));
+ expressions[123] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[124] = BinaryenBinary(the_module, 33, expressions[123], expressions[122]);
+ expressions[125] = BinaryenConst(the_module, BinaryenLiteralInt32(-11));
+ expressions[126] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[127] = BinaryenBinary(the_module, 9, expressions[126], expressions[125]);
+ expressions[128] = BinaryenConst(the_module, BinaryenLiteralInt64(-23));
+ expressions[129] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[130] = BinaryenBinary(the_module, 35, expressions[129], expressions[128]);
+ expressions[131] = BinaryenConst(the_module, BinaryenLiteralInt64(-23));
+ expressions[132] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[133] = BinaryenBinary(the_module, 36, expressions[132], expressions[131]);
+ expressions[134] = BinaryenConst(the_module, BinaryenLiteralInt32(-11));
+ expressions[135] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[136] = BinaryenBinary(the_module, 12, expressions[135], expressions[134]);
+ expressions[137] = BinaryenConst(the_module, BinaryenLiteralInt32(-11));
+ expressions[138] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[139] = BinaryenBinary(the_module, 13, expressions[138], expressions[137]);
+ expressions[140] = BinaryenConst(the_module, BinaryenLiteralInt64(-23));
+ expressions[141] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[142] = BinaryenBinary(the_module, 39, expressions[141], expressions[140]);
+ expressions[143] = BinaryenConst(the_module, BinaryenLiteralFloat32(-62.5));
+ expressions[144] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[145] = BinaryenBinary(the_module, 53, expressions[144], expressions[143]);
+ expressions[146] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9007.33));
+ expressions[147] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84));
+ expressions[148] = BinaryenBinary(the_module, 67, expressions[147], expressions[146]);
+ expressions[149] = BinaryenConst(the_module, BinaryenLiteralFloat32(-62.5));
+ expressions[150] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[151] = BinaryenBinary(the_module, 55, expressions[150], expressions[149]);
+ expressions[152] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9007.33));
+ expressions[153] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84));
+ expressions[154] = BinaryenBinary(the_module, 69, expressions[153], expressions[152]);
+ expressions[155] = BinaryenConst(the_module, BinaryenLiteralInt32(-11));
+ expressions[156] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[157] = BinaryenBinary(the_module, 15, expressions[156], expressions[155]);
+ expressions[158] = BinaryenConst(the_module, BinaryenLiteralFloat32(-62.5));
+ expressions[159] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[160] = BinaryenBinary(the_module, 58, expressions[159], expressions[158]);
+ expressions[161] = BinaryenConst(the_module, BinaryenLiteralInt32(-11));
+ expressions[162] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[163] = BinaryenBinary(the_module, 17, expressions[162], expressions[161]);
+ expressions[164] = BinaryenConst(the_module, BinaryenLiteralInt64(-23));
+ expressions[165] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[166] = BinaryenBinary(the_module, 43, expressions[165], expressions[164]);
+ expressions[167] = BinaryenConst(the_module, BinaryenLiteralInt64(-23));
+ expressions[168] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[169] = BinaryenBinary(the_module, 44, expressions[168], expressions[167]);
+ expressions[170] = BinaryenConst(the_module, BinaryenLiteralInt32(-11));
+ expressions[171] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[172] = BinaryenBinary(the_module, 20, expressions[171], expressions[170]);
+ expressions[173] = BinaryenConst(the_module, BinaryenLiteralInt64(-23));
+ expressions[174] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[175] = BinaryenBinary(the_module, 46, expressions[174], expressions[173]);
+ expressions[176] = BinaryenConst(the_module, BinaryenLiteralInt32(-11));
+ expressions[177] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[178] = BinaryenBinary(the_module, 22, expressions[177], expressions[176]);
+ expressions[179] = BinaryenConst(the_module, BinaryenLiteralInt32(-11));
+ expressions[180] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ expressions[181] = BinaryenBinary(the_module, 23, expressions[180], expressions[179]);
+ expressions[182] = BinaryenConst(the_module, BinaryenLiteralInt64(-23));
+ expressions[183] = BinaryenConst(the_module, BinaryenLiteralInt64(-22));
+ expressions[184] = BinaryenBinary(the_module, 49, expressions[183], expressions[182]);
+ expressions[185] = BinaryenConst(the_module, BinaryenLiteralFloat32(-62.5));
+ expressions[186] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[187] = BinaryenBinary(the_module, 59, expressions[186], expressions[185]);
+ expressions[188] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9007.33));
+ expressions[189] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84));
+ expressions[190] = BinaryenBinary(the_module, 73, expressions[189], expressions[188]);
+ expressions[191] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9007.33));
+ expressions[192] = BinaryenConst(the_module, BinaryenLiteralFloat64(-9005.84));
+ expressions[193] = BinaryenBinary(the_module, 74, expressions[192], expressions[191]);
+ expressions[194] = BinaryenConst(the_module, BinaryenLiteralFloat32(-62.5));
+ expressions[195] = BinaryenConst(the_module, BinaryenLiteralFloat32(-33.612));
+ expressions[196] = BinaryenBinary(the_module, 62, expressions[195], expressions[194]);
+ {
+ BinaryenExpressionRef children[] = { };
+ expressions[197] = BinaryenBlock(the_module, NULL, children, sizeof(children) / sizeof(BinaryenExpressionRef));
+ }
+ expressions[198] = BinaryenIf(the_module, expressions[13], expressions[14], expressions[15]);
+ expressions[199] = BinaryenIf(the_module, expressions[16], expressions[17], expressions[0]);
+ expressions[200] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ expressions[201] = BinaryenLoop(the_module, "out", "in", expressions[200]);
+ expressions[202] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ expressions[203] = BinaryenLoop(the_module, NULL, "in2", expressions[202]);
+ expressions[204] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ expressions[205] = BinaryenLoop(the_module, NULL, NULL, expressions[204]);
+ expressions[206] = BinaryenBreak(the_module, "the-value", expressions[18], expressions[19]);
+ expressions[207] = BinaryenConst(the_module, BinaryenLiteralInt32(2));
+ expressions[208] = BinaryenBreak(the_module, "the-nothing", expressions[207], expressions[0]);
+ expressions[209] = BinaryenConst(the_module, BinaryenLiteralInt32(3));
+ expressions[210] = BinaryenBreak(the_module, "the-value", expressions[0], expressions[209]);
+ expressions[211] = BinaryenBreak(the_module, "the-nothing", expressions[0], expressions[0]);
+ {
+ const char* names[] = { "the-value" };
+ expressions[212] = BinaryenSwitch(the_module, names, sizeof(names) / sizeof(const char *), "the-value", expressions[20], expressions[21]);
+ }
+ expressions[213] = BinaryenConst(the_module, BinaryenLiteralInt32(2));
+ {
+ const char* names[] = { "the-nothing" };
+ expressions[214] = BinaryenSwitch(the_module, names, sizeof(names) / sizeof(const char *), "the-nothing", expressions[213], expressions[0]);
+ }
+ {
+ BinaryenExpressionRef operands[] = { expressions[9], expressions[10], expressions[11], expressions[12] };
+ expressions[215] = BinaryenCall(the_module, "kitchen()sinker", operands, 4, 1);
+ }
+ expressions[216] = BinaryenUnary(the_module, 20, expressions[215]);
+ {
+ BinaryenExpressionRef operands[] = { expressions[7], expressions[8] };
+ expressions[217] = BinaryenCallImport(the_module, "an-imported", operands, 2, 3);
+ }
+ expressions[218] = BinaryenUnary(the_module, 25, expressions[217]);
+ expressions[219] = BinaryenUnary(the_module, 20, expressions[218]);
+ expressions[220] = BinaryenConst(the_module, BinaryenLiteralInt32(2449));
+ {
+ BinaryenExpressionRef operands[] = { expressions[9], expressions[10], expressions[11], expressions[12] };
+ expressions[221] = BinaryenCallIndirect(the_module, expressions[220], operands, 4, "iiIfF");
+ }
+ expressions[222] = BinaryenUnary(the_module, 20, expressions[221]);
+ expressions[223] = BinaryenGetLocal(the_module, 0, 1);
+ expressions[224] = BinaryenConst(the_module, BinaryenLiteralInt32(101));
+ expressions[225] = BinaryenSetLocal(the_module, 0, expressions[224]);
+ expressions[226] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ expressions[227] = BinaryenLoad(the_module, 4, 0, 0, 0, 1, expressions[226]);
+ expressions[228] = BinaryenConst(the_module, BinaryenLiteralInt32(8));
+ expressions[229] = BinaryenLoad(the_module, 1, 1, 2, 4, 2, expressions[228]);
+ expressions[230] = BinaryenConst(the_module, BinaryenLiteralInt32(2));
+ expressions[231] = BinaryenLoad(the_module, 4, 0, 0, 0, 3, expressions[230]);
+ expressions[232] = BinaryenConst(the_module, BinaryenLiteralInt32(9));
+ expressions[233] = BinaryenLoad(the_module, 8, 0, 2, 8, 4, expressions[232]);
+ expressions[234] = BinaryenStore(the_module, 4, 0, 0, expressions[25], expressions[26]);
+ expressions[235] = BinaryenStore(the_module, 8, 2, 4, expressions[27], expressions[28]);
+ expressions[236] = BinaryenSelect(the_module, expressions[22], expressions[23], expressions[24]);
+ 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[36]);
+(f32.neg
+ (f32.const -33.61199951171875)
+)
+ {
+ BinaryenExpressionRef children[] = { 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[86], expressions[88], expressions[90], expressions[92], expressions[94], expressions[96], expressions[98], expressions[100], expressions[103], expressions[106], expressions[109], expressions[112], expressions[115], expressions[118], expressions[121], expressions[124], expressions[127], expressions[130], expressions[133], expressions[136], expressions[139], expressions[142], expressions[145], expressions[148], expressions[151], expressions[154], expressions[157], expressions[160], expressions[163], expressions[166], expressions[169], expressions[172], expressions[175], expressions[178], expressions[181], expressions[184], expressions[187], expressions[190], expressions[193], expressions[196], expressions[197], expressions[198], expressions[199], expressions[201], expressions[203], expressions[205], expressions[206], expressions[208], expressions[210], expressions[211], expressions[212], expressions[214], expressions[216], expressions[219], expressions[222], expressions[223], expressions[225], expressions[227], expressions[229], expressions[231], expressions[233], expressions[234], expressions[235], 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);
+ functionTypes.clear();
+ expressions.clear();
+ functions.clear();
+ relooperBlocks.clear();
+ the_module = BinaryenModuleCreate();
+ expressions[size_t(NULL)] = BinaryenExpressionRef(NULL);
+ {
+ BinaryenIndex paramTypes[] = { };
+ functionTypes[0] = BinaryenAddFunctionType(the_module, "v", 0, paramTypes, sizeof(paramTypes) / sizeof(BinaryenIndex));
+ }
+ the_relooper = RelooperCreate();
+ expressions[1] = BinaryenConst(the_module, BinaryenLiteralInt32(1337));
+ relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[1]);
+ expressions[2] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ {
+ BinaryenType varTypes[] = { 1 };
+ functions[0] = BinaryenAddFunction(the_module, "just-one-block", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[2]);
+ }
+ the_relooper = RelooperCreate();
+ expressions[3] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[3]);
+ expressions[4] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[4]);
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[0], expressions[0]);
+ expressions[5] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ {
+ BinaryenType varTypes[] = { 1 };
+ functions[1] = BinaryenAddFunction(the_module, "two-blocks", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[5]);
+ }
+ the_relooper = RelooperCreate();
+ expressions[6] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[6]);
+ expressions[7] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[7]);
+ expressions[8] = BinaryenConst(the_module, BinaryenLiteralInt32(77));
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[0], expressions[8]);
+ expressions[9] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ {
+ BinaryenType varTypes[] = { 1 };
+ functions[2] = BinaryenAddFunction(the_module, "two-blocks-plus-code", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[9]);
+ }
+ the_relooper = RelooperCreate();
+ expressions[10] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[10]);
+ expressions[11] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[11]);
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[0], expressions[0]);
+ RelooperAddBranch(relooperBlocks[1], relooperBlocks[0], expressions[0], expressions[0]);
+ expressions[12] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ {
+ BinaryenType varTypes[] = { 1 };
+ functions[3] = BinaryenAddFunction(the_module, "loop", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[12]);
+ }
+ the_relooper = RelooperCreate();
+ expressions[13] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[13]);
+ expressions[14] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[14]);
+ expressions[15] = BinaryenConst(the_module, BinaryenLiteralInt32(33));
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[0], expressions[15]);
+ expressions[16] = BinaryenConst(the_module, BinaryenLiteralInt32(-66));
+ RelooperAddBranch(relooperBlocks[1], relooperBlocks[0], expressions[0], expressions[16]);
+ expressions[17] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ {
+ BinaryenType varTypes[] = { 1 };
+ functions[4] = BinaryenAddFunction(the_module, "loop-plus-code", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[17]);
+ }
+ the_relooper = RelooperCreate();
+ expressions[18] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[18]);
+ expressions[19] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[19]);
+ expressions[20] = BinaryenConst(the_module, BinaryenLiteralInt32(2));
+ relooperBlocks[2] = RelooperAddBlock(the_relooper, expressions[20]);
+ expressions[21] = BinaryenConst(the_module, BinaryenLiteralInt32(55));
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[21], expressions[0]);
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[2], expressions[0], expressions[0]);
+ expressions[22] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ {
+ BinaryenType varTypes[] = { 1 };
+ functions[5] = BinaryenAddFunction(the_module, "split", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[22]);
+ }
+ the_relooper = RelooperCreate();
+ expressions[23] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[23]);
+ expressions[24] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[24]);
+ expressions[25] = BinaryenConst(the_module, BinaryenLiteralInt32(2));
+ relooperBlocks[2] = RelooperAddBlock(the_relooper, expressions[25]);
+ expressions[26] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
+ expressions[27] = BinaryenConst(the_module, BinaryenLiteralInt32(55));
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[27], expressions[26]);
+ expressions[28] = BinaryenConst(the_module, BinaryenLiteralInt32(20));
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[2], expressions[0], expressions[28]);
+ expressions[29] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ {
+ BinaryenType varTypes[] = { 1 };
+ functions[6] = BinaryenAddFunction(the_module, "split-plus-code", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[29]);
+ }
+ the_relooper = RelooperCreate();
+ expressions[30] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[30]);
+ expressions[31] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[31]);
+ expressions[32] = BinaryenConst(the_module, BinaryenLiteralInt32(2));
+ relooperBlocks[2] = RelooperAddBlock(the_relooper, expressions[32]);
+ expressions[33] = BinaryenConst(the_module, BinaryenLiteralInt32(55));
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[33], expressions[0]);
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[2], expressions[0], expressions[0]);
+ RelooperAddBranch(relooperBlocks[1], relooperBlocks[2], expressions[0], expressions[0]);
+ expressions[34] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ {
+ BinaryenType varTypes[] = { 1 };
+ functions[7] = BinaryenAddFunction(the_module, "if", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[34]);
+ }
+ the_relooper = RelooperCreate();
+ expressions[35] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[35]);
+ expressions[36] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[36]);
+ expressions[37] = BinaryenConst(the_module, BinaryenLiteralInt32(2));
+ relooperBlocks[2] = RelooperAddBlock(the_relooper, expressions[37]);
+ expressions[38] = BinaryenConst(the_module, BinaryenLiteralInt32(-1));
+ expressions[39] = BinaryenConst(the_module, BinaryenLiteralInt32(55));
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[39], expressions[38]);
+ expressions[40] = BinaryenConst(the_module, BinaryenLiteralInt32(-2));
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[2], expressions[0], expressions[40]);
+ expressions[41] = BinaryenConst(the_module, BinaryenLiteralInt32(-3));
+ RelooperAddBranch(relooperBlocks[1], relooperBlocks[2], expressions[0], expressions[41]);
+ expressions[42] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ {
+ BinaryenType varTypes[] = { 1 };
+ functions[8] = BinaryenAddFunction(the_module, "if-plus-code", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[42]);
+ }
+ the_relooper = RelooperCreate();
+ expressions[43] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[43]);
+ expressions[44] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[44]);
+ expressions[45] = BinaryenConst(the_module, BinaryenLiteralInt32(2));
+ relooperBlocks[2] = RelooperAddBlock(the_relooper, expressions[45]);
+ expressions[46] = BinaryenConst(the_module, BinaryenLiteralInt32(3));
+ relooperBlocks[3] = RelooperAddBlock(the_relooper, expressions[46]);
+ expressions[47] = BinaryenConst(the_module, BinaryenLiteralInt32(55));
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[47], expressions[0]);
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[2], expressions[0], expressions[0]);
+ RelooperAddBranch(relooperBlocks[1], relooperBlocks[3], expressions[0], expressions[0]);
+ RelooperAddBranch(relooperBlocks[2], relooperBlocks[3], expressions[0], expressions[0]);
+ expressions[48] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ {
+ BinaryenType varTypes[] = { 1 };
+ functions[9] = BinaryenAddFunction(the_module, "if-else", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[48]);
+ }
+ the_relooper = RelooperCreate();
+ expressions[49] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[49]);
+ expressions[50] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[50]);
+ expressions[51] = BinaryenConst(the_module, BinaryenLiteralInt32(2));
+ relooperBlocks[2] = RelooperAddBlock(the_relooper, expressions[51]);
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[0], expressions[0]);
+ expressions[52] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
+ RelooperAddBranch(relooperBlocks[1], relooperBlocks[0], expressions[52], expressions[0]);
+ RelooperAddBranch(relooperBlocks[1], relooperBlocks[2], expressions[0], expressions[0]);
+ expressions[53] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ {
+ BinaryenType varTypes[] = { 1 };
+ functions[10] = BinaryenAddFunction(the_module, "loop-tail", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[53]);
+ }
+ the_relooper = RelooperCreate();
+ expressions[54] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[54]);
+ expressions[55] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[55]);
+ expressions[56] = BinaryenConst(the_module, BinaryenLiteralInt32(2));
+ relooperBlocks[2] = RelooperAddBlock(the_relooper, expressions[56]);
+ expressions[57] = BinaryenConst(the_module, BinaryenLiteralInt32(3));
+ relooperBlocks[3] = RelooperAddBlock(the_relooper, expressions[57]);
+ expressions[58] = BinaryenConst(the_module, BinaryenLiteralInt32(4));
+ relooperBlocks[4] = RelooperAddBlock(the_relooper, expressions[58]);
+ expressions[59] = BinaryenConst(the_module, BinaryenLiteralInt32(5));
+ relooperBlocks[5] = RelooperAddBlock(the_relooper, expressions[59]);
+ expressions[60] = BinaryenConst(the_module, BinaryenLiteralInt32(6));
+ relooperBlocks[6] = RelooperAddBlock(the_relooper, expressions[60]);
+ expressions[61] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[0], expressions[61]);
+ expressions[62] = BinaryenConst(the_module, BinaryenLiteralInt32(-2));
+ RelooperAddBranch(relooperBlocks[1], relooperBlocks[2], expressions[62], expressions[0]);
+ expressions[63] = BinaryenConst(the_module, BinaryenLiteralInt32(20));
+ RelooperAddBranch(relooperBlocks[1], relooperBlocks[6], expressions[0], expressions[63]);
+ expressions[64] = BinaryenConst(the_module, BinaryenLiteralInt32(-6));
+ RelooperAddBranch(relooperBlocks[2], relooperBlocks[3], expressions[64], expressions[0]);
+ expressions[65] = BinaryenConst(the_module, BinaryenLiteralInt32(30));
+ RelooperAddBranch(relooperBlocks[2], relooperBlocks[1], expressions[0], expressions[65]);
+ expressions[66] = BinaryenConst(the_module, BinaryenLiteralInt32(-10));
+ RelooperAddBranch(relooperBlocks[3], relooperBlocks[4], expressions[66], expressions[0]);
+ RelooperAddBranch(relooperBlocks[3], relooperBlocks[5], expressions[0], expressions[0]);
+ RelooperAddBranch(relooperBlocks[4], relooperBlocks[5], expressions[0], expressions[0]);
+ expressions[67] = BinaryenConst(the_module, BinaryenLiteralInt32(40));
+ RelooperAddBranch(relooperBlocks[5], relooperBlocks[6], expressions[0], expressions[67]);
+ expressions[68] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ {
+ BinaryenType varTypes[] = { 1 };
+ functions[11] = BinaryenAddFunction(the_module, "nontrivial-loop-plus-phi-to-head", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[68]);
+ }
+ the_relooper = RelooperCreate();
+ expressions[69] = BinaryenConst(the_module, BinaryenLiteralInt32(-99));
+ expressions[70] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ relooperBlocks[0] = RelooperAddBlockWithSwitch(the_relooper, expressions[70], expressions[69]);
+ expressions[71] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[71]);
+ expressions[72] = BinaryenConst(the_module, BinaryenLiteralInt32(2));
+ relooperBlocks[2] = RelooperAddBlock(the_relooper, expressions[72]);
+ expressions[73] = BinaryenConst(the_module, BinaryenLiteralInt32(3));
+ relooperBlocks[3] = RelooperAddBlock(the_relooper, expressions[73]);
+ {
+ BinaryenIndex indexes[] = { 2, 5 };
+ RelooperAddBranchForSwitch(relooperBlocks[0], relooperBlocks[1], indexes, 2, expressions[0]);
+ }
+ expressions[74] = BinaryenConst(the_module, BinaryenLiteralInt32(55));
+ {
+ BinaryenIndex indexes[] = { 4 };
+ RelooperAddBranchForSwitch(relooperBlocks[0], relooperBlocks[2], indexes, 1, expressions[74]);
+ }
+ {
+ BinaryenIndex indexes[] = { };
+ RelooperAddBranchForSwitch(relooperBlocks[0], relooperBlocks[3], indexes, 0, expressions[0]);
+ }
+ expressions[75] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ {
+ BinaryenType varTypes[] = { 1 };
+ functions[12] = BinaryenAddFunction(the_module, "switch", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[75]);
+ }
+ the_relooper = RelooperCreate();
+ expressions[76] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
+ relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[76]);
+ expressions[77] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
+ relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[77]);
+ expressions[78] = BinaryenConst(the_module, BinaryenLiteralInt32(2));
+ relooperBlocks[2] = RelooperAddBlock(the_relooper, expressions[78]);
+ expressions[79] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[79], expressions[0]);
+ RelooperAddBranch(relooperBlocks[0], relooperBlocks[2], expressions[0], expressions[0]);
+ RelooperAddBranch(relooperBlocks[1], relooperBlocks[2], expressions[0], expressions[0]);
+ RelooperAddBranch(relooperBlocks[2], relooperBlocks[1], expressions[0], expressions[0]);
+ expressions[80] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 3, the_module);
+ {
+ BinaryenType varTypes[] = { 1, 1, 2, 1, 3, 4, 1 };
+ functions[13] = BinaryenAddFunction(the_module, "duffs-device", functionTypes[0], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[80]);
+ }
+ {
+ BinaryenIndex paramTypes[] = { };
+ functionTypes[1] = BinaryenAddFunctionType(the_module, "i", 1, paramTypes, sizeof(paramTypes) / sizeof(BinaryenIndex));
+ }
+ the_relooper = RelooperCreate();
+ expressions[81] = BinaryenConst(the_module, BinaryenLiteralInt32(42));
+ expressions[82] = BinaryenConst(the_module, BinaryenLiteralInt32(1337));
+ expressions[83] = BinaryenReturn(the_module, expressions[82]);
+ {
+ BinaryenExpressionRef children[] = { expressions[81], expressions[83] };
+ expressions[84] = BinaryenBlock(the_module, "the-list", children, sizeof(children) / sizeof(BinaryenExpressionRef));
+ }
+ relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[84]);
+ expressions[85] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ {
+ BinaryenType varTypes[] = { 1 };
+ functions[14] = BinaryenAddFunction(the_module, "return", functionTypes[1], varTypes, sizeof(varTypes) / sizeof(BinaryenType), expressions[85]);
+ }
+raw:
+ BinaryenModulePrint(the_module);
+(module
+ (memory 0)
+ (type $v (func))
+ (type $i (func (result i32)))
+ (func $just-one-block (type $v)
+ (local $0 i32)
+ (i32.const 1337)
+ )
+ (func $two-blocks (type $v)
+ (local $0 i32)
+ (block
+ (i32.const 0)
+ )
+ (block
+ (i32.const 1)
+ )
+ )
+ (func $two-blocks-plus-code (type $v)
+ (local $0 i32)
+ (block
+ (i32.const 0)
+ (block
+ (i32.const 77)
+ )
+ )
+ (block
+ (i32.const 1)
+ )
+ )
+ (func $loop (type $v)
+ (local $0 i32)
+ (loop $shape$0$break $shape$0$continue
+ (block
+ (i32.const 0)
+ )
+ (block
+ (i32.const 1)
+ (block
+ (br $shape$0$continue)
+ )
+ )
+ )
+ )
+ (func $loop-plus-code (type $v)
+ (local $0 i32)
+ (loop $shape$0$break $shape$0$continue
+ (block
+ (i32.const 0)
+ (block
+ (i32.const 33)
+ )
+ )
+ (block
+ (i32.const 1)
+ (block
+ (i32.const -66)
+ (br $shape$0$continue)
+ )
+ )
+ )
+ )
+ (func $split (type $v)
+ (local $0 i32)
+ (i32.const 0)
+ (block $shape$1$break
+ (if
+ (i32.const 55)
+ (block
+ (i32.const 1)
+ )
+ (block
+ (i32.const 2)
+ )
+ )
+ )
+ )
+ (func $split-plus-code (type $v)
+ (local $0 i32)
+ (i32.const 0)
+ (block $shape$1$break
+ (if
+ (i32.const 55)
+ (block
+ (i32.const 10)
+ (block
+ (i32.const 1)
+ )
+ )
+ (block
+ (i32.const 20)
+ (block
+ (i32.const 2)
+ )
+ )
+ )
+ )
+ )
+ (func $if (type $v)
+ (local $0 i32)
+ (block
+ (i32.const 0)
+ (block $shape$1$break
+ (if
+ (i32.const 55)
+ (block
+ (i32.const 1)
+ (block
+ (br $shape$1$break)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (i32.const 2)
+ )
+ )
+ (func $if-plus-code (type $v)
+ (local $0 i32)
+ (block
+ (i32.const 0)
+ (block $shape$1$break
+ (if
+ (i32.const 55)
+ (block
+ (i32.const -1)
+ (block
+ (i32.const 1)
+ (block
+ (i32.const -3)
+ (br $shape$1$break)
+ )
+ )
+ )
+ (i32.const -2)
+ )
+ )
+ )
+ (block
+ (i32.const 2)
+ )
+ )
+ (func $if-else (type $v)
+ (local $0 i32)
+ (block
+ (i32.const 0)
+ (block $shape$1$break
+ (if
+ (i32.const 55)
+ (block
+ (i32.const 1)
+ (block
+ (br $shape$1$break)
+ )
+ )
+ (block
+ (i32.const 2)
+ (block
+ (br $shape$1$break)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (i32.const 3)
+ )
+ )
+ (func $loop-tail (type $v)
+ (local $0 i32)
+ (loop $shape$0$break $shape$0$continue
+ (block
+ (i32.const 0)
+ )
+ (block
+ (i32.const 1)
+ (if
+ (i32.const 10)
+ (br $shape$0$continue)
+ (br $shape$0$break)
+ )
+ )
+ )
+ (block
+ (i32.const 2)
+ )
+ )
+ (func $nontrivial-loop-plus-phi-to-head (type $v)
+ (local $0 i32)
+ (block
+ (i32.const 0)
+ (block
+ (i32.const 10)
+ )
+ )
+ (block
+ (loop $shape$1$break $shape$1$continue
+ (block
+ (i32.const 1)
+ (if
+ (i32.eqz
+ (i32.const -2)
+ )
+ (block
+ (i32.const 20)
+ (br $shape$1$break)
+ )
+ )
+ )
+ (block
+ (i32.const 2)
+ (if
+ (i32.const -6)
+ (block
+ (set_local $0
+ (i32.const 4)
+ )
+ (br $shape$1$break)
+ )
+ (block
+ (i32.const 30)
+ (br $shape$1$continue)
+ )
+ )
+ )
+ )
+ (block
+ (block $shape$4$break
+ (if
+ (i32.eq
+ (get_local $0)
+ (i32.const 4)
+ )
+ (block
+ (block
+ (i32.const 3)
+ (block $shape$6$break
+ (if
+ (i32.const -10)
+ (block
+ (i32.const 4)
+ (block
+ (br $shape$6$break)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (i32.const 5)
+ (block
+ (i32.const 40)
+ (br $shape$4$break)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (i32.const 6)
+ )
+ )
+ )
+ )
+ (func $switch (type $v)
+ (local $0 i32)
+ (i32.const 0)
+ (block $shape$1$break
+ (block $switch$1$leave
+ (block $switch$1$default
+ (block $switch$1$case$3
+ (block $switch$1$case$2
+ (br_table $switch$1$default $switch$1$default $switch$1$case$2 $switch$1$default $switch$1$case$3 $switch$1$case$2 $switch$1$default
+ (i32.const -99)
+ )
+ )
+ (block
+ (block
+ (i32.const 1)
+ )
+ )
+ (br $switch$1$leave)
+ )
+ (block
+ (i32.const 55)
+ (block
+ (i32.const 2)
+ )
+ )
+ (br $switch$1$leave)
+ )
+ (block
+ (block
+ (i32.const 3)
+ )
+ )
+ (br $switch$1$leave)
+ )
+ )
+ )
+ (func $duffs-device (type $v)
+ (local $0 i32)
+ (local $1 i32)
+ (local $2 i64)
+ (local $3 i32)
+ (local $4 f32)
+ (local $5 f64)
+ (local $6 i32)
+ (block
+ (i32.const 0)
+ (if
+ (i32.const 10)
+ (set_local $3
+ (i32.const 2)
+ )
+ (set_local $3
+ (i32.const 3)
+ )
+ )
+ )
+ (loop $shape$1$break $shape$1$continue
+ (block $shape$2$break
+ (if
+ (i32.eq
+ (get_local $3)
+ (i32.const 2)
+ )
+ (block
+ (set_local $3
+ (i32.const 0)
+ )
+ (i32.const 1)
+ (block
+ (set_local $3
+ (i32.const 3)
+ )
+ (br $shape$1$continue)
+ )
+ )
+ (if
+ (i32.eq
+ (get_local $3)
+ (i32.const 3)
+ )
+ (block
+ (set_local $3
+ (i32.const 0)
+ )
+ (i32.const 2)
+ (block
+ (set_local $3
+ (i32.const 2)
+ )
+ (br $shape$1$continue)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (func $return (type $i) (result i32)
+ (local $0 i32)
+ (block $the-list
+ (i32.const 42)
+ (return
+ (i32.const 1337)
+ )
+ )
+ )
+)
+ BinaryenModuleValidate(the_module);
+ BinaryenModuleOptimize(the_module);
+ BinaryenModuleValidate(the_module);
+optimized:
+ BinaryenModulePrint(the_module);
+(module
+ (memory 0)
+ (type $v (func))
+ (type $i (func (result i32)))
+ (func $just-one-block (type $v)
+ (nop)
+ )
+ (func $duffs-device (type $v)
+ (local $0 i32)
+ (set_local $0
+ (i32.const 2)
+ )
+ (loop $shape$1$break $shape$1$continue
+ (if
+ (i32.eq
+ (get_local $0)
+ (i32.const 2)
+ )
+ (block
+ (set_local $0
+ (i32.const 3)
+ )
+ (br $shape$1$continue)
+ )
+ (if
+ (i32.eq
+ (get_local $0)
+ (i32.const 3)
+ )
+ (block
+ (set_local $0
+ (i32.const 2)
+ )
+ (br $shape$1$continue)
+ )
+ )
+ )
+ )
+ )
+ (func $return (type $i) (result i32)
+ (i32.const 1337)
+ )
+)
+ BinaryenModuleDispose(the_module);
+ functionTypes.clear();
+ expressions.clear();
+ functions.clear();
+ relooperBlocks.clear();
+ 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..a9e599bef
--- /dev/null
+++ b/test/example/c-api-kitchen-sink.txt.txt
@@ -0,0 +1,777 @@
+(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)
+ )
+)
+(module
+ (memory 0)
+ (type $v (func))
+ (type $i (func (result i32)))
+ (func $just-one-block (type $v)
+ (local $0 i32)
+ (i32.const 1337)
+ )
+ (func $two-blocks (type $v)
+ (local $0 i32)
+ (block
+ (i32.const 0)
+ )
+ (block
+ (i32.const 1)
+ )
+ )
+ (func $two-blocks-plus-code (type $v)
+ (local $0 i32)
+ (block
+ (i32.const 0)
+ (block
+ (i32.const 77)
+ )
+ )
+ (block
+ (i32.const 1)
+ )
+ )
+ (func $loop (type $v)
+ (local $0 i32)
+ (loop $shape$0$break $shape$0$continue
+ (block
+ (i32.const 0)
+ )
+ (block
+ (i32.const 1)
+ (block
+ (br $shape$0$continue)
+ )
+ )
+ )
+ )
+ (func $loop-plus-code (type $v)
+ (local $0 i32)
+ (loop $shape$0$break $shape$0$continue
+ (block
+ (i32.const 0)
+ (block
+ (i32.const 33)
+ )
+ )
+ (block
+ (i32.const 1)
+ (block
+ (i32.const -66)
+ (br $shape$0$continue)
+ )
+ )
+ )
+ )
+ (func $split (type $v)
+ (local $0 i32)
+ (i32.const 0)
+ (block $shape$1$break
+ (if
+ (i32.const 55)
+ (block
+ (i32.const 1)
+ )
+ (block
+ (i32.const 2)
+ )
+ )
+ )
+ )
+ (func $split-plus-code (type $v)
+ (local $0 i32)
+ (i32.const 0)
+ (block $shape$1$break
+ (if
+ (i32.const 55)
+ (block
+ (i32.const 10)
+ (block
+ (i32.const 1)
+ )
+ )
+ (block
+ (i32.const 20)
+ (block
+ (i32.const 2)
+ )
+ )
+ )
+ )
+ )
+ (func $if (type $v)
+ (local $0 i32)
+ (block
+ (i32.const 0)
+ (block $shape$1$break
+ (if
+ (i32.const 55)
+ (block
+ (i32.const 1)
+ (block
+ (br $shape$1$break)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (i32.const 2)
+ )
+ )
+ (func $if-plus-code (type $v)
+ (local $0 i32)
+ (block
+ (i32.const 0)
+ (block $shape$1$break
+ (if
+ (i32.const 55)
+ (block
+ (i32.const -1)
+ (block
+ (i32.const 1)
+ (block
+ (i32.const -3)
+ (br $shape$1$break)
+ )
+ )
+ )
+ (i32.const -2)
+ )
+ )
+ )
+ (block
+ (i32.const 2)
+ )
+ )
+ (func $if-else (type $v)
+ (local $0 i32)
+ (block
+ (i32.const 0)
+ (block $shape$1$break
+ (if
+ (i32.const 55)
+ (block
+ (i32.const 1)
+ (block
+ (br $shape$1$break)
+ )
+ )
+ (block
+ (i32.const 2)
+ (block
+ (br $shape$1$break)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (i32.const 3)
+ )
+ )
+ (func $loop-tail (type $v)
+ (local $0 i32)
+ (loop $shape$0$break $shape$0$continue
+ (block
+ (i32.const 0)
+ )
+ (block
+ (i32.const 1)
+ (if
+ (i32.const 10)
+ (br $shape$0$continue)
+ (br $shape$0$break)
+ )
+ )
+ )
+ (block
+ (i32.const 2)
+ )
+ )
+ (func $nontrivial-loop-plus-phi-to-head (type $v)
+ (local $0 i32)
+ (block
+ (i32.const 0)
+ (block
+ (i32.const 10)
+ )
+ )
+ (block
+ (loop $shape$1$break $shape$1$continue
+ (block
+ (i32.const 1)
+ (if
+ (i32.eqz
+ (i32.const -2)
+ )
+ (block
+ (i32.const 20)
+ (br $shape$1$break)
+ )
+ )
+ )
+ (block
+ (i32.const 2)
+ (if
+ (i32.const -6)
+ (block
+ (set_local $0
+ (i32.const 4)
+ )
+ (br $shape$1$break)
+ )
+ (block
+ (i32.const 30)
+ (br $shape$1$continue)
+ )
+ )
+ )
+ )
+ (block
+ (block $shape$4$break
+ (if
+ (i32.eq
+ (get_local $0)
+ (i32.const 4)
+ )
+ (block
+ (block
+ (i32.const 3)
+ (block $shape$6$break
+ (if
+ (i32.const -10)
+ (block
+ (i32.const 4)
+ (block
+ (br $shape$6$break)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (i32.const 5)
+ (block
+ (i32.const 40)
+ (br $shape$4$break)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (i32.const 6)
+ )
+ )
+ )
+ )
+ (func $switch (type $v)
+ (local $0 i32)
+ (i32.const 0)
+ (block $shape$1$break
+ (block $switch$1$leave
+ (block $switch$1$default
+ (block $switch$1$case$3
+ (block $switch$1$case$2
+ (br_table $switch$1$default $switch$1$default $switch$1$case$2 $switch$1$default $switch$1$case$3 $switch$1$case$2 $switch$1$default
+ (i32.const -99)
+ )
+ )
+ (block
+ (block
+ (i32.const 1)
+ )
+ )
+ (br $switch$1$leave)
+ )
+ (block
+ (i32.const 55)
+ (block
+ (i32.const 2)
+ )
+ )
+ (br $switch$1$leave)
+ )
+ (block
+ (block
+ (i32.const 3)
+ )
+ )
+ (br $switch$1$leave)
+ )
+ )
+ )
+ (func $duffs-device (type $v)
+ (local $0 i32)
+ (local $1 i32)
+ (local $2 i64)
+ (local $3 i32)
+ (local $4 f32)
+ (local $5 f64)
+ (local $6 i32)
+ (block
+ (i32.const 0)
+ (if
+ (i32.const 10)
+ (set_local $3
+ (i32.const 2)
+ )
+ (set_local $3
+ (i32.const 3)
+ )
+ )
+ )
+ (loop $shape$1$break $shape$1$continue
+ (block $shape$2$break
+ (if
+ (i32.eq
+ (get_local $3)
+ (i32.const 2)
+ )
+ (block
+ (set_local $3
+ (i32.const 0)
+ )
+ (i32.const 1)
+ (block
+ (set_local $3
+ (i32.const 3)
+ )
+ (br $shape$1$continue)
+ )
+ )
+ (if
+ (i32.eq
+ (get_local $3)
+ (i32.const 3)
+ )
+ (block
+ (set_local $3
+ (i32.const 0)
+ )
+ (i32.const 2)
+ (block
+ (set_local $3
+ (i32.const 2)
+ )
+ (br $shape$1$continue)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (func $return (type $i) (result i32)
+ (local $0 i32)
+ (block $the-list
+ (i32.const 42)
+ (return
+ (i32.const 1337)
+ )
+ )
+ )
+)
+(module
+ (memory 0)
+ (type $v (func))
+ (type $i (func (result i32)))
+ (func $just-one-block (type $v)
+ (nop)
+ )
+ (func $duffs-device (type $v)
+ (local $0 i32)
+ (set_local $0
+ (i32.const 2)
+ )
+ (loop $shape$1$break $shape$1$continue
+ (if
+ (i32.eq
+ (get_local $0)
+ (i32.const 2)
+ )
+ (block
+ (set_local $0
+ (i32.const 3)
+ )
+ (br $shape$1$continue)
+ )
+ (if
+ (i32.eq
+ (get_local $0)
+ (i32.const 3)
+ )
+ (block
+ (set_local $0
+ (i32.const 2)
+ )
+ (br $shape$1$continue)
+ )
+ )
+ )
+ )
+ )
+ (func $return (type $i) (result i32)
+ (i32.const 1337)
+ )
+)