diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc index 723c12ebd..85cb802cf 100644 --- a/src/binary-reader-ir.cc +++ b/src/binary-reader-ir.cc @@ -204,7 +204,7 @@ class BinaryReaderIR : public BinaryReaderNop { Result OnElemSegmentCount(Index count) override; Result BeginElemSegment(Index index, Index table_index, - bool passive, + uint8_t flags, Type elem_type) override; Result BeginElemSegmentInitExpr(Index index) override; Result EndElemSegmentInitExpr(Index index) override; @@ -214,7 +214,9 @@ class BinaryReaderIR : public BinaryReaderNop { Index func_index) override; Result OnDataSegmentCount(Index count) override; - Result BeginDataSegment(Index index, Index memory_index, bool passive) override; + Result BeginDataSegment(Index index, + Index memory_index, + uint8_t flags) override; Result BeginDataSegmentInitExpr(Index index) override; Result EndDataSegmentInitExpr(Index index) override; Result OnDataSegmentData(Index index, @@ -1003,12 +1005,12 @@ Result BinaryReaderIR::OnElemSegmentCount(Index count) { Result BinaryReaderIR::BeginElemSegment(Index index, Index table_index, - bool passive, + uint8_t flags, Type elem_type) { auto field = MakeUnique(GetLocation()); ElemSegment& elem_segment = field->elem_segment; elem_segment.table_var = Var(table_index, GetLocation()); - elem_segment.passive = passive; + elem_segment.flags = flags; elem_segment.elem_type = elem_type; module_->AppendField(std::move(field)); return Result::Ok; @@ -1059,11 +1061,11 @@ Result BinaryReaderIR::OnDataSegmentCount(Index count) { Result BinaryReaderIR::BeginDataSegment(Index index, Index memory_index, - bool passive) { + uint8_t flags) { auto field = MakeUnique(GetLocation()); DataSegment& data_segment = field->data_segment; data_segment.memory_var = Var(memory_index, GetLocation()); - data_segment.passive = passive; + data_segment.flags = flags; module_->AppendField(std::move(field)); return Result::Ok; } diff --git a/src/binary-reader-logging.cc b/src/binary-reader-logging.cc index 706bda6eb..9a23337a4 100644 --- a/src/binary-reader-logging.cc +++ b/src/binary-reader-logging.cc @@ -363,12 +363,12 @@ Result BinaryReaderLogging::OnSimdShuffleOpExpr(Opcode opcode, v128 value) { Result BinaryReaderLogging::BeginElemSegment(Index index, Index table_index, - bool passive, + uint8_t flags, Type elem_type) { LOGF("BeginElemSegment(index: %" PRIindex ", table_index: %" PRIindex - ", passive: %s, elem_type: %s)\n", - index, table_index, passive ? "true" : "false", GetTypeName(elem_type)); - return reader_->BeginElemSegment(index, table_index, passive, elem_type); + ", flags: %d, elem_type: %s)\n", + index, table_index, flags, GetTypeName(elem_type)); + return reader_->BeginElemSegment(index, table_index, flags, elem_type); } Result BinaryReaderLogging::OnDataSegmentData(Index index, @@ -623,12 +623,13 @@ Result BinaryReaderLogging::OnComdatEntry(ComdatType kind, Index index) { return reader_->name(value0, value1); \ } -#define DEFINE_INDEX_INDEX_BOOL(name, desc0, desc1, desc2) \ - Result BinaryReaderLogging::name(Index value0, Index value1, bool value2) { \ - LOGF(#name "(" desc0 ": %" PRIindex ", " desc1 ": %" PRIindex \ - ", " desc2 ": %s)\n", \ - value0, value1, value2 ? "true" : "false"); \ - return reader_->name(value0, value1, value2); \ +#define DEFINE_INDEX_INDEX_U8(name, desc0, desc1, desc2) \ + Result BinaryReaderLogging::name(Index value0, Index value1, \ + uint8_t value2) { \ + LOGF(#name "(" desc0 ": %" PRIindex ", " desc1 ": %" PRIindex ", " desc2 \ + ": %d)\n", \ + value0, value1, value2); \ + return reader_->name(value0, value1, value2); \ } #define DEFINE_OPCODE(name) \ @@ -761,7 +762,7 @@ DEFINE_END(EndElemSection) DEFINE_BEGIN(BeginDataSection) DEFINE_INDEX(OnDataSegmentCount) -DEFINE_INDEX_INDEX_BOOL(BeginDataSegment, "index", "memory_index", "passive") +DEFINE_INDEX_INDEX_U8(BeginDataSegment, "index", "memory_index", "flags") DEFINE_INDEX(BeginDataSegmentInitExpr) DEFINE_INDEX(EndDataSegmentInitExpr) DEFINE_INDEX(EndDataSegment) diff --git a/src/binary-reader-logging.h b/src/binary-reader-logging.h index 4f187ba80..901ef79a5 100644 --- a/src/binary-reader-logging.h +++ b/src/binary-reader-logging.h @@ -230,7 +230,7 @@ class BinaryReaderLogging : public BinaryReaderDelegate { Result OnElemSegmentCount(Index count) override; Result BeginElemSegment(Index index, Index table_index, - bool passive, + uint8_t flags, Type elem_type) override; Result BeginElemSegmentInitExpr(Index index) override; Result EndElemSegmentInitExpr(Index index) override; @@ -243,7 +243,9 @@ class BinaryReaderLogging : public BinaryReaderDelegate { Result BeginDataSection(Offset size) override; Result OnDataSegmentCount(Index count) override; - Result BeginDataSegment(Index index, Index memory_index, bool passive) override; + Result BeginDataSegment(Index index, + Index memory_index, + uint8_t flags) override; Result BeginDataSegmentInitExpr(Index index) override; Result EndDataSegmentInitExpr(Index index) override; Result OnDataSegmentData(Index index, diff --git a/src/binary-reader-nop.h b/src/binary-reader-nop.h index fb7ddc99c..eae1fc084 100644 --- a/src/binary-reader-nop.h +++ b/src/binary-reader-nop.h @@ -301,7 +301,7 @@ class BinaryReaderNop : public BinaryReaderDelegate { Result OnElemSegmentCount(Index count) override { return Result::Ok; } Result BeginElemSegment(Index index, Index table_index, - bool passive, + uint8_t flags, Type elem_type) override { return Result::Ok; } @@ -323,7 +323,9 @@ class BinaryReaderNop : public BinaryReaderDelegate { /* Data section */ Result BeginDataSection(Offset size) override { return Result::Ok; } Result OnDataSegmentCount(Index count) override { return Result::Ok; } - Result BeginDataSegment(Index index, Index memory_index, bool passive) override { + Result BeginDataSegment(Index index, + Index memory_index, + uint8_t flags) override { return Result::Ok; } Result BeginDataSegmentInitExpr(Index index) override { return Result::Ok; } diff --git a/src/binary-reader-objdump.cc b/src/binary-reader-objdump.cc index 417fdf086..69f3a2c98 100644 --- a/src/binary-reader-objdump.cc +++ b/src/binary-reader-objdump.cc @@ -791,7 +791,7 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase { Result OnElemSegmentCount(Index count) override; Result BeginElemSegment(Index index, Index table_index, - bool passive, + uint8_t flags, Type elem_type) override; Result OnElemSegmentElemExprCount(Index index, Index count) override; Result OnElemSegmentElemExpr_RefNull(Index segment_index) override; @@ -810,7 +810,7 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase { Result OnDataSegmentCount(Index count) override; Result BeginDataSegment(Index index, Index memory_index, - bool passive) override; + uint8_t flags) override; Result OnDataSegmentData(Index index, const void* data, Address size) override; @@ -896,8 +896,8 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase { bool in_elem_section_ = false; InitExpr data_init_expr_; InitExpr elem_init_expr_; - bool data_is_passive_ = false; - bool elem_is_passive_ = false; + uint8_t data_flags_ = 0; + uint8_t elem_flags_ = 0; Index data_mem_index_ = 0; uint32_t data_offset_ = 0; uint32_t elem_offset_ = 0; @@ -1264,20 +1264,21 @@ Result BinaryReaderObjdump::OnElemSegmentCount(Index count) { Result BinaryReaderObjdump::BeginElemSegment(Index index, Index table_index, - bool passive, + uint8_t flags, Type elem_type) { table_index_ = table_index; elem_index_ = 0; - elem_is_passive_ = passive; + elem_flags_ = flags; return Result::Ok; } Result BinaryReaderObjdump::OnElemSegmentElemExprCount(Index index, Index count) { - PrintDetails(" - segment[%" PRIindex "] table=%" PRIindex " count=%" PRIindex, - index, table_index_, count); - if (elem_is_passive_) { - PrintDetails(" passive\n"); + PrintDetails(" - segment[%" PRIindex "] flags=%d table=%" PRIindex + " count=%" PRIindex, + index, elem_flags_, table_index_, count); + if (elem_flags_ & SegPassive) { + PrintDetails("\n"); } else { PrintInitExpr(elem_init_expr_); } @@ -1463,9 +1464,9 @@ Result BinaryReaderObjdump::OnDataSegmentCount(Index count) { Result BinaryReaderObjdump::BeginDataSegment(Index index, Index memory_index, - bool passive) { + uint8_t flags) { data_mem_index_ = memory_index; - data_is_passive_ = passive; + data_flags_ = flags; return Result::Ok; } @@ -1481,13 +1482,13 @@ Result BinaryReaderObjdump::OnDataSegmentData(Index index, if (!name.empty()) { PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name)); } - if (data_is_passive_) { + if (data_flags_ & SegPassive) { PrintDetails(" passive"); } else { PrintDetails(" memory=%" PRIindex, data_mem_index_); } PrintDetails(" size=%" PRIaddress, size); - if (data_is_passive_) { + if (data_flags_ & SegPassive) { PrintDetails("\n"); } else { PrintInitExpr(data_init_expr_); diff --git a/src/binary-reader.cc b/src/binary-reader.cc index 79aa7e491..238f1d9d9 100644 --- a/src/binary-reader.cc +++ b/src/binary-reader.cc @@ -36,14 +36,16 @@ #include #endif -#define ERROR_UNLESS(expr, ...) \ - do { \ - if (!(expr)) { \ - PrintError(__VA_ARGS__); \ - return Result::Error; \ - } \ +#define ERROR_IF(expr, ...) \ + do { \ + if (expr) { \ + PrintError(__VA_ARGS__); \ + return Result::Error; \ + } \ } while (0) +#define ERROR_UNLESS(expr, ...) ERROR_IF(!(expr), __VA_ARGS__) + #define ERROR_UNLESS_OPCODE_ENABLED(opcode) \ do { \ if (!opcode.IsEnabled(options_.features)) { \ @@ -519,7 +521,7 @@ Result BinaryReader::ReadTable(Type* out_elem_type, Limits* out_elem_limits) { CHECK_RESULT(ReadU32Leb128(&initial, "table initial elem count")); bool has_max = flags & WABT_BINARY_LIMITS_HAS_MAX_FLAG; bool is_shared = flags & WABT_BINARY_LIMITS_IS_SHARED_FLAG; - ERROR_UNLESS(!is_shared, "tables may not be shared"); + ERROR_IF(is_shared, "tables may not be shared"); if (has_max) { CHECK_RESULT(ReadU32Leb128(&max, "table max elem count")); ERROR_UNLESS(initial <= max, @@ -541,7 +543,7 @@ Result BinaryReader::ReadMemory(Limits* out_page_limits) { ERROR_UNLESS(initial <= WABT_MAX_PAGES, "invalid memory initial size"); bool has_max = flags & WABT_BINARY_LIMITS_HAS_MAX_FLAG; bool is_shared = flags & WABT_BINARY_LIMITS_IS_SHARED_FLAG; - ERROR_UNLESS(!is_shared || has_max, "shared memory must have a max size"); + ERROR_IF(is_shared && !has_max, "shared memory must have a max size"); if (has_max) { CHECK_RESULT(ReadU32Leb128(&max, "memory max page count")); ERROR_UNLESS(max <= WABT_MAX_PAGES, "invalid memory max size"); @@ -2130,17 +2132,16 @@ Result BinaryReader::ReadElemSection(Offset section_size) { ERROR_UNLESS(num_elem_segments == 0 || NumTotalTables() > 0, "elem section without table section"); for (Index i = 0; i < num_elem_segments; ++i) { - uint32_t flags_u32; - CHECK_RESULT(ReadU32Leb128(&flags_u32, "elem segment flags")); - ERROR_UNLESS(flags_u32 <= static_cast(SegmentFlags::IndexOther), - "invalid elem segment flags"); - SegmentFlags flags = static_cast(flags_u32); + uint32_t flags; + CHECK_RESULT(ReadU32Leb128(&flags, "elem segment flags")); + ERROR_IF(flags > ~(~0u << SegFlagMax), "invalid elem segment flags: %#x", + flags); Index table_index(0); - if (flags == SegmentFlags::IndexOther) { + if (flags & SegIndexOther) { CHECK_RESULT(ReadIndex(&table_index, "elem segment table index")); } Type elem_type; - if (flags == SegmentFlags::Passive) { + if (flags & SegPassive) { CHECK_RESULT(ReadType(&elem_type, "table elem type")); ERROR_UNLESS(elem_type == Type::Funcref || elem_type == Type::Anyref, "segment elem type must by funcref or anyref"); @@ -2148,10 +2149,9 @@ Result BinaryReader::ReadElemSection(Offset section_size) { elem_type = Type::Funcref; } - CALLBACK(BeginElemSegment, i, table_index, flags == SegmentFlags::Passive, - elem_type); + CALLBACK(BeginElemSegment, i, table_index, flags, elem_type); - if (flags != SegmentFlags::Passive) { + if (!(flags & SegPassive)) { CALLBACK(BeginElemSegmentInitExpr, i); CHECK_RESULT(ReadI32InitExpr(i)); CALLBACK(EndElemSegmentInitExpr, i); @@ -2159,9 +2159,10 @@ Result BinaryReader::ReadElemSection(Offset section_size) { Index num_elem_exprs; CHECK_RESULT(ReadCount(&num_elem_exprs, "elem expr count")); + CALLBACK(OnElemSegmentElemExprCount, i, num_elem_exprs); for (Index j = 0; j < num_elem_exprs; ++j) { - if (flags == SegmentFlags::Passive) { + if (flags & SegPassive) { Opcode opcode; CHECK_RESULT(ReadOpcode(&opcode, "elem expr opcode")); if (opcode == Opcode::RefNull) { @@ -2240,17 +2241,16 @@ Result BinaryReader::ReadDataSection(Offset section_size) { ERROR_UNLESS(data_count_ == kInvalidIndex || data_count_ == num_data_segments, "data segment count does not equal count in DataCount section"); for (Index i = 0; i < num_data_segments; ++i) { - uint32_t flags_u32; - CHECK_RESULT(ReadU32Leb128(&flags_u32, "data segment flags")); - ERROR_UNLESS(flags_u32 <= static_cast(SegmentFlags::IndexOther), - "invalid data segment flags"); - SegmentFlags flags = static_cast(flags_u32); + uint32_t flags; + CHECK_RESULT(ReadU32Leb128(&flags, "data segment flags")); + ERROR_IF(flags > ~(~0u << SegFlagMax), "invalid data segment flags: %#x", + flags); Index memory_index(0); - if (flags == SegmentFlags::IndexOther) { + if (flags & SegIndexOther) { CHECK_RESULT(ReadIndex(&memory_index, "data segment memory index")); } - CALLBACK(BeginDataSegment, i, memory_index, flags == SegmentFlags::Passive); - if (flags != SegmentFlags::Passive) { + CALLBACK(BeginDataSegment, i, memory_index, flags); + if (!(flags & SegPassive)) { CALLBACK(BeginDataSegmentInitExpr, i); CHECK_RESULT(ReadI32InitExpr(i)); CALLBACK(EndDataSegmentInitExpr, i); diff --git a/src/binary-reader.h b/src/binary-reader.h index 3effdb504..59d106556 100644 --- a/src/binary-reader.h +++ b/src/binary-reader.h @@ -286,7 +286,7 @@ class BinaryReaderDelegate { virtual Result OnElemSegmentCount(Index count) = 0; virtual Result BeginElemSegment(Index index, Index table_index, - bool passive, + uint8_t flags, Type elem_type) = 0; virtual Result BeginElemSegmentInitExpr(Index index) = 0; virtual Result EndElemSegmentInitExpr(Index index) = 0; @@ -302,7 +302,7 @@ class BinaryReaderDelegate { virtual Result OnDataSegmentCount(Index count) = 0; virtual Result BeginDataSegment(Index index, Index memory_index, - bool passive) = 0; + uint8_t flags) = 0; virtual Result BeginDataSegmentInitExpr(Index index) = 0; virtual Result EndDataSegmentInitExpr(Index index) = 0; virtual Result OnDataSegmentData(Index index, diff --git a/src/binary-writer.cc b/src/binary-writer.cc index ef9f352f0..1ffc2536b 100644 --- a/src/binary-writer.cc +++ b/src/binary-writer.cc @@ -1032,19 +1032,18 @@ Result BinaryWriter::WriteModule() { for (size_t i = 0; i < module_->elem_segments.size(); ++i) { ElemSegment* segment = module_->elem_segments[i]; WriteHeader("elem segment header", i); - if (segment->passive) { - stream_->WriteU8(static_cast(SegmentFlags::Passive)); + stream_->WriteU8(segment->flags, "segment flags"); + if (segment->is_passive()) { WriteType(stream_, segment->elem_type); - } else if (module_->GetTableIndex(segment->table_var)) { - stream_->WriteU8(static_cast(SegmentFlags::IndexOther)); + } else if (segment->flags & SegIndexOther) { WriteU32Leb128(stream_, module_->GetTableIndex(segment->table_var), "table index"); WriteInitExpr(segment->offset); } else { - stream_->WriteU8(static_cast(SegmentFlags::IndexZero)); + assert(module_->GetTableIndex(segment->table_var) == 0); WriteInitExpr(segment->offset); } - WriteU32Leb128(stream_, segment->elem_exprs.size(), "num elem exprs"); - if (segment->passive) { + WriteU32Leb128(stream_, segment->elem_exprs.size(), "num elems"); + if (segment->is_passive()) { for (const ElemExpr& elem_expr : segment->elem_exprs) { switch (elem_expr.kind) { case ElemExprKind::RefNull: @@ -1104,11 +1103,11 @@ Result BinaryWriter::WriteModule() { for (size_t i = 0; i < module_->data_segments.size(); ++i) { const DataSegment* segment = module_->data_segments[i]; WriteHeader("data segment header", i); - if (segment->passive) { - stream_->WriteU8(static_cast(SegmentFlags::Passive)); + if (segment->is_passive()) { + stream_->WriteU8(SegPassive); } else { assert(module_->GetMemoryIndex(segment->memory_var) == 0); - stream_->WriteU8(static_cast(SegmentFlags::IndexZero)); + stream_->WriteU8(SegIndexZero); WriteInitExpr(segment->offset); } WriteU32Leb128(stream_, segment->data.size(), "data segment size"); diff --git a/src/binary.h b/src/binary.h index 7302a8ad0..01c9b95af 100644 --- a/src/binary.h +++ b/src/binary.h @@ -75,12 +75,6 @@ enum class NameSectionSubsection { Local = 2, }; -enum class SegmentFlags : uint8_t { - IndexZero = 0, - Passive = 1, - IndexOther = 2, -}; - } // namespace wabt #endif /* WABT_BINARY_H_ */ diff --git a/src/common.h b/src/common.h index 18eece375..3152e2878 100644 --- a/src/common.h +++ b/src/common.h @@ -224,6 +224,15 @@ enum class Type : int32_t { }; typedef std::vector TypeVector; +// Matches binary format, do not change. +enum SegmentFlags : uint8_t { + SegIndexZero = 0, + SegPassive = 1, + SegIndexOther = 2, + + SegFlagMax = SegIndexOther, +}; + enum class RelocType { FuncIndexLEB = 0, // e.g. Immediate of call instruction TableIndexSLEB = 1, // e.g. Loading address of function diff --git a/src/interp/binary-reader-interp.cc b/src/interp/binary-reader-interp.cc index 22595e8e8..ce257113e 100644 --- a/src/interp/binary-reader-interp.cc +++ b/src/interp/binary-reader-interp.cc @@ -226,7 +226,7 @@ class BinaryReaderInterp : public BinaryReaderNop { wabt::Result OnElemSegmentCount(Index count) override; wabt::Result BeginElemSegment(Index index, Index table_index, - bool passive, + uint8_t flags, Type elem_type) override; wabt::Result BeginElemSegmentInitExpr(Index index) override; wabt::Result EndElemSegmentInitExpr(Index index) override; @@ -238,7 +238,7 @@ class BinaryReaderInterp : public BinaryReaderNop { wabt::Result OnDataCount(Index count) override; wabt::Result BeginDataSegment(Index index, Index memory_index, - bool passive) override; + uint8_t flags) override; wabt::Result BeginDataSegmentInitExpr(Index index) override; wabt::Result OnDataSegmentData(Index index, const void* data, @@ -375,7 +375,7 @@ class BinaryReaderInterp : public BinaryReaderNop { // Values cached so they can be shared between callbacks. TypedValue init_expr_value_; IstreamOffset table_offset_ = 0; - bool segment_is_passive_ = false; + uint8_t segment_flags_ = 0; Index segment_table_index_ = kInvalidIndex; ElemSegment* elem_segment_ = nullptr; ElemSegmentInfo* elem_segment_info_ = nullptr; @@ -1092,9 +1092,9 @@ wabt::Result BinaryReaderInterp::OnElemSegmentCount(Index count) { wabt::Result BinaryReaderInterp::BeginElemSegment(Index index, Index table_index, - bool passive, + uint8_t flags, Type elem_type) { - segment_is_passive_ = passive; + segment_flags_ = flags; segment_table_index_ = table_index; return wabt::Result::Ok; } @@ -1105,7 +1105,7 @@ wabt::Result BinaryReaderInterp::BeginElemSegmentInitExpr(Index index) { } wabt::Result BinaryReaderInterp::EndElemSegmentInitExpr(Index index) { - assert(segment_is_passive_ == false); + assert(!(segment_flags_ & SegPassive)); if (init_expr_value_.type != Type::I32) { PrintError( @@ -1122,7 +1122,7 @@ wabt::Result BinaryReaderInterp::EndElemSegmentInitExpr(Index index) { wabt::Result BinaryReaderInterp::OnElemSegmentElemExprCount(Index index, Index count) { elem_segment_ = env_->EmplaceBackElemSegment(); - if (segment_is_passive_) { + if (segment_flags_ & SegPassive) { elem_segment_info_ = nullptr; } else { // An active segment still is present in the segment index space, but @@ -1140,7 +1140,7 @@ wabt::Result BinaryReaderInterp::OnElemSegmentElemExprCount(Index index, wabt::Result BinaryReaderInterp::OnElemSegmentElemExpr_RefNull( Index segment_index) { - assert(segment_is_passive_); + assert(segment_flags_ & SegPassive); elem_segment_->elems.push_back({RefType::Null, kInvalidIndex}); return wabt::Result::Ok; } @@ -1157,7 +1157,7 @@ wabt::Result BinaryReaderInterp::OnElemSegmentElemExpr_RefFunc( func_index = TranslateFuncIndexToEnv(func_index); - if (segment_is_passive_) { + if (segment_flags_ & SegPassive) { elem_segment_->elems.push_back({RefType::Func, func_index}); } else { elem_segment_info_->src.push_back({RefType::Func, func_index}); @@ -1174,8 +1174,8 @@ wabt::Result BinaryReaderInterp::OnDataCount(Index count) { wabt::Result BinaryReaderInterp::BeginDataSegment(Index index, Index memory_index, - bool passive) { - segment_is_passive_ = passive; + uint8_t flags) { + segment_flags_ = flags; return wabt::Result::Ok; } @@ -1188,7 +1188,7 @@ wabt::Result BinaryReaderInterp::OnDataSegmentData(Index index, const void* src_data, Address size) { DataSegment* segment = env_->EmplaceBackDataSegment(); - if (segment_is_passive_) { + if (segment_flags_ & SegPassive) { segment->data.resize(size); if (size > 0) { memcpy(segment->data.data(), src_data, size); diff --git a/src/ir.h b/src/ir.h index 1625d6343..3e42bb291 100644 --- a/src/ir.h +++ b/src/ir.h @@ -592,11 +592,12 @@ typedef std::vector ElemExprVector; struct ElemSegment { explicit ElemSegment(string_view name) : name(name.to_string()) {} + bool is_passive() const { return flags & SegPassive; } std::string name; Var table_var; - bool passive = false; - Type elem_type; // If passive == false, this is always Type::Funcref. + uint8_t flags = 0; + Type elem_type; ExprList offset; ElemExprVector elem_exprs; }; @@ -610,10 +611,11 @@ struct Memory { struct DataSegment { explicit DataSegment(string_view name) : name(name.to_string()) {} + bool is_passive() const { return flags & SegPassive; } std::string name; Var memory_var; - bool passive = false; + uint8_t flags = 0; ExprList offset; std::vector data; }; diff --git a/src/validator.cc b/src/validator.cc index 30dba007b..11b4bef23 100644 --- a/src/validator.cc +++ b/src/validator.cc @@ -1160,7 +1160,7 @@ void Validator::CheckElemSegments(const Module* module) { } } - if (elem_segment.passive) { + if (elem_segment.is_passive()) { continue; } if (Failed(CheckTableVar(&elem_segment.table_var, nullptr))) { @@ -1192,7 +1192,7 @@ void Validator::CheckDataSegments(const Module* module) { if (auto data_segment_field = dyn_cast(&field)) { auto&& data_segment = data_segment_field->data_segment; const Memory* memory; - if (data_segment.passive) { + if (data_segment.is_passive()) { continue; } if (Failed(CheckMemoryVar(&data_segment.memory_var, &memory))) { diff --git a/src/wast-parser.cc b/src/wast-parser.cc index eab003801..f40ea65a4 100644 --- a/src/wast-parser.cc +++ b/src/wast-parser.cc @@ -922,7 +922,7 @@ Result WastParser::ParseDataModuleField(Module* module) { if (ParseVarOpt(&field->data_segment.memory_var, Var(0, loc))) { CHECK_RESULT(ParseOffsetExpr(&field->data_segment.offset)); } else if (!ParseOffsetExprOpt(&field->data_segment.offset)) { - field->data_segment.passive = true; + field->data_segment.flags |= SegPassive; } ParseTextListOpt(&field->data_segment.data); @@ -946,7 +946,8 @@ Result WastParser::ParseElemModuleField(Module* module) { if (ParseRefTypeOpt(&field->elem_segment.elem_type)) { field->elem_segment.name = name; - field->elem_segment.passive = true; + field->elem_segment.flags |= SegPassive; + // Parse a potentially empty sequence of ElemExprs. while (true) { Var var; @@ -978,10 +979,14 @@ Result WastParser::ParseElemModuleField(Module* module) { // If we have only one name, and we are an active segment, we treat // that as the name of the table, since naming an active elem segment // is not practically useful. - if (has_second_name) + if (has_second_name) { field->elem_segment.table_var = second_name; - else + } else { field->elem_segment.table_var = has_name ? Var(name, loc) : Var(0, loc); + } + } + if (module->GetTableIndex(field->elem_segment.table_var) > 0) { + field->elem_segment.flags |= SegIndexOther; } field->elem_segment.elem_type = Type::Funcref; @@ -1287,6 +1292,8 @@ Result WastParser::ParseTableModuleField(Module* module) { auto elem_segment_field = MakeUnique(loc); ElemSegment& elem_segment = elem_segment_field->elem_segment; elem_segment.table_var = Var(module->tables.size()); + if (module->tables.size() > 0) + elem_segment.flags |= SegIndexOther; elem_segment.offset.push_back(MakeUnique(Const::I32(0))); elem_segment.offset.back().loc = loc; CHECK_RESULT(ParseElemExprVarList(&elem_segment.elem_exprs)); diff --git a/src/wat-writer.cc b/src/wat-writer.cc index cc964a24d..8eb7e6174 100644 --- a/src/wat-writer.cc +++ b/src/wat-writer.cc @@ -1250,13 +1250,13 @@ void WatWriter::WriteTable(const Table& table) { void WatWriter::WriteElemSegment(const ElemSegment& segment) { WriteOpenSpace("elem"); WriteNameOrIndex(segment.name, elem_segment_index_, NextChar::Space); - if (segment.passive) { + if (segment.is_passive()) { WriteType(segment.elem_type, NextChar::Space); } else { WriteInitExpr(segment.offset); } for (const ElemExpr& expr : segment.elem_exprs) { - if (segment.passive) { + if (segment.is_passive()) { if (expr.kind == ElemExprKind::RefNull) { WriteOpenSpace("ref.null"); WriteCloseSpace(); @@ -1287,7 +1287,7 @@ void WatWriter::WriteMemory(const Memory& memory) { void WatWriter::WriteDataSegment(const DataSegment& segment) { WriteOpenSpace("data"); WriteNameOrIndex(segment.name, data_segment_index_, NextChar::Space); - if (!segment.passive) { + if (!segment.is_passive()) { WriteInitExpr(segment.offset); } WriteQuotedData(segment.data.data(), segment.data.size()); diff --git a/test/dump/callindirect.txt b/test/dump/callindirect.txt index 82ac6a6c0..983c8b8a2 100644 --- a/test/dump/callindirect.txt +++ b/test/dump/callindirect.txt @@ -41,11 +41,11 @@ 000001b: 00 ; section size (guess) 000001c: 01 ; num elem segments ; elem segment header 0 -000001d: 00 +000001d: 00 ; segment flags 000001e: 41 ; i32.const 000001f: 00 ; i32 literal 0000020: 0b ; end -0000021: 01 ; num elem exprs +0000021: 01 ; num elems 0000022: 00 ; elem expr function index 000001b: 07 ; FIXUP section size ; section "Code" (10) diff --git a/test/dump/invalid-elem-segment-no-table.txt b/test/dump/invalid-elem-segment-no-table.txt index 43406a7a0..44e10793e 100644 --- a/test/dump/invalid-elem-segment-no-table.txt +++ b/test/dump/invalid-elem-segment-no-table.txt @@ -28,11 +28,11 @@ 0000014: 00 ; section size (guess) 0000015: 01 ; num elem segments ; elem segment header 0 -0000016: 00 +0000016: 00 ; segment flags 0000017: 41 ; i32.const 0000018: 00 ; i32 literal 0000019: 0b ; end -000001a: 02 ; num elem exprs +000001a: 02 ; num elems 000001b: 00 ; elem expr function index 000001c: 01 ; elem expr function index 0000014: 08 ; FIXUP section size diff --git a/test/dump/invalid-elem-segment-offset.txt b/test/dump/invalid-elem-segment-offset.txt index 9a8044181..8f7f445ea 100644 --- a/test/dump/invalid-elem-segment-offset.txt +++ b/test/dump/invalid-elem-segment-offset.txt @@ -36,12 +36,12 @@ 0000019: 00 ; section size (guess) 000001a: 01 ; num elem segments ; elem segment header 0 -000001b: 00 +000001b: 00 ; segment flags 000001c: 41 ; i32.const 000001d: 01 ; i32 literal 000001e: 45 ; i32.eqz 000001f: 0b ; end -0000020: 01 ; num elem exprs +0000020: 01 ; num elems 0000021: 00 ; elem expr function index 0000019: 08 ; FIXUP section size ; section "Code" (10) diff --git a/test/dump/no-canonicalize.txt b/test/dump/no-canonicalize.txt index 34ed4c9ae..6ef052287 100644 --- a/test/dump/no-canonicalize.txt +++ b/test/dump/no-canonicalize.txt @@ -98,11 +98,11 @@ 000005d: 0000 0000 00 ; section size (guess) 0000062: 01 ; num elem segments ; elem segment header 0 -0000063: 00 +0000063: 00 ; segment flags 0000064: 41 ; i32.const 0000065: 00 ; i32 literal 0000066: 0b ; end -0000067: 02 ; num elem exprs +0000067: 02 ; num elems 0000068: 02 ; elem expr function index 0000069: 03 ; elem expr function index 000005d: 8880 8080 00 ; FIXUP section size diff --git a/test/dump/reference-types.txt b/test/dump/reference-types.txt index 75d9ee69e..4b174f26f 100644 --- a/test/dump/reference-types.txt +++ b/test/dump/reference-types.txt @@ -84,9 +84,9 @@ Table[3]: - table[1] type=anyref initial=1 - table[2] type=funcref initial=1 Elem[2]: - - segment[0] table=2 count=1 - init i32=0 + - segment[0] flags=2 table=2 count=1 - init i32=0 - elem[0] = func[0] - - segment[1] table=0 count=1 passive + - segment[1] flags=1 table=0 count=1 - elem[0] = nullref Code[10]: - func[0] size=6 diff --git a/test/dump/table-multi.txt b/test/dump/table-multi.txt index e2e3456aa..d1c062bab 100644 --- a/test/dump/table-multi.txt +++ b/test/dump/table-multi.txt @@ -44,19 +44,19 @@ 000001f: 00 ; section size (guess) 0000020: 02 ; num elem segments ; elem segment header 0 -0000021: 00 +0000021: 00 ; segment flags 0000022: 41 ; i32.const 0000023: 00 ; i32 literal 0000024: 0b ; end -0000025: 01 ; num elem exprs +0000025: 01 ; num elems 0000026: 00 ; elem expr function index ; elem segment header 1 -0000027: 02 +0000027: 02 ; segment flags 0000028: 01 ; table index 0000029: 41 ; i32.const 000002a: 00 ; i32 literal 000002b: 0b ; end -000002c: 01 ; num elem exprs +000002c: 01 ; num elems 000002d: 00 ; elem expr function index 000001f: 0e ; FIXUP section size ; section "Code" (10) @@ -82,9 +82,9 @@ Table[2]: - table[0] type=funcref initial=1 max=1 - table[1] type=funcref initial=1 max=1 Elem[2]: - - segment[0] table=0 count=1 - init i32=0 + - segment[0] flags=0 table=0 count=1 - init i32=0 - elem[0] = func[0] - - segment[1] table=1 count=1 - init i32=0 + - segment[1] flags=2 table=1 count=1 - init i32=0 - elem[0] = func[0] Code[1]: - func[0] size=2 diff --git a/test/dump/table.txt b/test/dump/table.txt index 8715d4d89..27ae9c433 100644 --- a/test/dump/table.txt +++ b/test/dump/table.txt @@ -57,19 +57,19 @@ 0000026: 00 ; section size (guess) 0000027: 02 ; num elem segments ; elem segment header 0 -0000028: 00 +0000028: 00 ; segment flags 0000029: 41 ; i32.const 000002a: 00 ; i32 literal 000002b: 0b ; end -000002c: 02 ; num elem exprs +000002c: 02 ; num elems 000002d: 01 ; elem expr function index 000002e: 01 ; elem expr function index ; elem segment header 1 -000002f: 00 +000002f: 00 ; segment flags 0000030: 41 ; i32.const 0000031: 02 ; i32 literal 0000032: 0b ; end -0000033: 04 ; num elem exprs +0000033: 04 ; num elems 0000034: 00 ; elem expr function index 0000035: 00 ; elem expr function index 0000036: 01 ; elem expr function index @@ -113,10 +113,10 @@ Function[3]: Table[1]: - table[0] type=funcref initial=6 max=6 Elem[2]: - - segment[0] table=0 count=2 - init i32=0 + - segment[0] flags=0 table=0 count=2 - init i32=0 - elem[0] = func[1] - elem[1] = func[1] - - segment[1] table=0 count=4 - init i32=2 + - segment[1] flags=0 table=0 count=4 - init i32=2 - elem[2] = func[0] - elem[3] = func[0] - elem[4] = func[1] diff --git a/test/interp/logging-all-opcodes.txt b/test/interp/logging-all-opcodes.txt index ed21f9148..bcbac7155 100644 --- a/test/interp/logging-all-opcodes.txt +++ b/test/interp/logging-all-opcodes.txt @@ -2646,17 +2646,17 @@ 0001b16: 00 ; section size (guess) 0001b17: 02 ; num elem segments ; elem segment header 0 -0001b18: 00 +0001b18: 00 ; segment flags 0001b19: 41 ; i32.const 0001b1a: 00 ; i32 literal 0001b1b: 0b ; end -0001b1c: 02 ; num elem exprs +0001b1c: 02 ; num elems 0001b1d: 01 ; elem expr function index 0001b1e: 01 ; elem expr function index ; elem segment header 1 -0001b1f: 01 +0001b1f: 01 ; segment flags 0001b20: 70 ; funcref -0001b21: 00 ; num elem exprs +0001b21: 00 ; num elems 0001b16: 0b ; FIXUP section size ; section "DataCount" (12) 0001b22: 0c ; section code @@ -8302,7 +8302,7 @@ BeginModule(version: 1) EndExportSection BeginElemSection(11) OnElemSegmentCount(2) - BeginElemSegment(index: 0, table_index: 0, passive: false, elem_type: funcref) + BeginElemSegment(index: 0, table_index: 0, flags: 0, elem_type: funcref) BeginElemSegmentInitExpr(0) OnInitExprI32ConstExpr(index: 0, value: 0) EndElemSegmentInitExpr(0) @@ -8310,7 +8310,7 @@ BeginModule(version: 1) OnElemSegmentElemExpr_RefFunc(index: 0, func_index: 1) OnElemSegmentElemExpr_RefFunc(index: 0, func_index: 1) EndElemSegment(0) - BeginElemSegment(index: 1, table_index: 0, passive: true, elem_type: funcref) + BeginElemSegment(index: 1, table_index: 0, flags: 1, elem_type: funcref) OnElemSegmentElemExprCount(index: 1, count: 0) EndElemSegment(1) EndElemSection @@ -10958,7 +10958,7 @@ BeginModule(version: 1) EndCodeSection BeginDataSection(3) OnDataSegmentCount(1) - BeginDataSegment(index: 0, memory_index: 0, passive: true) + BeginDataSegment(index: 0, memory_index: 0, flags: 1) OnDataSegmentData(index:0, size:0) EndDataSegment(0) EndDataSection