Chromium Code Reviews| 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])); |