MCPcopy Create free account
hub / github.com/WebAssembly/wabt / OnTryTableExpr

Method OnTryTableExpr

src/interp/binary-reader-interp.cc:1670–1742  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1668}
1669
1670Result BinaryReaderInterp::OnTryTableExpr(Type sig_type,
1671 const CatchClauseVector& catches) {
1672 // we can just emit the catch handlers beforehand, so long as we skip over
1673 // them when entering the try.
1674 CHECK_RESULT(validator_.BeginTryTable(GetLocation(), sig_type));
1675
1676 u32 exn_stack_height;
1677 CHECK_RESULT(
1678 validator_.GetCatchCount(label_stack_.size() - 1, &exn_stack_height));
1679 // NOTE: *NOT* GetLocalCount. we don't count the parameters, as they're not
1680 // part of the frame.
1681 u32 value_stack_height = validator_.type_stack_size() + local_count_;
1682
1683 HandlerDesc desc =
1684 HandlerDesc{HandlerKind::Catch, Istream::kInvalidOffset,
1685 Istream::kInvalidOffset, {},
1686 {Istream::kInvalidOffset}, value_stack_height,
1687 exn_stack_height};
1688
1689 istream_.Emit(Opcode::Br);
1690 auto offset = istream_.EmitFixupU32();
1691
1692 bool has_catch_all = false;
1693 for (const auto& raw_catch : catches) {
1694 TableCatch catch_;
1695 catch_.kind = raw_catch.kind;
1696 catch_.tag = Var(raw_catch.tag, GetLocation());
1697 catch_.target = Var(raw_catch.depth, GetLocation());
1698 CHECK_RESULT(validator_.OnTryTableCatch(GetLocation(), catch_));
1699 // stop emitting handlers after catch_all - but we must still validate the
1700 // handlers we don't emit
1701 if (has_catch_all) {
1702 continue;
1703 }
1704 if (catch_.IsCatchAll()) {
1705 has_catch_all = true;
1706 desc.catch_all_ref = catch_.IsRef();
1707 desc.catch_all_offset = istream_.end();
1708 } else {
1709 desc.catches.push_back(
1710 CatchDesc{raw_catch.tag, istream_.end(), catch_.IsRef()});
1711 }
1712 // we can't use GetBrDropKeepCount because we're not in a real block.
1713 SharedValidator::Label* vlabel;
1714 CHECK_RESULT(validator_.GetLabel(raw_catch.depth, &vlabel));
1715 // we keep the exception's results.
1716 // (this has already been validated, above)
1717 Index keep_count = vlabel->br_types().size();
1718 // we drop everything between the current block and the br target.
1719 // (we have already taken the TryTable block parameters into account, in
1720 // BeginTryTable)
1721 Index drop_count = validator_.type_stack_size() - vlabel->type_stack_limit;
1722 Index catch_drop_count;
1723 // we use the regular catch count
1724 CHECK_RESULT(validator_.GetCatchCount(raw_catch.depth, &catch_drop_count));
1725 // but increment, as we are semantically in a catch
1726 catch_drop_count++;
1727 EmitBr(raw_catch.depth, drop_count, keep_count, catch_drop_count);

Callers

nothing calls this directly

Calls 15

EmitMethod · 0.80
EmitFixupU32Method · 0.80
ResolveFixupU32Method · 0.80
VarClass · 0.50
BeginTryTableMethod · 0.45
GetCatchCountMethod · 0.45
sizeMethod · 0.45
type_stack_sizeMethod · 0.45
OnTryTableCatchMethod · 0.45
IsCatchAllMethod · 0.45
IsRefMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected