diff options
author | Asumu Takikawa <asumu@igalia.com> | 2021-02-18 07:09:32 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-18 07:09:32 -0800 |
commit | ffb22e3c900e8246d806d2e9a765dc14251b33e8 (patch) | |
tree | 45c7d2caef95ac03b237e8b3c2f29fe1db9686b6 /src | |
parent | 036a632a24679062e7fc891e7743195139bfa0a9 (diff) | |
download | wabt-ffb22e3c900e8246d806d2e9a765dc14251b33e8.tar.gz wabt-ffb22e3c900e8246d806d2e9a765dc14251b33e8.tar.bz2 wabt-ffb22e3c900e8246d806d2e9a765dc14251b33e8.zip |
Update rethrow depth handling and catch_all opcode (#1608)
Give `catch_all` its own opcode:
Previously `catch_all` shared an opcode with `else`, but
the spec now allocates it the 0x19 opcode.
Adjust rethrow depth semantics:
Previously this had interpreted the rethrow depth argument
as counting only catch blocks, but the spec has clarified that
it should count all blocks (in a similar fashion as `br` and
related instructions).
Diffstat (limited to 'src')
-rw-r--r-- | src/binary-reader-ir.cc | 7 | ||||
-rw-r--r-- | src/binary-reader-logging.cc | 1 | ||||
-rw-r--r-- | src/binary-reader-logging.h | 1 | ||||
-rw-r--r-- | src/binary-reader-nop.h | 1 | ||||
-rw-r--r-- | src/binary-reader-objdump.cc | 1 | ||||
-rw-r--r-- | src/binary-reader.cc | 6 | ||||
-rw-r--r-- | src/binary-reader.h | 1 | ||||
-rw-r--r-- | src/binary-writer.cc | 2 | ||||
-rw-r--r-- | src/interp/interp.cc | 1 | ||||
-rw-r--r-- | src/interp/istream.cc | 1 | ||||
-rw-r--r-- | src/opcode-code-table.c | 1 | ||||
-rw-r--r-- | src/opcode.def | 1 | ||||
-rw-r--r-- | src/opcode.h | 1 | ||||
-rw-r--r-- | src/type-checker.cc | 32 | ||||
-rw-r--r-- | src/wat-writer.cc | 4 |
15 files changed, 36 insertions, 25 deletions
diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc index 53a52233..cdda3311 100644 --- a/src/binary-reader-ir.cc +++ b/src/binary-reader-ir.cc @@ -145,6 +145,7 @@ class BinaryReaderIR : public BinaryReaderNop { Index default_target_depth) override; Result OnCallExpr(Index func_index) override; Result OnCatchExpr(Index event_index) override; + Result OnCatchAllExpr() override; Result OnCallIndirectExpr(Index sig_index, Index table_index) override; Result OnReturnCallExpr(Index func_index) override; Result OnReturnCallIndirectExpr(Index sig_index, Index table_index) override; @@ -759,8 +760,6 @@ Result BinaryReaderIR::OnElseExpr() { if_expr->true_.end_loc = GetLocation(); label->exprs = &if_expr->false_; label->label_type = LabelType::Else; - } else if (label->label_type == LabelType::Try) { - return AppendCatch(Catch(GetLocation())); } else { PrintError("else expression without matching if"); return Result::Error; @@ -1007,6 +1006,10 @@ Result BinaryReaderIR::OnCatchExpr(Index except_index) { return AppendCatch(Catch(Var(except_index, GetLocation()))); } +Result BinaryReaderIR::OnCatchAllExpr() { + return AppendCatch(Catch(GetLocation())); +} + Result BinaryReaderIR::OnUnwindExpr() { LabelNode* label = nullptr; CHECK_RESULT(TopLabel(&label)); diff --git a/src/binary-reader-logging.cc b/src/binary-reader-logging.cc index 2c2d1e7f..5cebbe92 100644 --- a/src/binary-reader-logging.cc +++ b/src/binary-reader-logging.cc @@ -794,6 +794,7 @@ DEFINE_OPCODE(OnBinaryExpr) DEFINE_INDEX_DESC(OnCallExpr, "func_index") DEFINE_INDEX_INDEX(OnCallIndirectExpr, "sig_index", "table_index") DEFINE_INDEX_DESC(OnCatchExpr, "event_index"); +DEFINE0(OnCatchAllExpr); DEFINE_OPCODE(OnCompareExpr) DEFINE_OPCODE(OnConvertExpr) DEFINE_INDEX_DESC(OnDelegateExpr, "depth"); diff --git a/src/binary-reader-logging.h b/src/binary-reader-logging.h index 30dc0712..70dcbae6 100644 --- a/src/binary-reader-logging.h +++ b/src/binary-reader-logging.h @@ -164,6 +164,7 @@ class BinaryReaderLogging : public BinaryReaderDelegate { Index default_target_depth) override; Result OnCallExpr(Index func_index) override; Result OnCatchExpr(Index event_index) override; + Result OnCatchAllExpr() override; Result OnCallIndirectExpr(Index sig_index, Index table_index) override; Result OnCompareExpr(Opcode opcode) override; Result OnConvertExpr(Opcode opcode) override; diff --git a/src/binary-reader-nop.h b/src/binary-reader-nop.h index 1f29a670..f72dbf10 100644 --- a/src/binary-reader-nop.h +++ b/src/binary-reader-nop.h @@ -234,6 +234,7 @@ class BinaryReaderNop : public BinaryReaderDelegate { Result OnCallExpr(Index func_index) override { return Result::Ok; } Result OnCallIndirectExpr(Index sig_index, Index table_index) override { return Result::Ok; } Result OnCatchExpr(Index event_index) override { return Result::Ok; } + Result OnCatchAllExpr() override { return Result::Ok; } Result OnCompareExpr(Opcode opcode) override { return Result::Ok; } Result OnConvertExpr(Opcode opcode) override { return Result::Ok; } Result OnDelegateExpr(Index depth) override { return Result::Ok; } diff --git a/src/binary-reader-objdump.cc b/src/binary-reader-objdump.cc index f03283e7..11fba30b 100644 --- a/src/binary-reader-objdump.cc +++ b/src/binary-reader-objdump.cc @@ -596,6 +596,7 @@ void BinaryReaderObjdumpDisassemble::LogOpcode(size_t data_size, switch (current_opcode) { case Opcode::Else: case Opcode::Catch: + case Opcode::CatchAll: case Opcode::Unwind: indent_level--; default: diff --git a/src/binary-reader.cc b/src/binary-reader.cc index 495de306..9b365e87 100644 --- a/src/binary-reader.cc +++ b/src/binary-reader.cc @@ -1341,6 +1341,12 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) { break; } + case Opcode::CatchAll: { + CALLBACK(OnCatchAllExpr); + CALLBACK(OnOpcodeBare); + break; + } + case Opcode::Unwind: { CALLBACK0(OnUnwindExpr); CALLBACK0(OnOpcodeBare); diff --git a/src/binary-reader.h b/src/binary-reader.h index 6ba4c9b7..19643aa8 100644 --- a/src/binary-reader.h +++ b/src/binary-reader.h @@ -231,6 +231,7 @@ class BinaryReaderDelegate { virtual Result OnCallExpr(Index func_index) = 0; virtual Result OnCallIndirectExpr(Index sig_index, Index table_index) = 0; virtual Result OnCatchExpr(Index event_index) = 0; + virtual Result OnCatchAllExpr() = 0; virtual Result OnCompareExpr(Opcode opcode) = 0; virtual Result OnConvertExpr(Opcode opcode) = 0; virtual Result OnDelegateExpr(Index depth) = 0; diff --git a/src/binary-writer.cc b/src/binary-writer.cc index 6ef3e71d..c744aca4 100644 --- a/src/binary-writer.cc +++ b/src/binary-writer.cc @@ -976,7 +976,7 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) { case TryKind::Catch: for (const Catch& catch_ : try_expr->catches) { if (catch_.IsCatchAll()) { - WriteOpcode(stream_, Opcode::Else); + WriteOpcode(stream_, Opcode::CatchAll); } else { WriteOpcode(stream_, Opcode::Catch); WriteU32Leb128(stream_, GetEventVarDepth(&catch_.var), diff --git a/src/interp/interp.cc b/src/interp/interp.cc index ce1897bb..5988be1e 100644 --- a/src/interp/interp.cc +++ b/src/interp/interp.cc @@ -1736,6 +1736,7 @@ RunResult Thread::StepInternal(Trap::Ptr* out_trap) { case O::Try: case O::Catch: + case O::CatchAll: case O::Unwind: case O::Delegate: case O::Throw: diff --git a/src/interp/istream.cc b/src/interp/istream.cc index 6c531a88..6e956675 100644 --- a/src/interp/istream.cc +++ b/src/interp/istream.cc @@ -693,6 +693,7 @@ Instr Istream::Read(Offset* offset) const { case Opcode::Block: case Opcode::Catch: + case Opcode::CatchAll: case Opcode::Delegate: case Opcode::Else: case Opcode::End: diff --git a/src/opcode-code-table.c b/src/opcode-code-table.c index 6a746c5e..c3e06d03 100644 --- a/src/opcode-code-table.c +++ b/src/opcode-code-table.c @@ -27,7 +27,6 @@ typedef enum WabtOpcodeEnum { #include "opcode.def" #undef WABT_OPCODE Invalid, - CatchAll = Else, } WabtOpcodeEnum; WABT_STATIC_ASSERT(Invalid <= WABT_OPCODE_CODE_TABLE_SIZE); diff --git a/src/opcode.def b/src/opcode.def index 2156f118..0c661c19 100644 --- a/src/opcode.def +++ b/src/opcode.def @@ -56,6 +56,7 @@ WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x11, CallIndirect, "call_indirect WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x12, ReturnCall, "return_call", "") WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x13, ReturnCallIndirect, "return_call_indirect", "") WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x18, Delegate, "delegate", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x19, CatchAll, "catch_all", "") WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x1a, Drop, "drop", "") WABT_OPCODE(___, ___, ___, I32, 0, 0, 0x1b, Select, "select", "") WABT_OPCODE(___, ___, ___, I32, 0, 0, 0x1c, SelectT, "select", "") diff --git a/src/opcode.h b/src/opcode.h index 80d3181b..94cd4cb8 100644 --- a/src/opcode.h +++ b/src/opcode.h @@ -39,7 +39,6 @@ struct Opcode { #include "src/opcode.def" #undef WABT_OPCODE Invalid, - CatchAll = Else, }; // Static opcode objects. diff --git a/src/type-checker.cc b/src/type-checker.cc index 9136442b..40325fac 100644 --- a/src/type-checker.cc +++ b/src/type-checker.cc @@ -71,28 +71,26 @@ Result TypeChecker::GetLabel(Index depth, Label** out_label) { } Result TypeChecker::GetRethrowLabel(Index depth, Label** out_label) { - Index cur = 0, catches = 0; - std::string candidates; + if (Failed(GetLabel(depth, out_label))) { + return Result::Error; + } + + if ((*out_label)->label_type == LabelType::Catch) { + return Result::Ok; + } - while (cur < label_stack_.size()) { - *out_label = &label_stack_[label_stack_.size() - cur - 1]; - - if ((*out_label)->label_type == LabelType::Catch) { - if (catches == depth) { - return Result::Ok; - } else { - if (!candidates.empty()) { - candidates.append(", "); - } - candidates.append(std::to_string(catches)); - catches++; + std::string candidates; + for (Index idx = 0; idx < label_stack_.size(); idx++) { + LabelType type = label_stack_[label_stack_.size() - idx - 1].label_type; + if (type == LabelType::Catch) { + if (!candidates.empty()) { + candidates.append(", "); } + candidates.append(std::to_string(idx)); } - - cur++; } - if (catches == 0) { + if (candidates.empty()) { PrintError("rethrow not in try catch block"); } else { PrintError("invalid rethrow depth: %" PRIindex " (catches: %s)", depth, diff --git a/src/wat-writer.cc b/src/wat-writer.cc index fd102130..cdea3b1b 100644 --- a/src/wat-writer.cc +++ b/src/wat-writer.cc @@ -881,9 +881,7 @@ Result WatWriter::ExprVisitorDelegate::OnCatchExpr( TryExpr* expr, Catch* catch_) { writer_->Dedent(); if (catch_->IsCatchAll()) { - // We use a literal instead of doing GetName() on the opcode because - // `else` and `catch_all` share an opcode. - writer_->WritePutsNewline("catch_all"); + writer_->WritePutsNewline(Opcode::CatchAll_Opcode.GetName()); } else { writer_->WritePutsSpace(Opcode::Catch_Opcode.GetName()); writer_->WriteVar(catch_->var, NextChar::Newline); |