diff options
-rw-r--r-- | src/binaryen-c.cpp | 12 | ||||
-rw-r--r-- | src/binaryen-c.h | 8 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.c | 31 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.txt | 658 |
4 files changed, 369 insertions, 340 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index bbafdf49d..a876c998b 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -23,6 +23,7 @@ #include "wasm.h" #include "wasm-builder.h" #include "wasm-printing.h" +#include "wasm-validator.h" #include "cfg/Relooper.h" using namespace wasm; @@ -193,7 +194,7 @@ BinaryenExpressionRef BinaryenLoop(BinaryenModuleRef module, const char* out, co if (out && !in) abort(); return Builder(*((Module*)module)).makeLoop(out ? Name(out) : Name(), in ? Name(in) : Name(), (Expression*)body); } -BinaryenExpressionRef BinaryenBreak(BinaryenModuleRef module, const char* name, BinaryenExpressionRef value, BinaryenExpressionRef condition) { +BinaryenExpressionRef BinaryenBreak(BinaryenModuleRef module, const char* name, BinaryenExpressionRef condition, BinaryenExpressionRef value) { return Builder(*((Module*)module)).makeBreak(name, (Expression*)value, (Expression*)condition); } BinaryenExpressionRef BinaryenSwitch(BinaryenModuleRef module, const char **names, BinaryenIndex numNames, const char* defaultName, BinaryenExpressionRef condition, BinaryenExpressionRef value) { @@ -372,9 +373,9 @@ void BinaryenSetMemory(BinaryenModuleRef module, BinaryenIndex initial, Binaryen // Start function. One per module -void BinaryenSetStart(BinaryenModuleRef module, const char* name) { +void BinaryenSetStart(BinaryenModuleRef module, BinaryenFunctionRef start) { auto* wasm = (Module*)module; - wasm->addStart(name); + wasm->addStart(((Function*)start)->name); } // @@ -385,6 +386,11 @@ void BinaryenModulePrint(BinaryenModuleRef module) { WasmPrinter::printModule((Module*)module); } +int BinaryenModuleValidate(BinaryenModuleRef module) { + Module* wasm = (Module*)module; + return WasmValidator().validate(*wasm) ? 1 : 0; +} + void BinaryenModuleOptimize(BinaryenModuleRef module) { Module* wasm = (Module*)module; PassRunner passRunner(wasm); diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 2e0a7b996..9319de209 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -196,7 +196,7 @@ BinaryenExpressionRef BinaryenIf(BinaryenModuleRef module, BinaryenExpressionRef // Loop: both out and in can be NULL, or just out can be NULL BinaryenExpressionRef BinaryenLoop(BinaryenModuleRef module, const char* out, const char* in, BinaryenExpressionRef body); // Break: value and condition can be NULL -BinaryenExpressionRef BinaryenBreak(BinaryenModuleRef module, const char* name, BinaryenExpressionRef value, BinaryenExpressionRef condition); +BinaryenExpressionRef BinaryenBreak(BinaryenModuleRef module, const char* name, BinaryenExpressionRef condition, BinaryenExpressionRef value); // Switch: value can be NULL BinaryenExpressionRef BinaryenSwitch(BinaryenModuleRef module, const char **names, BinaryenIndex numNames, const char* defaultName, BinaryenExpressionRef condition, BinaryenExpressionRef value); BinaryenExpressionRef BinaryenCall(BinaryenModuleRef module, const char *target, BinaryenExpressionRef* operands, BinaryenIndex numOperands); @@ -257,7 +257,7 @@ void BinaryenSetMemory(BinaryenModuleRef module, BinaryenIndex initial, Binaryen // Start function. One per module -void BinaryenSetStart(BinaryenModuleRef module, const char* name); +void BinaryenSetStart(BinaryenModuleRef module, BinaryenFunctionRef start); // // ========== Module Operations ========== @@ -266,6 +266,10 @@ void BinaryenSetStart(BinaryenModuleRef module, const char* name); // Print a module to stdout. void BinaryenModulePrint(BinaryenModuleRef module); +// Validate a module, showing errors on problems. +// @return 0 if an error occurred, 1 if validated succesfully +int BinaryenModuleValidate(BinaryenModuleRef module); + // Run the standard optimization passes on the module. void BinaryenModuleOptimize(BinaryenModuleRef module); diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index b7b938c55..ee32725c1 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -1,4 +1,5 @@ +#include <assert.h> #include <stdio.h> #include <stdlib.h> @@ -71,7 +72,8 @@ void test_core() { constF32Bits = BinaryenConst(module, BinaryenLiteralFloat32Bits(0xffff1234)), constF64Bits = BinaryenConst(module, BinaryenLiteralFloat64Bits(0xffff12345678abcdLL)); - const char* switchNames[] = { "the-body" }; + const char* switchValueNames[] = { "the-value" }; + const char* switchBodyNames[] = { "the-body" }; BinaryenExpressionRef callOperands2[] = { makeInt32(module, 13), makeFloat64(module, 3.7) }; BinaryenExpressionRef callOperands4[] = { makeInt32(module, 13), makeInt64(module, 37), makeFloat32(module, 1.3), makeFloat64(module, 3.7) }; @@ -157,12 +159,12 @@ void test_core() { BinaryenLoop(module, "out", "in", makeInt32(module, 0)), BinaryenLoop(module, NULL, "in2", makeInt32(module, 0)), BinaryenLoop(module, NULL, NULL, makeInt32(module, 0)), - BinaryenBreak(module, "the-body", makeInt32(module, 0), makeInt32(module, 1)), + BinaryenBreak(module, "the-value", makeInt32(module, 0), makeInt32(module, 1)), BinaryenBreak(module, "the-body", makeInt32(module, 2), NULL), - BinaryenBreak(module, "the-body", NULL, makeInt32(module, 3)), + BinaryenBreak(module, "the-value", NULL, makeInt32(module, 3)), BinaryenBreak(module, "the-body", NULL, NULL), - BinaryenSwitch(module, switchNames, 1, "the-body", makeInt32(module, 0), makeInt32(module, 1)), - BinaryenSwitch(module, switchNames, 1, "the-body", makeInt32(module, 2), NULL), + BinaryenSwitch(module, switchValueNames, 1, "the-value", makeInt32(module, 0), makeInt32(module, 1)), + BinaryenSwitch(module, switchBodyNames, 1, "the-body", makeInt32(module, 2), NULL), BinaryenCall(module, "kitchen-sinker", callOperands4, 4), BinaryenCallImport(module, "an-imported", callOperands2, 2), BinaryenCallIndirect(module, makeInt32(module, 2449), callOperands4, 4, iiIfF), @@ -182,8 +184,9 @@ void test_core() { BinaryenUnreachable(module), }; - // Make the main body of the function - BinaryenExpressionRef body = BinaryenBlock(module, "the-body", bodyList, sizeof(bodyList) / sizeof(BinaryenExpressionRef)); + // Make the main body of the function. one block with a return value, one without + BinaryenExpressionRef value = BinaryenBlock(module, "the-value", bodyList, sizeof(bodyList) / sizeof(BinaryenExpressionRef)); + BinaryenExpressionRef body = BinaryenBlock(module, "the-body", &value, 1); // Create the function BinaryenType localTypes[] = { BinaryenInt32() }; @@ -212,7 +215,12 @@ void test_core() { // Start function. One per module - BinaryenSetStart(module, "sinker"); + BinaryenFunctionTypeRef v = BinaryenAddFunctionType(module, "v", BinaryenNone(), NULL, 0); + BinaryenFunctionRef starter = BinaryenAddFunction(module, "starter", v, NULL, 0, BinaryenNop(module)); + BinaryenSetStart(module, starter); + + // Verify it validates + assert(BinaryenModuleValidate(module)); // Print it out BinaryenModulePrint(module); @@ -354,11 +362,16 @@ void test_relooper() { BinaryenFunctionRef sinker = BinaryenAddFunction(module, "nontrivial-loop-plus-phi-to-head", v, localTypes, 1, body); } + assert(BinaryenModuleValidate(module)); + printf("raw:\n"); BinaryenModulePrint(module); - printf("optimized:\n"); BinaryenModuleOptimize(module); + + assert(BinaryenModuleValidate(module)); + + printf("optimized:\n"); BinaryenModulePrint(module); BinaryenModuleDispose(module); diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 71b937219..226e937ce 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -8,343 +8,349 @@ BinaryenFloat64: 4 (segment 10 "hello, world") ) (export "mem" memory) - (start $sinker) + (start $starter) (type $iiIfF (func (param i32 i64 f32 f64) (result i32))) (type $viF (func (param i32 f64))) + (type $v (func)) (import $an-imported "module" "base" (param i32 f64)) (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 - (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 - (i32.const -10) - ) - (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-body - (i32.const 0) - (i32.const 1) - ) - (br $the-body - (i32.const 2) - ) - (br_if $the-body - (i32.const 3) - ) - (br $the-body) - (br_table $the-body $the-body - (i32.const 1) - (i32.const 0) - ) - (br_table $the-body $the-body - (i32.const 2) - ) - (call $kitchen-sinker - (i32.const 13) - (i64.const 37) - (f32.const 1.2999999523162842) - (f64.const 3.7) - ) - (call_import $an-imported - (i32.const 13) - (f64.const 3.7) - ) - (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) - (return - (f32.const 1) + (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 + (i32.const -10) + ) + (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-body + (i32.const 2) + ) + (br $the-value + (i32.const 3) + ) + (br $the-body) + (br_table $the-value $the-value + (i32.const 1) + (i32.const 0) + ) + (br_table $the-body $the-body + (i32.const 2) + ) + (call $kitchen-sinker + (i32.const 13) + (i64.const 37) + (f32.const 1.2999999523162842) + (f64.const 3.7) + ) + (call_import $an-imported + (i32.const 13) + (f64.const 3.7) + ) + (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) + (return + (f32.const 1) + ) + (nop) + (unreachable) ) - (nop) - (unreachable) ) ) + (func $starter (type $v) + (nop) + ) ) raw: (module |