summaryrefslogtreecommitdiff
path: root/src/asm2wasm.h
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-07-14 17:59:33 -0700
committerGitHub <noreply@github.com>2016-07-14 17:59:33 -0700
commite4f99f6c81a5f23318787adba6fea1137dc755bb (patch)
tree2fff27409e894cbfb0d473c4e768455795903505 /src/asm2wasm.h
parent4994da80284c337e5395ad836948ee38ffb967f1 (diff)
downloadbinaryen-e4f99f6c81a5f23318787adba6fea1137dc755bb.tar.gz
binaryen-e4f99f6c81a5f23318787adba6fea1137dc755bb.tar.bz2
binaryen-e4f99f6c81a5f23318787adba6fea1137dc755bb.zip
emit safe calls for i32 div/rem when in precise mode in asm2wasm, as they can trap (#637)
Diffstat (limited to 'src/asm2wasm.h')
-rw-r--r--src/asm2wasm.h25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h
index 994342b4e..c0f13ff8f 100644
--- a/src/asm2wasm.h
+++ b/src/asm2wasm.h
@@ -1075,6 +1075,31 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
wasm.addImport(import);
}
return call;
+ } else if (!imprecise && (ret->op == BinaryOp::RemSInt32 || ret->op == BinaryOp::RemUInt32 ||
+ ret->op == BinaryOp::DivSInt32 || ret->op == BinaryOp::DivUInt32)) {
+ // we are precise, and the wasm operation might trap if done over 0, so generate a safe call
+ CallImport *call = allocator.alloc<CallImport>();
+ switch (ret->op) {
+ case BinaryOp::RemSInt32: call->target = I32S_REM; break;
+ case BinaryOp::RemUInt32: call->target = I32U_REM; break;
+ case BinaryOp::DivSInt32: call->target = I32S_DIV; break;
+ case BinaryOp::DivUInt32: call->target = I32U_DIV; break;
+ default: WASM_UNREACHABLE();
+ }
+ call->operands.push_back(ret->left);
+ call->operands.push_back(ret->right);
+ call->type = i32;
+ static std::set<Name> addedImport;
+ if (addedImport.count(call->target) == 0) {
+ addedImport.insert(call->target);
+ auto import = new Import;
+ import->name = call->target;
+ import->module = ASM2WASM;
+ import->base = call->target;
+ import->type = ensureFunctionType("iii", &wasm);
+ wasm.addImport(import);
+ }
+ return call;
}
return ret;
} else if (what == NUM) {