summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binary-reader.cc22
-rw-r--r--src/common.h1
-rw-r--r--src/interp/binary-reader-interp.cc4
-rw-r--r--src/interp/interp.cc9
-rw-r--r--src/shared-validator.cc10
-rw-r--r--src/type-checker.cc2
-rw-r--r--src/wast-parser.cc3
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);