| #include <assert.h> | |
| #include <stdio.h> | |
| #include "binaryen-c.h" | |
| // globals: address 4 is index | |
| // decisions are at address 8+ | |
| int main() { | |
| BinaryenModuleRef module = BinaryenModuleCreate(); | |
| // check() | |
| // if the end, halt | |
| BinaryenExpressionRef halter = BinaryenIf( | |
| module, | |
| BinaryenBinary( | |
| module, | |
| BinaryenGeUInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 27)) // jumps of 4 bytes | |
| ), | |
| BinaryenUnreachable(module), | |
| NULL); | |
| // increment index | |
| BinaryenExpressionRef incer = BinaryenStore( | |
| module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary(module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4))), | |
| BinaryenTypeInt32(), | |
| "0"); | |
| // optionally, print the return value | |
| BinaryenExpressionRef args[] = {BinaryenBinary( | |
| module, | |
| BinaryenSubInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(0)), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 4, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| "0"))}; | |
| BinaryenExpressionRef debugger; | |
| if (1) | |
| debugger = BinaryenCall(module, "print", args, 1, BinaryenTypeNone()); | |
| else | |
| debugger = BinaryenNop(module); | |
| // return the decision. need to subtract 4 that we just added, | |
| // and add 8 since that's where we start, so overall offset 4 | |
| BinaryenExpressionRef returner = | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 4, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| "0"); | |
| BinaryenExpressionRef checkBodyList[] = {halter, incer, debugger, returner}; | |
| BinaryenExpressionRef checkBody = | |
| BinaryenBlock(module, | |
| NULL, | |
| checkBodyList, | |
| sizeof(checkBodyList) / sizeof(BinaryenExpressionRef), | |
| BinaryenTypeInt32()); | |
| BinaryenAddFunction(module, | |
| "check", | |
| BinaryenTypeNone(), | |
| BinaryenTypeInt32(), | |
| NULL, | |
| 0, | |
| checkBody); | |
| // contents of main() begin here | |
| RelooperRef relooper = RelooperCreate(module); | |
| RelooperBlockRef b0; | |
| { | |
| BinaryenExpressionRef args[] = { | |
| BinaryenConst(module, BinaryenLiteralInt32(0))}; | |
| BinaryenExpressionRef list[] = { | |
| BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), | |
| BinaryenLocalSet( | |
| module, | |
| 0, | |
| BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32()))}; | |
| b0 = RelooperAddBlock( | |
| relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone())); | |
| } | |
| RelooperBlockRef b1; | |
| { | |
| BinaryenExpressionRef args[] = { | |
| BinaryenConst(module, BinaryenLiteralInt32(0))}; | |
| BinaryenExpressionRef list[] = { | |
| BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), | |
| BinaryenLocalSet( | |
| module, | |
| 0, | |
| BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32()))}; | |
| b1 = RelooperAddBlock( | |
| relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone())); | |
| } | |
| RelooperBlockRef b2; | |
| { | |
| BinaryenExpressionRef args[] = { | |
| BinaryenConst(module, BinaryenLiteralInt32(0))}; | |
| BinaryenExpressionRef list[] = { | |
| BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), | |
| BinaryenLocalSet( | |
| module, | |
| 0, | |
| BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32()))}; | |
| b2 = RelooperAddBlockWithSwitch( | |
| relooper, | |
| BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()), | |
| BinaryenBinary(module, | |
| BinaryenRemUInt32(), | |
| BinaryenLocalGet(module, 0, BinaryenTypeInt32()), | |
| BinaryenConst(module, BinaryenLiteralInt32(2)))); | |
| } | |
| RelooperBlockRef b3; | |
| { | |
| BinaryenExpressionRef args[] = { | |
| BinaryenConst(module, BinaryenLiteralInt32(0))}; | |
| BinaryenExpressionRef list[] = { | |
| BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), | |
| BinaryenLocalSet( | |
| module, | |
| 0, | |
| BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32()))}; | |
| b3 = RelooperAddBlockWithSwitch( | |
| relooper, | |
| BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()), | |
| BinaryenBinary(module, | |
| BinaryenRemUInt32(), | |
| BinaryenLocalGet(module, 0, BinaryenTypeInt32()), | |
| BinaryenConst(module, BinaryenLiteralInt32(1)))); | |
| } | |
| RelooperBlockRef b4; | |
| { | |
| BinaryenExpressionRef args[] = { | |
| BinaryenConst(module, BinaryenLiteralInt32(4))}; | |
| BinaryenExpressionRef list[] = { | |
| BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), | |
| BinaryenLocalSet( | |
| module, | |
| 0, | |
| BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32()))}; | |
| b4 = RelooperAddBlock( | |
| relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone())); | |
| } | |
| RelooperBlockRef b5; | |
| { | |
| BinaryenExpressionRef args[] = { | |
| BinaryenConst(module, BinaryenLiteralInt32(0))}; | |
| BinaryenExpressionRef list[] = { | |
| BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), | |
| BinaryenLocalSet( | |
| module, | |
| 0, | |
| BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32()))}; | |
| b5 = RelooperAddBlockWithSwitch( | |
| relooper, | |
| BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()), | |
| BinaryenBinary(module, | |
| BinaryenRemUInt32(), | |
| BinaryenLocalGet(module, 0, BinaryenTypeInt32()), | |
| BinaryenConst(module, BinaryenLiteralInt32(1)))); | |
| } | |
| RelooperBlockRef b6; | |
| { | |
| BinaryenExpressionRef args[] = { | |
| BinaryenConst(module, BinaryenLiteralInt32(6))}; | |
| BinaryenExpressionRef list[] = { | |
| BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), | |
| BinaryenLocalSet( | |
| module, | |
| 0, | |
| BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32()))}; | |
| b6 = RelooperAddBlockWithSwitch( | |
| relooper, | |
| BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()), | |
| BinaryenBinary(module, | |
| BinaryenRemUInt32(), | |
| BinaryenLocalGet(module, 0, BinaryenTypeInt32()), | |
| BinaryenConst(module, BinaryenLiteralInt32(3)))); | |
| } | |
| RelooperBlockRef b7; | |
| { | |
| BinaryenExpressionRef args[] = { | |
| BinaryenConst(module, BinaryenLiteralInt32(0))}; | |
| BinaryenExpressionRef list[] = { | |
| BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), | |
| BinaryenLocalSet( | |
| module, | |
| 0, | |
| BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32()))}; | |
| b7 = RelooperAddBlock( | |
| relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone())); | |
| } | |
| RelooperBlockRef b8; | |
| { | |
| BinaryenExpressionRef args[] = { | |
| BinaryenConst(module, BinaryenLiteralInt32(0))}; | |
| BinaryenExpressionRef list[] = { | |
| BinaryenCall(module, "print", args, 1, BinaryenTypeNone()), | |
| BinaryenLocalSet( | |
| module, | |
| 0, | |
| BinaryenCall(module, "check", NULL, 0, BinaryenTypeInt32()))}; | |
| b8 = RelooperAddBlock( | |
| relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone())); | |
| } | |
| RelooperAddBranch( | |
| b0, | |
| b1, | |
| NULL, | |
| BinaryenStore(module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary( | |
| module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), | |
| BinaryenTypeInt32(), | |
| "0")); | |
| RelooperAddBranch( | |
| b1, | |
| b1, | |
| NULL, | |
| BinaryenStore(module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary( | |
| module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), | |
| BinaryenTypeInt32(), | |
| "0")); | |
| { | |
| BinaryenIndex values[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, | |
| 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, | |
| 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, | |
| 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86}; | |
| RelooperAddBranchForSwitch( | |
| b2, | |
| b7, | |
| values, | |
| sizeof(values) / sizeof(BinaryenIndex), | |
| BinaryenStore( | |
| module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary( | |
| module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 6))), | |
| BinaryenTypeInt32(), | |
| "0")); | |
| } | |
| RelooperAddBranchForSwitch( | |
| b2, | |
| b4, | |
| NULL, | |
| 0, | |
| BinaryenStore(module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary( | |
| module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), | |
| BinaryenTypeInt32(), | |
| "0")); | |
| RelooperAddBranchForSwitch( | |
| b3, | |
| b6, | |
| NULL, | |
| 0, | |
| BinaryenStore(module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary( | |
| module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 5))), | |
| BinaryenTypeInt32(), | |
| "0")); | |
| RelooperAddBranch( | |
| b4, | |
| b7, | |
| BinaryenBinary( | |
| module, | |
| BinaryenEqInt32(), | |
| BinaryenBinary(module, | |
| BinaryenRemUInt32(), | |
| BinaryenLocalGet(module, 0, BinaryenTypeInt32()), | |
| BinaryenConst(module, BinaryenLiteralInt32(2))), | |
| BinaryenConst(module, BinaryenLiteralInt32(0))), | |
| BinaryenStore(module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary( | |
| module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 5))), | |
| BinaryenTypeInt32(), | |
| "0")); | |
| RelooperAddBranch( | |
| b4, | |
| b3, | |
| NULL, | |
| BinaryenStore(module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary( | |
| module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 3))), | |
| BinaryenTypeInt32(), | |
| "0")); | |
| RelooperAddBranchForSwitch( | |
| b5, | |
| b1, | |
| NULL, | |
| 0, | |
| BinaryenStore(module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary( | |
| module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), | |
| BinaryenTypeInt32(), | |
| "0")); | |
| { | |
| BinaryenIndex values[] = {0, 3, 6, 9, 12, 15, 18, 21, 24, 27, | |
| 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, | |
| 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, | |
| 90, 93, 96, 99, 102, 105, 108}; | |
| RelooperAddBranchForSwitch( | |
| b6, | |
| b1, | |
| values, | |
| sizeof(values) / sizeof(BinaryenIndex), | |
| BinaryenStore( | |
| module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary( | |
| module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 2))), | |
| BinaryenTypeInt32(), | |
| "0")); | |
| } | |
| { | |
| BinaryenIndex values[] = { | |
| 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, | |
| 43, 46, 49, 52, 55, 58, 61, 64, 67, 70, 73, 76, 79, 82, | |
| 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, | |
| 127, 130, 133, 136, 139, 142, 145, 148, 151, 154, 157, 160}; | |
| RelooperAddBranchForSwitch( | |
| b6, | |
| b7, | |
| values, | |
| sizeof(values) / sizeof(BinaryenIndex), | |
| BinaryenStore( | |
| module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary( | |
| module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 3))), | |
| BinaryenTypeInt32(), | |
| "0")); | |
| } | |
| RelooperAddBranchForSwitch( | |
| b6, | |
| b2, | |
| NULL, | |
| 0, | |
| BinaryenStore(module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary( | |
| module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 3))), | |
| BinaryenTypeInt32(), | |
| "0")); | |
| RelooperAddBranch( | |
| b7, | |
| b5, | |
| BinaryenBinary( | |
| module, | |
| BinaryenEqInt32(), | |
| BinaryenBinary(module, | |
| BinaryenRemUInt32(), | |
| BinaryenLocalGet(module, 0, BinaryenTypeInt32()), | |
| BinaryenConst(module, BinaryenLiteralInt32(2))), | |
| BinaryenConst(module, BinaryenLiteralInt32(0))), | |
| BinaryenStore(module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary( | |
| module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 1))), | |
| BinaryenTypeInt32(), | |
| "0")); | |
| RelooperAddBranch( | |
| b7, | |
| b1, | |
| NULL, | |
| BinaryenStore(module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary( | |
| module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), | |
| BinaryenTypeInt32(), | |
| "0")); | |
| RelooperAddBranch( | |
| b8, | |
| b8, | |
| NULL, | |
| BinaryenStore(module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| BinaryenBinary( | |
| module, | |
| BinaryenAddInt32(), | |
| BinaryenLoad(module, | |
| 4, | |
| 0, | |
| 0, | |
| 0, | |
| BinaryenTypeInt32(), | |
| BinaryenConst(module, BinaryenLiteralInt32(4)), | |
| "0"), | |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 2))), | |
| BinaryenTypeInt32(), | |
| "0")); | |
| BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1); | |
| int decisions[] = {5, 111, 119, 17, 179, 41, 32, 3, 171, | |
| 126, 13, 95, 70, 91, 9, 140, 99, 161, | |
| 38, 87, 153, 117, 140, 11, 157, 48, 4}; | |
| int numDecisions = sizeof(decisions) / sizeof(int); | |
| // write out all the decisions, then the body of the function | |
| BinaryenExpressionRef full[numDecisions + 1]; | |
| { | |
| int i; | |
| for (i = 0; i < numDecisions; i++) { | |
| full[i] = | |
| BinaryenStore(module, | |
| 4, | |
| 0, | |
| 0, | |
| BinaryenConst(module, BinaryenLiteralInt32(8 + 4 * i)), | |
| BinaryenConst(module, BinaryenLiteralInt32(decisions[i])), | |
| BinaryenTypeInt32(), | |
| "0"); | |
| } | |
| } | |
| full[numDecisions] = body; | |
| BinaryenExpressionRef all = | |
| BinaryenBlock(module, NULL, full, numDecisions + 1, BinaryenTypeNone()); | |
| // locals: state, free-for-label | |
| BinaryenType localTypes[] = {BinaryenTypeInt32(), BinaryenTypeInt32()}; | |
| BinaryenFunctionRef theMain = BinaryenAddFunction( | |
| module, "main", BinaryenTypeNone(), BinaryenTypeNone(), localTypes, 2, all); | |
| BinaryenSetStart(module, theMain); | |
| // import | |
| BinaryenAddFunctionImport(module, | |
| "print", | |
| "spectest", | |
| "print", | |
| BinaryenTypeInt32(), | |
| BinaryenTypeNone()); | |
| // memory | |
| BinaryenSetMemory( | |
| module, 1, 1, "mem", NULL, NULL, NULL, NULL, NULL, 0, 0, 0, "0"); | |
| // optionally, optimize | |
| if (0) | |
| BinaryenModuleOptimize(module); | |
| assert(BinaryenModuleValidate(module)); | |
| // write it out | |
| BinaryenModulePrint(module); | |
| BinaryenModuleDispose(module); | |
| return 0; | |
| } |