Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update rethrow depth handling and catch_all opcode #1608

Merged
merged 2 commits into from
Feb 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/binary-reader-ir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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));
Expand Down
1 change: 1 addition & 0 deletions src/binary-reader-logging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
1 change: 1 addition & 0 deletions src/binary-reader-logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/binary-reader-nop.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
1 change: 1 addition & 0 deletions src/binary-reader-objdump.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
6 changes: 6 additions & 0 deletions src/binary-reader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/binary-reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/binary-writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
1 change: 1 addition & 0 deletions src/interp/interp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions src/interp/istream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 0 additions & 1 deletion src/opcode-code-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/opcode.def
Original file line number Diff line number Diff line change
Expand Up @@ -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", "")
Expand Down
1 change: 0 additions & 1 deletion src/opcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ struct Opcode {
#include "src/opcode.def"
#undef WABT_OPCODE
Invalid,
CatchAll = Else,
};

// Static opcode objects.
Expand Down
32 changes: 15 additions & 17 deletions src/type-checker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 1 addition & 3 deletions src/wat-writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions test/binary/bad-multiple-catch-all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ section(CODE) {
}
(;; STDERR ;;;
error: only one catch_all allowed in try block
000001b: error: OnElseExpr callback failed
000001b: error: OnCatchAllExpr callback failed
error: only one catch_all allowed in try block
000001b: error: OnElseExpr callback failed
000001b: error: OnCatchAllExpr callback failed
;;; STDERR ;;)
87 changes: 87 additions & 0 deletions test/dump/try-catch-all.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
;;; TOOL: run-objdump
;;; ARGS0: -v --enable-exceptions
(module
(event $e (param i32))
(func
try $try1 (result i32)
nop
i32.const 7
catch_all
i32.const 8
end
drop))
(;; STDERR ;;;
0000000: 0061 736d ; WASM_BINARY_MAGIC
0000004: 0100 0000 ; WASM_BINARY_VERSION
; section "Type" (1)
0000008: 01 ; section code
0000009: 00 ; section size (guess)
000000a: 02 ; num types
; func type 0
000000b: 60 ; func
000000c: 01 ; num params
000000d: 7f ; i32
000000e: 00 ; num results
; func type 1
000000f: 60 ; func
0000010: 00 ; num params
0000011: 00 ; num results
0000009: 08 ; FIXUP section size
; section "Function" (3)
0000012: 03 ; section code
0000013: 00 ; section size (guess)
0000014: 01 ; num functions
0000015: 01 ; function 0 signature index
0000013: 02 ; FIXUP section size
; section "Event" (13)
0000016: 0d ; section code
0000017: 00 ; section size (guess)
0000018: 01 ; event count
; event 0
0000019: 00 ; event attribute
000001a: 00 ; event signature index
0000017: 03 ; FIXUP section size
; section "DataCount" (12)
000001b: 0c ; section code
000001c: 00 ; section size (guess)
000001d: 00 ; data count
000001c: 01 ; FIXUP section size
; section "Code" (10)
000001e: 0a ; section code
000001f: 00 ; section size (guess)
0000020: 01 ; num functions
; function body 0
0000021: 00 ; func body size (guess)
0000022: 00 ; local decl count
0000023: 06 ; try
0000024: 7f ; i32
0000025: 01 ; nop
0000026: 41 ; i32.const
0000027: 07 ; i32 literal
0000028: 19 ; catch_all
0000029: 41 ; i32.const
000002a: 08 ; i32 literal
000002b: 0b ; end
000002c: 1a ; drop
000002d: 0b ; end
0000021: 0c ; FIXUP func body size
000001f: 0e ; FIXUP section size
; move data: [1e, 2e) -> [1b, 2b)
; truncate to 43 (0x2b)
;;; STDERR ;;)
(;; STDOUT ;;;

try-catch-all.wasm: file format wasm 0x1

Code Disassembly:

00001f func[0]:
000020: 06 7f | try i32
000022: 01 | nop
000023: 41 07 | i32.const 7
000025: 19 | catch_all
000026: 41 08 | i32.const 8
000028: 0b | end
000029: 1a | drop
00002a: 0b | end
;;; STDOUT ;;)
2 changes: 1 addition & 1 deletion test/gen-wasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@

# exceptions
"try": 0x06,
"catch_all": 0x05,
"catch_all": 0x19,
}

keywords = {
Expand Down
49 changes: 41 additions & 8 deletions test/typecheck/bad-rethrow-depth.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,52 @@
(module
(event $e)
(func
try
try $l1
nop
catch $e
block
try
block $l2
try $l3
nop
catch $e
rethrow 2
try $l4
rethrow $l4
rethrow 0
rethrow $l2
rethrow 2
catch $e
rethrow $l2
rethrow 2
end
end
end
end))
end)

(func
try
unwind
rethrow 0
end)
)
(;; STDERR ;;;
out/test/typecheck/bad-rethrow-depth.txt:14:11: error: invalid rethrow depth: 2 (catches: 0, 1)
rethrow 2
^^^^^^^
out/test/typecheck/bad-rethrow-depth.txt:15:13: error: invalid rethrow depth: 0 (catches: 1, 3)
rethrow $l4
^^^^^^^
out/test/typecheck/bad-rethrow-depth.txt:16:13: error: invalid rethrow depth: 0 (catches: 1, 3)
rethrow 0
^^^^^^^
out/test/typecheck/bad-rethrow-depth.txt:17:13: error: invalid rethrow depth: 2 (catches: 1, 3)
rethrow $l2
^^^^^^^
out/test/typecheck/bad-rethrow-depth.txt:18:13: error: invalid rethrow depth: 2 (catches: 1, 3)
rethrow 2
^^^^^^^
out/test/typecheck/bad-rethrow-depth.txt:20:13: error: invalid rethrow depth: 2 (catches: 0, 1, 3)
rethrow $l2
^^^^^^^
out/test/typecheck/bad-rethrow-depth.txt:21:13: error: invalid rethrow depth: 2 (catches: 0, 1, 3)
rethrow 2
^^^^^^^
out/test/typecheck/bad-rethrow-depth.txt:30:7: error: rethrow not in try catch block
rethrow 0
^^^^^^^
;;; STDERR ;;)
Loading