|
118 | 118 | * instrument gets notified that a certain line in the source code was reached. |
119 | 119 | */ |
120 | 120 | public final class WasmFunctionNode extends Node implements BytecodeOSRNode { |
121 | | - private static final float MIN_FLOAT_TRUNCATABLE_TO_INT = Integer.MIN_VALUE; |
122 | | - private static final float MAX_FLOAT_TRUNCATABLE_TO_INT = 2147483520f; |
123 | | - private static final float MIN_FLOAT_TRUNCATABLE_TO_U_INT = -0.99999994f; |
124 | | - private static final float MAX_FLOAT_TRUNCATABLE_TO_U_INT = 4294967040f; |
125 | | - |
126 | | - private static final double MIN_DOUBLE_TRUNCATABLE_TO_INT = -2147483648.9999997; |
127 | | - private static final double MAX_DOUBLE_TRUNCATABLE_TO_INT = 2147483647.9999998; |
128 | | - private static final double MIN_DOUBLE_TRUNCATABLE_TO_U_INT = -0.9999999999999999; |
129 | | - private static final double MAX_DOUBLE_TRUNCATABLE_TO_U_INT = 4294967295.9999995; |
130 | | - |
131 | | - private static final float MIN_FLOAT_TRUNCATABLE_TO_LONG = Long.MIN_VALUE; |
132 | | - private static final float MAX_FLOAT_TRUNCATABLE_TO_LONG = 9223371487098961900.0f; |
133 | | - private static final float MIN_FLOAT_TRUNCATABLE_TO_U_LONG = MIN_FLOAT_TRUNCATABLE_TO_U_INT; |
134 | | - private static final float MAX_FLOAT_TRUNCATABLE_TO_U_LONG = 18446742974197924000.0f; |
135 | | - |
136 | | - private static final double MIN_DOUBLE_TRUNCATABLE_TO_LONG = Long.MIN_VALUE; |
137 | | - private static final double MAX_DOUBLE_TRUNCATABLE_TO_LONG = 9223372036854774800.0; |
138 | | - private static final double MIN_DOUBLE_TRUNCATABLE_TO_U_LONG = MIN_DOUBLE_TRUNCATABLE_TO_U_INT; |
139 | | - private static final double MAX_DOUBLE_TRUNCATABLE_TO_U_LONG = 18446744073709550000.0; |
140 | 121 |
|
141 | 122 | private static final int REPORT_LOOP_STRIDE = 1 << 8; |
142 | 123 |
|
@@ -4095,55 +4076,67 @@ private static void i32_wrap_i64(VirtualFrame frame, int stackPointer) { |
4095 | 4076 | pushInt(frame, stackPointer - 1, result); |
4096 | 4077 | } |
4097 | 4078 |
|
| 4079 | + private WasmException trunc_f32_trap(float x) { |
| 4080 | + if (Float.isNaN(x)) { |
| 4081 | + throw WasmException.create(Failure.INVALID_CONVERSION_TO_INT, this); |
| 4082 | + } else { |
| 4083 | + throw WasmException.create(Failure.INT_OVERFLOW, this); |
| 4084 | + } |
| 4085 | + } |
| 4086 | + |
| 4087 | + private WasmException trunc_f64_trap(double x) { |
| 4088 | + if (Double.isNaN(x)) { |
| 4089 | + throw WasmException.create(Failure.INVALID_CONVERSION_TO_INT, this); |
| 4090 | + } else { |
| 4091 | + throw WasmException.create(Failure.INT_OVERFLOW, this); |
| 4092 | + } |
| 4093 | + } |
| 4094 | + |
4098 | 4095 | private void i32_trunc_f32_s(VirtualFrame frame, int stackPointer) { |
4099 | 4096 | final float x = popFloat(frame, stackPointer - 1); |
4100 | | - if (Float.isNaN(x)) { |
4101 | | - enterErrorBranch(); |
4102 | | - throw WasmException.create(Failure.INVALID_CONVERSION_TO_INT); |
4103 | | - } else if (x < MIN_FLOAT_TRUNCATABLE_TO_INT || x > MAX_FLOAT_TRUNCATABLE_TO_INT) { |
| 4097 | + final int result; |
| 4098 | + if (x >= -0x1p31f && x < 0x1p31f) { |
| 4099 | + result = (int) x; |
| 4100 | + } else { |
4104 | 4101 | enterErrorBranch(); |
4105 | | - throw WasmException.create(Failure.INT_OVERFLOW); |
| 4102 | + throw trunc_f32_trap(x); |
4106 | 4103 | } |
4107 | | - final int result = (int) x; |
4108 | 4104 | pushInt(frame, stackPointer - 1, result); |
4109 | 4105 | } |
4110 | 4106 |
|
4111 | 4107 | private void i32_trunc_f32_u(VirtualFrame frame, int stackPointer) { |
4112 | 4108 | final float x = popFloat(frame, stackPointer - 1); |
4113 | | - if (Float.isNaN(x)) { |
4114 | | - enterErrorBranch(); |
4115 | | - throw WasmException.create(Failure.INVALID_CONVERSION_TO_INT); |
4116 | | - } else if (x < MIN_FLOAT_TRUNCATABLE_TO_U_INT || x > MAX_FLOAT_TRUNCATABLE_TO_U_INT) { |
| 4109 | + final int result; |
| 4110 | + if (x > -1.0f && x < 0x1p32f) { |
| 4111 | + result = ExactMath.truncateToUnsignedInt(x); |
| 4112 | + } else { |
4117 | 4113 | enterErrorBranch(); |
4118 | | - throw WasmException.create(Failure.INT_OVERFLOW); |
| 4114 | + throw trunc_f32_trap(x); |
4119 | 4115 | } |
4120 | | - final int result = ExactMath.truncateToUnsignedInt(x); |
4121 | 4116 | pushInt(frame, stackPointer - 1, result); |
4122 | 4117 | } |
4123 | 4118 |
|
4124 | 4119 | private void i32_trunc_f64_s(VirtualFrame frame, int stackPointer) { |
4125 | 4120 | final double x = popDouble(frame, stackPointer - 1); |
4126 | | - if (Double.isNaN(x)) { |
4127 | | - enterErrorBranch(); |
4128 | | - throw WasmException.create(Failure.INVALID_CONVERSION_TO_INT); |
4129 | | - } else if (x < MIN_DOUBLE_TRUNCATABLE_TO_INT || x > MAX_DOUBLE_TRUNCATABLE_TO_INT) { |
| 4121 | + final int result; |
| 4122 | + if (x > -0x1.00000002p31 && x < 0x1p31) { // sic! |
| 4123 | + result = (int) x; |
| 4124 | + } else { |
4130 | 4125 | enterErrorBranch(); |
4131 | | - throw WasmException.create(Failure.INT_OVERFLOW); |
| 4126 | + throw trunc_f64_trap(x); |
4132 | 4127 | } |
4133 | | - final int result = (int) x; |
4134 | 4128 | pushInt(frame, stackPointer - 1, result); |
4135 | 4129 | } |
4136 | 4130 |
|
4137 | 4131 | private void i32_trunc_f64_u(VirtualFrame frame, int stackPointer) { |
4138 | 4132 | final double x = popDouble(frame, stackPointer - 1); |
4139 | | - if (Double.isNaN(x)) { |
4140 | | - enterErrorBranch(); |
4141 | | - throw WasmException.create(Failure.INVALID_CONVERSION_TO_INT); |
4142 | | - } else if (x < MIN_DOUBLE_TRUNCATABLE_TO_U_INT || x > MAX_DOUBLE_TRUNCATABLE_TO_U_INT) { |
| 4133 | + final int result; |
| 4134 | + if (x > -1.0 && x < 0x1p32) { |
| 4135 | + result = ExactMath.truncateToUnsignedInt(x); |
| 4136 | + } else { |
4143 | 4137 | enterErrorBranch(); |
4144 | | - throw WasmException.create(Failure.INT_OVERFLOW); |
| 4138 | + throw trunc_f64_trap(x); |
4145 | 4139 | } |
4146 | | - final int result = ExactMath.truncateToUnsignedInt(x); |
4147 | 4140 | pushInt(frame, stackPointer - 1, result); |
4148 | 4141 | } |
4149 | 4142 |
|
@@ -4184,53 +4177,49 @@ private static void i64_extend_i32_u(VirtualFrame frame, int stackPointer) { |
4184 | 4177 |
|
4185 | 4178 | private void i64_trunc_f32_s(VirtualFrame frame, int stackPointer) { |
4186 | 4179 | final float x = popFloat(frame, stackPointer - 1); |
4187 | | - if (Float.isNaN(x)) { |
4188 | | - enterErrorBranch(); |
4189 | | - throw WasmException.create(Failure.INVALID_CONVERSION_TO_INT); |
4190 | | - } else if (x < MIN_FLOAT_TRUNCATABLE_TO_LONG || x > MAX_FLOAT_TRUNCATABLE_TO_LONG) { |
| 4180 | + final long result; |
| 4181 | + if (x >= -0x1p63f && x < 0x1p63f) { |
| 4182 | + result = (long) x; |
| 4183 | + } else { |
4191 | 4184 | enterErrorBranch(); |
4192 | | - throw WasmException.create(Failure.INT_OVERFLOW); |
| 4185 | + throw trunc_f32_trap(x); |
4193 | 4186 | } |
4194 | | - final long result = (long) x; |
4195 | 4187 | pushLong(frame, stackPointer - 1, result); |
4196 | 4188 | } |
4197 | 4189 |
|
4198 | 4190 | private void i64_trunc_f32_u(VirtualFrame frame, int stackPointer) { |
4199 | 4191 | final float x = popFloat(frame, stackPointer - 1); |
4200 | | - if (Float.isNaN(x)) { |
4201 | | - enterErrorBranch(); |
4202 | | - throw WasmException.create(Failure.INVALID_CONVERSION_TO_INT); |
4203 | | - } else if (x < MIN_FLOAT_TRUNCATABLE_TO_U_LONG || x > MAX_FLOAT_TRUNCATABLE_TO_U_LONG) { |
| 4192 | + final long result; |
| 4193 | + if (x > -1.0f && x < 0x1p64f) { |
| 4194 | + result = ExactMath.truncateToUnsignedLong(x); |
| 4195 | + } else { |
4204 | 4196 | enterErrorBranch(); |
4205 | | - throw WasmException.create(Failure.INT_OVERFLOW); |
| 4197 | + throw trunc_f32_trap(x); |
4206 | 4198 | } |
4207 | | - final long result = ExactMath.truncateToUnsignedLong(x); |
4208 | 4199 | pushLong(frame, stackPointer - 1, result); |
4209 | 4200 | } |
4210 | 4201 |
|
4211 | 4202 | private void i64_trunc_f64_s(VirtualFrame frame, int stackPointer) { |
4212 | 4203 | final double x = popDouble(frame, stackPointer - 1); |
4213 | | - if (Double.isNaN(x)) { |
4214 | | - enterErrorBranch(); |
4215 | | - throw WasmException.create(Failure.INVALID_CONVERSION_TO_INT); |
4216 | | - } else if (x < MIN_DOUBLE_TRUNCATABLE_TO_LONG || x > MAX_DOUBLE_TRUNCATABLE_TO_LONG) { |
| 4204 | + final long result; |
| 4205 | + if (x >= -0x1p63 && x < 0x1p63) { |
| 4206 | + result = (long) x; |
| 4207 | + } else { |
4217 | 4208 | enterErrorBranch(); |
4218 | | - throw WasmException.create(Failure.INT_OVERFLOW); |
| 4209 | + throw trunc_f64_trap(x); |
4219 | 4210 | } |
4220 | | - final long result = (long) x; |
4221 | 4211 | pushLong(frame, stackPointer - 1, result); |
4222 | 4212 | } |
4223 | 4213 |
|
4224 | 4214 | private void i64_trunc_f64_u(VirtualFrame frame, int stackPointer) { |
4225 | 4215 | final double x = popDouble(frame, stackPointer - 1); |
4226 | | - if (Double.isNaN(x)) { |
4227 | | - enterErrorBranch(); |
4228 | | - throw WasmException.create(Failure.INVALID_CONVERSION_TO_INT); |
4229 | | - } else if (x < MIN_DOUBLE_TRUNCATABLE_TO_U_LONG || x > MAX_DOUBLE_TRUNCATABLE_TO_U_LONG) { |
| 4216 | + final long result; |
| 4217 | + if (x > -1.0 && x < 0x1p64) { |
| 4218 | + result = ExactMath.truncateToUnsignedLong(x); |
| 4219 | + } else { |
4230 | 4220 | enterErrorBranch(); |
4231 | | - throw WasmException.create(Failure.INT_OVERFLOW); |
| 4221 | + throw trunc_f64_trap(x); |
4232 | 4222 | } |
4233 | | - final long result = ExactMath.truncateToUnsignedLong(x); |
4234 | 4223 | pushLong(frame, stackPointer - 1, result); |
4235 | 4224 | } |
4236 | 4225 |
|
|
0 commit comments