summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm/wasm-emscripten.cpp16
-rw-r--r--test/lit/wasm-emscripten-finalize/passive-pic.wat38
2 files changed, 50 insertions, 4 deletions
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index 19498300f..f8dc16a32 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -85,9 +85,19 @@ std::vector<Address> getSegmentOffsets(Module& wasm) {
OffsetSearcher(std::unordered_map<unsigned, Address>& offsets)
: offsets(offsets) {}
void visitMemoryInit(MemoryInit* curr) {
+ // The desitination of the memory.init is either a constant
+ // or the result of an addition with __memory_base in the
+ // case of PIC code.
auto* dest = curr->dest->dynCast<Const>();
if (!dest) {
- return;
+ auto* add = curr->dest->dynCast<Binary>();
+ if (!add) {
+ return;
+ }
+ dest = add->left->dynCast<Const>();
+ if (!dest) {
+ return;
+ }
}
auto it = offsets.find(curr->segment);
if (it != offsets.end()) {
@@ -170,9 +180,7 @@ std::string codeForConstAddr(Module& wasm,
int32_t address) {
const char* str = stringAtAddr(wasm, segmentOffsets, address);
if (!str) {
- // If we can't find the segment corresponding with the address, then we
- // omitted the segment and the address points to an empty string.
- return escape("");
+ Fatal() << "unable to find data for ASM/EM_JS const at: " << address;
}
return escape(str);
}
diff --git a/test/lit/wasm-emscripten-finalize/passive-pic.wat b/test/lit/wasm-emscripten-finalize/passive-pic.wat
new file mode 100644
index 000000000..e9af5b1d9
--- /dev/null
+++ b/test/lit/wasm-emscripten-finalize/passive-pic.wat
@@ -0,0 +1,38 @@
+;; Test that wasm-emscripten-finalize can locate data within passive segments
+;; even when compiled with PIC, which means that segment addresses are non-constant.
+
+;; RUN: wasm-emscripten-finalize --enable-bulk-memory %s -o out.wasm | filecheck %s
+
+;; CHECK: "asmConsts": {
+;; CHECK: "3": ["hello", ["iii"], [""]]
+;; CHECK: },
+
+(module
+ (import "env" "memory" (memory $memory 1 1))
+ (import "env" "__memory_base" (global $__memory_base i32))
+ (import "env" "emscripten_asm_const_int" (func $emscripten_asm_const_int (param i32 i32 i32) (result i32)))
+ (data passive "xxxhello\00yyy")
+ ;; memory init function similar to those generated by wasm-ld
+ (start $__wasm_init_memory)
+ (func $__wasm_init_memory
+ (memory.init 0
+ (i32.add
+ (i32.const 0)
+ (global.get $__memory_base)
+ )
+ (i32.const 0)
+ (i32.const 12)
+ )
+ )
+ ;; EM_ASM call passing string at address 3 in the passive segment
+ (func $foo (result i32)
+ (call $emscripten_asm_const_int
+ (i32.add
+ (global.get $__memory_base)
+ (i32.const 3)
+ )
+ (i32.const 0)
+ (i32.const 0)
+ )
+ )
+)