summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2019-10-31 09:29:09 -0700
committerGitHub <noreply@github.com>2019-10-31 09:29:09 -0700
commitfb78a120277c023531020b146dd6506608aa9bcc (patch)
tree30a7066e5e63b214b562c6d4f23af309f7a32c23 /src
parent2a787cdbe4cfb84801d4f885b155555c864ac006 (diff)
downloadbinaryen-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.cpp61
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;
}
};