diff options
-rw-r--r-- | src/asm2wasm.h | 23 | ||||
-rw-r--r-- | src/js/post.js | 3 | ||||
-rw-r--r-- | test/emcc_hello_world.wast | 5 | ||||
-rw-r--r-- | test/unit.wast | 3 |
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) ) ) |