Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: src/wasm/wasm-interpreter.cc

Issue 2671803002: [wasm] Refactor the non-determinism detection in the interpreter. (Closed)
Patch Set: Also adjust copysign Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/cctest/wasm/test-run-wasm-interpreter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <type_traits>
6
5 #include "src/wasm/wasm-interpreter.h" 7 #include "src/wasm/wasm-interpreter.h"
6 8
7 #include "src/utils.h" 9 #include "src/utils.h"
8 #include "src/wasm/decoder.h" 10 #include "src/wasm/decoder.h"
9 #include "src/wasm/function-body-decoder.h" 11 #include "src/wasm/function-body-decoder.h"
10 #include "src/wasm/wasm-external-refs.h" 12 #include "src/wasm/wasm-external-refs.h"
11 #include "src/wasm/wasm-limits.h" 13 #include "src/wasm/wasm-limits.h"
12 #include "src/wasm/wasm-module.h" 14 #include "src/wasm/wasm-module.h"
13 15
14 #include "src/zone/accounting-allocator.h" 16 #include "src/zone/accounting-allocator.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 V(F32Le, float, <=) \ 72 V(F32Le, float, <=) \
71 V(F32Gt, float, >) \ 73 V(F32Gt, float, >) \
72 V(F32Ge, float, >=) \ 74 V(F32Ge, float, >=) \
73 V(F64Add, double, +) \ 75 V(F64Add, double, +) \
74 V(F64Sub, double, -) \ 76 V(F64Sub, double, -) \
75 V(F64Eq, double, ==) \ 77 V(F64Eq, double, ==) \
76 V(F64Ne, double, !=) \ 78 V(F64Ne, double, !=) \
77 V(F64Lt, double, <) \ 79 V(F64Lt, double, <) \
78 V(F64Le, double, <=) \ 80 V(F64Le, double, <=) \
79 V(F64Gt, double, >) \ 81 V(F64Gt, double, >) \
80 V(F64Ge, double, >=) 82 V(F64Ge, double, >=) \
81 83 V(F32Mul, float, *) \
82 #define FOREACH_SIMPLE_BINOP_NAN(V) \ 84 V(F64Mul, double, *) \
83 V(F32Mul, float, *) \ 85 V(F32Div, float, /) \
84 V(F64Mul, double, *) \
85 V(F32Div, float, /) \
86 V(F64Div, double, /) 86 V(F64Div, double, /)
87 87
88 #define FOREACH_OTHER_BINOP(V) \ 88 #define FOREACH_OTHER_BINOP(V) \
89 V(I32DivS, int32_t) \ 89 V(I32DivS, int32_t) \
90 V(I32DivU, uint32_t) \ 90 V(I32DivU, uint32_t) \
91 V(I32RemS, int32_t) \ 91 V(I32RemS, int32_t) \
92 V(I32RemU, uint32_t) \ 92 V(I32RemU, uint32_t) \
93 V(I32Shl, uint32_t) \ 93 V(I32Shl, uint32_t) \
94 V(I32ShrU, uint32_t) \ 94 V(I32ShrU, uint32_t) \
95 V(I32ShrS, int32_t) \ 95 V(I32ShrS, int32_t) \
96 V(I64DivS, int64_t) \ 96 V(I64DivS, int64_t) \
97 V(I64DivU, uint64_t) \ 97 V(I64DivU, uint64_t) \
98 V(I64RemS, int64_t) \ 98 V(I64RemS, int64_t) \
99 V(I64RemU, uint64_t) \ 99 V(I64RemU, uint64_t) \
100 V(I64Shl, uint64_t) \ 100 V(I64Shl, uint64_t) \
101 V(I64ShrU, uint64_t) \ 101 V(I64ShrU, uint64_t) \
102 V(I64ShrS, int64_t) \ 102 V(I64ShrS, int64_t) \
103 V(I32Ror, int32_t) \ 103 V(I32Ror, int32_t) \
104 V(I32Rol, int32_t) \ 104 V(I32Rol, int32_t) \
105 V(I64Ror, int64_t) \ 105 V(I64Ror, int64_t) \
106 V(I64Rol, int64_t) \ 106 V(I64Rol, int64_t) \
107 V(F32Min, float) \ 107 V(F32Min, float) \
108 V(F32Max, float) \ 108 V(F32Max, float) \
109 V(F32CopySign, float) \
110 V(F64Min, double) \ 109 V(F64Min, double) \
111 V(F64Max, double) \ 110 V(F64Max, double) \
112 V(F64CopySign, double) \
113 V(I32AsmjsDivS, int32_t) \ 111 V(I32AsmjsDivS, int32_t) \
114 V(I32AsmjsDivU, uint32_t) \ 112 V(I32AsmjsDivU, uint32_t) \
115 V(I32AsmjsRemS, int32_t) \ 113 V(I32AsmjsRemS, int32_t) \
116 V(I32AsmjsRemU, uint32_t) 114 V(I32AsmjsRemU, uint32_t)
117 115
118 #define FOREACH_OTHER_UNOP(V) \ 116 #define FOREACH_OTHER_UNOP(V) \
119 V(I32Clz, uint32_t) \ 117 V(I32Clz, uint32_t) \
120 V(I32Ctz, uint32_t) \ 118 V(I32Ctz, uint32_t) \
121 V(I32Popcnt, uint32_t) \ 119 V(I32Popcnt, uint32_t) \
122 V(I32Eqz, uint32_t) \ 120 V(I32Eqz, uint32_t) \
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 V(F32ReinterpretI32, int32_t) \ 153 V(F32ReinterpretI32, int32_t) \
156 V(F64SConvertI32, int32_t) \ 154 V(F64SConvertI32, int32_t) \
157 V(F64UConvertI32, uint32_t) \ 155 V(F64UConvertI32, uint32_t) \
158 V(F64SConvertI64, int64_t) \ 156 V(F64SConvertI64, int64_t) \
159 V(F64UConvertI64, uint64_t) \ 157 V(F64UConvertI64, uint64_t) \
160 V(F64ConvertF32, float) \ 158 V(F64ConvertF32, float) \
161 V(F64ReinterpretI64, int64_t) \ 159 V(F64ReinterpretI64, int64_t) \
162 V(I32AsmjsSConvertF32, float) \ 160 V(I32AsmjsSConvertF32, float) \
163 V(I32AsmjsUConvertF32, float) \ 161 V(I32AsmjsUConvertF32, float) \
164 V(I32AsmjsSConvertF64, double) \ 162 V(I32AsmjsSConvertF64, double) \
165 V(I32AsmjsUConvertF64, double) 163 V(I32AsmjsUConvertF64, double) \
166 164 V(F32Sqrt, float) \
167 #define FOREACH_OTHER_UNOP_NAN(V) \
168 V(F32Sqrt, float) \
169 V(F64Sqrt, double) 165 V(F64Sqrt, double)
170 166
171 static inline int32_t ExecuteI32DivS(int32_t a, int32_t b, TrapReason* trap) { 167 static inline int32_t ExecuteI32DivS(int32_t a, int32_t b, TrapReason* trap) {
172 if (b == 0) { 168 if (b == 0) {
173 *trap = kTrapDivByZero; 169 *trap = kTrapDivByZero;
174 return 0; 170 return 0;
175 } 171 }
176 if (b == -1 && a == std::numeric_limits<int32_t>::min()) { 172 if (b == -1 && a == std::numeric_limits<int32_t>::min()) {
177 *trap = kTrapDivUnrepresentable; 173 *trap = kTrapDivUnrepresentable;
178 return 0; 174 return 0;
(...skipping 990 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 // ^ 0 ^ stack_.size() 1165 // ^ 0 ^ stack_.size()
1170 DCHECK_LE(dest, stack_.size()); 1166 DCHECK_LE(dest, stack_.size());
1171 DCHECK_LE(dest + arity, stack_.size()); 1167 DCHECK_LE(dest + arity, stack_.size());
1172 size_t pop_count = stack_.size() - dest - arity; 1168 size_t pop_count = stack_.size() - dest - arity;
1173 for (size_t i = 0; i < arity; i++) { 1169 for (size_t i = 0; i < arity; i++) {
1174 stack_[dest + i] = stack_[dest + pop_count + i]; 1170 stack_[dest + i] = stack_[dest + pop_count + i];
1175 } 1171 }
1176 stack_.resize(stack_.size() - pop_count); 1172 stack_.resize(stack_.size() - pop_count);
1177 } 1173 }
1178 1174
1175 template <typename ctype, typename mtype>
1176 bool ExecuteLoad(Decoder* decoder, InterpreterCode* code, pc_t pc, int& len) {
1177 MemoryAccessOperand operand(decoder, code->at(pc), sizeof(ctype));
1178 uint32_t index = Pop().to<uint32_t>();
1179 size_t effective_mem_size = instance()->mem_size - sizeof(mtype);
1180 if (operand.offset > effective_mem_size ||
1181 index > (effective_mem_size - operand.offset)) {
1182 DoTrap(kTrapMemOutOfBounds, pc);
1183 return false;
1184 }
1185 byte* addr = instance()->mem_start + operand.offset + index;
1186 WasmVal result(static_cast<ctype>(ReadLittleEndianValue<mtype>(addr)));
1187
1188 Push(pc, result);
1189 len = 1 + operand.length;
1190 return true;
1191 }
1192
1193 template <typename ctype, typename mtype>
1194 bool ExecuteStore(Decoder* decoder, InterpreterCode* code, pc_t pc,
1195 int& len) {
1196 MemoryAccessOperand operand(decoder, code->at(pc), sizeof(ctype));
1197 WasmVal val = Pop();
1198
1199 uint32_t index = Pop().to<uint32_t>();
1200 size_t effective_mem_size = instance()->mem_size - sizeof(mtype);
1201 if (operand.offset > effective_mem_size ||
1202 index > (effective_mem_size - operand.offset)) {
1203 DoTrap(kTrapMemOutOfBounds, pc);
1204 return false;
1205 }
1206 byte* addr = instance()->mem_start + operand.offset + index;
1207 WriteLittleEndianValue<mtype>(addr, static_cast<mtype>(val.to<ctype>()));
1208 len = 1 + operand.length;
1209
1210 if (std::is_same<float, ctype>::value) {
1211 possible_nondeterminism_ |= std::isnan(val.to<float>());
1212 } else if (std::is_same<double, ctype>::value) {
1213 possible_nondeterminism_ |= std::isnan(val.to<double>());
1214 }
1215 return true;
1216 }
1217
1179 void Execute(InterpreterCode* code, pc_t pc, int max) { 1218 void Execute(InterpreterCode* code, pc_t pc, int max) {
1180 Decoder decoder(code->start, code->end); 1219 Decoder decoder(code->start, code->end);
1181 pc_t limit = code->end - code->start; 1220 pc_t limit = code->end - code->start;
1182 while (--max >= 0) { 1221 while (--max >= 0) {
1183 #define PAUSE_IF_BREAK_FLAG(flag) \ 1222 #define PAUSE_IF_BREAK_FLAG(flag) \
1184 if (V8_UNLIKELY(break_flags_ & WasmInterpreter::BreakFlag::flag)) max = 0; 1223 if (V8_UNLIKELY(break_flags_ & WasmInterpreter::BreakFlag::flag)) max = 0;
1185 1224
1186 DCHECK_GT(limit, pc); 1225 DCHECK_GT(limit, pc);
1187 1226
1188 const char* skip = " "; 1227 const char* skip = " ";
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1420 *reinterpret_cast<float*>(ptr) = val.to<float>(); 1459 *reinterpret_cast<float*>(ptr) = val.to<float>();
1421 } else if (type == kWasmF64) { 1460 } else if (type == kWasmF64) {
1422 *reinterpret_cast<double*>(ptr) = val.to<double>(); 1461 *reinterpret_cast<double*>(ptr) = val.to<double>();
1423 } else { 1462 } else {
1424 UNREACHABLE(); 1463 UNREACHABLE();
1425 } 1464 }
1426 len = 1 + operand.length; 1465 len = 1 + operand.length;
1427 break; 1466 break;
1428 } 1467 }
1429 1468
1430 #define LOAD_CASE(name, ctype, mtype) \ 1469 #define LOAD_CASE(name, ctype, mtype) \
1431 case kExpr##name: { \ 1470 case kExpr##name: { \
1432 MemoryAccessOperand operand(&decoder, code->at(pc), sizeof(ctype)); \ 1471 if (!ExecuteLoad<ctype, mtype>(&decoder, code, pc, len)) return; \
1433 uint32_t index = Pop().to<uint32_t>(); \ 1472 break; \
1434 size_t effective_mem_size = instance()->mem_size - sizeof(mtype); \
1435 if (operand.offset > effective_mem_size || \
1436 index > (effective_mem_size - operand.offset)) { \
1437 return DoTrap(kTrapMemOutOfBounds, pc); \
1438 } \
1439 byte* addr = instance()->mem_start + operand.offset + index; \
1440 WasmVal result(static_cast<ctype>(ReadLittleEndianValue<mtype>(addr))); \
1441 Push(pc, result); \
1442 len = 1 + operand.length; \
1443 break; \
1444 } 1473 }
1445 1474
1446 LOAD_CASE(I32LoadMem8S, int32_t, int8_t); 1475 LOAD_CASE(I32LoadMem8S, int32_t, int8_t);
1447 LOAD_CASE(I32LoadMem8U, int32_t, uint8_t); 1476 LOAD_CASE(I32LoadMem8U, int32_t, uint8_t);
1448 LOAD_CASE(I32LoadMem16S, int32_t, int16_t); 1477 LOAD_CASE(I32LoadMem16S, int32_t, int16_t);
1449 LOAD_CASE(I32LoadMem16U, int32_t, uint16_t); 1478 LOAD_CASE(I32LoadMem16U, int32_t, uint16_t);
1450 LOAD_CASE(I64LoadMem8S, int64_t, int8_t); 1479 LOAD_CASE(I64LoadMem8S, int64_t, int8_t);
1451 LOAD_CASE(I64LoadMem8U, int64_t, uint8_t); 1480 LOAD_CASE(I64LoadMem8U, int64_t, uint8_t);
1452 LOAD_CASE(I64LoadMem16S, int64_t, int16_t); 1481 LOAD_CASE(I64LoadMem16S, int64_t, int16_t);
1453 LOAD_CASE(I64LoadMem16U, int64_t, uint16_t); 1482 LOAD_CASE(I64LoadMem16U, int64_t, uint16_t);
1454 LOAD_CASE(I64LoadMem32S, int64_t, int32_t); 1483 LOAD_CASE(I64LoadMem32S, int64_t, int32_t);
1455 LOAD_CASE(I64LoadMem32U, int64_t, uint32_t); 1484 LOAD_CASE(I64LoadMem32U, int64_t, uint32_t);
1456 LOAD_CASE(I32LoadMem, int32_t, int32_t); 1485 LOAD_CASE(I32LoadMem, int32_t, int32_t);
1457 LOAD_CASE(I64LoadMem, int64_t, int64_t); 1486 LOAD_CASE(I64LoadMem, int64_t, int64_t);
1458 LOAD_CASE(F32LoadMem, float, float); 1487 LOAD_CASE(F32LoadMem, float, float);
1459 LOAD_CASE(F64LoadMem, double, double); 1488 LOAD_CASE(F64LoadMem, double, double);
1460 #undef LOAD_CASE 1489 #undef LOAD_CASE
1461 1490
1462 #define STORE_CASE(name, ctype, mtype) \ 1491 #define STORE_CASE(name, ctype, mtype) \
1463 case kExpr##name: { \ 1492 case kExpr##name: { \
1464 MemoryAccessOperand operand(&decoder, code->at(pc), sizeof(ctype)); \ 1493 if (!ExecuteStore<ctype, mtype>(&decoder, code, pc, len)) return; \
1465 WasmVal val = Pop(); \ 1494 break; \
1466 uint32_t index = Pop().to<uint32_t>(); \
1467 size_t effective_mem_size = instance()->mem_size - sizeof(mtype); \
1468 if (operand.offset > effective_mem_size || \
1469 index > (effective_mem_size - operand.offset)) { \
1470 return DoTrap(kTrapMemOutOfBounds, pc); \
1471 } \
1472 byte* addr = instance()->mem_start + operand.offset + index; \
1473 WriteLittleEndianValue<mtype>(addr, static_cast<mtype>(val.to<ctype>())); \
1474 len = 1 + operand.length; \
1475 break; \
1476 } 1495 }
1477 1496
1478 STORE_CASE(I32StoreMem8, int32_t, int8_t); 1497 STORE_CASE(I32StoreMem8, int32_t, int8_t);
1479 STORE_CASE(I32StoreMem16, int32_t, int16_t); 1498 STORE_CASE(I32StoreMem16, int32_t, int16_t);
1480 STORE_CASE(I64StoreMem8, int64_t, int8_t); 1499 STORE_CASE(I64StoreMem8, int64_t, int8_t);
1481 STORE_CASE(I64StoreMem16, int64_t, int16_t); 1500 STORE_CASE(I64StoreMem16, int64_t, int16_t);
1482 STORE_CASE(I64StoreMem32, int64_t, int32_t); 1501 STORE_CASE(I64StoreMem32, int64_t, int32_t);
1483 STORE_CASE(I32StoreMem, int32_t, int32_t); 1502 STORE_CASE(I32StoreMem, int32_t, int32_t);
1484 STORE_CASE(I64StoreMem, int64_t, int64_t); 1503 STORE_CASE(I64StoreMem, int64_t, int64_t);
1485 STORE_CASE(F32StoreMem, float, float); 1504 STORE_CASE(F32StoreMem, float, float);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1541 MemoryIndexOperand operand(&decoder, code->at(pc)); 1560 MemoryIndexOperand operand(&decoder, code->at(pc));
1542 Push(pc, WasmVal(static_cast<uint32_t>(instance()->mem_size / 1561 Push(pc, WasmVal(static_cast<uint32_t>(instance()->mem_size /
1543 WasmModule::kPageSize))); 1562 WasmModule::kPageSize)));
1544 len = 1 + operand.length; 1563 len = 1 + operand.length;
1545 break; 1564 break;
1546 } 1565 }
1547 // We need to treat kExprI32ReinterpretF32 and kExprI64ReinterpretF64 1566 // We need to treat kExprI32ReinterpretF32 and kExprI64ReinterpretF64
1548 // specially to guarantee that the quiet bit of a NaN is preserved on 1567 // specially to guarantee that the quiet bit of a NaN is preserved on
1549 // ia32 by the reinterpret casts. 1568 // ia32 by the reinterpret casts.
1550 case kExprI32ReinterpretF32: { 1569 case kExprI32ReinterpretF32: {
1551 WasmVal result(ExecuteI32ReinterpretF32(Pop())); 1570 WasmVal val = Pop();
1571 WasmVal result(ExecuteI32ReinterpretF32(val));
1552 Push(pc, result); 1572 Push(pc, result);
1573 possible_nondeterminism_ |= std::isnan(val.to<float>());
1553 break; 1574 break;
1554 } 1575 }
1555 case kExprI64ReinterpretF64: { 1576 case kExprI64ReinterpretF64: {
1556 WasmVal result(ExecuteI64ReinterpretF64(Pop())); 1577 WasmVal val = Pop();
1578 WasmVal result(ExecuteI64ReinterpretF64(val));
1557 Push(pc, result); 1579 Push(pc, result);
1580 possible_nondeterminism_ |= std::isnan(val.to<double>());
1558 break; 1581 break;
1559 } 1582 }
1560 #define EXECUTE_SIMPLE_BINOP(name, ctype, op) \ 1583 #define EXECUTE_SIMPLE_BINOP(name, ctype, op) \
1561 case kExpr##name: { \ 1584 case kExpr##name: { \
1562 WasmVal rval = Pop(); \ 1585 WasmVal rval = Pop(); \
1563 WasmVal lval = Pop(); \ 1586 WasmVal lval = Pop(); \
1564 WasmVal result(lval.to<ctype>() op rval.to<ctype>()); \ 1587 WasmVal result(lval.to<ctype>() op rval.to<ctype>()); \
1565 Push(pc, result); \ 1588 Push(pc, result); \
1566 break; \ 1589 break; \
1567 } 1590 }
1568 FOREACH_SIMPLE_BINOP(EXECUTE_SIMPLE_BINOP) 1591 FOREACH_SIMPLE_BINOP(EXECUTE_SIMPLE_BINOP)
1569 #undef EXECUTE_SIMPLE_BINOP 1592 #undef EXECUTE_SIMPLE_BINOP
1570 1593
1571 #define EXECUTE_SIMPLE_BINOP_NAN(name, ctype, op) \
1572 case kExpr##name: { \
1573 WasmVal rval = Pop(); \
1574 WasmVal lval = Pop(); \
1575 ctype result = lval.to<ctype>() op rval.to<ctype>(); \
1576 possible_nondeterminism_ |= std::isnan(result); \
1577 WasmVal result_val(result); \
1578 Push(pc, result_val); \
1579 break; \
1580 }
1581 FOREACH_SIMPLE_BINOP_NAN(EXECUTE_SIMPLE_BINOP_NAN)
1582 #undef EXECUTE_SIMPLE_BINOP_NAN
1583
1584 #define EXECUTE_OTHER_BINOP(name, ctype) \ 1594 #define EXECUTE_OTHER_BINOP(name, ctype) \
1585 case kExpr##name: { \ 1595 case kExpr##name: { \
1586 TrapReason trap = kTrapCount; \ 1596 TrapReason trap = kTrapCount; \
1587 volatile ctype rval = Pop().to<ctype>(); \ 1597 volatile ctype rval = Pop().to<ctype>(); \
1588 volatile ctype lval = Pop().to<ctype>(); \ 1598 volatile ctype lval = Pop().to<ctype>(); \
1589 WasmVal result(Execute##name(lval, rval, &trap)); \ 1599 WasmVal result(Execute##name(lval, rval, &trap)); \
1590 if (trap != kTrapCount) return DoTrap(trap, pc); \ 1600 if (trap != kTrapCount) return DoTrap(trap, pc); \
1591 Push(pc, result); \ 1601 Push(pc, result); \
1592 break; \ 1602 break; \
1593 } 1603 }
1594 FOREACH_OTHER_BINOP(EXECUTE_OTHER_BINOP) 1604 FOREACH_OTHER_BINOP(EXECUTE_OTHER_BINOP)
1595 #undef EXECUTE_OTHER_BINOP 1605 #undef EXECUTE_OTHER_BINOP
1596 1606
1607 case kExprF32CopySign: {
1608 // Handle kExprF32CopySign separately because it may introduce
1609 // observable non-determinism.
1610 TrapReason trap = kTrapCount;
1611 volatile float rval = Pop().to<float>();
1612 volatile float lval = Pop().to<float>();
1613 WasmVal result(ExecuteF32CopySign(lval, rval, &trap));
1614 Push(pc, result);
1615 possible_nondeterminism_ |= std::isnan(rval);
1616 break;
1617 }
1618 case kExprF64CopySign: {
1619 // Handle kExprF32CopySign separately because it may introduce
1620 // observable non-determinism.
1621 TrapReason trap = kTrapCount;
1622 volatile double rval = Pop().to<double>();
1623 volatile double lval = Pop().to<double>();
1624 WasmVal result(ExecuteF64CopySign(lval, rval, &trap));
1625 Push(pc, result);
1626 possible_nondeterminism_ |= std::isnan(rval);
1627 break;
1628 }
1597 #define EXECUTE_OTHER_UNOP(name, ctype) \ 1629 #define EXECUTE_OTHER_UNOP(name, ctype) \
1598 case kExpr##name: { \ 1630 case kExpr##name: { \
1599 TrapReason trap = kTrapCount; \ 1631 TrapReason trap = kTrapCount; \
1600 volatile ctype val = Pop().to<ctype>(); \ 1632 volatile ctype val = Pop().to<ctype>(); \
1601 WasmVal result(Execute##name(val, &trap)); \ 1633 WasmVal result(Execute##name(val, &trap)); \
1602 if (trap != kTrapCount) return DoTrap(trap, pc); \ 1634 if (trap != kTrapCount) return DoTrap(trap, pc); \
1603 Push(pc, result); \ 1635 Push(pc, result); \
1604 break; \ 1636 break; \
1605 } 1637 }
1606 FOREACH_OTHER_UNOP(EXECUTE_OTHER_UNOP) 1638 FOREACH_OTHER_UNOP(EXECUTE_OTHER_UNOP)
1607 #undef EXECUTE_OTHER_UNOP 1639 #undef EXECUTE_OTHER_UNOP
1608 1640
1609 #define EXECUTE_OTHER_UNOP_NAN(name, ctype) \
1610 case kExpr##name: { \
1611 TrapReason trap = kTrapCount; \
1612 volatile ctype val = Pop().to<ctype>(); \
1613 ctype result = Execute##name(val, &trap); \
1614 possible_nondeterminism_ |= std::isnan(result); \
1615 WasmVal result_val(result); \
1616 if (trap != kTrapCount) return DoTrap(trap, pc); \
1617 Push(pc, result_val); \
1618 break; \
1619 }
1620 FOREACH_OTHER_UNOP_NAN(EXECUTE_OTHER_UNOP_NAN)
1621 #undef EXECUTE_OTHER_UNOP_NAN
1622
1623 default: 1641 default:
1624 V8_Fatal(__FILE__, __LINE__, "Unknown or unimplemented opcode #%d:%s", 1642 V8_Fatal(__FILE__, __LINE__, "Unknown or unimplemented opcode #%d:%s",
1625 code->start[pc], OpcodeName(code->start[pc])); 1643 code->start[pc], OpcodeName(code->start[pc]));
1626 UNREACHABLE(); 1644 UNREACHABLE();
1627 } 1645 }
1628 1646
1629 pc += len; 1647 pc += len;
1630 if (pc == limit) { 1648 if (pc == limit) {
1631 // Fell off end of code; do an implicit return. 1649 // Fell off end of code; do an implicit return.
1632 TRACE("@%-3zu: ImplicitReturn\n", pc); 1650 TRACE("@%-3zu: ImplicitReturn\n", pc);
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
1922 return none; 1940 return none;
1923 } 1941 }
1924 1942
1925 void InterpretedFrame::SetLocalVal(int index, WasmVal val) { UNIMPLEMENTED(); } 1943 void InterpretedFrame::SetLocalVal(int index, WasmVal val) { UNIMPLEMENTED(); }
1926 1944
1927 void InterpretedFrame::SetExprVal(int pc, WasmVal val) { UNIMPLEMENTED(); } 1945 void InterpretedFrame::SetExprVal(int pc, WasmVal val) { UNIMPLEMENTED(); }
1928 1946
1929 } // namespace wasm 1947 } // namespace wasm
1930 } // namespace internal 1948 } // namespace internal
1931 } // namespace v8 1949 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/cctest/wasm/test-run-wasm-interpreter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698