diff options
author | Sam Clegg <sbc@chromium.org> | 2019-10-31 09:29:09 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-31 09:29:09 -0700 |
commit | fb78a120277c023531020b146dd6506608aa9bcc (patch) | |
tree | 30a7066e5e63b214b562c6d4f23af309f7a32c23 /src | |
parent | 2a787cdbe4cfb84801d4f885b155555c864ac006 (diff) | |
download | binaryen-fb78a120277c023531020b146dd6506608aa9bcc.tar.gz binaryen-fb78a120277c023531020b146dd6506608aa9bcc.tar.bz2 binaryen-fb78a120277c023531020b146dd6506608aa9bcc.zip |
Use absolute memory addresses for emasm string indexes. (#2408)
Before we used 0-based indexes which meant that we needed to modify the
code calling the emasm function to replace the first argument.
Now we use the string address itself as the index/code for the emasm
constant. This allows use code to go unmodifed as the emscripten side
will accept the memory address as the index/code.
See: https://github.com/emscripten-core/emscripten/issues/9013
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp index 37cd2f431..d12bb9bba 100644 --- a/src/wasm/wasm-emscripten.cpp +++ b/src/wasm/wasm-emscripten.cpp @@ -653,8 +653,7 @@ const char* stringAtAddr(Module& wasm, std::string codeForConstAddr(Module& wasm, std::vector<Address> const& segmentOffsets, - Const* addrConst) { - auto address = addrConst->value.geti32(); + 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 @@ -710,7 +709,8 @@ struct AsmConstWalker : public LinearExecutionWalker<AsmConstWalker> { private: std::string fixupName(Name& name, std::string baseSig, Proxying proxy); - AsmConst& createAsmConst(std::string code, std::string sig, Name name); + AsmConst& + createAsmConst(uint32_t id, std::string code, std::string sig, Name name); std::string asmConstSig(std::string baseSig); Name nameForImportWithSig(std::string sig, Proxying proxy); void queueImport(Name importName, std::string baseSig); @@ -757,29 +757,38 @@ void AsmConstWalker::visitCall(Call* curr) { << ".\nThis might be caused by aggressive compiler " "transformations. Consider using EM_JS instead."; } - } 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: " << importName; + continue; + } + + if (auto* setlocal = arg->dynCast<LocalSet>()) { + // The argument may be a local.tee, in which case we take first child + // which is the value being copied into the local. + if (setlocal->isTee()) { + arg = setlocal->value; + continue; } } + + if (auto* bin = arg->dynCast<Binary>()) { + if (bin->op == AddInt32) { + // 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 from __memory_base + // the RHS of the addition is just what we want. + arg = bin->right; + continue; + } + } + + Fatal() << "Unexpected arg0 type (" << getExpressionName(arg) + << ") in call to: " << importName; } auto* value = arg->cast<Const>(); - auto code = codeForConstAddr(wasm, segmentOffsets, value); - auto& asmConst = createAsmConst(code, sig, importName); + int32_t address = value->value.geti32(); + auto code = codeForConstAddr(wasm, segmentOffsets, address); + auto& asmConst = createAsmConst(address, code, sig, importName); fixupName(curr->target, baseSig, asmConst.proxy); - - // Replace the first argument to the call with a Const index - Builder builder(wasm); - curr->operands[0] = builder.makeConst(Literal(asmConst.id)); } Proxying AsmConstWalker::proxyType(Name name) { @@ -826,14 +835,15 @@ AsmConstWalker::fixupName(Name& name, std::string baseSig, Proxying proxy) { return sig; } -AsmConstWalker::AsmConst& -AsmConstWalker::createAsmConst(std::string code, std::string sig, Name name) { +AsmConstWalker::AsmConst& AsmConstWalker::createAsmConst(uint32_t id, + std::string code, + std::string sig, + Name name) { if (asmConsts.count(code) == 0) { AsmConst asmConst; - asmConst.id = asmConsts.size(); + asmConst.id = id; asmConst.sigs.insert(sig); asmConst.proxy = proxyType(name); - asmConsts[code] = asmConst; } return asmConsts[code]; @@ -918,7 +928,8 @@ struct EmJsWalker : public PostWalker<EmJsWalker> { Fatal() << "Unexpected generated __em_js__ function body: " << curr->name; } auto* addrConst = consts.list[0]; - auto code = codeForConstAddr(wasm, segmentOffsets, addrConst); + int32_t address = addrConst->value.geti32(); + auto code = codeForConstAddr(wasm, segmentOffsets, address); codeByName[funcName] = code; } }; |