diff options
author | Jacob Gravelle <jgravelle@google.com> | 2018-11-14 16:33:28 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-14 16:33:28 -0800 |
commit | a259699cfed19b56469ccff88e1c76c7199e4a45 (patch) | |
tree | 67eb708ae8146914596b9514a8a63844625adaf9 | |
parent | 4442d98dbfcd54c8e920bd11bb376a1003957daa (diff) | |
download | binaryen-a259699cfed19b56469ccff88e1c76c7199e4a45.tar.gz binaryen-a259699cfed19b56469ccff88e1c76c7199e4a45.tar.bz2 binaryen-a259699cfed19b56469ccff88e1c76c7199e4a45.zip |
Handle EM_ASM functions in Tables (#1739)
Not at all sure why we're seeing any there, but it's easy enough to
handle that we might as well.
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 34 | ||||
-rw-r--r-- | test/lld/em_asm_table.wast | 13 | ||||
-rw-r--r-- | test/lld/em_asm_table.wast.out | 64 |
3 files changed, 104 insertions, 7 deletions
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp index a99482d39..c61e40b1d 100644 --- a/src/wasm/wasm-emscripten.cpp +++ b/src/wasm/wasm-emscripten.cpp @@ -376,10 +376,12 @@ struct AsmConstWalker : public PostWalker<AsmConstWalker> { segmentOffsets(getSegmentOffsets(wasm)) { } void visitCall(Call* curr); + void visitTable(Table* curr); void process(); private: + std::string fixupNameWithSig(Name& name, std::string baseSig); Literal idLiteralForCode(std::string code); std::string asmConstSig(std::string baseSig); Name nameForImportWithSig(std::string sig); @@ -392,18 +394,24 @@ private: void AsmConstWalker::visitCall(Call* curr) { auto* import = wasm.getFunction(curr->target); if (import->imported() && import->base.hasSubstring(EMSCRIPTEN_ASM_CONST)) { + auto baseSig = getSig(curr); + auto sig = fixupNameWithSig(curr->target, baseSig); + auto arg = curr->operands[0]->cast<Const>(); auto code = codeForConstAddr(wasm, segmentOffsets, arg); arg->value = idLiteralForCode(code); - auto baseSig = getSig(curr); - auto sig = asmConstSig(baseSig); sigsForCode[code].insert(sig); - auto importName = nameForImportWithSig(sig); - curr->target = importName; + } +} - if (allSigs.count(sig) == 0) { - allSigs.insert(sig); - queueImport(importName, baseSig); +void AsmConstWalker::visitTable(Table* curr) { + for (auto& segment : curr->segments) { + for (auto& name : segment.data) { + auto* func = wasm.getFunction(name); + if (func->imported() && func->base.hasSubstring(EMSCRIPTEN_ASM_CONST)) { + std::string baseSig = getSig(func); + fixupNameWithSig(name, baseSig); + } } } } @@ -416,6 +424,18 @@ void AsmConstWalker::process() { addImports(); } +std::string AsmConstWalker::fixupNameWithSig(Name& name, std::string baseSig) { + auto sig = asmConstSig(baseSig); + auto importName = nameForImportWithSig(sig); + name = importName; + + if (allSigs.count(sig) == 0) { + allSigs.insert(sig); + queueImport(importName, baseSig); + } + return sig; +} + Literal AsmConstWalker::idLiteralForCode(std::string code) { int32_t id; if (ids.count(code) == 0) { diff --git a/test/lld/em_asm_table.wast b/test/lld/em_asm_table.wast new file mode 100644 index 000000000..01039bf09 --- /dev/null +++ b/test/lld/em_asm_table.wast @@ -0,0 +1,13 @@ +(module + (type $0 (func (param i32 i32))) + (type $1 (func (param i32 i32 i32) (result i32))) + (import "env" "memory" (memory $2 8192)) + (import "env" "emscripten_log" (func $fimport$0 (param i32 i32))) + (import "env" "emscripten_asm_const_int" (func $fimport$1 (param i32 i32 i32) (result i32))) + (table $0 159609 anyfunc) + (elem (i32.const 1) $fimport$0 $fimport$1) + (global $global$0 (mut i32) (i32.const 1024)) + (global $global$1 i32 (i32.const 1048)) + (export "__data_end" (global $global$1)) +) + diff --git a/test/lld/em_asm_table.wast.out b/test/lld/em_asm_table.wast.out new file mode 100644 index 000000000..8d99e9a6f --- /dev/null +++ b/test/lld/em_asm_table.wast.out @@ -0,0 +1,64 @@ +(module + (type $0 (func (param i32 i32))) + (type $1 (func (param i32 i32 i32) (result i32))) + (type $FUNCSIG$vii (func (param i32 i32))) + (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) + (import "env" "memory" (memory $0 8192)) + (import "env" "emscripten_log" (func $fimport$0 (param i32 i32))) + (import "env" "emscripten_asm_const_iii" (func $emscripten_asm_const_iii (param i32 i32 i32) (result i32))) + (table $0 159609 anyfunc) + (elem (i32.const 1) $fimport$0 $emscripten_asm_const_iii) + (global $global$0 (mut i32) (i32.const 1024)) + (global $global$1 i32 (i32.const 1048)) + (export "__data_end" (global $global$1)) + (export "stackSave" (func $stackSave)) + (export "stackAlloc" (func $stackAlloc)) + (export "stackRestore" (func $stackRestore)) + (export "__growWasmMemory" (func $__growWasmMemory)) + (export "dynCall_vii" (func $dynCall_vii)) + (export "dynCall_iiii" (func $dynCall_iiii)) + (func $stackSave (; 2 ;) (result i32) + (get_global $global$0) + ) + (func $stackAlloc (; 3 ;) (param $0 i32) (result i32) + (local $1 i32) + (set_global $global$0 + (tee_local $1 + (i32.and + (i32.sub + (get_global $global$0) + (get_local $0) + ) + (i32.const -16) + ) + ) + ) + (get_local $1) + ) + (func $stackRestore (; 4 ;) (param $0 i32) + (set_global $global$0 + (get_local $0) + ) + ) + (func $__growWasmMemory (; 5 ;) (param $newSize i32) (result i32) + (grow_memory + (get_local $newSize) + ) + ) + (func $dynCall_vii (; 6 ;) (param $fptr i32) (param $0 i32) (param $1 i32) + (call_indirect (type $FUNCSIG$vii) + (get_local $0) + (get_local $1) + (get_local $fptr) + ) + ) + (func $dynCall_iiii (; 7 ;) (param $fptr i32) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (call_indirect (type $FUNCSIG$iiii) + (get_local $0) + (get_local $1) + (get_local $2) + (get_local $fptr) + ) + ) +) +;; METADATA: { "asmConsts": {},"staticBump": 480, "initializers": [], "declares": ["emscripten_log"], "externs": [], "implementedFunctions": ["_stackSave","_stackAlloc","_stackRestore","___growWasmMemory","_dynCall_vii","_dynCall_iiii"], "exports": ["__data_end","stackSave","stackAlloc","stackRestore","__growWasmMemory","dynCall_vii","dynCall_iiii"], "invokeFuncs": [] } |