diff options
-rw-r--r-- | CMakeLists.txt | 8 | ||||
-rwxr-xr-x | build-js.sh | 4 | ||||
-rwxr-xr-x | check.py | 1 | ||||
-rw-r--r-- | src/wasm.cpp | 84 | ||||
-rw-r--r-- | src/wasm.h | 17 |
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 @@ -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); } } |