summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2019-04-22 11:36:50 -0700
committerGitHub <noreply@github.com>2019-04-22 11:36:50 -0700
commitf87de2ae0d430f8d4204df8fceb194c24e29b413 (patch)
tree45f601d00a65f3f0424cf3e9777d6b1afc270479 /src
parentb2161e3148e40cec252abb0ef33538b797954579 (diff)
downloadbinaryen-f87de2ae0d430f8d4204df8fceb194c24e29b413.tar.gz
binaryen-f87de2ae0d430f8d4204df8fceb194c24e29b413.tar.bz2
binaryen-f87de2ae0d430f8d4204df8fceb194c24e29b413.zip
wasm-emscripten-finalize: Handle relocatable code in AsmConstWalker (#2035)
When replacing the first argument to an asm call, allow more complex expressions for expressing the address. This fixes the case where the first argument might be the result of adding a constant to __memory_base.
Diffstat (limited to 'src')
-rw-r--r--src/wasm/wasm-emscripten.cpp49
1 files changed, 28 insertions, 21 deletions
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));
}
}