summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2015-11-11 20:38:18 -0800
committerAlon Zakai <alonzakai@gmail.com>2015-11-11 20:38:18 -0800
commita43caa75ce7293a4aea91228daf379f06817f5d8 (patch)
treecf19d50e137e9c4a80180bfb90d084f418e337f5
parented47fbc9ce48e712548d937195e0f7d333da55c4 (diff)
downloadbinaryen-a43caa75ce7293a4aea91228daf379f06817f5d8.tar.gz
binaryen-a43caa75ce7293a4aea91228daf379f06817f5d8.tar.bz2
binaryen-a43caa75ce7293a4aea91228daf379f06817f5d8.zip
add simple example
-rw-r--r--README.md4
-rwxr-xr-xbuild.sh6
-rwxr-xr-xcheck.py8
-rw-r--r--src/asm2wasm.h2
-rw-r--r--src/pretty_printing.h2
-rw-r--r--src/wasm.h21
-rw-r--r--test/example/find_div0s.cpp44
-rw-r--r--test/example/find_div0s.txt10
8 files changed, 86 insertions, 11 deletions
diff --git a/README.md b/README.md
index 4483a1a22..d8a059720 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/build.sh b/build.sh
index 9794de42f..db3033cdc 100755
--- a/build.sh
+++ b/build.sh
@@ -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
diff --git a/check.py b/check.py
index 6717fccb2..c4bce02aa 100755
--- a/check.py
+++ b/check.py
@@ -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 = &div;
+ 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