int main() { BinaryenModuleRef module = BinaryenModuleCreate(); // Create a function type for i32 (i32, i32) BinaryenType params[2] = { BinaryenTypeInt32(), BinaryenTypeInt32() }; BinaryenFunctionTypeRef iii = BinaryenAddFunctionType(module, "iii", BinaryenTypeInt32(), params, 2); // Get the 0 and 1 arguments, and add them BinaryenExpressionRef x = BinaryenGetLocal(module, 0, BinaryenTypeInt32()), y = BinaryenGetLocal(module, 1, BinaryenTypeInt32()); BinaryenExpressionRef add = BinaryenBinary(module, BinaryenAddInt32(), 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); return 0; }
int main() { BinaryenModuleRef module = BinaryenModuleCreate(); #if 1 #if 0 BinaryenType params[4] = { BinaryenInt32(), BinaryenInt64(), BinaryenFloat32(), BinaryenFloat64() }; BinaryenFunctionTypeRef iiIfF = BinaryenAddFunctionType(module, "iiIfF", BinaryenInt32(), params, 4); BinaryenExpressionRef callOperands4[] = { makeInt32(module, 13), makeInt64(module, 37), makeFloat32(module, 1.3f), makeFloat64(module, 3.7) }; BinaryenExpressionRef c = BinaryenCallImport(module, "importname", callOperands4, 4, BinaryenInt32()); #else BinaryenFunctionTypeRef i = BinaryenAddFunctionType(module, "i", BinaryenInt32(), 0, 0); BinaryenAddImport(module, "importname", "WScript.Shell", "CurrentDirectory", i); BinaryenExpressionRef c = BinaryenCallImport(module, "importname", 0, 0, BinaryenInt32()); #endif #else BinaryenExpressionRef b = BinaryenReturn(module, makeInt32(module, 123)); BinaryenFunctionRef fiiIfF = BinaryenAddFunction(module, "fiiIfF", iiIfF, NULL, 0, b); BinaryenExpressionRef callOperands4[] = { makeInt32(module, 13), makeInt64(module, 37), makeFloat32(module, 1.3f), makeFloat64(module, 3.7) }; #if 0 BinaryenExpressionRef c = BinaryenCall(module, "fiiIfF", callOperands4, 4, BinaryenNop(module)); #else BinaryenExpressionRef c = BinaryenCallIndirect(module, makeInt32(module, 123), callOperands4, 4, iiIfF); #endif #endif BinaryenFunctionTypeRef v = BinaryenAddFunctionType(module, "v", BinaryenNone(), NULL, 0); BinaryenFunctionRef f = BinaryenAddFunction(module, "f", v, NULL, 0, c); BinaryenExpressionRef s = BinaryenCall(module, "f", NULL, 0, BinaryenNone()); BinaryenFunctionRef starter = BinaryenAddFunction(module, "starter", v, NULL, 0, s); // BinaryenSetStart(module, starter); BinaryenAddExport(module, "starter", "starter"); printf("validate module\n"); assert(BinaryenModuleValidate(module)); char buffer[1024]; size_t size; printf("write module\n"); size = BinaryenModuleWrite(module, buffer, 1024); assert(size > 0); // must have non-zero size assert(size < 512); // must be very small #if 1 // must Dispose, BinaryenModuleRead to populate unimplemented param properties, maybe others printf("dispose module\n"); BinaryenModuleDispose(module); printf("read module\n"); module = BinaryenModuleRead(buffer, size); printf("validate module\n"); assert(BinaryenModuleValidate(module)); #endif printf("print module\n"); BinaryenModulePrint(module); struct BinaryenLiteral retVal; BinaryenRun(module, "starter", &retVal); char printbuf[64]; printf("retVal: %s\n", BinaryenLiteralPrint(printbuf, sizeof(printbuf), retVal)); printf("dispose module\n"); BinaryenModuleDispose(module); }
int main() { BinaryenModuleRef module = BinaryenModuleCreate(); // check() // if the end, halt BinaryenExpressionRef halter = BinaryenIf(module, BinaryenBinary(module, BinaryenEqInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4 * 30)) // 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, BinaryenInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), BinaryenConst(module, BinaryenLiteralInt32(4)) ), BinaryenInt32() ); // optionally, print the return value BinaryenExpressionRef args[] = { BinaryenBinary(module, BinaryenSubInt32(), BinaryenConst(module, BinaryenLiteralInt32(0)), BinaryenLoad(module, 4, 0, 4, 0, BinaryenInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))) ) ) }; BinaryenExpressionRef debugger; if (1) debugger = BinaryenCallImport(module, "print", args, 1, BinaryenNone()); 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, BinaryenInt32(), BinaryenLoad(module, 4, 0, 0, 0, BinaryenInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))) ); BinaryenExpressionRef checkBodyList[] = { halter, incer, debugger, returner }; BinaryenExpressionRef checkBody = BinaryenBlock(module, NULL, checkBodyList, sizeof(checkBodyList) / sizeof(BinaryenExpressionRef) ); BinaryenFunctionTypeRef i = BinaryenAddFunctionType(module, "i", BinaryenInt32(), NULL, 0); BinaryenAddFunction(module, "check", i, NULL, 0, checkBody); // contents of main() begin here RelooperRef relooper = RelooperCreate(); RelooperBlockRef b0; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(0)) }; BinaryenExpressionRef list[] = { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; b0 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); } RelooperBlockRef b1; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(1)) }; BinaryenExpressionRef list[] = { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; b1 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); } RelooperBlockRef b2; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(2)) }; BinaryenExpressionRef list[] = { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; b2 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); } RelooperBlockRef b3; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(3)) }; BinaryenExpressionRef list[] = { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; b3 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); } RelooperBlockRef b4; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(4)) }; BinaryenExpressionRef list[] = { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; b4 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); } RelooperBlockRef b5; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(5)) }; BinaryenExpressionRef list[] = { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; b5 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); } RelooperBlockRef b6; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(6)) }; BinaryenExpressionRef list[] = { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; b6 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); } RelooperBlockRef b7; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(7)) }; BinaryenExpressionRef list[] = { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; b7 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); } RelooperBlockRef b8; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(8)) }; BinaryenExpressionRef list[] = { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; b8 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); } RelooperBlockRef b9; { BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(9)) }; BinaryenExpressionRef list[] = { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; b9 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); } RelooperAddBranch(b0, b2, BinaryenBinary(module, BinaryenEqInt32(), BinaryenBinary(module, BinaryenRemUInt32(), BinaryenGetLocal(module, 0, BinaryenInt32()), BinaryenConst(module, BinaryenLiteralInt32(4)) ), BinaryenConst(module, BinaryenLiteralInt32(0)) ), NULL); RelooperAddBranch(b0, b7, BinaryenBinary(module, BinaryenEqInt32(), BinaryenBinary(module, BinaryenRemUInt32(), BinaryenGetLocal(module, 0, BinaryenInt32()), BinaryenConst(module, BinaryenLiteralInt32(4)) ), BinaryenConst(module, BinaryenLiteralInt32(2)) ), NULL); RelooperAddBranch(b0, b3, NULL, NULL); RelooperAddBranch(b2, b3, BinaryenBinary(module, BinaryenEqInt32(), BinaryenBinary(module, BinaryenRemUInt32(), BinaryenGetLocal(module, 0, BinaryenInt32()), BinaryenConst(module, BinaryenLiteralInt32(2)) ), BinaryenConst(module, BinaryenLiteralInt32(0)) ), NULL); RelooperAddBranch(b2, b9, NULL, NULL); RelooperAddBranch(b3, b3, NULL, NULL); RelooperAddBranch(b7, b2, BinaryenBinary(module, BinaryenEqInt32(), BinaryenBinary(module, BinaryenRemUInt32(), BinaryenGetLocal(module, 0, BinaryenInt32()), BinaryenConst(module, BinaryenLiteralInt32(3)) ), BinaryenConst(module, BinaryenLiteralInt32(0)) ), NULL); RelooperAddBranch(b7, b9, NULL, NULL); BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1, module); int decisions[] = { 67, 131, 49, 36, 112, 161, 62, 166, 16, 88, 176, 152, 161, 194, 117, 180, 60, 166, 55, 183, 150, 73, 196, 143, 76, 182, 97, 140, 126, 3 }; 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])), BinaryenInt32() ); } } full[numDecisions] = body; BinaryenExpressionRef all = BinaryenBlock(module, NULL, full, numDecisions + 1); BinaryenFunctionTypeRef v = BinaryenAddFunctionType(module, "v", BinaryenNone(), NULL, 0); // locals: state, free-for-label BinaryenType localTypes[] = { BinaryenInt32(), BinaryenInt32() }; BinaryenFunctionRef theMain = BinaryenAddFunction(module, "main", v, localTypes, 2, all); BinaryenSetStart(module, theMain); // import BinaryenType iparams[] = { BinaryenInt32() }; BinaryenFunctionTypeRef vi = BinaryenAddFunctionType(module, "vi", BinaryenNone(), iparams, 1); BinaryenAddImport(module, "print", "spectest", "print", vi); // memory BinaryenSetMemory(module, 1, 1, "mem", NULL, NULL, NULL, 0); assert(BinaryenModuleValidate(module)); BinaryenModulePrint(module); BinaryenModuleOptimize(module); assert(BinaryenModuleValidate(module)); BinaryenModulePrint(module); BinaryenModuleDispose(module); return 0; }
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); BinaryenModuleAutoDrop(the_module); { const char* segments[] = { 0 }; int8_t segmentPassive[] = { 0 }; BinaryenExpressionRef segmentOffsets[] = { 0 }; BinaryenIndex segmentSizes[] = { 0 }; BinaryenSetMemory(the_module, 256, 256, "memory", segments, segmentPassive, segmentOffsets, segmentSizes, 0, 0); } the_relooper = RelooperCreate(the_module); { BinaryenExpressionRef children[] = { 0 }; expressions[1] = BinaryenBlock(the_module, "bb0", children, 0, BinaryenTypeAuto()); } relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[1]); expressions[2] = BinaryenGetLocal(the_module, 0, 1); expressions[3] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); expressions[4] = BinaryenStore(the_module, 4, 0, 0, expressions[3], expressions[2], 1); expressions[5] = BinaryenReturn(the_module, expressions[0]); { BinaryenExpressionRef children[] = { expressions[4], expressions[5] }; expressions[6] = BinaryenBlock(the_module, "bb1", children, 2, BinaryenTypeAuto()); } relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[6]); RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[0], expressions[0]); { BinaryenType paramTypes[] = { 0 }; functionTypes[0] = BinaryenAddFunctionType(the_module, "rustfn-0-3", 0, paramTypes, 0); } expressions[7] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); expressions[8] = BinaryenLoad(the_module, 4, 0, 0, 0, 1, expressions[7]); expressions[9] = BinaryenSetLocal(the_module, 0, expressions[8]); relooperBlocks[2] = RelooperAddBlock(the_relooper, expressions[9]); RelooperAddBranch(relooperBlocks[2], relooperBlocks[0], expressions[0], expressions[0]); expressions[10] = RelooperRenderAndDispose(the_relooper, relooperBlocks[2], 1); { BinaryenType varTypes[] = { 1, 1, 2 }; functions[0] = BinaryenAddFunction(the_module, "main", functionTypes[0], varTypes, 3, expressions[10]); } BinaryenAddFunctionExport(the_module, "main", "main"); { BinaryenType paramTypes[] = { 0 }; functionTypes[1] = BinaryenAddFunctionType(the_module, "__wasm_start", 0, paramTypes, 0); } { const char* segments[] = { 0 }; int8_t segmentPassive[] = { 0 }; BinaryenExpressionRef segmentOffsets[] = { 0 }; BinaryenIndex segmentSizes[] = { 0 }; BinaryenSetMemory(the_module, 1024, 1024, NULL, segments, segmentPassive, segmentOffsets, segmentSizes, 0, 0); } expressions[11] = BinaryenConst(the_module, BinaryenLiteralInt32(65535)); expressions[12] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); expressions[13] = BinaryenStore(the_module, 4, 0, 0, expressions[12], expressions[11], 1); { BinaryenExpressionRef operands[] = { 0 }; expressions[14] = BinaryenCall(the_module, "main", operands, 0, 0); } { BinaryenExpressionRef children[] = { expressions[13], expressions[14] }; expressions[15] = BinaryenBlock(the_module, NULL, children, 2, BinaryenTypeAuto()); } BinaryenAddFunctionExport(the_module, "__wasm_start", "rust_entry"); { BinaryenType varTypes[] = { 0 }; functions[1] = BinaryenAddFunction(the_module, "__wasm_start", functionTypes[1], varTypes, 0, expressions[15]); } BinaryenModuleValidate(the_module); BinaryenModulePrint(the_module); // check that binary read-write works { char buffer[1024]; BinaryenSetDebugInfo(1); size_t size = BinaryenModuleWrite(the_module, buffer, 1024); printf("%d\n", size); BinaryenModuleRef copy = BinaryenModuleRead(buffer, size); BinaryenModulePrint(copy); BinaryenModuleDispose(copy); } BinaryenModuleDispose(the_module); return 0; }