diff options
author | Derek Schuff <dschuff@chromium.org> | 2016-04-06 15:12:14 -0700 |
---|---|---|
committer | Derek Schuff <dschuff@chromium.org> | 2016-04-06 15:12:14 -0700 |
commit | c4c82597aaf43d7fee3cd8877801d9dd91e33f7b (patch) | |
tree | 04795d214e9d818bf0d1b9d81a47ea8924e40878 | |
parent | 0d1a66c540a2c89e1d4543fe318976ad1c6411f1 (diff) | |
download | binaryen-c4c82597aaf43d7fee3cd8877801d9dd91e33f7b.tar.gz binaryen-c4c82597aaf43d7fee3cd8877801d9dd91e33f7b.tar.bz2 binaryen-c4c82597aaf43d7fee3cd8877801d9dd91e33f7b.zip |
Fix s2wasm handling of aliased functions
This fixes 2 bugs in s2wasm:
* Handle address-taken aliases (i.e. when they appear in relocations), by looking up and subsituting the address of the aliasee.
* Skip whitespace at the top of the scan() loop instead of requiring it to match. When there are multiple alias declarations in a row, the match("FUNCTION") at the end of an alias delcaration consumes the whitespace at the beginning of the next line, causing it to fail to match the tab character specified in the match pattern at the top of the loop.
-rw-r--r-- | src/s2wasm.h | 7 | ||||
-rw-r--r-- | test/dot_s/alias.s | 4 | ||||
-rw-r--r-- | test/dot_s/alias.wast | 10 |
3 files changed, 15 insertions, 6 deletions
diff --git a/src/s2wasm.h b/src/s2wasm.h index c85a214a1..c2e8c77a0 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -405,9 +405,10 @@ class S2WasmBuilder { void scan() { while (*s) { - s = strstr(s, "\n .type "); + skipWhitespace(); + s = strstr(s, ".type"); if (!s) break; - mustMatch("\n .type "); + mustMatch(".type"); Name name = getCommaSeparated(); skipComma(); if (!match("@function")) continue; @@ -1282,6 +1283,8 @@ class S2WasmBuilder { if (debug) std::cerr << " ==> " << *(relocation.data) << '\n'; } else { // must be a function address + auto aliased = aliasedFunctions.find(name); + if (aliased != aliasedFunctions.end()) name = aliased->second; if (!wasm.checkFunction(name)) { std::cerr << "Unknown symbol: " << name << '\n'; if (!ignoreUnknownSymbols) abort(); diff --git a/test/dot_s/alias.s b/test/dot_s/alias.s index a29470b2f..85a89a16f 100644 --- a/test/dot_s/alias.s +++ b/test/dot_s/alias.s @@ -16,9 +16,11 @@ __exit: # @__exit .globl __needs_exit .type __needs_exit,@function __needs_exit: # @__needs_exit + .result i32 # BB#0: # %entry call __exit_needed@FUNCTION - return + i32.const $push0=, __exit_needed@FUNCTION + return $pop0 .endfunc .Lfunc_end1: .size __needs_exit, .Lfunc_end1-__needs_exit diff --git a/test/dot_s/alias.wast b/test/dot_s/alias.wast index a6c9994b9..c9c64117b 100644 --- a/test/dot_s/alias.wast +++ b/test/dot_s/alias.wast @@ -1,15 +1,19 @@ (module (memory 1) (export "memory" memory) + (type $FUNCSIG$v (func)) (export "__exit" $__exit) (export "__needs_exit" $__needs_exit) - (func $__exit + (table $__exit) + (func $__exit (type $FUNCSIG$v) (local $$0 i32) (return) ) - (func $__needs_exit + (func $__needs_exit (result i32) (call $__exit) - (return) + (return + (i32.const 0) + ) ) ) ;; METADATA: { "asmConsts": {},"staticBump": 12, "initializers": [] } |