summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm/wasm-emscripten.cpp16
-rw-r--r--test/lld/shared.c9
-rw-r--r--test/lld/shared.cpp10
-rw-r--r--test/lld/shared.wast31
-rw-r--r--test/lld/shared.wast.out69
5 files changed, 93 insertions, 42 deletions
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index da2604383..b969a1fbd 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -230,10 +230,20 @@ Function* EmscriptenGlueGenerator::generateAssignGOTEntriesFunction() {
}
for (Global* g : got_entries_func) {
- Name getter(std::string("fp$") + g->base.c_str());
- if (auto* f = wasm.getFunctionOrNull(g->base)) {
- getter.set((getter.c_str() + std::string("$") + getSig(f)).c_str(), false);
+ Function* f = nullptr;
+ // The function has to exist either as export or an import.
+ // Note that we don't search for the function by name since its internal
+ // name may be different.
+ auto* ex = wasm.getExportOrNull(g->base);
+ if (ex) {
+ assert(ex->kind == ExternalKind::Function);
+ f = wasm.getFunction(ex->value);
+ } else {
+ ImportInfo info(wasm);
+ f = info.getImportedFunction(ENV, g->base);
}
+
+ Name getter((std::string("fp$") + g->base.c_str() + std::string("$") + getSig(f)).c_str());
ensureFunctionImport(&wasm, getter, "i");
Expression* call = builder.makeCall(getter, {}, i32);
SetGlobal* set_global = builder.makeSetGlobal(g->name, call);
diff --git a/test/lld/shared.c b/test/lld/shared.c
deleted file mode 100644
index fb5b93756..000000000
--- a/test/lld/shared.c
+++ /dev/null
@@ -1,9 +0,0 @@
-int puts(const char* str);
-extern int external_var;
-
-void* ptr = &puts;
-
-int print_message() {
- puts("Hello, world");
- return external_var;
-}
diff --git a/test/lld/shared.cpp b/test/lld/shared.cpp
new file mode 100644
index 000000000..51bdee833
--- /dev/null
+++ b/test/lld/shared.cpp
@@ -0,0 +1,10 @@
+extern "C" int puts(const char* str);
+extern "C" int external_var;
+
+int print_message() {
+ puts("Hello, world");
+ return external_var;
+}
+
+void* ptr_puts = (void*)&puts;
+void* ptr_local_func = (void*)&print_message;
diff --git a/test/lld/shared.wast b/test/lld/shared.wast
index b55584a9a..019fc67fe 100644
--- a/test/lld/shared.wast
+++ b/test/lld/shared.wast
@@ -3,18 +3,21 @@
(type $1 (func))
(type $2 (func (result i32)))
(import "env" "memory" (memory $0 0))
- (data (global.get $gimport$2) "\00\00\00\00Hello, world\00")
- (import "env" "__indirect_function_table" (table $timport$1 1 funcref))
- (elem (global.get $gimport$3) $puts)
+ (data (global.get $gimport$2) "Hello, world\00\00\00\00\00\00\00\00\01\00\00\00")
+ (import "env" "__indirect_function_table" (table $timport$1 2 funcref))
+ (elem (global.get $gimport$3) $puts $print_message\28\29)
(import "env" "__memory_base" (global $gimport$2 i32))
(import "env" "__table_base" (global $gimport$3 i32))
(import "GOT.mem" "external_var" (global $gimport$5 (mut i32)))
(import "GOT.func" "puts" (global $gimport$6 (mut i32)))
+ (import "GOT.func" "_Z13print_messagev" (global $gimport$7 (mut i32)))
(import "env" "puts" (func $puts (param i32) (result i32)))
- (global $global$0 i32 (i32.const 0))
+ (global $global$0 i32 (i32.const 16))
+ (global $global$1 i32 (i32.const 20))
(export "__wasm_call_ctors" (func $__wasm_call_ctors))
- (export "print_message" (func $print_message))
- (export "ptr" (global $global$0))
+ (export "_Z13print_messagev" (func $print_message\28\29))
+ (export "ptr_puts" (global $global$0))
+ (export "ptr_local_func" (global $global$1))
(func $__wasm_call_ctors (; 1 ;) (type $1)
(call $__wasm_apply_relocs)
)
@@ -22,20 +25,30 @@
(i32.store
(i32.add
(global.get $gimport$2)
- (i32.const 0)
+ (i32.const 16)
)
(i32.add
(global.get $gimport$3)
(i32.const 0)
)
)
+ (i32.store
+ (i32.add
+ (global.get $gimport$2)
+ (i32.const 20)
+ )
+ (i32.add
+ (global.get $gimport$3)
+ (i32.const 1)
+ )
+ )
)
- (func $print_message (; 3 ;) (type $2) (result i32)
+ (func $print_message\28\29 (; 3 ;) (type $2) (result i32)
(drop
(call $puts
(i32.add
(global.get $gimport$2)
- (i32.const 4)
+ (i32.const 0)
)
)
)
diff --git a/test/lld/shared.wast.out b/test/lld/shared.wast.out
index 8d44279b8..7716daa32 100644
--- a/test/lld/shared.wast.out
+++ b/test/lld/shared.wast.out
@@ -5,42 +5,57 @@
(type $FUNCSIG$ii (func (param i32) (result i32)))
(type $FUNCSIG$i (func (result i32)))
(import "env" "memory" (memory $0 0))
- (data (global.get $gimport$2) "\00\00\00\00Hello, world\00")
- (import "env" "table" (table $0 1 funcref))
- (elem (global.get $gimport$3) $puts)
+ (data (global.get $gimport$2) "Hello, world\00\00\00\00\00\00\00\00\01\00\00\00")
+ (import "env" "table" (table $0 2 funcref))
+ (elem (global.get $gimport$3) $puts $print_message\28\29)
(import "env" "__memory_base" (global $gimport$2 i32))
(import "env" "__table_base" (global $gimport$3 i32))
(import "env" "puts" (func $puts (param i32) (result i32)))
(import "env" "g$external_var" (func $g$external_var (result i32)))
(import "env" "fp$puts$ii" (func $fp$puts$ii (result i32)))
+ (import "env" "fp$_Z13print_messagev$i" (func $fp$_Z13print_messagev$i (result i32)))
(global $gimport$5 (mut i32) (i32.const 0))
(global $gimport$6 (mut i32) (i32.const 0))
- (global $global$0 i32 (i32.const 0))
- (export "print_message" (func $print_message))
- (export "ptr" (global $global$0))
+ (global $gimport$7 (mut i32) (i32.const 0))
+ (global $global$0 i32 (i32.const 16))
+ (global $global$1 i32 (i32.const 20))
+ (export "_Z13print_messagev" (func $print_message\28\29))
+ (export "ptr_puts" (global $global$0))
+ (export "ptr_local_func" (global $global$1))
(export "__post_instantiate" (func $__post_instantiate))
(export "dynCall_ii" (func $dynCall_ii))
- (func $__wasm_call_ctors (; 3 ;) (type $1)
+ (export "dynCall_i" (func $dynCall_i))
+ (func $__wasm_call_ctors (; 4 ;) (type $1)
(call $__wasm_apply_relocs)
)
- (func $__wasm_apply_relocs (; 4 ;) (type $1)
+ (func $__wasm_apply_relocs (; 5 ;) (type $1)
(i32.store
(i32.add
(global.get $gimport$2)
- (i32.const 0)
+ (i32.const 16)
)
(i32.add
(global.get $gimport$3)
(i32.const 0)
)
)
+ (i32.store
+ (i32.add
+ (global.get $gimport$2)
+ (i32.const 20)
+ )
+ (i32.add
+ (global.get $gimport$3)
+ (i32.const 1)
+ )
+ )
)
- (func $print_message (; 5 ;) (type $2) (result i32)
+ (func $print_message\28\29 (; 6 ;) (type $2) (result i32)
(drop
(call $puts
(i32.add
(global.get $gimport$2)
- (i32.const 4)
+ (i32.const 0)
)
)
)
@@ -48,51 +63,63 @@
(global.get $gimport$5)
)
)
- (func $__post_instantiate (; 6 ;)
+ (func $__post_instantiate (; 7 ;)
(call $__assign_got_enties)
(call $__wasm_call_ctors)
)
- (func $__assign_got_enties (; 7 ;)
+ (func $__assign_got_enties (; 8 ;)
(global.set $gimport$5
(call $g$external_var)
)
(global.set $gimport$6
(call $fp$puts$ii)
)
+ (global.set $gimport$7
+ (call $fp$_Z13print_messagev$i)
+ )
)
- (func $dynCall_ii (; 8 ;) (param $fptr i32) (param $0 i32) (result i32)
+ (func $dynCall_ii (; 9 ;) (param $fptr i32) (param $0 i32) (result i32)
(call_indirect (type $FUNCSIG$ii)
(local.get $0)
(local.get $fptr)
)
)
+ (func $dynCall_i (; 10 ;) (param $fptr i32) (result i32)
+ (call_indirect (type $FUNCSIG$i)
+ (local.get $fptr)
+ )
+ )
)
(;
--BEGIN METADATA --
{
"staticBump": 0,
- "tableSize": 1,
+ "tableSize": 2,
"declares": [
"puts",
"g$external_var",
- "fp$puts$ii"
+ "fp$puts$ii",
+ "fp$_Z13print_messagev$i"
],
"externs": [
"___memory_base",
"___table_base"
],
"implementedFunctions": [
- "_print_message",
+ "__Z13print_messagev",
"___post_instantiate",
- "_dynCall_ii"
+ "_dynCall_ii",
+ "_dynCall_i"
],
"exports": [
- "print_message",
+ "_Z13print_messagev",
"__post_instantiate",
- "dynCall_ii"
+ "dynCall_ii",
+ "dynCall_i"
],
"namedGlobals": {
- "ptr" : "0"
+ "ptr_puts" : "16",
+ "ptr_local_func" : "20"
},
"invokeFuncs": [
],