diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-11-11 20:38:18 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-11-11 20:38:18 -0800 |
commit | a43caa75ce7293a4aea91228daf379f06817f5d8 (patch) | |
tree | cf19d50e137e9c4a80180bfb90d084f418e337f5 | |
parent | ed47fbc9ce48e712548d937195e0f7d333da55c4 (diff) | |
download | binaryen-a43caa75ce7293a4aea91228daf379f06817f5d8.tar.gz binaryen-a43caa75ce7293a4aea91228daf379f06817f5d8.tar.bz2 binaryen-a43caa75ce7293a4aea91228daf379f06817f5d8.zip |
add simple example
-rw-r--r-- | README.md | 4 | ||||
-rwxr-xr-x | build.sh | 6 | ||||
-rwxr-xr-x | check.py | 8 | ||||
-rw-r--r-- | src/asm2wasm.h | 2 | ||||
-rw-r--r-- | src/pretty_printing.h | 2 | ||||
-rw-r--r-- | src/wasm.h | 21 | ||||
-rw-r--r-- | test/example/find_div0s.cpp | 44 | ||||
-rw-r--r-- | test/example/find_div0s.txt | 10 |
8 files changed, 86 insertions, 11 deletions
@@ -6,7 +6,9 @@ Binaryen is a C++ library for processing WebAssembly. It can: * **Compile** asm.js to WebAssembly, which together with [Emscripten](http://emscripten.org), gives you a complete compiler toolchain from C and C++ to WebAssembly. * **Polyfill** WebAssembly, by running it in the interpreter compiled to JavaScript, if the browser does not yet have native support. -To provide those capabilities, Binaryen has a simple and flexible API for representing and processing WebAssembly modules. The interpreter, validator, pretty-printer, etc. are built on that foundation. (TODO: an example of writing a new processing pass.) +To provide those capabilities, Binaryen has a simple and flexible API for representing and processing WebAssembly modules. The interpreter, validator, pretty-printer, etc. are built on that foundation. The core of this is in [wasm.h](https://github.com/WebAssembly/binaryen/blob/master/src/wasm.h), which contains both classes that define a WebAssembly module, and tools to process those. + +(TODO: an example of writing a new processing pass.) ## Tools @@ -1,8 +1,8 @@ echo "building binaryen shell" -g++ -O2 -std=c++11 src/binaryen-shell.cpp -g -o bin/binaryen-shell -Isrc/emscripten-optimizer +g++ -O2 -std=c++11 src/binaryen-shell.cpp -g -o bin/binaryen-shell echo "building asm2wasm" -g++ -O2 -std=c++11 src/asm2wasm-main.cpp src/emscripten-optimizer/parser.cpp src/emscripten-optimizer/simple_ast.cpp src/emscripten-optimizer/optimizer-shared.cpp -g -o bin/asm2wasm -Isrc/emscripten-optimizer +g++ -O2 -std=c++11 src/asm2wasm-main.cpp src/emscripten-optimizer/parser.cpp src/emscripten-optimizer/simple_ast.cpp src/emscripten-optimizer/optimizer-shared.cpp -g -o bin/asm2wasm echo "building interpreter/js" -em++ -std=c++11 src/wasm-js.cpp src/emscripten-optimizer/parser.cpp src/emscripten-optimizer/simple_ast.cpp src/emscripten-optimizer/optimizer-shared.cpp -o bin/wasm.js -s MODULARIZE=1 -s 'EXPORT_NAME="WasmJS"' --memory-init-file 0 -s DEMANGLE_SUPPORT=1 -O3 -profiling -s TOTAL_MEMORY=67108864 -s SAFE_HEAP=1 -s ASSERTIONS=1 -Isrc/emscripten-optimizer #-DWASM_JS_DEBUG #-DWASM_INTERPRETER_DEBUG +em++ -std=c++11 src/wasm-js.cpp src/emscripten-optimizer/parser.cpp src/emscripten-optimizer/simple_ast.cpp src/emscripten-optimizer/optimizer-shared.cpp -o bin/wasm.js -s MODULARIZE=1 -s 'EXPORT_NAME="WasmJS"' --memory-init-file 0 -s DEMANGLE_SUPPORT=1 -O3 -profiling -s TOTAL_MEMORY=67108864 -s SAFE_HEAP=1 -s ASSERTIONS=1 #-DWASM_JS_DEBUG #-DWASM_INTERPRETER_DEBUG cat src/js/post.js >> bin/wasm.js @@ -77,6 +77,14 @@ for t in tests: if actual != expected: fail(actual, expected) +print '\n[ checking example testcases... ]\n' + +subprocess.check_call(['g++', '-std=c++11', os.path.join('test', 'example', 'find_div0s.cpp'), '-Isrc', '-g']) +actual = subprocess.Popen(['./a.out'], stdout=subprocess.PIPE).communicate()[0] +expected = open(os.path.join('test', 'example', 'find_div0s.txt')).read() +if actual != expected: + fail(actual, expected) + print '\n[ checking binaryen-shell spec testcases... ]\n' if len(requested) == 0: diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 61c67c5d8..ce5b669d1 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -5,7 +5,7 @@ // #include "wasm.h" -#include "optimizer.h" +#include "emscripten-optimizer/optimizer.h" #include "mixed_arena.h" namespace wasm { diff --git a/src/pretty_printing.h b/src/pretty_printing.h index cc2d88272..88028fdec 100644 --- a/src/pretty_printing.h +++ b/src/pretty_printing.h @@ -5,7 +5,7 @@ #include <ostream> -#include "colors.h" +#include "emscripten-optimizer/colors.h" std::ostream &doIndent(std::ostream &o, unsigned indent) { for (unsigned i = 0; i < indent; i++) { diff --git a/src/wasm.h b/src/wasm.h index 769c0ecad..dfd540155 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -24,7 +24,7 @@ #include <map> #include <vector> -#include "simple_ast.h" +#include "emscripten-optimizer/simple_ast.h" #include "pretty_printing.h" namespace wasm { @@ -263,12 +263,10 @@ public: }; Id _id; - Expression() : _id(InvalidId) {} - Expression(Id id) : _id(id) {} - WasmType type; // the type of the expression: its *output*, not necessarily its input(s) - std::ostream& print(std::ostream &o, unsigned indent); // avoid virtual here, for performance + Expression() : _id(InvalidId), type(none) {} + Expression(Id id) : _id(id), type(none) {} template<class T> bool is() { @@ -280,6 +278,12 @@ public: return _id == T()._id ? (T*)this : nullptr; } + std::ostream& print(std::ostream &o, unsigned indent); // avoid virtual here, for performance + + friend std::ostream& operator<<(std::ostream &o, Expression* expression) { + return expression->print(o, 0); + } + static std::ostream& printFullLine(std::ostream &o, unsigned indent, Expression *expression) { doIndent(o, indent); expression->print(o, indent); @@ -704,6 +708,11 @@ public: printFullLine(o, indent, right); return decIndent(o, indent); } + + // the type is always the type of the operands + void finalize() { + type = left->type; + } }; class Compare : public Expression { @@ -849,6 +858,8 @@ public: Name type; // if null, it is implicit in params and result Expression *body; + Function() : result(none) {} + std::ostream& print(std::ostream &o, unsigned indent) { printOpening(o, "func ", true) << name; if (params.size() > 0) { diff --git a/test/example/find_div0s.cpp b/test/example/find_div0s.cpp new file mode 100644 index 000000000..77a5d2c61 --- /dev/null +++ b/test/example/find_div0s.cpp @@ -0,0 +1,44 @@ + +#include <ostream> +#include <wasm.h> + +using namespace wasm; + +int main() { + // A module with a function with a division by zero in the body + Module module; + Function func; + func.name = "func"; + Binary div; + div.op = BinaryOp::DivS; + Const left; + left.value = 5; + Const right; + right.value = 0; + div.left = &left; + div.right = &right; + div.finalize(); + func.body = ÷ + module.addFunction(&func); + + // Print it out + std::cout << module; + + // Search it for divisions by zero: Walk the module, looking for + // that operation. + struct DivZeroSeeker : public WasmWalker { + void visitBinary(Binary* curr) { + // In every Binary, look for integer divisions + if (curr->op == BinaryOp::DivS || curr->op == BinaryOp::DivU) { + // Check if the right operand is a constant, and if it is 0 + auto right = curr->right->dyn_cast<Const>(); + if (right && right->value.getInteger() == 0) { + std::cout << "We found that " << curr->left << " is divided by zero\n"; + } + } + } + }; + DivZeroSeeker seeker; + seeker.startWalk(&module); +} + diff --git a/test/example/find_div0s.txt b/test/example/find_div0s.txt new file mode 100644 index 000000000..44397fbde --- /dev/null +++ b/test/example/find_div0s.txt @@ -0,0 +1,10 @@ +(module + (memory 0 4294967295) + (func $func + (none.div_s + (i32.const 5) + (i32.const 0) + ) + ) +) +We found that (i32.const 5) is divided by zero |