summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-04-29 14:58:17 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-04-29 15:03:30 -0700
commit8ac323bb58c0e1891dea6492160939eb1b6bb1d2 (patch)
treed86a3fe87034f59051c21eb581af0b24143f6c6f
parent623918767242c36b9197e83a9e3b4e35ee17f8db (diff)
downloadbinaryen-8ac323bb58c0e1891dea6492160939eb1b6bb1d2.tar.gz
binaryen-8ac323bb58c0e1891dea6492160939eb1b6bb1d2.tar.bz2
binaryen-8ac323bb58c0e1891dea6492160939eb1b6bb1d2.zip
add wasm.cpp which does full type detection for blocks, and prepare for full type checking everywhere
-rw-r--r--CMakeLists.txt8
-rwxr-xr-xbuild-js.sh4
-rwxr-xr-xcheck.py1
-rw-r--r--src/wasm.cpp84
-rw-r--r--src/wasm.h17
5 files changed, 107 insertions, 7 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9e6834c57..b948328f1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -106,6 +106,7 @@ SET(binaryen-shell_SOURCES
src/passes/ReorderLocals.cpp
src/passes/Vacuum.cpp
src/passes/Metrics.cpp
+ src/wasm.cpp
)
ADD_EXECUTABLE(binaryen-shell
${binaryen-shell_SOURCES})
@@ -129,6 +130,7 @@ SET(asm2wasm_SOURCES
src/emscripten-optimizer/parser.cpp
src/emscripten-optimizer/simple_ast.cpp
src/emscripten-optimizer/optimizer-shared.cpp
+ src/wasm.cpp
)
ADD_EXECUTABLE(asm2wasm
${asm2wasm_SOURCES})
@@ -142,6 +144,7 @@ SET(wasm2asm_SOURCES
src/emscripten-optimizer/parser.cpp
src/emscripten-optimizer/simple_ast.cpp
src/emscripten-optimizer/optimizer-shared.cpp
+ src/wasm.cpp
)
ADD_EXECUTABLE(wasm2asm
${wasm2asm_SOURCES})
@@ -155,6 +158,7 @@ SET(s2wasm_SOURCES
src/passes/Print.cpp
src/wasm-linker.cpp
src/s2wasm-main.cpp
+ src/wasm.cpp
)
ADD_EXECUTABLE(s2wasm
${s2wasm_SOURCES})
@@ -164,7 +168,10 @@ SET_PROPERTY(TARGET s2wasm PROPERTY CXX_STANDARD_REQUIRED ON)
INSTALL(TARGETS s2wasm DESTINATION bin)
SET(wasm_as_SOURCES
+ src/pass.cpp
+ src/passes/Print.cpp
src/wasm-as.cpp
+ src/wasm.cpp
)
ADD_EXECUTABLE(wasm-as
${wasm_as_SOURCES})
@@ -177,6 +184,7 @@ SET(wasm_dis_SOURCES
src/pass.cpp
src/passes/Print.cpp
src/wasm-dis.cpp
+ src/wasm.cpp
)
ADD_EXECUTABLE(wasm-dis
${wasm_dis_SOURCES})
diff --git a/build-js.sh b/build-js.sh
index c4dc57b27..ce8038f51 100755
--- a/build-js.sh
+++ b/build-js.sh
@@ -6,9 +6,9 @@
echo "building wasm.js"
-em++ -std=c++11 src/wasm-js.cpp src/pass.cpp src/passes/MergeBlocks.cpp src/passes/Print.cpp src/passes/OptimizeInstructions.cpp src/passes/RemoveUnusedBrs.cpp src/passes/RemoveUnusedNames.cpp src/passes/PostEmscripten.cpp src/passes/SimplifyLocals.cpp src/passes/ReorderLocals.cpp src/passes/Vacuum.cpp src/emscripten-optimizer/parser.cpp src/emscripten-optimizer/simple_ast.cpp src/emscripten-optimizer/optimizer-shared.cpp src/support/colors.cpp src/support/safe_integer.cpp src/support/bits.cpp src/support/threads.cpp src/asmjs/asm_v_wasm.cpp src/asmjs/shared-constants.cpp -Isrc/ -o bin/wasm.js -s MODULARIZE=1 -s 'EXPORT_NAME="WasmJS"' --memory-init-file 0 -Oz -s ALLOW_MEMORY_GROWTH=1 -profiling -s DEMANGLE_SUPPORT=1 #-DWASM_JS_DEBUG -DWASM_INTERPRETER_DEBUG=2
+em++ -std=c++11 src/wasm-js.cpp src/pass.cpp src/passes/MergeBlocks.cpp src/passes/Print.cpp src/passes/OptimizeInstructions.cpp src/passes/RemoveUnusedBrs.cpp src/passes/RemoveUnusedNames.cpp src/passes/PostEmscripten.cpp src/passes/SimplifyLocals.cpp src/passes/ReorderLocals.cpp src/passes/Vacuum.cpp src/emscripten-optimizer/parser.cpp src/emscripten-optimizer/simple_ast.cpp src/emscripten-optimizer/optimizer-shared.cpp src/support/colors.cpp src/support/safe_integer.cpp src/support/bits.cpp src/support/threads.cpp src/asmjs/asm_v_wasm.cpp src/asmjs/shared-constants.cpp src/wasm.cpp -Isrc/ -o bin/wasm.js -s MODULARIZE=1 -s 'EXPORT_NAME="WasmJS"' --memory-init-file 0 -Oz -s ALLOW_MEMORY_GROWTH=1 -profiling -s DEMANGLE_SUPPORT=1 #-DWASM_JS_DEBUG -DWASM_INTERPRETER_DEBUG=2
echo "building binaryen.js"
python ~/Dev/emscripten/tools/webidl_binder.py src/js/binaryen.idl glue
-em++ -std=c++11 src/binaryen-js.cpp src/pass.cpp src/passes/MergeBlocks.cpp src/passes/Print.cpp src/passes/RemoveUnusedBrs.cpp src/passes/RemoveUnusedNames.cpp src/passes/PostEmscripten.cpp src/passes/SimplifyLocals.cpp src/passes/ReorderLocals.cpp src/passes/Vacuum.cpp src/emscripten-optimizer/parser.cpp src/emscripten-optimizer/simple_ast.cpp src/emscripten-optimizer/optimizer-shared.cpp src/support/colors.cpp src/support/safe_integer.cpp src/support/bits.cpp src/support/threads.cpp src/asmjs/asm_v_wasm.cpp src/asmjs/shared-constants.cpp -Isrc/ -o bin/binaryen.js -s MODULARIZE=1 -s 'EXPORT_NAME="Binaryen"' --memory-init-file 0 -Oz -s ALLOW_MEMORY_GROWTH=1 -profiling -s DEMANGLE_SUPPORT=1 -s INVOKE_RUN=0 --post-js glue.js
+em++ -std=c++11 src/binaryen-js.cpp src/pass.cpp src/passes/MergeBlocks.cpp src/passes/Print.cpp src/passes/RemoveUnusedBrs.cpp src/passes/RemoveUnusedNames.cpp src/passes/PostEmscripten.cpp src/passes/SimplifyLocals.cpp src/passes/ReorderLocals.cpp src/passes/Vacuum.cpp src/emscripten-optimizer/parser.cpp src/emscripten-optimizer/simple_ast.cpp src/emscripten-optimizer/optimizer-shared.cpp src/support/colors.cpp src/support/safe_integer.cpp src/support/bits.cpp src/support/threads.cpp src/asmjs/asm_v_wasm.cpp src/asmjs/shared-constants.cpp src/wasm.cpp -Isrc/ -o bin/binaryen.js -s MODULARIZE=1 -s 'EXPORT_NAME="Binaryen"' --memory-init-file 0 -Oz -s ALLOW_MEMORY_GROWTH=1 -profiling -s DEMANGLE_SUPPORT=1 -s INVOKE_RUN=0 --post-js glue.js
diff --git a/check.py b/check.py
index d59358311..977da0764 100755
--- a/check.py
+++ b/check.py
@@ -572,6 +572,7 @@ print '\n[ checking example testcases... ]\n'
cmd = [os.environ.get('CXX') or 'g++', '-std=c++11',
os.path.join('test', 'example', 'find_div0s.cpp'),
os.path.join('src', 'pass.cpp'),
+ os.path.join('src', 'wasm.cpp'),
os.path.join('src', 'passes', 'Print.cpp'),
'-Isrc', '-g', '-lasmjs', '-lsupport', '-Llib/.', '-pthread']
if os.environ.get('COMPILER_FLAGS'):
diff --git a/src/wasm.cpp b/src/wasm.cpp
new file mode 100644
index 000000000..2157992e3
--- /dev/null
+++ b/src/wasm.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2016 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wasm.h"
+#include "wasm-traversal.h"
+#include "ast_utils.h"
+
+namespace wasm {
+
+struct BlockTypeSeeker : public PostWalker<BlockTypeSeeker, Visitor<BlockTypeSeeker>> {
+ Block* target; // look for this one
+ WasmType type = unreachable;
+
+ BlockTypeSeeker(Block* target) : target(target) {}
+
+ void noteType(WasmType other) {
+ // once none, stop. it then indicates a poison value, that must not be consumed
+ // and ignore unreachable
+ if (type != none) {
+ if (other == none) {
+ type = none;
+ } else if (other != unreachable) {
+ type = other;
+ }
+ }
+ }
+
+ void visitBreak(Break *curr) {
+ if (curr->name == target->name) {
+ noteType(curr->value ? curr->value->type : none);
+ }
+ }
+
+ void visitSwitch(Switch *curr) {
+ for (auto name : curr->targets) {
+ if (name == target->name) noteType(curr->value ? curr->value->type : none);
+ }
+ }
+
+ void visitBlock(Block *curr) {
+ if (curr == target) {
+ if (curr->list.size() > 0) noteType(curr->list.back()->type);
+ } else {
+ type = unreachable; // ignore all breaks til now, they were captured by someone with the same name
+ }
+ }
+};
+
+void Block::finalize() {
+ if (list.size() > 0) {
+ auto last = list.back()->type;
+ if (last != unreachable) {
+ // well that was easy
+ type = last;
+ return;
+ }
+ }
+ if (!name.is()) {
+ // that was rather silly
+ type = unreachable;
+ return;
+ }
+ // oh no this is hard
+ BlockTypeSeeker seeker(this);
+ Expression* temp = this;
+ seeker.walk(temp);
+ type = seeker.type;
+}
+
+} // namespace wasm
+
diff --git a/src/wasm.h b/src/wasm.h
index b5dee81b8..b13011bae 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -833,11 +833,13 @@ public:
Name name;
ExpressionList list;
- void finalize() {
- if (list.size() > 0) {
- type = list.back()->type;
- }
+ // set the type of a block if you already know it
+ void finalize(WasmType type_) {
+ type = type;
}
+
+ // set the type of a block based on its contents. this scans the block, so it is not fast
+ void finalize();
};
class If : public SpecificExpression<Expression::IfId> {
@@ -877,6 +879,12 @@ public:
Name name;
Expression *value;
Expression *condition;
+
+ void finalize() {
+ if (condition) {
+ type = none;
+ }
+ }
};
class Switch : public SpecificExpression<Expression::SwitchId> {
@@ -1022,7 +1030,6 @@ public:
if (isRelational()) {
type = i32;
} else {
- assert(left->type != unreachable && right->type != unreachable ? left->type == right->type : true);
type = getReachableWasmType(left->type, right->type);
}
}