Skip to content

Commit

Permalink
binary/wat: Implement EHv4 (#2470)
Browse files Browse the repository at this point in the history
This pull request implements EHv4. Binary is mostly untested until
interp is working.
  • Loading branch information
SoniEx2 authored Nov 20, 2024
1 parent 958d0a7 commit a0b7abe
Show file tree
Hide file tree
Showing 43 changed files with 2,014 additions and 1,324 deletions.
3 changes: 3 additions & 0 deletions include/wabt/binary-reader-logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,10 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
Address alignment_log2,
Address offset) override;
Result OnThrowExpr(Index tag_index) override;
Result OnThrowRefExpr() override;
Result OnTryExpr(Type sig_type) override;
Result OnTryTableExpr(Type sig_type,
const CatchClauseVector& catches) override;
Result OnUnaryExpr(Opcode opcode) override;
Result OnTernaryExpr(Opcode opcode) override;
Result OnUnreachableExpr() override;
Expand Down
5 changes: 5 additions & 0 deletions include/wabt/binary-reader-nop.h
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,12 @@ class BinaryReaderNop : public BinaryReaderDelegate {
return Result::Ok;
}
Result OnThrowExpr(Index depth) override { return Result::Ok; }
Result OnThrowRefExpr() override { return Result::Ok; }
Result OnTryExpr(Type sig_type) override { return Result::Ok; }
Result OnTryTableExpr(Type sig_type,
const CatchClauseVector& catches) override {
return Result::Ok;
}
Result OnUnaryExpr(Opcode opcode) override { return Result::Ok; }
Result OnTernaryExpr(Opcode opcode) override { return Result::Ok; }
Result OnUnreachableExpr() override { return Result::Ok; }
Expand Down
10 changes: 10 additions & 0 deletions include/wabt/binary-reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ struct TypeMut {
};
using TypeMutVector = std::vector<TypeMut>;

struct CatchClause {
CatchKind kind;
Index tag;
Index depth;
};
using CatchClauseVector = std::vector<CatchClause>;

class BinaryReaderDelegate {
public:
struct State {
Expand Down Expand Up @@ -302,7 +309,10 @@ class BinaryReaderDelegate {
Address alignment_log2,
Address offset) = 0;
virtual Result OnThrowExpr(Index tag_index) = 0;
virtual Result OnThrowRefExpr() = 0;
virtual Result OnTryExpr(Type sig_type) = 0;
virtual Result OnTryTableExpr(Type sig_type,
const CatchClauseVector& catches) = 0;

virtual Result OnUnaryExpr(Opcode opcode) = 0;
virtual Result OnTernaryExpr(Opcode opcode) = 0;
Expand Down
8 changes: 8 additions & 0 deletions include/wabt/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ enum class LabelType {
If,
Else,
Try,
TryTable,
Catch,

First = Func,
Expand Down Expand Up @@ -239,6 +240,13 @@ enum class SegmentKind {
Declared,
};

enum class CatchKind {
Catch,
CatchRef,
CatchAll,
CatchAllRef,
};

// Used in test asserts for special expected values "nan:canonical" and
// "nan:arithmetic"
enum class ExpectedNan {
Expand Down
7 changes: 7 additions & 0 deletions include/wabt/expr-visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class ExprVisitor {
IfFalse,
Loop,
Try,
TryTable,
Catch,
};

Expand Down Expand Up @@ -73,6 +74,8 @@ class ExprVisitor::Delegate {
virtual Result OnBrExpr(BrExpr*) = 0;
virtual Result OnBrIfExpr(BrIfExpr*) = 0;
virtual Result OnBrTableExpr(BrTableExpr*) = 0;
virtual Result BeginTryTableExpr(TryTableExpr*) = 0;
virtual Result EndTryTableExpr(TryTableExpr*) = 0;
virtual Result OnCallExpr(CallExpr*) = 0;
virtual Result OnCallIndirectExpr(CallIndirectExpr*) = 0;
virtual Result OnCallRefExpr(CallRefExpr*) = 0;
Expand Down Expand Up @@ -122,6 +125,7 @@ class ExprVisitor::Delegate {
virtual Result OnDelegateExpr(TryExpr*) = 0;
virtual Result EndTryExpr(TryExpr*) = 0;
virtual Result OnThrowExpr(ThrowExpr*) = 0;
virtual Result OnThrowRefExpr(ThrowRefExpr*) = 0;
virtual Result OnRethrowExpr(RethrowExpr*) = 0;
virtual Result OnAtomicWaitExpr(AtomicWaitExpr*) = 0;
virtual Result OnAtomicFenceExpr(AtomicFenceExpr*) = 0;
Expand All @@ -147,6 +151,8 @@ class ExprVisitor::DelegateNop : public ExprVisitor::Delegate {
Result OnBrExpr(BrExpr*) override { return Result::Ok; }
Result OnBrIfExpr(BrIfExpr*) override { return Result::Ok; }
Result OnBrTableExpr(BrTableExpr*) override { return Result::Ok; }
Result BeginTryTableExpr(TryTableExpr*) override { return Result::Ok; }
Result EndTryTableExpr(TryTableExpr*) override { return Result::Ok; }
Result OnCallExpr(CallExpr*) override { return Result::Ok; }
Result OnCallIndirectExpr(CallIndirectExpr*) override { return Result::Ok; }
Result OnCallRefExpr(CallRefExpr*) override { return Result::Ok; }
Expand Down Expand Up @@ -198,6 +204,7 @@ class ExprVisitor::DelegateNop : public ExprVisitor::Delegate {
Result OnDelegateExpr(TryExpr*) override { return Result::Ok; }
Result EndTryExpr(TryExpr*) override { return Result::Ok; }
Result OnThrowExpr(ThrowExpr*) override { return Result::Ok; }
Result OnThrowRefExpr(ThrowRefExpr*) override { return Result::Ok; }
Result OnRethrowExpr(RethrowExpr*) override { return Result::Ok; }
Result OnAtomicWaitExpr(AtomicWaitExpr*) override { return Result::Ok; }
Result OnAtomicFenceExpr(AtomicFenceExpr*) override { return Result::Ok; }
Expand Down
29 changes: 28 additions & 1 deletion include/wabt/ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
#include <cstddef>
#include <cstdint>
#include <memory>
#include <set>
#include <string>
#include <string_view>
#include <type_traits>
#include <vector>
#include <set>

#include "wabt/binding-hash.h"
#include "wabt/common.h"
Expand Down Expand Up @@ -422,7 +422,9 @@ enum class ExprType {
TableFill,
Ternary,
Throw,
ThrowRef,
Try,
TryTable,
Unary,
Unreachable,

Expand Down Expand Up @@ -460,6 +462,21 @@ struct Catch {
};
using CatchVector = std::vector<Catch>;

struct TableCatch {
explicit TableCatch(const Location& loc = Location()) : loc(loc) {}
Location loc;
Var tag;
Var target;
CatchKind kind;
bool IsCatchAll() const {
return kind == CatchKind::CatchAll || kind == CatchKind::CatchAllRef;
}
bool IsRef() const {
return kind == CatchKind::CatchRef || kind == CatchKind::CatchAllRef;
}
};
using TryTableVector = std::vector<TableCatch>;

enum class TryKind { Plain, Catch, Delegate };

class Expr : public intrusive_list_base<Expr> {
Expand Down Expand Up @@ -516,6 +533,7 @@ using DropExpr = ExprMixin<ExprType::Drop>;
using NopExpr = ExprMixin<ExprType::Nop>;
using ReturnExpr = ExprMixin<ExprType::Return>;
using UnreachableExpr = ExprMixin<ExprType::Unreachable>;
using ThrowRefExpr = ExprMixin<ExprType::ThrowRef>;

using MemoryGrowExpr = MemoryExpr<ExprType::MemoryGrow>;
using MemorySizeExpr = MemoryExpr<ExprType::MemorySize>;
Expand Down Expand Up @@ -743,6 +761,15 @@ class IfExpr : public ExprMixin<ExprType::If> {
Location false_end_loc;
};

class TryTableExpr : public ExprMixin<ExprType::TryTable> {
public:
explicit TryTableExpr(const Location& loc = Location())
: ExprMixin<ExprType::TryTable>(loc) {}

Block block;
TryTableVector catches;
};

class TryExpr : public ExprMixin<ExprType::Try> {
public:
explicit TryExpr(const Location& loc = Location())
Expand Down
2 changes: 2 additions & 0 deletions include/wabt/opcode.def
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x06, Try, "try", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x07, Catch, "catch", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x08, Throw, "throw", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x09, Rethrow, "rethrow", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x0a, ThrowRef, "throw_ref", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x0b, End, "end", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x0c, Br, "br", "")
WABT_OPCODE(___, I32, ___, ___, 0, 0, 0x0d, BrIf, "br_if", "")
Expand All @@ -60,6 +61,7 @@ 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", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x1f, TryTable, "try_table", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x20, LocalGet, "local.get", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x21, LocalSet, "local.set", "")
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0x22, LocalTee, "local.tee", "")
Expand Down
4 changes: 4 additions & 0 deletions include/wabt/shared-validator.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,11 @@ class SharedValidator {
Result OnTableSize(const Location&, Var table_var);
Result OnTernary(const Location&, Opcode);
Result OnThrow(const Location&, Var tag_var);
Result OnThrowRef(const Location&);
Result OnTry(const Location&, Type sig_type);
Result BeginTryTable(const Location&, Type sig_type);
Result OnTryTableCatch(const Location&, const TableCatch&);
Result EndTryTable(const Location&, Type sig_type);
Result OnUnary(const Location&, Opcode);
Result OnUnreachable(const Location&);

Expand Down
4 changes: 4 additions & 0 deletions include/wabt/token.def
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ WABT_TOKEN(CallIndirect, "call_indirect")
WABT_TOKEN(CallRef, "call_ref")
WABT_TOKEN(Catch, "catch")
WABT_TOKEN(CatchAll, "catch_all")
WABT_TOKEN(CatchRef, "catch_ref")
WABT_TOKEN(CatchAllRef, "catch_all_ref")
WABT_TOKEN(Compare, "COMPARE")
WABT_TOKEN(Const, "CONST")
WABT_TOKEN(Convert, "CONVERT")
Expand Down Expand Up @@ -151,7 +153,9 @@ WABT_TOKEN(TableSet, "table.set")
WABT_TOKEN(TableSize, "table.size")
WABT_TOKEN(Ternary, "TERNARY")
WABT_TOKEN(Throw, "throw")
WABT_TOKEN(ThrowRef, "throw_ref")
WABT_TOKEN(Try, "try")
WABT_TOKEN(TryTable, "try_table")
WABT_TOKEN(Unary, "UNARY")
WABT_TOKEN(Unreachable, "unreachable")
WABT_TOKEN_FIRST(Opcode, AtomicFence)
Expand Down
5 changes: 5 additions & 0 deletions include/wabt/type-checker.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,12 @@ class TypeChecker {
Result OnStore(Opcode, const Limits& limits);
Result OnTernary(Opcode);
Result OnThrow(const TypeVector& sig);
Result OnThrowRef();
Result OnTry(const TypeVector& param_types, const TypeVector& result_types);
Result OnTryTableCatch(const TypeVector& sig, Index);
Result BeginTryTable(const TypeVector& param_types);
Result EndTryTable(const TypeVector& param_types,
const TypeVector& result_types);
Result OnUnary(Opcode);
Result OnUnreachable();
Result EndFunction();
Expand Down
1 change: 1 addition & 0 deletions include/wabt/wast-parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ class WastParser {
Result ParseBlock(Block*);
Result ParseExprList(ExprList*);
Result ParseExpr(ExprList*);
Result ParseTryTableCatches(TryTableVector* catches);
Result ParseCatchInstrList(CatchVector* catches);
Result ParseCatchExprList(CatchVector* catches);
Result ParseGlobalType(Global*);
Expand Down
19 changes: 19 additions & 0 deletions src/apply-names.cc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class NameApplier : public ExprVisitor::DelegateNop {
Result OnStoreExpr(StoreExpr*) override;
Result BeginTryExpr(TryExpr*) override;
Result EndTryExpr(TryExpr*) override;
Result BeginTryTableExpr(TryTableExpr*) override;
Result EndTryTableExpr(TryTableExpr*) override;
Result OnCatchExpr(TryExpr*, Catch*) override;
Result OnDelegateExpr(TryExpr*) override;
Result OnThrowExpr(ThrowExpr*) override;
Expand Down Expand Up @@ -369,6 +371,23 @@ Result NameApplier::EndTryExpr(TryExpr*) {
return Result::Ok;
}

Result NameApplier::BeginTryTableExpr(TryTableExpr* expr) {
for (TableCatch& catch_ : expr->catches) {
if (!catch_.IsCatchAll()) {
CHECK_RESULT(UseNameForTagVar(&catch_.tag));
}
std::string_view label = FindLabelByVar(&catch_.target);
UseNameForVar(label, &catch_.target);
}
PushLabel(expr->block.label);
return Result::Ok;
}

Result NameApplier::EndTryTableExpr(TryTableExpr*) {
PopLabel();
return Result::Ok;
}

Result NameApplier::OnCatchExpr(TryExpr*, Catch* expr) {
if (!expr->IsCatchAll()) {
CHECK_RESULT(UseNameForTagVar(&expr->var));
Expand Down
32 changes: 32 additions & 0 deletions src/binary-reader-ir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,10 @@ class BinaryReaderIR : public BinaryReaderNop {
Address alignment_log2,
Address offset) override;
Result OnThrowExpr(Index tag_index) override;
Result OnThrowRefExpr() override;
Result OnTryExpr(Type sig_type) override;
Result OnTryTableExpr(Type sig_type,
const CatchClauseVector& catches) override;
Result OnUnaryExpr(Opcode opcode) override;
Result OnTernaryExpr(Opcode opcode) override;
Result OnUnreachableExpr() override;
Expand Down Expand Up @@ -999,6 +1002,9 @@ Result BinaryReaderIR::OnEndExpr() {
case LabelType::Try:
cast<TryExpr>(expr)->block.end_loc = GetLocation();
break;
case LabelType::TryTable:
cast<TryTableExpr>(expr)->block.end_loc = GetLocation();
break;

case LabelType::InitExpr:
case LabelType::Func:
Expand Down Expand Up @@ -1195,6 +1201,11 @@ Result BinaryReaderIR::OnThrowExpr(Index tag_index) {
return AppendExpr(std::make_unique<ThrowExpr>(Var(tag_index, GetLocation())));
}

Result BinaryReaderIR::OnThrowRefExpr() {
module_->features_used.exceptions = true;
return AppendExpr(std::make_unique<ThrowRefExpr>());
}

Result BinaryReaderIR::OnLocalTeeExpr(Index local_index) {
return AppendExpr(
std::make_unique<LocalTeeExpr>(Var(local_index, GetLocation())));
Expand Down Expand Up @@ -1248,6 +1259,27 @@ Result BinaryReaderIR::OnCatchAllExpr() {
return AppendCatch(Catch(GetLocation()));
}

Result BinaryReaderIR::OnTryTableExpr(Type sig_type,
const CatchClauseVector& catches) {
auto expr_ptr = std::make_unique<TryTableExpr>();
TryTableExpr* expr = expr_ptr.get();
expr->catches.reserve(catches.size());
SetBlockDeclaration(&expr->block.decl, sig_type);
ExprList* expr_list = &expr->block.exprs;

for (auto& raw_catch : catches) {
TableCatch catch_;
catch_.kind = raw_catch.kind;
catch_.tag = Var(raw_catch.tag, GetLocation());
catch_.target = Var(raw_catch.depth, GetLocation());
expr->catches.push_back(std::move(catch_));
}

CHECK_RESULT(AppendExpr(std::move(expr_ptr)));
module_->features_used.exceptions = true;
return PushLabel(LabelType::TryTable, expr_list, expr);
}

Result BinaryReaderIR::OnDelegateExpr(Index depth) {
LabelNode* label = nullptr;
CHECK_RESULT(TopLabel(&label));
Expand Down
34 changes: 34 additions & 0 deletions src/binary-reader-logging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,39 @@ Result BinaryReaderLogging::OnTryExpr(Type sig_type) {
return reader_->OnTryExpr(sig_type);
}

Result BinaryReaderLogging::OnTryTableExpr(Type sig_type,
const CatchClauseVector& catches) {
LOGF("OnTryTableExpr(sig: ");
LogType(sig_type);
Index count = catches.size();
LOGF_NOINDENT(", n: %" PRIindex ", catches: [", count);

for (auto& catch_ : catches) {
auto tag = catch_.tag;
auto depth = catch_.depth;
switch (catch_.kind) {
case CatchKind::Catch:
LOGF_NOINDENT("catch %" PRIindex " %" PRIindex, tag, depth);
break;
case CatchKind::CatchRef:
LOGF_NOINDENT("catch_ref %" PRIindex " %" PRIindex, tag, depth);
break;
case CatchKind::CatchAll:
LOGF_NOINDENT("catch_all %" PRIindex, depth);
break;
case CatchKind::CatchAllRef:
LOGF_NOINDENT("catch_all_ref %" PRIindex, depth);
break;
}
if (--count != 0) {
LOGF_NOINDENT(", ");
}
}
LOGF_NOINDENT("])\n");

return reader_->OnTryTableExpr(sig_type, catches);
}

Result BinaryReaderLogging::OnSimdLaneOpExpr(Opcode opcode, uint64_t value) {
LOGF("OnSimdLaneOpExpr (lane: %" PRIu64 ")\n", value);
return reader_->OnSimdLaneOpExpr(opcode, value);
Expand Down Expand Up @@ -852,6 +885,7 @@ DEFINE_LOAD_STORE_OPCODE(OnLoadZeroExpr);
DEFINE_LOAD_STORE_OPCODE(OnStoreExpr);
DEFINE_INDEX_DESC(OnThrowExpr, "tag_index")
DEFINE0(OnUnreachableExpr)
DEFINE0(OnThrowRefExpr)
DEFINE_OPCODE(OnUnaryExpr)
DEFINE_OPCODE(OnTernaryExpr)
DEFINE_SIMD_LOAD_STORE_LANE_OPCODE(OnSimdLoadLaneExpr);
Expand Down
Loading

0 comments on commit a0b7abe

Please sign in to comment.