diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp index 95566f5b9..1b40b871e 100644 --- a/src/wasm/wasm-emscripten.cpp +++ b/src/wasm/wasm-emscripten.cpp @@ -509,20 +509,33 @@ void AsmConstWalker::visitSetLocal(SetLocal* curr) { void AsmConstWalker::visitCall(Call* curr) { auto* import = wasm.getFunction(curr->target); + // Find calls to emscripten_asm_const* functions whose first argument is + // is always a string constant. if (import->imported() && import->base.hasSubstring(EMSCRIPTEN_ASM_CONST)) { auto baseSig = getSig(curr); auto sig = fixupNameWithSig(curr->target, baseSig); auto* arg = curr->operands[0]; - // The argument may be a get, in which case, the last set in this basic block - // has the value. 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; } - } - auto* value = arg->cast<Const>(); + } 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) + << ") in call to to: " << import->base; auto code = codeForConstAddr(wasm, segmentOffsets, value); value->value = idLiteralForCode(code); sigsForCode[code].insert(sig); |