summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/asm2wasm.h23
-rw-r--r--src/js/post.js3
-rw-r--r--test/emcc_hello_world.wast5
-rw-r--r--test/unit.wast3
4 files changed, 30 insertions, 4 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h
index e44d2b5b1..a81f4af68 100644
--- a/src/asm2wasm.h
+++ b/src/asm2wasm.h
@@ -32,7 +32,8 @@ IString GLOBAL("global"), NAN_("NaN"), INFINITY_("Infinity"),
CLZ32("clz32"),
FROUND("fround"),
ASM2WASM("asm2wasm"),
- F64_REM("f64-rem");
+ F64_REM("f64-rem"),
+ F64_TO_INT("f64-to-int");
static void abort_on(std::string why) {
@@ -802,11 +803,31 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
} else if (ast[1] == B_NOT) {
// ~, might be ~~ as a coercion or just a not
if (ast[2][0] == UNARY_PREFIX && ast[2][1] == B_NOT) {
+#if 0
auto ret = allocator.alloc<Convert>();
ret->op = TruncSFloat64; // equivalent to U, except for error handling, which asm.js doesn't have anyhow
ret->value = process(ast[2][2]);
ret->type = WasmType::i32;
return ret;
+#endif
+ // WebAssembly traps on float-to-int overflows, but asm.js wouldn't, so we must emulate that
+ CallImport *ret = allocator.alloc<CallImport>();
+ ret->target = F64_TO_INT;
+ ret->operands.push_back(process(ast[2][2]));
+ ret->type = i32;
+ static bool addedImport = false;
+ if (!addedImport) {
+ addedImport = true;
+ auto import = allocator.alloc<Import>(); // f64-to-int = asm2wasm.f64-to-int;
+ import->name = F64_TO_INT;
+ import->module = ASM2WASM;
+ import->base = F64_TO_INT;
+ import->type.name = F64_TO_INT;
+ import->type.result = i32;
+ import->type.params.push_back(f64);
+ wasm.addImport(import);
+ }
+ return ret;
}
// no bitwise unary not, so do xor with -1
auto ret = allocator.alloc<Binary>();
diff --git a/src/js/post.js b/src/js/post.js
index 6406674ba..5c854b3df 100644
--- a/src/js/post.js
+++ b/src/js/post.js
@@ -32,6 +32,9 @@
"f64-rem": function(x, y) {
return x % y;
},
+ "f64-to-int": function(x) {
+ return x | 0;
+ },
},
parent: Module // Module inside wasm-js.cpp refers to wasm-js.cpp; this allows access to the outside program.
};
diff --git a/test/emcc_hello_world.wast b/test/emcc_hello_world.wast
index 4cba6cdd8..ace99ae01 100644
--- a/test/emcc_hello_world.wast
+++ b/test/emcc_hello_world.wast
@@ -3,6 +3,7 @@
(type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
(type $FUNCSIG$ii (func (param i32) (result i32)))
(type $FUNCSIG$vi (func (param i32)))
+ (import $f64-to-int "asm2wasm" "f64-to-int" (param f64) (result i32))
(export "_i64Subtract" $_i64Subtract)
(export "_free" $_free)
(export "_main" $_main)
@@ -9642,7 +9643,7 @@
(loop $while-out$53 $while-in$54
(block
(set_local $$conv116$i
- (i32.trunc_s/f64
+ (call_import $f64-to-int
(get_local $$y$addr$2$i)
)
)
@@ -10110,7 +10111,7 @@
(block
(set_local $$conv216$i
(i32.shr_u
- (i32.trunc_s/f64
+ (call_import $f64-to-int
(get_local $$y$addr$4$i)
)
(i32.const 0)
diff --git a/test/unit.wast b/test/unit.wast
index 170236efc..34dea557f 100644
--- a/test/unit.wast
+++ b/test/unit.wast
@@ -1,5 +1,6 @@
(module
(memory 16777216 16777216)
+ (import $f64-to-int "asm2wasm" "f64-to-int" (param f64) (result i32))
(import $f64-rem "asm2wasm" "f64-rem" (param f64 f64) (result f64))
(export "big_negative" $big_negative)
(table $z $big_negative $z $z $w $w $importedDoubles $w)
@@ -133,7 +134,7 @@
(local $d f64)
(block
(set_local $i
- (i32.trunc_s/f64
+ (call_import $f64-to-int
(get_local $d)
)
)