summaryrefslogtreecommitdiff
path: root/test/example/relooper-fuzz.c
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-05-06 10:28:47 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-05-06 17:52:36 -0700
commita2cfae4c54ba79d7e8b348da10c77840ca934595 (patch)
treec9dfdc133fdd77b5a62d2e9bab8f32c07c0ae5ab /test/example/relooper-fuzz.c
parentffb9e4b9cfac5091dfe19b9b5215c43bd0f98e72 (diff)
downloadbinaryen-a2cfae4c54ba79d7e8b348da10c77840ca934595.tar.gz
binaryen-a2cfae4c54ba79d7e8b348da10c77840ca934595.tar.bz2
binaryen-a2cfae4c54ba79d7e8b348da10c77840ca934595.zip
add a fuzzer for the relooper through the C API
Diffstat (limited to 'test/example/relooper-fuzz.c')
-rw-r--r--test/example/relooper-fuzz.c267
1 files changed, 267 insertions, 0 deletions
diff --git a/test/example/relooper-fuzz.c b/test/example/relooper-fuzz.c
new file mode 100644
index 000000000..ba9bcb3ed
--- /dev/null
+++ b/test/example/relooper-fuzz.c
@@ -0,0 +1,267 @@
+
+
+#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,
+ BinaryenEq(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenInt32(), 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,
+ BinaryenAdd(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4))
+ )
+ );
+
+ // optionally, print the return value
+ BinaryenExpressionRef args[] = {
+ BinaryenBinary(module,
+ BinaryenSub(),
+ 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));
+ }
+
+ RelooperAddBranch(b0, b5, BinaryenBinary(module,
+ BinaryenEq(),
+ BinaryenBinary(module,
+ BinaryenRemU(),
+ BinaryenGetLocal(module, 0, BinaryenInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(2))
+ ),
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ ), NULL);
+
+ RelooperAddBranch(b0, b8, NULL, NULL);
+
+ RelooperAddBranch(b1, b5, NULL, NULL);
+
+ RelooperAddBranch(b2, b5, NULL, NULL);
+
+ RelooperAddBranch(b3, b5, BinaryenBinary(module,
+ BinaryenEq(),
+ BinaryenBinary(module,
+ BinaryenRemU(),
+ BinaryenGetLocal(module, 0, BinaryenInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(2))
+ ),
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ ), NULL);
+
+ RelooperAddBranch(b3, b8, NULL, NULL);
+
+ RelooperAddBranch(b4, b4, BinaryenBinary(module,
+ BinaryenEq(),
+ BinaryenBinary(module,
+ BinaryenRemU(),
+ BinaryenGetLocal(module, 0, BinaryenInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(3))
+ ),
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ ), NULL);
+
+ RelooperAddBranch(b4, b5, BinaryenBinary(module,
+ BinaryenEq(),
+ BinaryenBinary(module,
+ BinaryenRemU(),
+ BinaryenGetLocal(module, 0, BinaryenInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(3))
+ ),
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ ), NULL);
+
+ RelooperAddBranch(b4, b2, NULL, NULL);
+
+ RelooperAddBranch(b5, b4, BinaryenBinary(module,
+ BinaryenEq(),
+ BinaryenBinary(module,
+ BinaryenRemU(),
+ BinaryenGetLocal(module, 0, BinaryenInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(2))
+ ),
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ ), NULL);
+
+ RelooperAddBranch(b5, b5, NULL, NULL);
+
+ RelooperAddBranch(b6, b6, NULL, NULL);
+
+ RelooperAddBranch(b7, b8, NULL, NULL);
+
+ RelooperAddBranch(b8, b4, NULL, NULL);
+
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1, module);
+
+ int decisions[] = { 89, 12, 78, 149, 118, 179, 127, 80, 21, 34, 119, 98, 38, 29, 36, 147, 13, 55, 166, 16, 143, 52, 130, 150, 176, 91, 34 };
+ int numDecisions = sizeof(decisions)/sizeof(int);
+
+ BinaryenExpressionRef full[numDecisions + 1]; // write out all the decisions, then the body of the function
+
+ for (int i = 0; i < numDecisions; i++) {
+ full[i] = BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(8 + 4 * i)),
+ BinaryenConst(module, BinaryenLiteralInt32(decisions[i]))
+ );
+ }
+ full[numDecisions] = body;
+ BinaryenExpressionRef all = BinaryenBlock(module, NULL, full, numDecisions + 1);
+
+ BinaryenFunctionTypeRef v = BinaryenAddFunctionType(module, "v", BinaryenNone(), NULL, 0);
+ BinaryenType localTypes[] = { BinaryenInt32(), BinaryenInt32() }; // state, free-for-label
+ 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);
+
+ BinaryenModuleOptimize(module);
+
+ assert(BinaryenModuleValidate(module));
+
+ // write it out
+
+ BinaryenModulePrint(module);
+
+ BinaryenModuleDispose(module);
+
+ return 0;
+}