summaryrefslogtreecommitdiff
path: root/src/interp/binary-reader-interp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/interp/binary-reader-interp.cc')
-rw-r--r--src/interp/binary-reader-interp.cc109
1 files changed, 29 insertions, 80 deletions
diff --git a/src/interp/binary-reader-interp.cc b/src/interp/binary-reader-interp.cc
index 62803fc7..47a2d256 100644
--- a/src/interp/binary-reader-interp.cc
+++ b/src/interp/binary-reader-interp.cc
@@ -78,8 +78,6 @@ class BinaryReaderInterp : public BinaryReaderNop {
Errors* errors,
const Features& features);
- ValueType GetType(InitExpr);
-
// Implement BinaryReader.
bool OnError(const Error&) override;
@@ -301,7 +299,7 @@ class BinaryReaderInterp : public BinaryReaderNop {
Index keep_extra,
Index* out_drop_count,
Index* out_keep_count);
- Result BeginInitExpr(Type type);
+ Result BeginInitExpr(Type type, FuncDesc* init_func);
Result EndInitExpr();
void EmitBr(Index depth,
@@ -326,8 +324,6 @@ class BinaryReaderInterp : public BinaryReaderNop {
FixupMap depth_fixups_;
FixupMap func_fixups_;
- bool reading_init_expr_ = false;
- InitExpr init_expr_;
u32 local_decl_count_;
u32 local_count_;
@@ -619,37 +615,37 @@ Result BinaryReaderInterp::OnGlobalCount(Index count) {
Result BinaryReaderInterp::BeginGlobal(Index index, Type type, bool mutable_) {
CHECK_RESULT(validator_.OnGlobal(GetLocation(), type, mutable_));
GlobalType global_type{type, ToMutability(mutable_)};
- module_.globals.push_back(GlobalDesc{global_type, InitExpr{}});
+ FuncDesc init_func{FuncType{{}, {type}}, {}, Istream::kInvalidOffset, {}};
+ module_.globals.push_back(GlobalDesc{global_type, init_func});
global_types_.push_back(global_type);
- init_expr_.kind = InitExprKind::None;
return Result::Ok;
}
Result BinaryReaderInterp::BeginGlobalInitExpr(Index index) {
- GlobalType type = global_types_[index];
- return BeginInitExpr(type.type);
+ GlobalDesc& global = module_.globals.back();
+ return BeginInitExpr(global.type.type, &global.init_func);
}
Result BinaryReaderInterp::EndInitExpr() {
- assert(reading_init_expr_);
- reading_init_expr_ = false;
+ FixupTopLabel();
CHECK_RESULT(validator_.EndInitExpr());
+ istream_.Emit(Opcode::Return);
+ PopLabel();
return Result::Ok;
}
-Result BinaryReaderInterp::BeginInitExpr(Type type) {
- assert(!reading_init_expr_);
- reading_init_expr_ = true;
- init_expr_.kind = InitExprKind::None;
+Result BinaryReaderInterp::BeginInitExpr(Type type, FuncDesc* func) {
+ label_stack_.clear();
+ func_ = func;
+ func_->code_offset = istream_.end();
CHECK_RESULT(validator_.BeginInitExpr(GetLocation(), type));
+ // Push implicit init func label (equivalent to return).
+ PushLabel(LabelKind::Try, Istream::kInvalidOffset, Istream::kInvalidOffset);
return Result::Ok;
}
Result BinaryReaderInterp::EndGlobalInitExpr(Index index) {
- CHECK_RESULT(EndInitExpr());
- GlobalDesc& global = module_.globals.back();
- global.init = init_expr_;
- return Result::Ok;
+ return EndInitExpr();
}
Result BinaryReaderInterp::OnTagCount(Index count) {
@@ -702,24 +698,20 @@ Result BinaryReaderInterp::BeginElemSegment(Index index,
auto mode = ToSegmentMode(flags);
CHECK_RESULT(validator_.OnElemSegment(GetLocation(), Var(table_index), mode));
- ElemDesc desc;
- desc.type = ValueType::Void; // Initialized later in OnElemSegmentElemType.
- desc.mode = mode;
- desc.table_index = table_index;
+ FuncDesc init_func{
+ FuncType{{}, {ValueType::I32}}, {}, Istream::kInvalidOffset, {}};
+ ElemDesc desc{{}, ValueType::Void, mode, table_index, init_func};
module_.elems.push_back(desc);
- init_expr_.kind = InitExprKind::None;
return Result::Ok;
}
Result BinaryReaderInterp::BeginElemSegmentInitExpr(Index index) {
- return BeginInitExpr(Type::I32);
+ ElemDesc& elem = module_.elems.back();
+ return BeginInitExpr(Type::I32, &elem.init_func);
}
Result BinaryReaderInterp::EndElemSegmentInitExpr(Index index) {
- CHECK_RESULT(EndInitExpr());
- ElemDesc& elem = module_.elems.back();
- elem.offset = init_expr_;
- return Result::Ok;
+ return EndInitExpr();
}
Result BinaryReaderInterp::OnElemSegmentElemType(Index index, Type elem_type) {
@@ -761,14 +753,12 @@ Result BinaryReaderInterp::OnDataCount(Index count) {
Result BinaryReaderInterp::BeginDataSegmentInitExpr(Index index) {
MemoryType t = memory_types_[0];
- return BeginInitExpr(t.limits.is_64 ? Type::I64 : Type::I32);
+ DataDesc& data = module_.datas.back();
+ return BeginInitExpr(t.limits.is_64 ? Type::I64 : Type::I32, &data.init_func);
}
Result BinaryReaderInterp::EndDataSegmentInitExpr(Index index) {
- CHECK_RESULT(EndInitExpr());
- DataDesc& data = module_.datas.back();
- data.offset = init_expr_;
- return Result::Ok;
+ return EndInitExpr();
}
Result BinaryReaderInterp::BeginDataSegment(Index index,
@@ -778,11 +768,10 @@ Result BinaryReaderInterp::BeginDataSegment(Index index,
CHECK_RESULT(
validator_.OnDataSegment(GetLocation(), Var(memory_index), mode));
- DataDesc desc;
- desc.mode = mode;
- desc.memory_index = memory_index;
+ FuncDesc init_func{
+ FuncType{{}, {ValueType::I32}}, {}, Istream::kInvalidOffset, {}};
+ DataDesc desc{{}, mode, memory_index, init_func};
module_.datas.push_back(desc);
- init_expr_.kind = InitExprKind::None;
return Result::Ok;
}
@@ -873,7 +862,7 @@ Index BinaryReaderInterp::num_func_imports() const {
}
Result BinaryReaderInterp::OnOpcode(Opcode opcode) {
- if ((func_ == nullptr || label_stack_.empty()) && !reading_init_expr_) {
+ if (func_ == nullptr || label_stack_.empty()) {
PrintError("Unexpected instruction after end of function");
return Result::Error;
}
@@ -1021,7 +1010,7 @@ Result BinaryReaderInterp::OnElseExpr() {
}
Result BinaryReaderInterp::OnEndExpr() {
- if (reading_init_expr_ || label_stack_.size() == 1) {
+ if (label_stack_.size() == 1) {
return Result::Ok;
}
SharedValidator::Label* label;
@@ -1188,66 +1177,36 @@ Result BinaryReaderInterp::OnDropExpr() {
Result BinaryReaderInterp::OnI32ConstExpr(uint32_t value) {
CHECK_RESULT(validator_.OnConst(GetLocation(), Type::I32));
- if (reading_init_expr_) {
- init_expr_.kind = InitExprKind::I32;
- init_expr_.i32_ = value;
- return Result::Ok;
- }
istream_.Emit(Opcode::I32Const, value);
return Result::Ok;
}
Result BinaryReaderInterp::OnI64ConstExpr(uint64_t value) {
CHECK_RESULT(validator_.OnConst(GetLocation(), Type::I64));
- if (reading_init_expr_) {
- init_expr_.kind = InitExprKind::I64;
- init_expr_.i64_ = value;
- return Result::Ok;
- }
istream_.Emit(Opcode::I64Const, value);
return Result::Ok;
}
Result BinaryReaderInterp::OnF32ConstExpr(uint32_t value_bits) {
CHECK_RESULT(validator_.OnConst(GetLocation(), Type::F32));
- if (reading_init_expr_) {
- init_expr_.kind = InitExprKind::F32;
- init_expr_.f32_ = Bitcast<f32>(value_bits);
- return Result::Ok;
- }
istream_.Emit(Opcode::F32Const, value_bits);
return Result::Ok;
}
Result BinaryReaderInterp::OnF64ConstExpr(uint64_t value_bits) {
CHECK_RESULT(validator_.OnConst(GetLocation(), Type::F64));
- if (reading_init_expr_) {
- init_expr_.kind = InitExprKind::F64;
- init_expr_.f64_ = Bitcast<f64>(value_bits);
- return Result::Ok;
- }
istream_.Emit(Opcode::F64Const, value_bits);
return Result::Ok;
}
Result BinaryReaderInterp::OnV128ConstExpr(v128 value_bits) {
CHECK_RESULT(validator_.OnConst(GetLocation(), Type::V128));
- if (reading_init_expr_) {
- init_expr_.kind = InitExprKind::V128;
- init_expr_.v128_ = Bitcast<v128>(value_bits);
- return Result::Ok;
- }
istream_.Emit(Opcode::V128Const, value_bits);
return Result::Ok;
}
Result BinaryReaderInterp::OnGlobalGetExpr(Index global_index) {
CHECK_RESULT(validator_.OnGlobalGet(GetLocation(), Var(global_index)));
- if (reading_init_expr_) {
- init_expr_.kind = InitExprKind::GlobalGet;
- init_expr_.index_ = global_index;
- return Result::Ok;
- }
istream_.Emit(Opcode::GlobalGet, global_index);
return Result::Ok;
}
@@ -1339,22 +1298,12 @@ Result BinaryReaderInterp::OnTableFillExpr(Index table_index) {
Result BinaryReaderInterp::OnRefFuncExpr(Index func_index) {
CHECK_RESULT(validator_.OnRefFunc(GetLocation(), Var(func_index)));
- if (reading_init_expr_) {
- init_expr_.kind = InitExprKind::RefFunc;
- init_expr_.index_ = func_index;
- return Result::Ok;
- }
istream_.Emit(Opcode::RefFunc, func_index);
return Result::Ok;
}
Result BinaryReaderInterp::OnRefNullExpr(Type type) {
CHECK_RESULT(validator_.OnRefNull(GetLocation(), type));
- if (reading_init_expr_) {
- init_expr_.kind = InitExprKind::RefNull;
- init_expr_.type_ = type;
- return Result::Ok;
- }
istream_.Emit(Opcode::RefNull);
return Result::Ok;
}