diff options
-rw-r--r-- | src/ast/global-utils.h | 55 | ||||
-rw-r--r-- | src/tools/wasm-ctor-eval.cpp | 22 | ||||
-rw-r--r-- | test/ctor-eval/bad-indirect-call.wast.out | 2 | ||||
-rw-r--r-- | test/ctor-eval/bad-indirect-call2.wast.out | 2 | ||||
-rw-r--r-- | test/ctor-eval/basics-flatten.wast.out | 5 | ||||
-rw-r--r-- | test/ctor-eval/basics.wast.out | 5 | ||||
-rw-r--r-- | test/ctor-eval/imported-min.wast | 48 | ||||
-rw-r--r-- | test/ctor-eval/imported-min.wast.ctors | 1 | ||||
-rw-r--r-- | test/ctor-eval/imported-min.wast.out | 34 | ||||
-rw-r--r-- | test/ctor-eval/imported.wast.out | 2 | ||||
-rw-r--r-- | test/ctor-eval/imported2.wast.out | 2 | ||||
-rw-r--r-- | test/ctor-eval/imported3.wast.out | 5 | ||||
-rw-r--r-- | test/ctor-eval/indirect-call3.wast.out | 2 | ||||
-rw-r--r-- | test/ctor-eval/just_some.wast.out | 6 | ||||
-rw-r--r-- | test/ctor-eval/no_partial.wast.out | 6 | ||||
-rw-r--r-- | test/ctor-eval/unsafe_call.wast.out | 2 | ||||
-rw-r--r-- | test/ctor-eval/unsafe_store.wast.out | 2 | ||||
-rw-r--r-- | test/ctor-eval/unsafe_store2.wast.out | 2 | ||||
-rw-r--r-- | test/ctor-eval/unsafe_store3.wast.out | 2 |
19 files changed, 171 insertions, 34 deletions
diff --git a/src/ast/global-utils.h b/src/ast/global-utils.h new file mode 100644 index 000000000..f5bebe8aa --- /dev/null +++ b/src/ast/global-utils.h @@ -0,0 +1,55 @@ +/* + * Copyright 2017 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. + */ + +#ifndef wasm_ast_global_h +#define wasm_ast_global_h + +#include <algorithm> +#include <vector> + +#include "literal.h" +#include "wasm.h" + +namespace wasm { + +namespace GlobalUtils { + // find a global initialized to the value of an import, or null if no such global + inline Global* getGlobalInitializedToImport(Module&wasm, Name module, Name base) { + // find the import + Name imported; + for (auto& import : wasm.imports) { + if (import->module == module && import->base == base) { + imported = import->name; + break; + } + } + if (imported.isNull()) return nullptr; + // find a global inited to it + for (auto& global : wasm.globals) { + if (auto* init = global->init->dynCast<GetGlobal>()) { + if (init->name == imported) { + return global.get(); + } + } + } + return nullptr; + } +}; + +} // namespace wasm + +#endif // wasm_ast_global_h + diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index 160e4a4f2..67c9f9707 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -32,6 +32,7 @@ #include "wasm-interpreter.h" #include "wasm-builder.h" #include "ast/memory-utils.h" +#include "ast/global-utils.h" using namespace wasm; @@ -153,10 +154,14 @@ public: // prepare scratch memory stack.resize(STACK_SIZE); // fill usable values for stack imports - auto total = STACK_START + STACK_SIZE; - globals["STACKTOP"] = Literal(int32_t(STACK_START)); - globals["STACK_MAX"] = Literal(int32_t(STACK_START + STACK_SIZE)); + if (auto* stackTop = GlobalUtils::getGlobalInitializedToImport(wasm, "env", "STACKTOP")) { + globals[stackTop->name] = Literal(int32_t(STACK_START)); + } + if (auto* stackMax = GlobalUtils::getGlobalInitializedToImport(wasm, "env", "STACK_MAX")) { + globals[stackMax->name] = Literal(int32_t(STACK_START)); + } // tell the module to accept writes up to the stack end + auto total = STACK_START + STACK_SIZE; memorySize = total / Memory::kPageSize; } @@ -398,6 +403,17 @@ int main(int argc, const char* argv[]) { } evalCtors(wasm, ctors); + // Do some useful optimizations after the evalling + { + PassRunner passRunner(&wasm); + passRunner.add("memory-packing"); // we flattened it, so re-optimize + passRunner.add("remove-unused-names"); + passRunner.add("dce"); + passRunner.add("merge-blocks"); + passRunner.add("vacuum"); + passRunner.run(); + } + if (options.extra.count("output") > 0) { if (options.debug) std::cerr << "writing..." << std::endl; ModuleWriter writer; diff --git a/test/ctor-eval/bad-indirect-call.wast.out b/test/ctor-eval/bad-indirect-call.wast.out index 27c849701..fc3d71e42 100644 --- a/test/ctor-eval/bad-indirect-call.wast.out +++ b/test/ctor-eval/bad-indirect-call.wast.out @@ -3,7 +3,7 @@ (table 1 1 anyfunc) (elem (i32.const 0) $call-indirect) (memory $0 256 256) - (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00waka waka waka waka waka") + (data (i32.const 10) "waka waka waka waka waka") (export "test1" (func $test1)) (func $test1 (type $v) (call_indirect $v diff --git a/test/ctor-eval/bad-indirect-call2.wast.out b/test/ctor-eval/bad-indirect-call2.wast.out index b07a2d40b..d63f1a11e 100644 --- a/test/ctor-eval/bad-indirect-call2.wast.out +++ b/test/ctor-eval/bad-indirect-call2.wast.out @@ -5,7 +5,7 @@ (table 2 2 anyfunc) (elem (i32.const 0) $_abort $call-indirect) (memory $0 256 256) - (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00waka waka waka waka waka") + (data (i32.const 10) "waka waka waka waka waka") (export "test1" (func $test1)) (func $test1 (type $v) (call_indirect $v diff --git a/test/ctor-eval/basics-flatten.wast.out b/test/ctor-eval/basics-flatten.wast.out index 33177707e..2c0502ab7 100644 --- a/test/ctor-eval/basics-flatten.wast.out +++ b/test/ctor-eval/basics-flatten.wast.out @@ -3,7 +3,7 @@ (table 1 1 anyfunc) (elem (i32.const 0) $call-indirect) (memory $0 256 256) - (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00nas\00\00\00aka\00yzkx waka wakm\00\00\00\00\00\00C") + (data (i32.const 10) "nas\00\00\00aka\00yzkx waka wakm\00\00\00\00\00\00C") (export "test1" (func $test1)) (export "test2" (func $test2)) (export "test3" (func $test3)) @@ -17,9 +17,6 @@ (nop) ) (func $safe-to-call (type $v) - (drop - (i32.const 1) - ) (i32.store8 (i32.const 10) (i32.const 110) diff --git a/test/ctor-eval/basics.wast.out b/test/ctor-eval/basics.wast.out index bf7735185..4e541385b 100644 --- a/test/ctor-eval/basics.wast.out +++ b/test/ctor-eval/basics.wast.out @@ -3,7 +3,7 @@ (table 1 1 anyfunc) (elem (i32.const 0) $call-indirect) (memory $0 256 256) - (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00nas\00\00\00aka yzkx waka wakm\00\00\00\00\00\00C") + (data (i32.const 10) "nas\00\00\00aka yzkx waka wakm\00\00\00\00\00\00C") (export "test1" (func $test1)) (export "test2" (func $test2)) (export "test3" (func $test3)) @@ -17,9 +17,6 @@ (nop) ) (func $safe-to-call (type $v) - (drop - (i32.const 1) - ) (i32.store8 (i32.const 10) (i32.const 110) diff --git a/test/ctor-eval/imported-min.wast b/test/ctor-eval/imported-min.wast new file mode 100644 index 000000000..8972a2ee1 --- /dev/null +++ b/test/ctor-eval/imported-min.wast @@ -0,0 +1,48 @@ +(module + (memory 256 256) + (data (i32.const 10) "waka waka waka waka waka") + ;; stack imports are special + (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) + (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32)) + ;; other imports must not be touched! + (import "env" "tempDoublePtr" (global $tempDoublePtr i32)) + (export "test1" $test1) + (export "test2" $test2) + (export "test3" $test3) + ;; ok to modify a global, if we keep it the same value + (global $mine (mut i32) (i32.const 1)) + ;; stack imports are ok to use. their uses are the same as other + ;; globals - must keep the same value (which means, unwind the stack) + ;; here the global names are "minified" + (global $global0 (mut i32) (get_global $STACKTOP$asm2wasm$import)) + (global $global1 (mut i32) (get_global $STACK_MAX$asm2wasm$import)) + ;; a global initialized by an import, so bad, but ok if not used + (global $do-not-use (mut i32) (get_global $tempDoublePtr)) + (func $test1 + (local $temp i32) + (set_global $mine (i32.const 1)) + (set_local $temp (get_global $global0)) + (set_global $global0 (i32.const 1337)) ;; bad + (set_global $global0 (get_local $temp)) ;; save us + (set_global $global1 (i32.const 913370)) ;; bad + (set_global $global1 (get_local $temp)) ;; save us + ;; use the stack memory + (i32.store (get_local $temp) (i32.const 1337)) + (if + (i32.ne + (i32.load (get_local $temp)) + (i32.const 1337) + ) + (unreachable) ;; they should be equal, never get here + ) + ;; finally, do a valid store + (i32.store8 (i32.const 12) (i32.const 115)) + ) + (func $test2 + (set_global $tempDoublePtr (i32.const 1)) ;; bad! + (i32.store8 (i32.const 13) (i32.const 115)) + ) + (func $test3 + (i32.store8 (i32.const 14) (i32.const 115)) + ) +) diff --git a/test/ctor-eval/imported-min.wast.ctors b/test/ctor-eval/imported-min.wast.ctors new file mode 100644 index 000000000..c7060ede5 --- /dev/null +++ b/test/ctor-eval/imported-min.wast.ctors @@ -0,0 +1 @@ +test1,test2,test3 diff --git a/test/ctor-eval/imported-min.wast.out b/test/ctor-eval/imported-min.wast.out new file mode 100644 index 000000000..48d4c5796 --- /dev/null +++ b/test/ctor-eval/imported-min.wast.out @@ -0,0 +1,34 @@ +(module + (type $0 (func)) + (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) + (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32)) + (import "env" "tempDoublePtr" (global $tempDoublePtr i32)) + (global $mine (mut i32) (i32.const 1)) + (global $global0 (mut i32) (get_global $STACKTOP$asm2wasm$import)) + (global $global1 (mut i32) (get_global $STACK_MAX$asm2wasm$import)) + (global $do-not-use (mut i32) (get_global $tempDoublePtr)) + (memory $0 256 256) + (data (i32.const 10) "wasa waka waka waka waka") + (export "test1" (func $test1)) + (export "test2" (func $test2)) + (export "test3" (func $test3)) + (func $test1 (type $0) + (local $temp i32) + (nop) + ) + (func $test2 (type $0) + (set_global $tempDoublePtr + (i32.const 1) + ) + (i32.store8 + (i32.const 13) + (i32.const 115) + ) + ) + (func $test3 (type $0) + (i32.store8 + (i32.const 14) + (i32.const 115) + ) + ) +) diff --git a/test/ctor-eval/imported.wast.out b/test/ctor-eval/imported.wast.out index eeb405454..38fcb1842 100644 --- a/test/ctor-eval/imported.wast.out +++ b/test/ctor-eval/imported.wast.out @@ -8,7 +8,7 @@ (global $STACK_MAX (mut i32) (get_global $STACK_MAX$asm2wasm$import)) (global $do-not-use (mut i32) (get_global $tempDoublePtr)) (memory $0 256 256) - (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00wasa waka waka waka waka") + (data (i32.const 10) "wasa waka waka waka waka") (export "test1" (func $test1)) (export "test2" (func $test2)) (export "test3" (func $test3)) diff --git a/test/ctor-eval/imported2.wast.out b/test/ctor-eval/imported2.wast.out index 7922dd944..26b91cc35 100644 --- a/test/ctor-eval/imported2.wast.out +++ b/test/ctor-eval/imported2.wast.out @@ -5,7 +5,7 @@ (import "env" "tempDoublePtr" (global $tempDoublePtr i32)) (global $mine (mut i32) (i32.const 1)) (memory $0 256 256) - (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00wasa waka waka waka waka") + (data (i32.const 10) "wasa waka waka waka waka") (export "test1" (func $test1)) (export "test2" (func $test2)) (export "test3" (func $test3)) diff --git a/test/ctor-eval/imported3.wast.out b/test/ctor-eval/imported3.wast.out index 4322a0237..6d8fab867 100644 --- a/test/ctor-eval/imported3.wast.out +++ b/test/ctor-eval/imported3.wast.out @@ -3,14 +3,11 @@ (import "env" "tempDoublePtr" (global $tempDoublePtr i32)) (global $mine (mut i32) (get_global $tempDoublePtr)) (memory $0 256 256) - (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00waka waka waka waka waka") + (data (i32.const 10) "waka waka waka waka waka") (export "test1" (func $test1)) (export "test2" (func $test2)) (export "test3" (func $test3)) (func $test1 (type $0) - (drop - (get_global $mine) - ) (i32.store8 (i32.const 13) (i32.const 115) diff --git a/test/ctor-eval/indirect-call3.wast.out b/test/ctor-eval/indirect-call3.wast.out index 63d6273da..27f661c30 100644 --- a/test/ctor-eval/indirect-call3.wast.out +++ b/test/ctor-eval/indirect-call3.wast.out @@ -6,7 +6,7 @@ (table 2 2 anyfunc) (elem (get_global $tableBase) $_abort $call-indirect) (memory $0 256 256) - (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00waka waka xaka waka waka\00\00\00\00\00\00C") + (data (i32.const 10) "waka waka xaka waka waka\00\00\00\00\00\00C") (export "test1" (func $test1)) (func $test1 (type $v) (nop) diff --git a/test/ctor-eval/just_some.wast.out b/test/ctor-eval/just_some.wast.out index 41e3d7338..79bb19df6 100644 --- a/test/ctor-eval/just_some.wast.out +++ b/test/ctor-eval/just_some.wast.out @@ -1,7 +1,7 @@ (module (type $0 (func)) (memory $0 256 256) - (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00wasa waka waka waka waka") + (data (i32.const 10) "wasa waka waka waka waka") (export "test1" (func $test1)) (export "test2" (func $test2)) (export "test3" (func $test3)) @@ -10,10 +10,6 @@ ) (func $test2 (type $0) (unreachable) - (i32.store8 - (i32.const 13) - (i32.const 114) - ) ) (func $test3 (type $0) (i32.store8 diff --git a/test/ctor-eval/no_partial.wast.out b/test/ctor-eval/no_partial.wast.out index fc25804a7..0caa401d4 100644 --- a/test/ctor-eval/no_partial.wast.out +++ b/test/ctor-eval/no_partial.wast.out @@ -1,7 +1,7 @@ (module (type $0 (func)) (memory $0 256 256) - (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00waka waka waka waka waka") + (data (i32.const 10) "waka waka waka waka waka") (export "test1" (func $test1)) (func $test1 (type $0) (i32.store8 @@ -9,9 +9,5 @@ (i32.const 115) ) (unreachable) - (i32.store8 - (i32.const 13) - (i32.const 114) - ) ) ) diff --git a/test/ctor-eval/unsafe_call.wast.out b/test/ctor-eval/unsafe_call.wast.out index 124cf2578..7d8867610 100644 --- a/test/ctor-eval/unsafe_call.wast.out +++ b/test/ctor-eval/unsafe_call.wast.out @@ -1,7 +1,7 @@ (module (type $0 (func)) (memory $0 256 256) - (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00waka waka waka waka waka") + (data (i32.const 10) "waka waka waka waka waka") (export "test1" (func $test1)) (export "test2" (func $test2)) (export "test3" (func $test3)) diff --git a/test/ctor-eval/unsafe_store.wast.out b/test/ctor-eval/unsafe_store.wast.out index 8bbc2fed4..7fa97d876 100644 --- a/test/ctor-eval/unsafe_store.wast.out +++ b/test/ctor-eval/unsafe_store.wast.out @@ -1,7 +1,7 @@ (module (type $0 (func)) (memory $0 256 256) - (data (i32.const 0) "\00\00\00\00\00\00\00\00\00mwaka waka waka waka waka") + (data (i32.const 9) "mwaka waka waka waka waka") (export "test1" (func $test1)) (export "test2" (func $test2)) (export "test3" (func $test3)) diff --git a/test/ctor-eval/unsafe_store2.wast.out b/test/ctor-eval/unsafe_store2.wast.out index 798a4a23d..7af56749a 100644 --- a/test/ctor-eval/unsafe_store2.wast.out +++ b/test/ctor-eval/unsafe_store2.wast.out @@ -1,7 +1,7 @@ (module (type $0 (func)) (memory $0 256 256) - (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00waka waka waka waka wakam") + (data (i32.const 10) "waka waka waka waka wakam") (export "test1" (func $test1)) (export "test2" (func $test2)) (export "test3" (func $test3)) diff --git a/test/ctor-eval/unsafe_store3.wast.out b/test/ctor-eval/unsafe_store3.wast.out index e8ad4f5b8..cbf66c6da 100644 --- a/test/ctor-eval/unsafe_store3.wast.out +++ b/test/ctor-eval/unsafe_store3.wast.out @@ -1,7 +1,7 @@ (module (type $0 (func)) (memory $0 256 256) - (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00waka waka waka waka wakm\00") + (data (i32.const 10) "waka waka waka waka wakm") (export "test1" (func $test1)) (export "test2" (func $test2)) (export "test3" (func $test3)) |