|
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