diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/apply-names.cc | 7 | ||||
-rw-r--r-- | src/binary-reader-ir.cc | 15 | ||||
-rw-r--r-- | src/binary-reader-logging.cc | 15 | ||||
-rw-r--r-- | src/binary-reader-logging.h | 4 | ||||
-rw-r--r-- | src/binary-reader-nop.h | 6 | ||||
-rw-r--r-- | src/binary-reader-objdump.cc | 12 | ||||
-rw-r--r-- | src/binary-reader.cc | 4 | ||||
-rw-r--r-- | src/binary-reader.h | 4 | ||||
-rw-r--r-- | src/interp/binary-reader-interp.cc | 19 | ||||
-rw-r--r-- | src/ir.cc | 11 | ||||
-rw-r--r-- | src/resolve-names.cc | 7 | ||||
-rw-r--r-- | src/shared-validator.cc | 31 | ||||
-rw-r--r-- | src/shared-validator.h | 14 | ||||
-rw-r--r-- | src/validator.cc | 7 | ||||
-rw-r--r-- | src/wast-parser.cc | 20 |
15 files changed, 123 insertions, 53 deletions
diff --git a/src/apply-names.cc b/src/apply-names.cc index ee638c9b..95868176 100644 --- a/src/apply-names.cc +++ b/src/apply-names.cc @@ -58,6 +58,7 @@ class NameApplier : public ExprVisitor::DelegateNop { Result OnDataDropExpr(DataDropExpr*) override; Result OnMemoryInitExpr(MemoryInitExpr*) override; Result OnElemDropExpr(ElemDropExpr*) override; + Result OnTableCopyExpr(TableCopyExpr*) override; Result OnTableInitExpr(TableInitExpr*) override; Result OnTableGetExpr(TableGetExpr*) override; Result OnTableSetExpr(TableSetExpr*) override; @@ -260,6 +261,12 @@ Result NameApplier::OnElemDropExpr(ElemDropExpr* expr) { return Result::Ok; } +Result NameApplier::OnTableCopyExpr(TableCopyExpr* expr) { + CHECK_RESULT(UseNameForTableVar(&expr->dst_table)); + CHECK_RESULT(UseNameForTableVar(&expr->src_table)); + return Result::Ok; +} + Result NameApplier::OnTableInitExpr(TableInitExpr* expr) { CHECK_RESULT(UseNameForElemSegmentVar(&expr->segment_index)); CHECK_RESULT(UseNameForTableVar(&expr->table_index)); diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc index 0bc03ebe..c907cba5 100644 --- a/src/binary-reader-ir.cc +++ b/src/binary-reader-ir.cc @@ -205,10 +205,10 @@ class BinaryReaderIR : public BinaryReaderNop { Result OnElemSegmentCount(Index count) override; Result BeginElemSegment(Index index, Index table_index, - uint8_t flags, - Type elem_type) override; + uint8_t flags) override; Result BeginElemSegmentInitExpr(Index index) override; 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) override; Result OnElemSegmentElemExpr_RefFunc(Index segment_index, @@ -1022,8 +1022,7 @@ Result BinaryReaderIR::OnElemSegmentCount(Index count) { Result BinaryReaderIR::BeginElemSegment(Index index, Index table_index, - uint8_t flags, - Type elem_type) { + uint8_t flags) { auto field = MakeUnique<ElemSegmentModuleField>(GetLocation()); ElemSegment& elem_segment = field->elem_segment; elem_segment.table_var = Var(table_index, GetLocation()); @@ -1034,7 +1033,6 @@ Result BinaryReaderIR::BeginElemSegment(Index index, } else { elem_segment.kind = SegmentKind::Active; } - elem_segment.elem_type = elem_type; module_->AppendField(std::move(field)); return Result::Ok; } @@ -1051,6 +1049,13 @@ Result BinaryReaderIR::EndElemSegmentInitExpr(Index index) { return Result::Ok; } +Result BinaryReaderIR::OnElemSegmentElemType(Index index, Type elem_type) { + assert(index == module_->elem_segments.size() - 1); + ElemSegment* segment = module_->elem_segments[index]; + segment->elem_type = elem_type; + return Result::Ok; +} + Result BinaryReaderIR::OnElemSegmentElemExprCount(Index index, Index count) { assert(index == module_->elem_segments.size() - 1); ElemSegment* segment = module_->elem_segments[index]; diff --git a/src/binary-reader-logging.cc b/src/binary-reader-logging.cc index 5ee062ed..81ddfbe9 100644 --- a/src/binary-reader-logging.cc +++ b/src/binary-reader-logging.cc @@ -368,12 +368,17 @@ Result BinaryReaderLogging::OnSimdShuffleOpExpr(Opcode opcode, v128 value) { Result BinaryReaderLogging::BeginElemSegment(Index index, Index table_index, - uint8_t flags, - Type elem_type) { + uint8_t flags) { LOGF("BeginElemSegment(index: %" PRIindex ", table_index: %" PRIindex - ", flags: %d, elem_type: %s)\n", - index, table_index, flags, GetTypeName(elem_type)); - return reader_->BeginElemSegment(index, table_index, flags, elem_type); + ", flags: %d)\n", + index, table_index, flags); + return reader_->BeginElemSegment(index, table_index, flags); +} + +Result BinaryReaderLogging::OnElemSegmentElemType(Index index, Type elem_type) { + LOGF("OnElemSegmentElemType(index: %" PRIindex ", type: %s)\n", index, + GetTypeName(elem_type)); + return reader_->OnElemSegmentElemType(index, elem_type); } Result BinaryReaderLogging::OnDataSegmentData(Index index, diff --git a/src/binary-reader-logging.h b/src/binary-reader-logging.h index 9e12d434..facc8d5d 100644 --- a/src/binary-reader-logging.h +++ b/src/binary-reader-logging.h @@ -231,10 +231,10 @@ class BinaryReaderLogging : public BinaryReaderDelegate { Result OnElemSegmentCount(Index count) override; Result BeginElemSegment(Index index, Index table_index, - uint8_t flags, - Type elem_type) override; + uint8_t flags) override; Result BeginElemSegmentInitExpr(Index index) override; 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) override; Result OnElemSegmentElemExpr_RefFunc(Index segment_index, diff --git a/src/binary-reader-nop.h b/src/binary-reader-nop.h index 2426103d..0124858c 100644 --- a/src/binary-reader-nop.h +++ b/src/binary-reader-nop.h @@ -302,12 +302,14 @@ class BinaryReaderNop : public BinaryReaderDelegate { Result OnElemSegmentCount(Index count) override { return Result::Ok; } Result BeginElemSegment(Index index, Index table_index, - uint8_t flags, - Type elem_type) override { + uint8_t flags) override { return Result::Ok; } Result BeginElemSegmentInitExpr(Index index) override { return Result::Ok; } Result EndElemSegmentInitExpr(Index index) override { return Result::Ok; } + Result OnElemSegmentElemType(Index index, Type elem_type) override { + return Result::Ok; + } Result OnElemSegmentElemExprCount(Index index, Index count) override { return Result::Ok; } diff --git a/src/binary-reader-objdump.cc b/src/binary-reader-objdump.cc index 6b80849a..a1c919ec 100644 --- a/src/binary-reader-objdump.cc +++ b/src/binary-reader-objdump.cc @@ -799,8 +799,8 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase { Result OnElemSegmentCount(Index count) override; Result BeginElemSegment(Index index, Index table_index, - uint8_t flags, - Type elem_type) override; + 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) override; Result OnElemSegmentElemExpr_RefFunc(Index segment_index, @@ -1273,14 +1273,18 @@ Result BinaryReaderObjdump::OnElemSegmentCount(Index count) { Result BinaryReaderObjdump::BeginElemSegment(Index index, Index table_index, - uint8_t flags, - Type elem_type) { + uint8_t flags) { table_index_ = table_index; elem_index_ = 0; elem_flags_ = flags; return Result::Ok; } +Result BinaryReaderObjdump::OnElemSegmentElemType(Index index, Type elem_type) { + // TODO: Add support for this. + return Result::Ok; +} + Result BinaryReaderObjdump::OnElemSegmentElemExprCount(Index index, Index count) { PrintDetails(" - segment[%" PRIindex "] flags=%d table=%" PRIindex diff --git a/src/binary-reader.cc b/src/binary-reader.cc index 74fd3a67..6041145b 100644 --- a/src/binary-reader.cc +++ b/src/binary-reader.cc @@ -2220,7 +2220,7 @@ Result BinaryReader::ReadElemSection(Offset section_size) { } Type elem_type = Type::Funcref; - CALLBACK(BeginElemSegment, i, table_index, flags, elem_type); + CALLBACK(BeginElemSegment, i, table_index, flags); if (!(flags & SegPassive)) { CALLBACK(BeginElemSegmentInitExpr, i); @@ -2245,6 +2245,8 @@ Result BinaryReader::ReadElemSection(Offset section_size) { } } + CALLBACK(OnElemSegmentElemType, i, elem_type); + Index num_elem_exprs; CHECK_RESULT(ReadCount(&num_elem_exprs, "elem count")); diff --git a/src/binary-reader.h b/src/binary-reader.h index b5f97a8f..67e2c80c 100644 --- a/src/binary-reader.h +++ b/src/binary-reader.h @@ -287,10 +287,10 @@ class BinaryReaderDelegate { virtual Result OnElemSegmentCount(Index count) = 0; virtual Result BeginElemSegment(Index index, Index table_index, - uint8_t flags, - Type elem_type) = 0; + uint8_t flags) = 0; virtual Result BeginElemSegmentInitExpr(Index index) = 0; 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) = 0; virtual Result OnElemSegmentElemExpr_RefFunc(Index segment_index, diff --git a/src/interp/binary-reader-interp.cc b/src/interp/binary-reader-interp.cc index 5e442b61..8149907c 100644 --- a/src/interp/binary-reader-interp.cc +++ b/src/interp/binary-reader-interp.cc @@ -221,9 +221,9 @@ class BinaryReaderInterp : public BinaryReaderNop { wabt::Result OnElemSegmentCount(Index count) override; wabt::Result BeginElemSegment(Index index, Index table_index, - uint8_t flags, - Type elem_type) override; + uint8_t flags) override; wabt::Result EndElemSegmentInitExpr(Index index) override; + wabt::Result OnElemSegmentElemType(Index index, Type elem_type) override; wabt::Result OnElemSegmentElemExprCount(Index index, Index count) override; wabt::Result OnElemSegmentElemExpr_RefNull(Index segment_index) override; wabt::Result OnElemSegmentElemExpr_RefFunc(Index segment_index, @@ -692,13 +692,12 @@ wabt::Result BinaryReaderInterp::OnElemSegmentCount(Index count) { wabt::Result BinaryReaderInterp::BeginElemSegment(Index index, Index table_index, - uint8_t flags, - Type elem_type) { + uint8_t flags) { auto mode = ToSegmentMode(flags); - CHECK_RESULT(validator_.OnElemSegment(loc, Var(table_index), mode, elem_type)); + CHECK_RESULT(validator_.OnElemSegment(loc, Var(table_index), mode)); ElemDesc desc; - desc.type = elem_type; + desc.type = ValueType::Void; // Initialized later in OnElemSegmentElemType. desc.mode = mode; desc.table_index = table_index; module_.elems.push_back(desc); @@ -727,6 +726,14 @@ wabt::Result BinaryReaderInterp::EndElemSegmentInitExpr(Index index) { return wabt::Result::Ok; } +wabt::Result BinaryReaderInterp::OnElemSegmentElemType(Index index, + Type elem_type) { + validator_.OnElemSegmentElemType(elem_type); + ElemDesc& elem = module_.elems.back(); + elem.type = elem_type; + return wabt::Result::Ok; +} + wabt::Result BinaryReaderInterp::OnElemSegmentElemExprCount(Index index, Index count) { ElemDesc& elem = module_.elems.back(); @@ -653,6 +653,8 @@ Const::Const(V128Tag, v128 value, const Location& loc_) uint8_t ElemSegment::GetFlags(const Module* module) const { uint8_t flags = 0; + bool all_ref_func = elem_type == Type::Funcref; + switch (kind) { case SegmentKind::Active: { Index table_index = module->GetTableIndex(table_var); @@ -671,10 +673,11 @@ uint8_t ElemSegment::GetFlags(const Module* module) const { break; } - bool all_ref_func = std::all_of( - elem_exprs.begin(), elem_exprs.end(), [](const ElemExpr& elem_expr) { - return elem_expr.kind == ElemExprKind::RefFunc; - }); + all_ref_func = all_ref_func && + std::all_of(elem_exprs.begin(), elem_exprs.end(), + [](const ElemExpr& elem_expr) { + return elem_expr.kind == ElemExprKind::RefFunc; + }); if (!all_ref_func) { flags |= SegUseElemExprs; } diff --git a/src/resolve-names.cc b/src/resolve-names.cc index 2dff2a62..59bb0493 100644 --- a/src/resolve-names.cc +++ b/src/resolve-names.cc @@ -58,6 +58,7 @@ class NameResolver : public ExprVisitor::DelegateNop { Result OnDataDropExpr(DataDropExpr*) override; Result OnMemoryInitExpr(MemoryInitExpr*) override; Result OnElemDropExpr(ElemDropExpr*) override; + Result OnTableCopyExpr(TableCopyExpr*) override; Result OnTableInitExpr(TableInitExpr*) override; Result OnTableGetExpr(TableGetExpr*) override; Result OnTableSetExpr(TableSetExpr*) override; @@ -354,6 +355,12 @@ Result NameResolver::OnElemDropExpr(ElemDropExpr* expr) { return Result::Ok; } +Result NameResolver::OnTableCopyExpr(TableCopyExpr* expr) { + ResolveTableVar(&expr->dst_table); + ResolveTableVar(&expr->src_table); + return Result::Ok; +} + Result NameResolver::OnTableInitExpr(TableInitExpr* expr) { ResolveElemSegmentVar(&expr->segment_index); ResolveTableVar(&expr->table_index); diff --git a/src/shared-validator.cc b/src/shared-validator.cc index 708d6189..e286dc96 100644 --- a/src/shared-validator.cc +++ b/src/shared-validator.cc @@ -287,16 +287,19 @@ Result SharedValidator::OnStart(const Location& loc, Var func_var) { Result SharedValidator::OnElemSegment(const Location& loc, Var table_var, - SegmentKind kind, - Type elem_type) { + SegmentKind kind) { Result result = Result::Ok; if (kind == SegmentKind::Active) { result |= CheckTableIndex(table_var); } - ++elem_segments_; + elems_.push_back(ElemType{Type::Void}); // Updated in OnElemSegmentElemType. return result; } +void SharedValidator::OnElemSegmentElemType(Type elem_type) { + elems_.back().element = elem_type; +} + Result SharedValidator::OnElemSegmentInitExpr_Const(const Location& loc, Type type) { return CheckType(loc, type, Type::I32, "elem segment offset"); @@ -450,8 +453,7 @@ Result SharedValidator::CheckMemoryIndex(Var memory_var, MemoryType* out) { } // TODO: Remove; this is only used to match previous error output. -Result SharedValidator::CheckMemoryIndex(Var memory_var, - Opcode opcode) { +Result SharedValidator::CheckMemoryIndex(Var memory_var, Opcode opcode) { if (memory_var.index() >= memories_.size()) { return PrintError(memory_var.loc, "%s requires an imported or defined memory.", @@ -483,8 +485,9 @@ Result SharedValidator::CheckEventIndex(Var event_var, EventType* out) { return CheckIndexWithValue(event_var, events_, out, "event"); } -Result SharedValidator::CheckElemSegmentIndex(Var elem_segment_var) { - return CheckIndex(elem_segment_var, elem_segments_, "elem_segment"); +Result SharedValidator::CheckElemSegmentIndex(Var elem_segment_var, + ElemType* out) { + return CheckIndexWithValue(elem_segment_var, elems_, out, "elem_segment"); } Result SharedValidator::CheckDataSegmentIndex(Var data_segment_var) { @@ -1052,9 +1055,12 @@ Result SharedValidator::OnTableCopy(const Location& loc, Var src_var) { Result result = Result::Ok; expr_loc_ = &loc; - result |= CheckTableIndex(dst_var, Opcode::TableCopy); - result |= CheckTableIndex(src_var, Opcode::TableCopy); + TableType dst_table; + TableType src_table; + result |= CheckTableIndex(dst_var, &dst_table); + result |= CheckTableIndex(src_var, &src_table); result |= typechecker_.OnTableCopy(); + result |= CheckType(loc, src_table.element, dst_table.element, "table.copy"); return result; } @@ -1090,9 +1096,12 @@ Result SharedValidator::OnTableInit(const Location& loc, Var table_var) { Result result = Result::Ok; expr_loc_ = &loc; - result |= CheckTableIndex(table_var, Opcode::TableInit); - result |= CheckElemSegmentIndex(segment_var); + TableType table_type; + ElemType elem_type; + result |= CheckTableIndex(table_var, &table_type); + result |= CheckElemSegmentIndex(segment_var, &elem_type); result |= typechecker_.OnTableInit(table_var.index(), segment_var.index()); + result |= CheckType(loc, elem_type.element, table_type.element, "table.init"); return result; } diff --git a/src/shared-validator.h b/src/shared-validator.h index 2143c1fa..3e2035e9 100644 --- a/src/shared-validator.h +++ b/src/shared-validator.h @@ -84,7 +84,8 @@ class SharedValidator { Result OnStart(const Location&, Var func_var); - Result OnElemSegment(const Location&, Var table_var, SegmentKind, Type elem_type); + Result OnElemSegment(const Location&, Var table_var, SegmentKind); + void OnElemSegmentElemType(Type elem_type); Result OnElemSegmentInitExpr_Const(const Location&, Type); Result OnElemSegmentInitExpr_GlobalGet(const Location&, Var global_var); Result OnElemSegmentInitExpr_Other(const Location&); @@ -200,6 +201,13 @@ class SharedValidator { TypeVector params; }; + struct ElemType { + ElemType() = default; + ElemType(Type element) : element(element) {} + + Type element; + }; + struct LocalDecl { Type type; Index end; @@ -232,7 +240,7 @@ class SharedValidator { Result CheckMemoryIndex(Var memory_var, Opcode); Result CheckGlobalIndex(Var global_var, GlobalType* out = nullptr); Result CheckEventIndex(Var event_var, EventType* out = nullptr); - Result CheckElemSegmentIndex(Var elem_segment_var); + Result CheckElemSegmentIndex(Var elem_segment_var, ElemType* out = nullptr); Result CheckDataSegmentIndex(Var data_segment_var); Result CheckAlign(const Location&, Address align, Address natural_align); @@ -258,9 +266,9 @@ class SharedValidator { std::vector<MemoryType> memories_; // Includes imported and defined. std::vector<GlobalType> globals_; // Includes imported and defined. std::vector<EventType> events_; // Includes imported and defined. + std::vector<ElemType> elems_; Index starts_ = 0; Index num_imported_globals_ = 0; - Index elem_segments_ = 0; Index data_segments_ = 0; // Includes parameters, since this is only used for validating diff --git a/src/validator.cc b/src/validator.cc index ce25df9e..7498ca40 100644 --- a/src/validator.cc +++ b/src/validator.cc @@ -731,9 +731,10 @@ Result Validator::CheckModule() { // Elem segment section. for (const ModuleField& field : module->fields) { if (auto* f = dyn_cast<ElemSegmentModuleField>(&field)) { - result_ |= validator_.OnElemSegment( - field.loc, f->elem_segment.table_var, f->elem_segment.kind, - f->elem_segment.elem_type); + result_ |= validator_.OnElemSegment(field.loc, f->elem_segment.table_var, + f->elem_segment.kind); + + validator_.OnElemSegmentElemType(f->elem_segment.elem_type); // Init expr. if (f->elem_segment.offset.size() == 1) { diff --git a/src/wast-parser.cc b/src/wast-parser.cc index 3468e008..3075ee91 100644 --- a/src/wast-parser.cc +++ b/src/wast-parser.cc @@ -1820,11 +1820,8 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) { Var dst(0, loc); Var src(0, loc); if (options_->features.reference_types_enabled()) { - // TODO: disabled for now, since the spec tests don't currently use. -#if 0 - CHECK_RESULT(ParseVar(&dst)); - CHECK_RESULT(ParseVar(&src)); -#endif + ParseVarOpt(&dst, dst); + ParseVarOpt(&src, src); } out_expr->reset(new TableCopyExpr(dst, src, loc)); break; @@ -1840,6 +1837,15 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) { Var segment_index(0, loc); CHECK_RESULT(ParseVar(&segment_index)); Var table_index(0, loc); + if (ParseVarOpt(&table_index, table_index)) { + // Here are the two forms: + // + // table.init $elemidx ... + // table.init $tableidx $elemidx ... + // + // So if both indexes are provided, we need to swap them. + std::swap(segment_index, table_index); + } out_expr->reset(new TableInitExpr(segment_index, table_index, loc)); break; } @@ -1851,21 +1857,25 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) { case TokenType::TableSet: ErrorUnlessOpcodeEnabled(Consume()); + // TODO: Table index. CHECK_RESULT(ParsePlainInstrVar<TableSetExpr>(loc, out_expr)); break; case TokenType::TableGrow: ErrorUnlessOpcodeEnabled(Consume()); + // TODO: Table index. CHECK_RESULT(ParsePlainInstrVar<TableGrowExpr>(loc, out_expr)); break; case TokenType::TableSize: ErrorUnlessOpcodeEnabled(Consume()); + // TODO: Table index. CHECK_RESULT(ParsePlainInstrVar<TableSizeExpr>(loc, out_expr)); break; case TokenType::TableFill: ErrorUnlessOpcodeEnabled(Consume()); + // TODO: Table index. CHECK_RESULT(ParsePlainInstrVar<TableFillExpr>(loc, out_expr)); break; |