| #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))), |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4)) |
| ), |
| BinaryenTypeInt32() |
| ); |
| |
| // 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))) |
| ) |
| ) |
| }; |
| 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))) |
| ); |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), |
| BinaryenTypeInt32())); |
| |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), |
| BinaryenTypeInt32())); |
| |
| { |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 6))), |
| BinaryenTypeInt32())); |
| } |
| |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), |
| BinaryenTypeInt32())); |
| |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 5))), |
| BinaryenTypeInt32())); |
| |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 5))), |
| BinaryenTypeInt32())); |
| |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 3))), |
| BinaryenTypeInt32())); |
| |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), |
| BinaryenTypeInt32())); |
| |
| { |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 2))), |
| BinaryenTypeInt32())); |
| } |
| |
| { |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 3))), |
| BinaryenTypeInt32())); |
| } |
| |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 3))), |
| BinaryenTypeInt32())); |
| |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 1))), |
| BinaryenTypeInt32())); |
| |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 4))), |
| BinaryenTypeInt32())); |
| |
| 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))), |
| BinaryenConst(module, BinaryenLiteralInt32(4 * 2))), |
| BinaryenTypeInt32())); |
| |
| 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() |
| ); |
| } |
| } |
| 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, 0, 0); |
| |
| // optionally, optimize |
| if (0) BinaryenModuleOptimize(module); |
| |
| assert(BinaryenModuleValidate(module)); |
| |
| // write it out |
| |
| BinaryenModulePrint(module); |
| |
| BinaryenModuleDispose(module); |
| |
| return 0; |
| } |