diff options
-rw-r--r-- | src/wasm-linker.cpp | 8 | ||||
-rw-r--r-- | src/wasm-linker.h | 2 | ||||
-rw-r--r-- | test/dot_s/indirect-import.c | 6 | ||||
-rw-r--r-- | test/dot_s/indirect-import.s | 14 | ||||
-rw-r--r-- | test/dot_s/indirect-import.wast | 4 |
5 files changed, 28 insertions, 6 deletions
diff --git a/src/wasm-linker.cpp b/src/wasm-linker.cpp index 1aba37b1b..d6c0edb4a 100644 --- a/src/wasm-linker.cpp +++ b/src/wasm-linker.cpp @@ -145,7 +145,7 @@ void Linker::layout() { if (FunctionType* f = out.getExternType(name)) { // Address of an imported function is taken, but imports do not have addresses in wasm. // Generate a thunk to forward to the call_import. - Function* thunk = generateImportThunk(name, f); + Function* thunk = getImportThunk(name, f); ensureFunctionIndex(thunk->name); *(relocation->data) = functionIndexes[thunk->name] + relocation->addend; } else { @@ -381,12 +381,14 @@ void Linker::makeDynCallThunks() { } } -Function* Linker::generateImportThunk(Name name, const FunctionType* funcType) { +Function* Linker::getImportThunk(Name name, const FunctionType* funcType) { + Name thunkName = std::string("__importThunk_") + name.c_str(); + if (Function* thunk = out.wasm.checkFunction(thunkName)) return thunk; wasm::Builder wasmBuilder(out.wasm); std::vector<NameType> params; Index p = 0; for (const auto& ty : funcType->params) params.emplace_back(std::to_string(p++), ty); - Function *f = wasmBuilder.makeFunction(std::string("__importThunk_") + name.c_str(), std::move(params), funcType->result, {}); + Function *f = wasmBuilder.makeFunction(thunkName, std::move(params), funcType->result, {}); std::vector<Expression*> args; for (Index i = 0; i < funcType->params.size(); ++i) { args.push_back(wasmBuilder.makeGetLocal(i, funcType->params[i])); diff --git a/src/wasm-linker.h b/src/wasm-linker.h index a0684d02b..97e1c9cd5 100644 --- a/src/wasm-linker.h +++ b/src/wasm-linker.h @@ -277,7 +277,7 @@ class Linker { out.wasm.addExport(exp); } - Function* generateImportThunk(Name name, const FunctionType* t); + Function* getImportThunk(Name name, const FunctionType* t); // The output module (linked executable) LinkerObject out; diff --git a/test/dot_s/indirect-import.c b/test/dot_s/indirect-import.c index 006424d84..679d862c7 100644 --- a/test/dot_s/indirect-import.c +++ b/test/dot_s/indirect-import.c @@ -23,5 +23,9 @@ intptr_t bar() { ijidf(1LL, 2, 3.0, 4.0f); void (*vs)(struct big) = &extern_struct; struct big (*s)(void) = &extern_sret; - return (intptr_t)fd; + return (intptr_t)fd; +} + +intptr_t baz() { + return (intptr_t)extern_v; } diff --git a/test/dot_s/indirect-import.s b/test/dot_s/indirect-import.s index 5131d86f3..f09291d84 100644 --- a/test/dot_s/indirect-import.s +++ b/test/dot_s/indirect-import.s @@ -45,8 +45,20 @@ bar: # @bar .Lfunc_end0: .size bar, .Lfunc_end0-bar + .hidden baz + .globl baz + .type baz,@function +baz: # @baz + .result i32 +# BB#0: # %entry + i32.const $push0=, extern_v@FUNCTION + # fallthrough-return: $pop0 + .endfunc +.Lfunc_end1: + .size baz, .Lfunc_end1-baz + - .ident "clang version 3.9.0 (trunk 271427) (llvm/trunk 271429)" + .ident "clang version 3.9.0 (trunk 271579) (llvm/trunk 271699)" .functype extern_fd, f32, f64 .functype extern_vj, void, i64 .functype extern_v, void diff --git a/test/dot_s/indirect-import.wast b/test/dot_s/indirect-import.wast index f3a989461..b24b5cd59 100644 --- a/test/dot_s/indirect-import.wast +++ b/test/dot_s/indirect-import.wast @@ -13,6 +13,7 @@ (import $extern_struct "env" "extern_struct" (param i32)) (import $extern_sret "env" "extern_sret" (param i32)) (export "bar" $bar) + (export "baz" $baz) (export "dynCall_fd" $dynCall_fd) (export "dynCall_vj" $dynCall_vj) (export "dynCall_v" $dynCall_v) @@ -80,6 +81,9 @@ ) (get_local $1) ) + (func $baz (result i32) + (i32.const 2) + ) (func $__importThunk_extern_fd (type $FUNCSIG$fd) (param $0 f64) (result f32) (call_import $extern_fd (get_local $0) |