| 1313 | } |
| 1314 | |
| 1315 | RunResult Thread::StepInternal(Trap::Ptr* out_trap) { |
| 1316 | using O = Opcode; |
| 1317 | |
| 1318 | u32& pc = frames_.back().offset; |
| 1319 | auto& istream = mod_->desc().istream; |
| 1320 | |
| 1321 | if (trace_stream_) { |
| 1322 | istream.Trace(trace_stream_, pc, trace_source_.get()); |
| 1323 | } |
| 1324 | |
| 1325 | // clang-format off |
| 1326 | auto instr = istream.Read(&pc); |
| 1327 | switch (instr.op) { |
| 1328 | case O::Unreachable: |
| 1329 | return TRAP("unreachable executed"); |
| 1330 | |
| 1331 | case O::Br: |
| 1332 | pc = instr.imm_u32; |
| 1333 | break; |
| 1334 | |
| 1335 | case O::BrIf: |
| 1336 | if (Pop<u32>()) { |
| 1337 | pc = instr.imm_u32; |
| 1338 | } |
| 1339 | break; |
| 1340 | |
| 1341 | case O::BrOnNonNull: { |
| 1342 | Ref ref = Pop<Ref>(); |
| 1343 | if (ref != Ref::Null) { |
| 1344 | Push(ref); |
| 1345 | pc = instr.imm_u32; |
| 1346 | } |
| 1347 | break; |
| 1348 | } |
| 1349 | |
| 1350 | case O::BrOnNull: { |
| 1351 | Ref ref = Pop<Ref>(); |
| 1352 | if (ref == Ref::Null) { |
| 1353 | pc = instr.imm_u32; |
| 1354 | } else { |
| 1355 | Push(ref); |
| 1356 | } |
| 1357 | break; |
| 1358 | } |
| 1359 | |
| 1360 | case O::BrTable: { |
| 1361 | auto key = Pop<u32>(); |
| 1362 | if (key >= instr.imm_u32) { |
| 1363 | key = instr.imm_u32; |
| 1364 | } |
| 1365 | pc += key * Istream::kBrTableEntrySize; |
| 1366 | break; |
| 1367 | } |
| 1368 | |
| 1369 | case O::Return: |
| 1370 | return PopCall(); |
| 1371 | |
| 1372 | case O::Call: { |
nothing calls this directly
no test coverage detected