diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-05-03 17:14:07 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-05-03 17:14:07 -0700 |
commit | 5b2adeb4b2a66dfcda7667ce7a4c27ec49c62b1b (patch) | |
tree | 01dc41e6217c6026e4c97f0fe5bbc28066f79479 /test | |
parent | d435670997e524df9707354d468a22432a181411 (diff) | |
parent | fd14d9cfc4cd744a8d143bb6a2622c68f5d33cfd (diff) | |
download | binaryen-5b2adeb4b2a66dfcda7667ce7a4c27ec49c62b1b.tar.gz binaryen-5b2adeb4b2a66dfcda7667ce7a4c27ec49c62b1b.tar.bz2 binaryen-5b2adeb4b2a66dfcda7667ce7a4c27ec49c62b1b.zip |
Merge pull request #427 from WebAssembly/c-api-nice
C API
Diffstat (limited to 'test')
-rw-r--r-- | test/example/c-api-hello-world.c | 29 | ||||
-rw-r--r-- | test/example/c-api-hello-world.txt | 10 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.c | 213 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.txt | 318 |
4 files changed, 570 insertions, 0 deletions
diff --git a/test/example/c-api-hello-world.c b/test/example/c-api-hello-world.c new file mode 100644 index 000000000..016c2404b --- /dev/null +++ b/test/example/c-api-hello-world.c @@ -0,0 +1,29 @@ + +#include <binaryen-c.h> + +// "hello world" type example: create a function that adds two i32s and returns the result + +int main() { + BinaryenModuleRef module = BinaryenModuleCreate(); + + // Creation a function type for i32 (i32, i32) + BinaryenType params[2] = { BinaryenInt32(), BinaryenInt32() }; + BinaryenFunctionTypeRef iii = BinaryenAddFunctionType(module, "iii", BinaryenInt32(), params, 2); + + // Get the 0 and 1 arguments, and add them + BinaryenExpressionRef x = BinaryenGetLocal(module, 0, BinaryenInt32()), + y = BinaryenGetLocal(module, 1, BinaryenInt32()); + BinaryenExpressionRef add = BinaryenBinary(module, BinaryenAdd(), x, y); + + // Create the add function + // Note: no additional local variables + // Note: no basic blocks here, we are an AST. The function body is just an expression node. + BinaryenFunctionRef adder = BinaryenAddFunction(module, "adder", iii, NULL, 0, add); + + // Print it out + BinaryenModulePrint(module); + + // Clean up the module, which owns all the objects we created above + BinaryenModuleDispose(module); +} + diff --git a/test/example/c-api-hello-world.txt b/test/example/c-api-hello-world.txt new file mode 100644 index 000000000..4360107d3 --- /dev/null +++ b/test/example/c-api-hello-world.txt @@ -0,0 +1,10 @@ +(module + (memory 0) + (type $iii (func (param i32 i32) (result i32))) + (func $adder (type $iii) (param $0 i32) (param $1 i32) (result i32) + (i32.add + (get_local $0) + (get_local $1) + ) + ) +) diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c new file mode 100644 index 000000000..f7dc5c341 --- /dev/null +++ b/test/example/c-api-kitchen-sink.c @@ -0,0 +1,213 @@ + +#include <stdio.h> +#include <stdlib.h> + +#include <binaryen-c.h> + + +// kitchen sink, tests the full API + + +// helpers + +BinaryenExpressionRef makeUnary(BinaryenModuleRef module, BinaryenOp op, BinaryenType inputType, BinaryenType outputType) { + if (inputType == BinaryenInt32()) return BinaryenUnary(module, op, BinaryenConst(module, BinaryenLiteralInt32(-10)), outputType); + if (inputType == BinaryenInt64()) return BinaryenUnary(module, op, BinaryenConst(module, BinaryenLiteralInt64(-22)), outputType); + if (inputType == BinaryenFloat32()) return BinaryenUnary(module, op, BinaryenConst(module, BinaryenLiteralFloat32(-33.612)), outputType); + if (inputType == BinaryenFloat64()) return BinaryenUnary(module, op, BinaryenConst(module, BinaryenLiteralFloat64(-9005.841)), outputType); + abort(); +} + +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.612)), BinaryenConst(module, BinaryenLiteralFloat32(-62.5))); + if (type == BinaryenFloat64()) return BinaryenBinary(module, op, BinaryenConst(module, BinaryenLiteralFloat64(-9005.841)), BinaryenConst(module, BinaryenLiteralFloat64(-9007.333))); + abort(); +} + +BinaryenExpressionRef makeInt32(BinaryenModuleRef module, int x) { + return BinaryenConst(module, BinaryenLiteralInt32(x)); +} + +BinaryenExpressionRef makeFloat32(BinaryenModuleRef module, float x) { + return BinaryenConst(module, BinaryenLiteralFloat32(x)); +} + +BinaryenExpressionRef makeInt64(BinaryenModuleRef module, int64_t x) { + return BinaryenConst(module, BinaryenLiteralInt64(x)); +} + +BinaryenExpressionRef makeFloat64(BinaryenModuleRef module, double x) { + return BinaryenConst(module, BinaryenLiteralFloat64(x)); +} + +BinaryenExpressionRef makeSomething(BinaryenModuleRef module) { + return makeInt32(module, 1337); +} + +// main + +int main() { + + // Core 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()); + + // Module creation + + BinaryenModuleRef module = BinaryenModuleCreate(); + + // Literals and consts + + BinaryenExpressionRef constI32 = BinaryenConst(module, BinaryenLiteralInt32(1)), + constI64 = BinaryenConst(module, BinaryenLiteralInt64(2)), + constF32 = BinaryenConst(module, BinaryenLiteralFloat32(3.14)), + constF64 = BinaryenConst(module, BinaryenLiteralFloat64(2.1828)), + constF32Bits = BinaryenConst(module, BinaryenLiteralFloat32Bits(0xffff1234)), + constF64Bits = BinaryenConst(module, BinaryenLiteralFloat64Bits(0xffff12345678abcdLL)); + + const char* switchNames[] = { "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) }; + + BinaryenType params[4] = { BinaryenInt32(), BinaryenInt64(), BinaryenFloat32(), BinaryenFloat64() }; + BinaryenFunctionTypeRef iiIfF = BinaryenAddFunctionType(module, "iiIfF", BinaryenInt32(), params, 4); + + BinaryenExpressionRef bodyList[] = { + // Unary + makeUnary(module, BinaryenClz(), 1, 1), + makeUnary(module, BinaryenCtz(), 2, 2), + makeUnary(module, BinaryenPopcnt(), 1, 1), + makeUnary(module, BinaryenNeg(), 3, 3), + makeUnary(module, BinaryenAbs(), 4, 3), + makeUnary(module, BinaryenCeil(), 3, 3), + makeUnary(module, BinaryenFloor(), 4, 4), + makeUnary(module, BinaryenTrunc(), 3, 3), + makeUnary(module, BinaryenNearest(), 3, 3), + makeUnary(module, BinaryenSqrt(), 4, 4), + makeUnary(module, BinaryenEqZ(), 1, 1), + makeUnary(module, BinaryenExtendSInt32(), 1, 2), + makeUnary(module, BinaryenExtentUInt32(), 1, 2), + makeUnary(module, BinaryenWrapInt64(), 2, 1), + makeUnary(module, BinaryenTruncSFloat32(), 3, 1), + makeUnary(module, BinaryenTruncUFloat32(), 3, 2), + makeUnary(module, BinaryenTruncSFloat64(), 4, 2), + makeUnary(module, BinaryenTruncUFloat64(), 4, 1), + makeUnary(module, BinaryenReinterpretFloat(), 3, 1), + makeUnary(module, BinaryenConvertSInt32(), 1, 3), + makeUnary(module, BinaryenConvertUInt32(), 1, 4), + makeUnary(module, BinaryenConvertSInt64(), 2, 3), + makeUnary(module, BinaryenConvertUInt64(), 2, 4), + makeUnary(module, BinaryenPromoteFloat32(), 3, 4), + makeUnary(module, BinaryenDemoteFloat64(), 4, 3), + makeUnary(module, BinaryenReinterpretInt(), 1, 3), + // Binary + makeBinary(module, BinaryenAdd(), 1), + makeBinary(module, BinaryenSub(), 4), + makeBinary(module, BinaryenDivS(), 1), + makeBinary(module, BinaryenDivU(), 2), + makeBinary(module, BinaryenRemS(), 2), + makeBinary(module, BinaryenRemU(), 1), + makeBinary(module, BinaryenAnd(), 1), + makeBinary(module, BinaryenOr(), 2), + makeBinary(module, BinaryenXor(), 1), + makeBinary(module, BinaryenShl(), 2), + makeBinary(module, BinaryenShrU(), 2), + makeBinary(module, BinaryenShrS(), 1), + makeBinary(module, BinaryenRotL(), 1), + makeBinary(module, BinaryenRotR(), 2), + makeBinary(module, BinaryenDiv(), 3), + makeBinary(module, BinaryenCopySign(), 4), + makeBinary(module, BinaryenMin(), 3), + makeBinary(module, BinaryenMax(), 4), + makeBinary(module, BinaryenEq(), 1), + makeBinary(module, BinaryenNe(), 3), + makeBinary(module, BinaryenLtS(), 1), + makeBinary(module, BinaryenLtU(), 2), + makeBinary(module, BinaryenLeS(), 2), + makeBinary(module, BinaryenLeU(), 1), + makeBinary(module, BinaryenGtS(), 2), + makeBinary(module, BinaryenGtU(), 1), + makeBinary(module, BinaryenGeS(), 1), + makeBinary(module, BinaryenGeU(), 2), + makeBinary(module, BinaryenLt(), 3), + makeBinary(module, BinaryenLe(), 4), + makeBinary(module, BinaryenGt(), 4), + makeBinary(module, BinaryenGe(), 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), + 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-body", makeInt32(module, 2), NULL), + BinaryenBreak(module, "the-body", 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), + BinaryenCall(module, "kitchen-sinker", callOperands4, 4), + BinaryenCallImport(module, "an-imported", callOperands2, 2), + BinaryenCallIndirect(module, makeInt32(module, 2449), callOperands4, 4, iiIfF), + BinaryenGetLocal(module, 0, BinaryenInt32()), + BinaryenSetLocal(module, 0, makeInt32(module, 101)), + BinaryenLoad(module, 4, 0, 0, 0, BinaryenInt32(), makeInt32(module, 1)), + 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)), + BinaryenReturn(module, NULL), + BinaryenReturn(module, makeFloat32(module, 1)), + // TODO: Host + BinaryenNop(module), + BinaryenUnreachable(module), + }; + + // Make the main body of the function + BinaryenExpressionRef body = BinaryenBlock(module, "the-body", bodyList, sizeof(bodyList) / sizeof(BinaryenExpressionRef)); + + // Create the function + BinaryenType localTypes[] = { BinaryenInt32() }; + BinaryenFunctionRef sinker = BinaryenAddFunction(module, "kitchen-sinker", iiIfF, localTypes, 1, body); + + // Imports + + BinaryenType iparams[2] = { BinaryenInt32(), BinaryenFloat64() }; + BinaryenFunctionTypeRef viF = BinaryenAddFunctionType(module, "viF", BinaryenNone(), iparams, 2); + BinaryenAddImport(module, "an-imported", "module", "base", viF); + + // Exports + + BinaryenAddExport(module, "kitchen-sinker", "kitchen_sinker"); + + // Function table. One per module + BinaryenFunctionRef functions[] = { sinker }; + BinaryenSetFunctionTable(module, functions, 1); + + // Memory. One per module + + const char *segments[] = { "hello, world" }; + BinaryenIndex segmentOffsets[] = { 10 }; + BinaryenIndex segmentSizes[] = { 12 }; + BinaryenSetMemory(module, 1, 256, "mem", segments, segmentOffsets, segmentSizes, 1); + + // Start function. One per module + + BinaryenSetStart(module, "sinker"); + + // Print it out + BinaryenModulePrint(module); + + // Clean up the module, which owns all the objects we created above + BinaryenModuleDispose(module); +} + diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt new file mode 100644 index 000000000..2c80d8706 --- /dev/null +++ b/test/example/c-api-kitchen-sink.txt @@ -0,0 +1,318 @@ +BinaryenNone: 0 +BinaryenInt32: 1 +BinaryenInt64: 2 +BinaryenFloat32: 3 +BinaryenFloat64: 4 +(module + (memory 1 256 + (segment 10 "hello, world") + ) + (export "mem" memory) + (start $sinker) + (type $iiIfF (func (param i32 i64 f32 f64) (result i32))) + (type $viF (func (param i32 f64))) + (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) + ) + (f32.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_u/f32 + (f32.const -33.61199951171875) + ) + (i64.trunc_s/f64 + (f64.const -9005.841) + ) + (i32.trunc_u/f64 + (f64.const -9005.841) + ) + (i32.reinterpret/f32 + (f32.const -33.61199951171875) + ) + (f32.convert_s/i32 + (i32.const -10) + ) + (f64.convert_u/i32 + (i32.const -10) + ) + (f32.convert_s/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) + ) + (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) + ) + (nop) + (unreachable) + ) + ) +) |