diff options
-rw-r--r-- | CHANGELOG.md | 5 | ||||
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 49 | ||||
-rw-r--r-- | test/lld/em_asm_O0.wast.out | 8 | ||||
-rw-r--r-- | test/lld/em_asm_shared.wast.out | 17 |
4 files changed, 40 insertions, 39 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 56672f8e9..a6885ed13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,11 @@ full changeset diff at the end of each section. Current Trunk ------------- +v81 +--- + +- Fix AsmConstWalker handling of string address in arg0 with -fPIC code + v80 --- diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp index 837dcbea1..680e145b4 100644 --- a/src/wasm/wasm-emscripten.cpp +++ b/src/wasm/wasm-emscripten.cpp @@ -525,30 +525,37 @@ void AsmConstWalker::visitCall(Call* curr) { auto baseSig = getSig(curr); auto sig = fixupNameWithSig(curr->target, baseSig); auto* arg = curr->operands[0]; - if (auto* get = arg->dynCast<GetLocal>()) { - // The argument may be a local.get, in which case, the last set in this - // basic block has the value. - auto* set = sets[get->index]; - if (set) { - assert(set->index == get->index); - arg = set->value; - } - } else if (auto* value = arg->dynCast<Binary>()) { - // In the dynamic linking case the address of the string constant - // is the result of adding its offset to __memory_base. - // In this case are only looking for the offset with the data segment so - // the RHS of the addition is just what we want. - assert(value->op == AddInt32); - arg = value->right; - } - - auto* value = arg->dynCast<Const>(); - if (!value) - Fatal() << "Unexpected arg0 type (" << getExpressionName(arg) + while (!arg->dynCast<Const>()) { + if (auto* get = arg->dynCast<GetLocal>()) { + // The argument may be a local.get, in which case, the last set in this + // basic block has the value. + auto* set = sets[get->index]; + if (set) { + assert(set->index == get->index); + arg = set->value; + } + } else if (auto* value = arg->dynCast<Binary>()) { + // In the dynamic linking case the address of the string constant + // is the result of adding its offset to __memory_base. + // In this case are only looking for the offset with the data segment so + // the RHS of the addition is just what we want. + assert(value->op == AddInt32); + arg = value->right; + } else { + if (!value) { + Fatal() << "Unexpected arg0 type (" << getExpressionName(arg) << ") in call to to: " << import->base; + } + } + } + + auto* value = arg->cast<Const>(); auto code = codeForConstAddr(wasm, segmentOffsets, value); - value->value = idLiteralForCode(code); sigsForCode[code].insert(sig); + + // Replace the first argument to the call with a Const index + Builder builder(wasm); + curr->operands[0] = builder.makeConst(idLiteralForCode(code)); } } diff --git a/test/lld/em_asm_O0.wast.out b/test/lld/em_asm_O0.wast.out index d194c8185..cb5cc1961 100644 --- a/test/lld/em_asm_O0.wast.out +++ b/test/lld/em_asm_O0.wast.out @@ -34,16 +34,16 @@ ) ) (local.set $t1 - (i32.const 2) + (i32.const 621) ) (local.set $t2 - (i32.const 1) + (i32.const 601) ) (drop (call $emscripten_asm_const_ii - (local.get $t1) + (i32.const 2) (call $emscripten_asm_const_iii - (local.get $t2) + (i32.const 1) (i32.const 13) (i32.const 27) ) diff --git a/test/lld/em_asm_shared.wast.out b/test/lld/em_asm_shared.wast.out index 220a10aca..3a5268380 100644 --- a/test/lld/em_asm_shared.wast.out +++ b/test/lld/em_asm_shared.wast.out @@ -48,12 +48,7 @@ ) (drop (call $emscripten_asm_const_iii - (i32.add - (local.tee $1 - (global.get $gimport$3) - ) - (i32.const 0) - ) + (i32.const 0) (i32.add (local.get $0) (i32.const 24) @@ -80,10 +75,7 @@ ) (local.tee $2 (call $emscripten_asm_const_iii - (i32.add - (local.get $1) - (i32.const 1) - ) + (i32.const 1) (i32.add (local.get $0) (i32.const 24) @@ -101,10 +93,7 @@ ) (drop (call $emscripten_asm_const_iii - (i32.add - (local.get $1) - (i32.const 2) - ) + (i32.const 2) (i32.add (local.get $0) (i32.const 24) |