summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAsumu Takikawa <asumu@igalia.com>2021-02-18 07:09:32 -0800
committerGitHub <noreply@github.com>2021-02-18 07:09:32 -0800
commitffb22e3c900e8246d806d2e9a765dc14251b33e8 (patch)
tree45c7d2caef95ac03b237e8b3c2f29fe1db9686b6 /src
parent036a632a24679062e7fc891e7743195139bfa0a9 (diff)
downloadwabt-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.cc7
-rw-r--r--src/binary-reader-logging.cc1
-rw-r--r--src/binary-reader-logging.h1
-rw-r--r--src/binary-reader-nop.h1
-rw-r--r--src/binary-reader-objdump.cc1
-rw-r--r--src/binary-reader.cc6
-rw-r--r--src/binary-reader.h1
-rw-r--r--src/binary-writer.cc2
-rw-r--r--src/interp/interp.cc1
-rw-r--r--src/interp/istream.cc1
-rw-r--r--src/opcode-code-table.c1
-rw-r--r--src/opcode.def1
-rw-r--r--src/opcode.h1
-rw-r--r--src/type-checker.cc32
-rw-r--r--src/wat-writer.cc4
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);