Skip to content

Commit

Permalink
Share reading/validation code between elem exprs & other const exprs
Browse files Browse the repository at this point in the history
This continues the work from #1783 and reduces special handling of elem
exprs, by treating them the same as other const expressions (init
expressions).

Fixes #2201 (now allows global.get in an elem expr)
  • Loading branch information
keithw committed Aug 30, 2023
1 parent e7c0309 commit 3fca756
Show file tree
Hide file tree
Showing 39 changed files with 318 additions and 255 deletions.
5 changes: 2 additions & 3 deletions include/wabt/binary-reader-logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,8 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
Result EndElemSegmentInitExpr(Index index) override;
Result OnElemSegmentElemType(Index index, Type elem_type) override;
Result OnElemSegmentElemExprCount(Index index, Index count) override;
Result OnElemSegmentElemExpr_RefNull(Index segment_index, Type type) override;
Result OnElemSegmentElemExpr_RefFunc(Index segment_index,
Index func_index) override;
Result BeginElemExpr(Index elem_index, Index expr_index) override;
Result EndElemExpr(Index elem_index, Index expr_index) override;
Result EndElemSegment(Index index) override;
Result EndElemSection() override;

Expand Down
6 changes: 2 additions & 4 deletions include/wabt/binary-reader-nop.h
Original file line number Diff line number Diff line change
Expand Up @@ -370,12 +370,10 @@ class BinaryReaderNop : public BinaryReaderDelegate {
Result OnElemSegmentElemExprCount(Index index, Index count) override {
return Result::Ok;
}
Result OnElemSegmentElemExpr_RefNull(Index segment_index,
Type type) override {
Result BeginElemExpr(Index elem_index, Index expr_index) override {
return Result::Ok;
}
Result OnElemSegmentElemExpr_RefFunc(Index segment_index,
Index func_index) override {
Result EndElemExpr(Index elem_index, Index expr_index) override {
return Result::Ok;
}
Result EndElemSegment(Index index) override { return Result::Ok; }
Expand Down
6 changes: 2 additions & 4 deletions include/wabt/binary-reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,8 @@ class BinaryReaderDelegate {
virtual Result EndElemSegmentInitExpr(Index index) = 0;
virtual Result OnElemSegmentElemType(Index index, Type elem_type) = 0;
virtual Result OnElemSegmentElemExprCount(Index index, Index count) = 0;
virtual Result OnElemSegmentElemExpr_RefNull(Index segment_index,
Type type) = 0;
virtual Result OnElemSegmentElemExpr_RefFunc(Index segment_index,
Index func_index) = 0;
virtual Result BeginElemExpr(Index elem_index, Index expr_index) = 0;
virtual Result EndElemExpr(Index elem_index, Index expr_index) = 0;
virtual Result EndElemSegment(Index index) = 0;
virtual Result EndElemSection() = 0;

Expand Down
10 changes: 2 additions & 8 deletions include/wabt/interp/interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ using ExternKind = ExternalKind;
enum class Mutability { Const, Var };
enum class TagAttr { Exception };
using SegmentMode = SegmentKind;
enum class ElemKind { RefNull, RefFunc };

enum class ObjectKind {
Null,
Expand Down Expand Up @@ -359,13 +358,8 @@ struct DataDesc {
FuncDesc init_func;
};

struct ElemExpr {
ElemKind kind;
Index index;
};

struct ElemDesc {
std::vector<ElemExpr> elements;
std::vector<FuncDesc> elements;
ValueType type;
SegmentMode mode;
Index table_index;
Expand Down Expand Up @@ -972,7 +966,7 @@ class Tag : public Extern {

class ElemSegment {
public:
explicit ElemSegment(const ElemDesc*, RefPtr<Instance>&);
explicit ElemSegment(Store& store, const ElemDesc*, RefPtr<Instance>&);

bool IsValidRange(u32 offset, u32 size) const;
void Drop();
Expand Down
3 changes: 0 additions & 3 deletions include/wabt/shared-validator.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@ class SharedValidator {

Result OnElemSegment(const Location&, Var table_var, SegmentKind);
Result OnElemSegmentElemType(const Location&, Type elem_type);
Result OnElemSegmentElemExpr_RefNull(const Location&, Type type);
Result OnElemSegmentElemExpr_RefFunc(const Location&, Var func_var);
Result OnElemSegmentElemExpr_Other(const Location&);

void OnDataCount(Index count);
Result OnDataSegment(const Location&, Var memory_var, SegmentKind);
Expand Down
2 changes: 1 addition & 1 deletion include/wabt/type-checker.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class TypeChecker {
Result OnTableGrow(Type elem_type);
Result OnTableSize();
Result OnTableFill(Type elem_type);
Result OnRefFuncExpr(Index func_type);
Result OnRefFuncExpr(Index func_type, bool force_generic_funcref);
Result OnRefNullExpr(Type type);
Result OnRefIsNullExpr();
Result OnRethrow(Index depth);
Expand Down
31 changes: 10 additions & 21 deletions src/binary-reader-ir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,8 @@ class BinaryReaderIR : public BinaryReaderNop {
Result EndElemSegmentInitExpr(Index index) override;
Result OnElemSegmentElemType(Index index, Type elem_type) override;
Result OnElemSegmentElemExprCount(Index index, Index count) override;
Result OnElemSegmentElemExpr_RefNull(Index segment_index, Type type) override;
Result OnElemSegmentElemExpr_RefFunc(Index segment_index,
Index func_index) override;
Result BeginElemExpr(Index elem_index, Index expr_index) override;
Result EndElemExpr(Index elem_index, Index expr_index) override;

Result OnDataSegmentCount(Index count) override;
Result BeginDataSegment(Index index,
Expand Down Expand Up @@ -1350,26 +1349,16 @@ Result BinaryReaderIR::OnElemSegmentElemExprCount(Index index, Index count) {
return Result::Ok;
}

Result BinaryReaderIR::OnElemSegmentElemExpr_RefNull(Index segment_index,
Type type) {
assert(segment_index == module_->elem_segments.size() - 1);
ElemSegment* segment = module_->elem_segments[segment_index];
Location loc = GetLocation();
ExprList init_expr;
init_expr.push_back(std::make_unique<RefNullExpr>(type, loc));
segment->elem_exprs.push_back(std::move(init_expr));
return Result::Ok;
Result BinaryReaderIR::BeginElemExpr(Index elem_index, Index expr_index) {
assert(elem_index == module_->elem_segments.size() - 1);
ElemSegment* segment = module_->elem_segments[elem_index];
assert(expr_index == segment->elem_exprs.size());
segment->elem_exprs.emplace_back();
return BeginInitExpr(&segment->elem_exprs.back());
}

Result BinaryReaderIR::OnElemSegmentElemExpr_RefFunc(Index segment_index,
Index func_index) {
assert(segment_index == module_->elem_segments.size() - 1);
ElemSegment* segment = module_->elem_segments[segment_index];
Location loc = GetLocation();
ExprList init_expr;
init_expr.push_back(std::make_unique<RefFuncExpr>(Var(func_index, loc), loc));
segment->elem_exprs.push_back(std::move(init_expr));
return Result::Ok;
Result BinaryReaderIR::EndElemExpr(Index elem_index, Index expr_index) {
return EndInitExpr();
}

Result BinaryReaderIR::OnDataSegmentCount(Index count) {
Expand Down
4 changes: 2 additions & 2 deletions src/binary-reader-logging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -850,8 +850,8 @@ DEFINE_INDEX(OnElemSegmentCount)
DEFINE_INDEX(BeginElemSegmentInitExpr)
DEFINE_INDEX(EndElemSegmentInitExpr)
DEFINE_INDEX_INDEX(OnElemSegmentElemExprCount, "index", "count")
DEFINE_INDEX_TYPE(OnElemSegmentElemExpr_RefNull)
DEFINE_INDEX_INDEX(OnElemSegmentElemExpr_RefFunc, "index", "func_index")
DEFINE_INDEX_INDEX(BeginElemExpr, "elem_index", "expr_index")
DEFINE_INDEX_INDEX(EndElemExpr, "elem_index", "expr_index")
DEFINE_INDEX(EndElemSegment)
DEFINE_END(EndElemSection)

Expand Down
96 changes: 57 additions & 39 deletions src/binary-reader-objdump.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1093,9 +1093,6 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase {
uint8_t flags) override;
Result OnElemSegmentElemType(Index index, Type elem_type) override;
Result OnElemSegmentElemExprCount(Index index, Index count) override;
Result OnElemSegmentElemExpr_RefNull(Index segment_index, Type type) override;
Result OnElemSegmentElemExpr_RefFunc(Index segment_index,
Index func_index) override;

void BeginInitExpr() { current_init_expr_.insts.clear(); }

Expand Down Expand Up @@ -1123,6 +1120,18 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase {

Result EndGlobalInitExpr(Index index) override { return EndInitExpr(); }

Result BeginElemExpr(Index elem_index, Index expr_index) override {
reading_elem_expr_ = true;
elem_index_ = expr_index;
BeginInitExpr();
return Result::Ok;
}

Result EndElemExpr(Index elem_index, Index expr_index) override {
assert(expr_index == elem_index_);
return EndInitExpr();
}

Result OnDataSegmentCount(Index count) override;
Result BeginDataSegment(Index index,
Index memory_index,
Expand Down Expand Up @@ -1209,6 +1218,8 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase {
Result OnI64ConstExpr(uint64_t value) override;
Result OnF32ConstExpr(uint32_t value) override;
Result OnF64ConstExpr(uint64_t value) override;
Result OnRefFuncExpr(Index func_index) override;
Result OnRefNullExpr(Type type) override;
Result OnGlobalGetExpr(Index global_index) override;
Result OnCodeMetadataCount(Index function_index, Index count) override;
Result OnCodeMetadata(Offset code_offset,
Expand All @@ -1221,7 +1232,9 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase {
void PrintDetails(const char* fmt, ...);
Result PrintSymbolFlags(uint32_t flags);
Result PrintSegmentFlags(uint32_t flags);
void PrintInitExpr(const InitExpr& expr, bool as_unsigned = false);
void PrintInitExpr(const InitExpr& expr,
bool as_unsigned = false,
bool with_prefix = true);
Result OnCount(Index count);

std::unique_ptr<FileStream> out_stream_;
Expand All @@ -1231,6 +1244,7 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase {
bool reading_elem_init_expr_ = false;
bool reading_data_init_expr_ = false;
bool reading_global_init_expr_ = false;
bool reading_elem_expr_ = false;
InitExpr current_init_expr_;
uint8_t data_flags_ = 0;
uint8_t elem_flags_ = 0;
Expand All @@ -1240,7 +1254,7 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase {

bool ReadingInitExpr() {
return reading_elem_init_expr_ || reading_data_init_expr_ ||
reading_global_init_expr_;
reading_global_init_expr_ || reading_elem_expr_;
}
};

Expand Down Expand Up @@ -1644,27 +1658,6 @@ Result BinaryReaderObjdump::OnExport(Index index,
return Result::Ok;
}

Result BinaryReaderObjdump::OnElemSegmentElemExpr_RefNull(Index segment_index,
Type type) {
PrintDetails(" - elem[%" PRIu64 "] = ref.null %s\n",
elem_offset_ + elem_index_, type.GetName().c_str());
elem_index_++;
return Result::Ok;
}

Result BinaryReaderObjdump::OnElemSegmentElemExpr_RefFunc(Index segment_index,
Index func_index) {
PrintDetails(" - elem[%" PRIu64 "] = func[%" PRIindex "]",
elem_offset_ + elem_index_, func_index);
auto name = GetFunctionName(func_index);
if (!name.empty()) {
PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
}
PrintDetails("\n");
elem_index_++;
return Result::Ok;
}

Result BinaryReaderObjdump::OnElemSegmentCount(Index count) {
return OnCount(count);
}
Expand Down Expand Up @@ -1711,14 +1704,19 @@ Result BinaryReaderObjdump::BeginGlobal(Index index, Type type, bool mutable_) {
}

void BinaryReaderObjdump::PrintInitExpr(const InitExpr& expr,
bool as_unsigned) {
bool as_unsigned,
bool with_prefix) {
assert(expr.insts.size() > 0);

if (with_prefix) {
PrintDetails(" - init ");
}

// We have two different way to print init expressions. One for
// extended expressions involving more than one instruction, and
// a short form for the more traditional single instruction form.
if (expr.insts.size() > 1) {
PrintDetails(" - init (");
PrintDetails("(");
bool first = true;
for (auto& inst : expr.insts) {
if (!first) {
Expand Down Expand Up @@ -1765,39 +1763,39 @@ void BinaryReaderObjdump::PrintInitExpr(const InitExpr& expr,
switch (expr.type) {
case InitExprType::I32:
if (as_unsigned) {
PrintDetails(" - init i32=%u\n", expr.insts[0].imm.i32);
PrintDetails("i32=%u\n", expr.insts[0].imm.i32);
} else {
PrintDetails(" - init i32=%d\n", expr.insts[0].imm.i32);
PrintDetails("i32=%d\n", expr.insts[0].imm.i32);
}
break;
case InitExprType::I64:
if (as_unsigned) {
PrintDetails(" - init i64=%" PRIu64 "\n", expr.insts[0].imm.i64);
PrintDetails("i64=%" PRIu64 "\n", expr.insts[0].imm.i64);
} else {
PrintDetails(" - init i64=%" PRId64 "\n", expr.insts[0].imm.i64);
PrintDetails("i64=%" PRId64 "\n", expr.insts[0].imm.i64);
}
break;
case InitExprType::F64: {
char buffer[WABT_MAX_DOUBLE_HEX];
WriteDoubleHex(buffer, sizeof(buffer), expr.insts[0].imm.f64);
PrintDetails(" - init f64=%s\n", buffer);
PrintDetails("f64=%s\n", buffer);
break;
}
case InitExprType::F32: {
char buffer[WABT_MAX_FLOAT_HEX];
WriteFloatHex(buffer, sizeof(buffer), expr.insts[0].imm.f32);
PrintDetails(" - init f32=%s\n", buffer);
PrintDetails("f32=%s\n", buffer);
break;
}
case InitExprType::V128: {
PrintDetails(
" - init v128=0x%08x 0x%08x 0x%08x 0x%08x \n",
"v128=0x%08x 0x%08x 0x%08x 0x%08x \n",
expr.insts[0].imm.v128_v.u32(0), expr.insts[0].imm.v128_v.u32(1),
expr.insts[0].imm.v128_v.u32(2), expr.insts[0].imm.v128_v.u32(3));
break;
}
case InitExprType::Global: {
PrintDetails(" - init global=%" PRIindex, expr.insts[0].imm.index);
PrintDetails("global=%" PRIindex, expr.insts[0].imm.index);
std::string_view name = GetGlobalName(expr.insts[0].imm.index);
if (!name.empty()) {
PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
Expand All @@ -1806,7 +1804,7 @@ void BinaryReaderObjdump::PrintInitExpr(const InitExpr& expr,
break;
}
case InitExprType::FuncRef: {
PrintDetails(" - init ref.func:%" PRIindex, expr.insts[0].imm.index);
PrintDetails("ref.func:%" PRIindex, expr.insts[0].imm.index);
std::string_view name = GetFunctionName(expr.insts[0].imm.index);
if (!name.empty()) {
PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
Expand All @@ -1815,8 +1813,7 @@ void BinaryReaderObjdump::PrintInitExpr(const InitExpr& expr,
break;
}
case InitExprType::NullRef:
PrintDetails(" - init null\n");
break;
PrintDetails("ref.null %s\n", expr.insts[0].imm.type.GetName().c_str());
break;
}
}
Expand Down Expand Up @@ -1846,6 +1843,11 @@ Result BinaryReaderObjdump::EndInitExpr() {
} else if (reading_global_init_expr_) {
reading_global_init_expr_ = false;
PrintInitExpr(current_init_expr_);
} else if (reading_elem_expr_) {
reading_elem_expr_ = false;
PrintDetails(" - elem[%" PRIu64 "] = ", elem_offset_ + elem_index_);
PrintInitExpr(current_init_expr_, /*as_unsigned=*/false,
/*with_prefix=*/false);
} else {
WABT_UNREACHABLE;
}
Expand Down Expand Up @@ -1884,6 +1886,22 @@ Result BinaryReaderObjdump::OnF64ConstExpr(uint64_t value) {
return Result::Ok;
}

Result BinaryReaderObjdump::OnRefFuncExpr(Index func_index) {
if (ReadingInitExpr()) {
current_init_expr_.type = InitExprType::FuncRef;
current_init_expr_.insts.back().imm.index = func_index;
}
return Result::Ok;
}

Result BinaryReaderObjdump::OnRefNullExpr(Type type) {
if (ReadingInitExpr()) {
current_init_expr_.type = InitExprType::NullRef;
current_init_expr_.insts.back().imm.type = type;
}
return Result::Ok;
}

Result BinaryReaderObjdump::OnOpcode(Opcode opcode) {
BinaryReaderObjdumpBase::OnOpcode(opcode);
if (ReadingInitExpr() && opcode != Opcode::End) {
Expand Down
Loading

0 comments on commit 3fca756

Please sign in to comment.