Index: src/wasm/wasm-interpreter.cc |
diff --git a/src/wasm/wasm-interpreter.cc b/src/wasm/wasm-interpreter.cc |
index d397b6d7f1b046bb1fe31f76a8e3e9b15224cd5b..5524e371f1aa04c57c269a0a825780dcf9e16b31 100644 |
--- a/src/wasm/wasm-interpreter.cc |
+++ b/src/wasm/wasm-interpreter.cc |
@@ -63,7 +63,6 @@ namespace wasm { |
V(I64GeS, int64_t, >=) \ |
V(F32Add, float, +) \ |
V(F32Mul, float, *) \ |
- V(F32Div, float, /) \ |
V(F32Eq, float, ==) \ |
V(F32Ne, float, !=) \ |
V(F32Lt, float, <) \ |
@@ -72,7 +71,6 @@ namespace wasm { |
V(F32Ge, float, >=) \ |
V(F64Add, double, +) \ |
V(F64Mul, double, *) \ |
- V(F64Div, double, /) \ |
V(F64Eq, double, ==) \ |
V(F64Ne, double, !=) \ |
V(F64Lt, double, <) \ |
@@ -80,6 +78,10 @@ namespace wasm { |
V(F64Gt, double, >) \ |
V(F64Ge, double, >=) |
+#define FOREACH_SIMPLE_BINOP_NAN(V) \ |
+ V(F32Div, float, /) \ |
+ V(F64Div, double, /) |
+ |
#define FOREACH_OTHER_BINOP(V) \ |
V(I32DivS, int32_t) \ |
V(I32DivU, uint32_t) \ |
@@ -127,14 +129,12 @@ namespace wasm { |
V(F32Floor, float) \ |
V(F32Trunc, float) \ |
V(F32NearestInt, float) \ |
- V(F32Sqrt, float) \ |
V(F64Abs, double) \ |
V(F64Neg, double) \ |
V(F64Ceil, double) \ |
V(F64Floor, double) \ |
V(F64Trunc, double) \ |
V(F64NearestInt, double) \ |
- V(F64Sqrt, double) \ |
V(I32SConvertF32, float) \ |
V(I32SConvertF64, double) \ |
V(I32UConvertF32, float) \ |
@@ -165,6 +165,10 @@ namespace wasm { |
V(I32AsmjsSConvertF64, double) \ |
V(I32AsmjsUConvertF64, double) |
+#define FOREACH_OTHER_UNOP_NAN(V) \ |
+ V(F32Sqrt, float) \ |
+ V(F64Sqrt, double) |
+ |
static inline int32_t ExecuteI32DivS(int32_t a, int32_t b, TrapReason* trap) { |
if (b == 0) { |
*trap = kTrapDivByZero; |
@@ -975,7 +979,8 @@ class ThreadImpl : public WasmInterpreter::Thread { |
blocks_(zone), |
state_(WasmInterpreter::STOPPED), |
break_pc_(kInvalidPc), |
- trap_reason_(kTrapCount) {} |
+ trap_reason_(kTrapCount), |
+ may_produced_nan_(false) {} |
virtual ~ThreadImpl() {} |
@@ -1030,6 +1035,7 @@ class ThreadImpl : public WasmInterpreter::Thread { |
frames_.clear(); |
state_ = WasmInterpreter::STOPPED; |
trap_reason_ = kTrapCount; |
+ may_produced_nan_ = false; |
} |
virtual int GetFrameCount() { return static_cast<int>(frames_.size()); } |
@@ -1053,6 +1059,8 @@ class ThreadImpl : public WasmInterpreter::Thread { |
virtual pc_t GetBreakpointPc() { return break_pc_; } |
+ virtual bool MayProducedNaN() { return may_produced_nan_; } |
+ |
bool Terminated() { |
return state_ == WasmInterpreter::TRAPPED || |
state_ == WasmInterpreter::FINISHED; |
@@ -1087,6 +1095,7 @@ class ThreadImpl : public WasmInterpreter::Thread { |
WasmInterpreter::State state_; |
pc_t break_pc_; |
TrapReason trap_reason_; |
+ bool may_produced_nan_; |
CodeMap* codemap() { return codemap_; } |
WasmInstance* instance() { return instance_; } |
@@ -1602,6 +1611,18 @@ class ThreadImpl : public WasmInterpreter::Thread { |
FOREACH_SIMPLE_BINOP(EXECUTE_SIMPLE_BINOP) |
#undef EXECUTE_SIMPLE_BINOP |
+#define EXECUTE_SIMPLE_BINOP_NAN(name, ctype, op) \ |
+ case kExpr##name: { \ |
+ may_produced_nan_ |= true; \ |
titzer
2016/10/20 10:53:24
Don't we want to set this flag only if the result
ahaas
2016/10/20 13:43:23
Done.
|
+ WasmVal rval = Pop(); \ |
+ WasmVal lval = Pop(); \ |
+ WasmVal result(lval.to<ctype>() op rval.to<ctype>()); \ |
+ Push(pc, result); \ |
+ break; \ |
+ } |
+ FOREACH_SIMPLE_BINOP_NAN(EXECUTE_SIMPLE_BINOP_NAN) |
+#undef EXECUTE_SIMPLE_BINOP_NAN |
+ |
#define EXECUTE_OTHER_BINOP(name, ctype) \ |
case kExpr##name: { \ |
TrapReason trap = kTrapCount; \ |
@@ -1627,6 +1648,19 @@ class ThreadImpl : public WasmInterpreter::Thread { |
FOREACH_OTHER_UNOP(EXECUTE_OTHER_UNOP) |
#undef EXECUTE_OTHER_UNOP |
+#define EXECUTE_OTHER_UNOP_NAN(name, ctype) \ |
+ case kExpr##name: { \ |
+ may_produced_nan_ |= true; \ |
+ TrapReason trap = kTrapCount; \ |
+ volatile ctype val = Pop().to<ctype>(); \ |
+ WasmVal result(Execute##name(val, &trap)); \ |
+ if (trap != kTrapCount) return DoTrap(trap, pc); \ |
+ Push(pc, result); \ |
+ break; \ |
+ } |
+ FOREACH_OTHER_UNOP_NAN(EXECUTE_OTHER_UNOP_NAN) |
+#undef EXECUTE_OTHER_UNOP_NAN |
+ |
default: |
V8_Fatal(__FILE__, __LINE__, "Unknown or unimplemented opcode #%d:%s", |
code->start[pc], OpcodeName(code->start[pc])); |