.
diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc index ab8fe15..c325135 100644 --- a/src/binary-reader-ir.cc +++ b/src/binary-reader-ir.cc
@@ -280,6 +280,7 @@ void PushLabel(LabelType label_type, ExprList* first, Expr* context = nullptr); + Result BeginInitExpr(InitExpr* init_expr); Result EndInitExpr(); Result PopLabel(); Result GetLabelAt(LabelNode** label, Index depth); @@ -367,13 +368,9 @@ Result BinaryReaderIR::AppendExpr(std::unique_ptr<Expr> expr) { expr->loc = GetLocation(); - if (current_init_expr_) { - current_init_expr_->exprs.push_back(std::move(expr)); - } else { - LabelNode* label; - CHECK_RESULT(TopLabel(&label)); - label->exprs->push_back(std::move(expr)); - } + LabelNode* label; + CHECK_RESULT(TopLabel(&label)); + label->exprs->push_back(std::move(expr)); return Result::Ok; } @@ -606,8 +603,7 @@ Result BinaryReaderIR::BeginGlobalInitExpr(Index index) { assert(index == module_->globals.size() - 1); Global* global = module_->globals[index]; - current_init_expr_ = &global->init_expr; - return Result::Ok; + return BeginInitExpr(&global->init_expr); } Result BinaryReaderIR::EndGlobalInitExpr(Index index) { @@ -798,9 +794,6 @@ } Result BinaryReaderIR::OnEndExpr() { - if (current_init_expr_) { - return Result::Ok; - } if (label_stack_.size() > 1) { LabelNode* label; Expr* expr; @@ -821,8 +814,12 @@ case LabelType::Try: cast<TryExpr>(expr)->block.end_loc = GetLocation(); break; - + case LabelType::InitExpr: + current_init_expr_->end_loc = GetLocation(); + break; case LabelType::Func: + current_func_->end_loc = GetLocation(); + break; case LabelType::Catch: break; } @@ -1151,11 +1148,16 @@ return Result::Ok; } +Result BinaryReaderIR::BeginInitExpr(InitExpr* expr) { + current_init_expr_ = expr; + PushLabel(LabelType::InitExpr, ¤t_init_expr_->exprs); + return Result::Ok; +} + Result BinaryReaderIR::BeginElemSegmentInitExpr(Index index) { assert(index == module_->elem_segments.size() - 1); ElemSegment* segment = module_->elem_segments[index]; - current_init_expr_ = &segment->offset; - return Result::Ok; + return BeginInitExpr(&segment->offset); } Result BinaryReaderIR::EndInitExpr() { @@ -1230,8 +1232,7 @@ Result BinaryReaderIR::BeginDataSegmentInitExpr(Index index) { assert(index == module_->data_segments.size() - 1); DataSegment* segment = module_->data_segments[index]; - current_init_expr_ = &segment->offset; - return Result::Ok; + return BeginInitExpr(&segment->offset); } Result BinaryReaderIR::EndDataSegmentInitExpr(Index index) {
diff --git a/src/binary-reader.cc b/src/binary-reader.cc index e077543..97f7a7a 100644 --- a/src/binary-reader.cc +++ b/src/binary-reader.cc
@@ -131,9 +131,7 @@ Result ReadFunctionBody(Offset end_offset) WABT_WARN_UNUSED; // ReadInstructions either until and END instruction, or until // the given end_offset. - Result ReadInstructions(bool stop_on_end, - Offset end_offset, - Opcode* final_opcode) WABT_WARN_UNUSED; + Result ReadInstructions(bool stop_on_end, Offset end_offset) WABT_WARN_UNUSED; Result ReadNameSection(Offset section_size) WABT_WARN_UNUSED; Result ReadRelocSection(Offset section_size) WABT_WARN_UNUSED; Result ReadDylinkSection(Offset section_size) WABT_WARN_UNUSED; @@ -494,7 +492,7 @@ Result BinaryReader::ReadInitExpr(Index index) { // Read instructions until END opcode is reached. - return ReadInstructions(/*stop_on_end=*/true, read_end_, NULL); + return ReadInstructions(/*stop_on_end=*/true, read_end_); } Result BinaryReader::ReadTable(Type* out_elem_type, Limits* out_elem_limits) { @@ -597,25 +595,19 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) { Opcode final_opcode(Opcode::Invalid); CHECK_RESULT( - ReadInstructions(/*stop_on_end=*/false, end_offset, &final_opcode)); + ReadInstructions(/*stop_on_end=*/false, end_offset)); ERROR_UNLESS(state_.offset == end_offset, "function body longer than given size"); - ERROR_UNLESS(final_opcode == Opcode::End, - "function body must end with END opcode"); return Result::Ok; } Result BinaryReader::ReadInstructions(bool stop_on_end, - Offset end_offset, - Opcode* final_opcode) { + Offset end_offset) { while (state_.offset < end_offset) { Opcode opcode; CHECK_RESULT(ReadOpcode(&opcode, "opcode")); CALLBACK(OnOpcode, opcode); ERROR_UNLESS_OPCODE_ENABLED(opcode); - if (final_opcode) { - *final_opcode = opcode; - } switch (opcode) { case Opcode::Unreachable:
diff --git a/src/common.h b/src/common.h index 312726e..046cb55 100644 --- a/src/common.h +++ b/src/common.h
@@ -224,6 +224,7 @@ enum class LabelType { Func, + InitExpr, Block, Loop, If,
diff --git a/src/expr-visitor.h b/src/expr-visitor.h index ab7dc9e..fdc2c4b 100644 --- a/src/expr-visitor.h +++ b/src/expr-visitor.h
@@ -68,6 +68,8 @@ virtual ~Delegate() {} virtual Result OnBinaryExpr(BinaryExpr*) = 0; + virtual Result BeginInitExpr(InitExpr*) = 0; + virtual Result EndInitExpr(InitExpr*) = 0; virtual Result BeginBlockExpr(BlockExpr*) = 0; virtual Result EndBlockExpr(BlockExpr*) = 0; virtual Result OnBrExpr(BrExpr*) = 0; @@ -141,6 +143,8 @@ class ExprVisitor::DelegateNop : public ExprVisitor::Delegate { public: Result OnBinaryExpr(BinaryExpr*) override { return Result::Ok; } + Result BeginInitExpr(InitExpr*) override { return Result::Ok; } + Result EndInitExpr(InitExpr*) override { return Result::Ok; } Result BeginBlockExpr(BlockExpr*) override { return Result::Ok; } Result EndBlockExpr(BlockExpr*) override { return Result::Ok; } Result OnBrExpr(BrExpr*) override { return Result::Ok; }
diff --git a/src/interp/binary-reader-interp.cc b/src/interp/binary-reader-interp.cc index 17b3803..9e066c4 100644 --- a/src/interp/binary-reader-interp.cc +++ b/src/interp/binary-reader-interp.cc
@@ -1096,6 +1096,7 @@ Result BinaryReaderInterp::OnEndExpr() { if (reading_init_expr_) { + //CHECK_RESULT(validator_.OnEnd(loc)); return Result::Ok; } if (label_stack_.size() == 1) {
diff --git a/src/ir.h b/src/ir.h index 4c82faf..ceca4cb 100644 --- a/src/ir.h +++ b/src/ir.h
@@ -377,6 +377,7 @@ explicit InitExpr(ExprList exprs) : exprs(std::move(exprs)) {} ExprList exprs; + Location end_loc; }; struct Catch { @@ -833,6 +834,7 @@ FuncDeclaration decl; LocalTypes local_types; BindingHash bindings; + Location end_loc; ExprList exprs; };
diff --git a/src/type-checker.cc b/src/type-checker.cc index 1efc482..9be13bd 100644 --- a/src/type-checker.cc +++ b/src/type-checker.cc
@@ -644,7 +644,7 @@ Result TypeChecker::OnEnd() { Result result = Result::Ok; static const char* s_label_type_name[] = { - "function", "block", "loop", "if", "if false branch", "try", "try catch"}; + "function", "init_expr", "block", "loop", "if", "if false branch", "try", "try catch"}; WABT_STATIC_ASSERT(WABT_ARRAY_SIZE(s_label_type_name) == kLabelTypeCount); Label* label; CHECK_RESULT(TopLabel(&label));
diff --git a/src/validator.cc b/src/validator.cc index f4351f6..1e23419 100644 --- a/src/validator.cc +++ b/src/validator.cc
@@ -88,6 +88,8 @@ Result OnBinaryExpr(BinaryExpr*) override; Result BeginBlockExpr(BlockExpr*) override; Result EndBlockExpr(BlockExpr*) override; + Result BeginInitExpr(InitExpr*) override; + Result EndInitExpr(InitExpr*) override; Result OnBrExpr(BrExpr*) override; Result OnBrIfExpr(BrIfExpr*) override; Result OnBrTableExpr(BrTableExpr*) override; @@ -243,6 +245,20 @@ return Result::Ok; } +Result Validator::BeginInitExpr(InitExpr* expr) { + /* + const Expr& expr = f->global.init_expr.exprs.front(); + result_ |= + validator_.OnBlock(expr->exprs.front()->loc, GetDeclarationType(expr->block.decl)); + */ + return Result::Ok; +} + +Result Validator::EndInitExpr(InitExpr* expr) { + result_ |= validator_.OnEnd(expr->end_loc); + return Result::Ok; +} + Result Validator::OnBrExpr(BrExpr* expr) { result_ |= validator_.OnBr(expr->loc, expr->var); return Result::Ok;
diff --git a/src/wat-writer.cc b/src/wat-writer.cc index 1e8d502..11d54b3 100644 --- a/src/wat-writer.cc +++ b/src/wat-writer.cc
@@ -552,6 +552,8 @@ Result OnBinaryExpr(BinaryExpr*) override; Result BeginBlockExpr(BlockExpr*) override; Result EndBlockExpr(BlockExpr*) override; + Result BeginInitExpr(InitExpr*) override; + Result EndInitExpr(InitExpr*) override; Result OnBrExpr(BrExpr*) override; Result OnBrIfExpr(BrIfExpr*) override; Result OnBrTableExpr(BrTableExpr*) override; @@ -639,6 +641,14 @@ return Result::Ok; } +Result WatWriter::ExprVisitorDelegate::BeginInitExpr(InitExpr* expr) { + return Result::Ok; +} + +Result WatWriter::ExprVisitorDelegate::EndInitExpr(InitExpr* expr) { + return Result::Ok; +} + Result WatWriter::ExprVisitorDelegate::OnBrExpr(BrExpr* expr) { writer_->WritePutsSpace(Opcode::Br_Opcode.GetName()); writer_->WriteBrVar(expr->var, NextChar::Newline);
diff --git a/test/binary/bad-function-missing-end.txt b/test/binary/bad-function-missing-end.txt new file mode 100644 index 0000000..d2a7b48 --- /dev/null +++ b/test/binary/bad-function-missing-end.txt
@@ -0,0 +1,17 @@ +;;; TOOL: run-gen-wasm-interp +;;; ERROR: 1 +magic +version +section(TYPE) { count[1] function params[0] results[0] } +section(FUNCTION) { count[1] sig[0] } +section(CODE) { + count[1] + size[4] + locals[0] + i32.const + leb_i32(42) + drop +} +(;; STDERR ;;; +0000019: error: function body longer than given size +;;; STDERR ;;)