diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/binary-reader.cc | 22 | ||||
-rw-r--r-- | src/common.h | 1 | ||||
-rw-r--r-- | src/interp/binary-reader-interp.cc | 4 | ||||
-rw-r--r-- | src/interp/interp.cc | 9 | ||||
-rw-r--r-- | src/shared-validator.cc | 10 | ||||
-rw-r--r-- | src/type-checker.cc | 2 | ||||
-rw-r--r-- | src/wast-parser.cc | 3 |
7 files changed, 32 insertions, 19 deletions
diff --git a/src/binary-reader.cc b/src/binary-reader.cc index a23ec3b2..8446c197 100644 --- a/src/binary-reader.cc +++ b/src/binary-reader.cc @@ -118,8 +118,7 @@ class BinaryReader { Index NumTotalFuncs(); - Result ReadI32InitExpr(Index index) WABT_WARN_UNUSED; - Result ReadInitExpr(Index index, bool require_i32 = false) WABT_WARN_UNUSED; + Result ReadInitExpr(Index index, Type required = Type::Any) WABT_WARN_UNUSED; Result ReadTable(Type* out_elem_type, Limits* out_elem_limits) WABT_WARN_UNUSED; Result ReadMemory(Limits* out_page_limits) WABT_WARN_UNUSED; @@ -468,11 +467,7 @@ Index BinaryReader::NumTotalFuncs() { return num_func_imports_ + num_function_signatures_; } -Result BinaryReader::ReadI32InitExpr(Index index) { - return ReadInitExpr(index, true); -} - -Result BinaryReader::ReadInitExpr(Index index, bool require_i32) { +Result BinaryReader::ReadInitExpr(Index index, Type required) { Opcode opcode; CHECK_RESULT(ReadOpcode(&opcode, "opcode")); ERROR_UNLESS_OPCODE_ENABLED(opcode); @@ -542,11 +537,16 @@ Result BinaryReader::ReadInitExpr(Index index, bool require_i32) { return ReportUnexpectedOpcode(opcode, "in initializer expression"); } - if (require_i32 && opcode != Opcode::I32Const && - opcode != Opcode::GlobalGet) { + if (required == Type::I32 && opcode != Opcode::I32Const && + opcode != Opcode::GlobalGet) { PrintError("expected i32 init_expr"); return Result::Error; } + if (required == Type::I64 && opcode != Opcode::I64Const && + opcode != Opcode::GlobalGet) { + PrintError("expected i64 init_expr"); + return Result::Error; + } CHECK_RESULT(ReadOpcode(&opcode, "opcode")); ERROR_UNLESS(opcode == Opcode::End, @@ -2443,7 +2443,7 @@ Result BinaryReader::ReadElemSection(Offset section_size) { if (!(flags & SegPassive)) { CALLBACK(BeginElemSegmentInitExpr, i); - CHECK_RESULT(ReadI32InitExpr(i)); + CHECK_RESULT(ReadInitExpr(i, Type::I32)); CALLBACK(EndElemSegmentInitExpr, i); } @@ -2559,7 +2559,7 @@ Result BinaryReader::ReadDataSection(Offset section_size) { CALLBACK(BeginDataSegment, i, memory_index, flags); if (!(flags & SegPassive)) { CALLBACK(BeginDataSegmentInitExpr, i); - CHECK_RESULT(ReadI32InitExpr(i)); + CHECK_RESULT(ReadInitExpr(i, memories[0].IndexType())); CALLBACK(EndDataSegmentInitExpr, i); } diff --git a/src/common.h b/src/common.h index dbac0a89..e0b50f17 100644 --- a/src/common.h +++ b/src/common.h @@ -394,6 +394,7 @@ struct Limits { has_max(true), is_shared(is_shared), is_64(is_64) {} + Type IndexType() const { return is_64 ? Type::I64 : Type::I32; } uint64_t initial = 0; uint64_t max = 0; diff --git a/src/interp/binary-reader-interp.cc b/src/interp/binary-reader-interp.cc index ca6568b9..10ba15f7 100644 --- a/src/interp/binary-reader-interp.cc +++ b/src/interp/binary-reader-interp.cc @@ -771,6 +771,10 @@ Result BinaryReaderInterp::EndDataSegmentInitExpr(Index index) { CHECK_RESULT(validator_.OnDataSegmentInitExpr_Const(loc, ValueType::I32)); break; + case InitExprKind::I64: + CHECK_RESULT(validator_.OnDataSegmentInitExpr_Const(loc, ValueType::I64)); + break; + case InitExprKind::GlobalGet: CHECK_RESULT(validator_.OnDataSegmentInitExpr_GlobalGet( loc, Var(init_expr_.index_))); diff --git a/src/interp/interp.cc b/src/interp/interp.cc index 6fd391ac..cbcfbaf6 100644 --- a/src/interp/interp.cc +++ b/src/interp/interp.cc @@ -850,7 +850,9 @@ Instance::Ptr Instance::Instantiate(Store& store, if (desc.mode == SegmentMode::Active) { Result result; Memory::Ptr memory{store, inst->memories_[desc.memory_index]}; - u32 offset = inst->ResolveInitExpr(store, desc.offset).Get<u32>(); + Value offset_op = inst->ResolveInitExpr(store, desc.offset); + u64 offset = memory->type().limits.is_64 ? offset_op.Get<u64>() + : offset_op.Get<u32>(); if (pass == Check) { result = memory->IsValidAccess(offset, 0, segment.size()) ? Result::Ok @@ -864,8 +866,9 @@ Instance::Ptr Instance::Instantiate(Store& store, *out_trap = Trap::New( store, StringPrintf("out of bounds memory access: data segment is " - "out of bounds: [%u, %" PRIu64 ") >= max value %" - PRIu64, offset, u64{offset} + segment.size(), + "out of bounds: [%" PRIu64 ", %" PRIu64 + ") >= max value %" + PRIu64, offset, offset + segment.size(), memory->ByteSize())); return {}; } diff --git a/src/shared-validator.cc b/src/shared-validator.cc index 354c8e93..9c62bf0f 100644 --- a/src/shared-validator.cc +++ b/src/shared-validator.cc @@ -371,7 +371,9 @@ Result SharedValidator::OnDataSegment(const Location& loc, Result SharedValidator::OnDataSegmentInitExpr_Const(const Location& loc, Type type) { - return CheckType(loc, type, Type::I32, "data segment offset"); + auto required = + memories_.empty() ? Type(Type::I32) : memories_[0].limits.IndexType(); + return CheckType(loc, type, required, "data segment offset"); } Result SharedValidator::OnDataSegmentInitExpr_GlobalGet(const Location& loc, @@ -385,14 +387,16 @@ Result SharedValidator::OnDataSegmentInitExpr_GlobalGet(const Location& loc, loc, "initializer expression cannot reference a mutable global"); } - result |= CheckType(loc, ref_global.type, Type::I32, "data segment offset"); + auto required = + memories_.empty() ? Type(Type::I32) : memories_[0].limits.IndexType(); + result |= CheckType(loc, ref_global.type, required, "data segment offset"); return result; } Result SharedValidator::OnDataSegmentInitExpr_Other(const Location& loc) { return PrintError(loc, "invalid data segment offset, must be a constant " - "expression; either i32.const or " + "expression; either iXX.const or " "global.get."); } diff --git a/src/type-checker.cc b/src/type-checker.cc index df302a1d..1826e1d2 100644 --- a/src/type-checker.cc +++ b/src/type-checker.cc @@ -697,7 +697,7 @@ Result TypeChecker::OnMemoryInit(uint32_t segment, const Limits& limits) { } Result TypeChecker::OnMemorySize(const Limits& limits) { - PushType(limits.is_64 ? Type::I64 : Type::I32); + PushType(limits.IndexType()); return Result::Ok; } diff --git a/src/wast-parser.cc b/src/wast-parser.cc index 9bff0156..fde32e50 100644 --- a/src/wast-parser.cc +++ b/src/wast-parser.cc @@ -1484,7 +1484,8 @@ Result WastParser::ParseMemoryModuleField(Module* module) { auto data_segment_field = MakeUnique<DataSegmentModuleField>(loc); DataSegment& data_segment = data_segment_field->data_segment; data_segment.memory_var = Var(module->memories.size()); - data_segment.offset.push_back(MakeUnique<ConstExpr>(Const::I32(0))); + data_segment.offset.push_back(MakeUnique<ConstExpr>( + field->memory.page_limits.is_64 ? Const::I64(0) : Const::I32(0))); data_segment.offset.back().loc = loc; ParseTextListOpt(&data_segment.data); EXPECT(Rpar); |