summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--test/interp/load64.txt8
-rw-r--r--test/regress/regress-27.txt2
-rw-r--r--test/spec/data.txt2
m---------third_party/testsuite0
11 files changed, 38 insertions, 25 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);
diff --git a/test/interp/load64.txt b/test/interp/load64.txt
index 387edb81..50765f20 100644
--- a/test/interp/load64.txt
+++ b/test/interp/load64.txt
@@ -2,10 +2,10 @@
;;; ARGS: --enable-memory64
(module
(memory i64 1)
- (data (i32.const 0) "\ff\ff\ff\ff")
- (data (i32.const 4) "\00\00\ce\41")
- (data (i32.const 8) "\00\00\00\00\00\ff\8f\40")
- (data (i32.const 16) "\ff\ff\ff\ff\ff\ff\ff\ff")
+ (data (i64.const 0) "\ff\ff\ff\ff")
+ (data (i64.const 4) "\00\00\ce\41")
+ (data (i64.const 8) "\00\00\00\00\00\ff\8f\40")
+ (data (i64.const 16) "\ff\ff\ff\ff\ff\ff\ff\ff")
(func (export "i32_load8_s") (result i32)
i64.const 0
diff --git a/test/regress/regress-27.txt b/test/regress/regress-27.txt
index f984b1ab..594e4162 100644
--- a/test/regress/regress-27.txt
+++ b/test/regress/regress-27.txt
@@ -14,6 +14,6 @@ section(DATA) {
data[str("test")]
}
(;; STDERR ;;;
-error: invalid data segment offset, must be a constant expression; either i32.const or global.get.
+error: invalid data segment offset, must be a constant expression; either iXX.const or global.get.
0000012: error: EndDataSegmentInitExpr callback failed
;;; STDERR ;;)
diff --git a/test/spec/data.txt b/test/spec/data.txt
index ced8756e..82c7d9f9 100644
--- a/test/spec/data.txt
+++ b/test/spec/data.txt
@@ -43,7 +43,7 @@ out/test/spec/data.wast:337: assert_invalid passed:
out/test/spec/data.wast:355: assert_invalid passed:
0000013: error: expected i32 init_expr
out/test/spec/data.wast:363: assert_invalid passed:
- error: invalid data segment offset, must be a constant expression; either i32.const or global.get.
+ error: invalid data segment offset, must be a constant expression; either iXX.const or global.get.
0000012: error: EndDataSegmentInitExpr callback failed
out/test/spec/data.wast:371: assert_invalid passed:
0000014: error: expected END opcode after initializer expression
diff --git a/third_party/testsuite b/third_party/testsuite
-Subproject 9994915e0cca8b42a16c577e4c85491822367dd
+Subproject 01efde81028c5b0d099eb836645a2dc5e775544