From d7c13c018efed2e22d72902e4f88832fb57cb5ca Mon Sep 17 00:00:00 2001 From: Volker Date: Sat, 11 Aug 2018 15:46:20 +0200 Subject: [PATCH] Use the new Non-trapping float-to-int conversions for Java like behavior. --- .../binary/BinaryModuleWriter.java | 11 +++-- .../binary/InstructionOpcodes.java | 18 ++++++++ .../jwebassembly/text/TextModuleWriter.java | 8 ++-- .../inetsoftware/jwebassembly/WasmRule.java | 2 +- .../jwebassembly/runtime/MathOperations.java | 46 +++++++++++++++++++ 5 files changed, 76 insertions(+), 9 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java index a622708..19f0b07 100644 --- a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java @@ -628,19 +628,19 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod op = F64_CONVERT_S_I64; break; case f2i: - op = I32_TRUNC_S_F32; + op = I32_TRUNC_S_SAT_F32; break; case f2l: - op = I64_TRUNC_S_F32; + op = I64_TRUNC_S_SAT_F32; break; case f2d: op = F64_PROMOTE_F32; break; case d2i: - op = I32_TRUNC_S_F64; + op = I32_TRUNC_S_SAT_F64; break; case d2l: - op = I64_TRUNC_S_F64; + op = I64_TRUNC_S_SAT_F64; break; case d2f: op = F32_DEMOTE_F64; @@ -654,6 +654,9 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod default: throw new Error( "Unknown cast: " + cast ); } + if( op > 255 ) { + codeStream.write( op >> 8 ); + } codeStream.write( op ); } diff --git a/src/de/inetsoftware/jwebassembly/binary/InstructionOpcodes.java b/src/de/inetsoftware/jwebassembly/binary/InstructionOpcodes.java index ed3a109..f50b4f2 100644 --- a/src/de/inetsoftware/jwebassembly/binary/InstructionOpcodes.java +++ b/src/de/inetsoftware/jwebassembly/binary/InstructionOpcodes.java @@ -352,4 +352,22 @@ interface InstructionOpcodes { static final int REF_NULL = 0xD0; static final int REF_ISNULL = 0xD1; + + // === Non-trapping float-to-int conversions ====== https://github.com/WebAssembly/design/issues/1143 + + static final int I32_TRUNC_S_SAT_F32 = 0xFC00; + + static final int I32_TRUNC_U_SAT_F32 = 0xFC01; + + static final int I32_TRUNC_S_SAT_F64 = 0xFC02; + + static final int I32_TRUNC_U_SAT_F64 = 0xFC03; + + static final int I64_TRUNC_S_SAT_F32 = 0xFC04; + + static final int I64_TRUNC_U_SAT_F32 = 0xFC05; + + static final int I64_TRUNC_S_SAT_F64 = 0xFC06; + + static final int I64_TRUNC_U_SAT_F64 = 0xFC07; } diff --git a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java index 640fd0c..ae07b75 100644 --- a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java @@ -188,19 +188,19 @@ public class TextModuleWriter extends ModuleWriter { op = "f64.convert_s/i64"; break; case f2i: - op = "i32.trunc_s/f32"; + op = "i32.trunc_s:sat/f32"; break; case f2l: - op = "i64.trunc_s/f32"; + op = "i64.trunc_s:sat/f32"; break; case f2d: op = "f64.promote/f32"; break; case d2i: - op = "i32.trunc_s/f64"; + op = "i32.trunc_s:sat/f64"; break; case d2l: - op = "i64.trunc_s/f64"; + op = "i64.trunc_s:sat/f64"; break; case d2f: op = "f32.demote/f64"; diff --git a/test/de/inetsoftware/jwebassembly/WasmRule.java b/test/de/inetsoftware/jwebassembly/WasmRule.java index d1f4a82..79397bf 100644 --- a/test/de/inetsoftware/jwebassembly/WasmRule.java +++ b/test/de/inetsoftware/jwebassembly/WasmRule.java @@ -279,7 +279,7 @@ public class WasmRule extends TemporaryFolder { command += "/bin/node"; } } - return new ProcessBuilder( command, "--experimental-wasm-se", nodeScript.getAbsolutePath() ); + return new ProcessBuilder( command, "--experimental-wasm-se", "--experimental-wasm-sat-f2i-conversions", nodeScript.getAbsolutePath() ); } /** diff --git a/test/de/inetsoftware/jwebassembly/runtime/MathOperations.java b/test/de/inetsoftware/jwebassembly/runtime/MathOperations.java index 7c8a4f4..f1dca73 100644 --- a/test/de/inetsoftware/jwebassembly/runtime/MathOperations.java +++ b/test/de/inetsoftware/jwebassembly/runtime/MathOperations.java @@ -63,6 +63,7 @@ public class MathOperations extends AbstractBaseTest { addParam( list, script, "byteDec", (byte)-128 ); addParam( list, script, "shortInc", (short)-32768 ); addParam( list, script, "charOp", (char)0xFFFF ); + addParam( list, script, "castNumberOverflow" ); } return list; } @@ -242,5 +243,50 @@ public class MathOperations extends AbstractBaseTest { a += 60; return a; } + + @Export + static int castNumberOverflow() { + int result = 0; + float f = 2E30F; + double d = f; + + int i = (int)f; + if( i == Integer.MAX_VALUE) { + result |= 0x1; + } + i = (int)-f; + if( i == Integer.MIN_VALUE) { + result |= 0x2; + } + + long l = (long)f; + if( l == Long.MAX_VALUE) { + result |= 0x4; + } + l = (long)-f; + if( l == Long.MIN_VALUE) { + result |= 0x8; + } + + i = (int)d; + if( i == Integer.MAX_VALUE) { + result |= 0x10; + } + i = (int)-d; + if( i == Integer.MIN_VALUE) { + result |= 0x20; + } + + l = (long)d; + if( l == Long.MAX_VALUE) { + result |= 0x40; + } + l = (long)-d; + if( l == Long.MIN_VALUE) { + result |= 0x80; + } + + return result; + } } }