summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binary-reader-logging.cc4
-rw-r--r--src/interp/interp-inl.h81
-rw-r--r--src/interp/interp.cc47
-rw-r--r--src/interp/interp.h34
-rw-r--r--src/shared-validator.cc8
-rw-r--r--src/tools/spectest-interp.cc4
-rw-r--r--src/wat-writer.cc4
7 files changed, 107 insertions, 75 deletions
diff --git a/src/binary-reader-logging.cc b/src/binary-reader-logging.cc
index fbc4af9c..dbf2593c 100644
--- a/src/binary-reader-logging.cc
+++ b/src/binary-reader-logging.cc
@@ -607,7 +607,7 @@ Result BinaryReaderLogging::OnSegmentInfo(Index index,
Address alignment,
uint32_t flags) {
LOGF("OnSegmentInfo(%d name: " PRIstringview
- ", alignment: %d, flags: 0x%x)\n",
+ ", alignment: %lu, flags: 0x%x)\n",
index, WABT_PRINTF_STRING_VIEW_ARG(name), alignment, flags);
return reader_->OnSegmentInfo(index, name, alignment, flags);
}
@@ -695,7 +695,7 @@ Result BinaryReaderLogging::OnComdatEntry(ComdatType kind, Index index) {
#define DEFINE_LOAD_STORE_OPCODE(name) \
Result BinaryReaderLogging::name(Opcode opcode, Address alignment_log2, \
Address offset) { \
- LOGF(#name "(opcode: \"%s\" (%u), align log2: %u, offset: %" PRIaddress \
+ LOGF(#name "(opcode: \"%s\" (%u), align log2: %lu, offset: %" PRIaddress\
")\n", \
opcode.GetName(), opcode.GetCode(), alignment_log2, offset); \
return reader_->name(opcode, alignment_log2, offset); \
diff --git a/src/interp/interp-inl.h b/src/interp/interp-inl.h
index ab755bbc..fbec1014 100644
--- a/src/interp/interp-inl.h
+++ b/src/interp/interp-inl.h
@@ -371,53 +371,54 @@ inline bool TypesMatch(ValueType expected, ValueType actual) {
}
//// Value ////
-inline Value WABT_VECTORCALL Value::Make(s32 val) { Value res; res.i32_ = val; return res; }
-inline Value WABT_VECTORCALL Value::Make(u32 val) { Value res; res.i32_ = val; return res; }
-inline Value WABT_VECTORCALL Value::Make(s64 val) { Value res; res.i64_ = val; return res; }
-inline Value WABT_VECTORCALL Value::Make(u64 val) { Value res; res.i64_ = val; return res; }
-inline Value WABT_VECTORCALL Value::Make(f32 val) { Value res; res.f32_ = val; return res; }
-inline Value WABT_VECTORCALL Value::Make(f64 val) { Value res; res.f64_ = val; return res; }
-inline Value WABT_VECTORCALL Value::Make(v128 val) { Value res; res.v128_ = val; return res; }
-inline Value WABT_VECTORCALL Value::Make(Ref val) { Value res; res.ref_ = val; return res; }
+inline Value WABT_VECTORCALL Value::Make(s32 val) { Value res; res.i32_ = val; res.SetType(ValueType::I32); return res; }
+inline Value WABT_VECTORCALL Value::Make(u32 val) { Value res; res.i32_ = val; res.SetType(ValueType::I32); return res; }
+inline Value WABT_VECTORCALL Value::Make(s64 val) { Value res; res.i64_ = val; res.SetType(ValueType::I64); return res; }
+inline Value WABT_VECTORCALL Value::Make(u64 val) { Value res; res.i64_ = val; res.SetType(ValueType::I64); return res; }
+inline Value WABT_VECTORCALL Value::Make(f32 val) { Value res; res.f32_ = val; res.SetType(ValueType::F32); return res; }
+inline Value WABT_VECTORCALL Value::Make(f64 val) { Value res; res.f64_ = val; res.SetType(ValueType::F64); return res; }
+inline Value WABT_VECTORCALL Value::Make(v128 val) { Value res; res.v128_ = val; res.SetType(ValueType::V128); return res; }
+inline Value WABT_VECTORCALL Value::Make(Ref val) { Value res; res.ref_ = val; res.SetType(ValueType::ExternRef); return res; }
template <typename T, u8 L>
Value WABT_VECTORCALL Value::Make(Simd<T, L> val) {
Value res;
res.v128_ = Bitcast<v128>(val);
+ res.SetType(ValueType::V128);
return res;
}
-template <> inline s8 WABT_VECTORCALL Value::Get<s8>() const { return i32_; }
-template <> inline u8 WABT_VECTORCALL Value::Get<u8>() const { return i32_; }
-template <> inline s16 WABT_VECTORCALL Value::Get<s16>() const { return i32_; }
-template <> inline u16 WABT_VECTORCALL Value::Get<u16>() const { return i32_; }
-template <> inline s32 WABT_VECTORCALL Value::Get<s32>() const { return i32_; }
-template <> inline u32 WABT_VECTORCALL Value::Get<u32>() const { return i32_; }
-template <> inline s64 WABT_VECTORCALL Value::Get<s64>() const { return i64_; }
-template <> inline u64 WABT_VECTORCALL Value::Get<u64>() const { return i64_; }
-template <> inline f32 WABT_VECTORCALL Value::Get<f32>() const { return f32_; }
-template <> inline f64 WABT_VECTORCALL Value::Get<f64>() const { return f64_; }
-template <> inline v128 WABT_VECTORCALL Value::Get<v128>() const { return v128_; }
-template <> inline Ref WABT_VECTORCALL Value::Get<Ref>() const { return ref_; }
-
-template <> inline s8x16 WABT_VECTORCALL Value::Get<s8x16>() const { return Bitcast<s8x16>(v128_); }
-template <> inline u8x16 WABT_VECTORCALL Value::Get<u8x16>() const { return Bitcast<u8x16>(v128_); }
-template <> inline s16x8 WABT_VECTORCALL Value::Get<s16x8>() const { return Bitcast<s16x8>(v128_); }
-template <> inline u16x8 WABT_VECTORCALL Value::Get<u16x8>() const { return Bitcast<u16x8>(v128_); }
-template <> inline s32x4 WABT_VECTORCALL Value::Get<s32x4>() const { return Bitcast<s32x4>(v128_); }
-template <> inline u32x4 WABT_VECTORCALL Value::Get<u32x4>() const { return Bitcast<u32x4>(v128_); }
-template <> inline s64x2 WABT_VECTORCALL Value::Get<s64x2>() const { return Bitcast<s64x2>(v128_); }
-template <> inline u64x2 WABT_VECTORCALL Value::Get<u64x2>() const { return Bitcast<u64x2>(v128_); }
-template <> inline f32x4 WABT_VECTORCALL Value::Get<f32x4>() const { return Bitcast<f32x4>(v128_); }
-template <> inline f64x2 WABT_VECTORCALL Value::Get<f64x2>() const { return Bitcast<f64x2>(v128_); }
-
-template <> inline void WABT_VECTORCALL Value::Set<s32>(s32 val) { i32_ = val; }
-template <> inline void WABT_VECTORCALL Value::Set<u32>(u32 val) { i32_ = val; }
-template <> inline void WABT_VECTORCALL Value::Set<s64>(s64 val) { i64_ = val; }
-template <> inline void WABT_VECTORCALL Value::Set<u64>(u64 val) { i64_ = val; }
-template <> inline void WABT_VECTORCALL Value::Set<f32>(f32 val) { f32_ = val; }
-template <> inline void WABT_VECTORCALL Value::Set<f64>(f64 val) { f64_ = val; }
-template <> inline void WABT_VECTORCALL Value::Set<v128>(v128 val) { v128_ = val; }
-template <> inline void WABT_VECTORCALL Value::Set<Ref>(Ref val) { ref_ = val; }
+template <> inline s8 WABT_VECTORCALL Value::Get<s8>() const { CheckType(ValueType::I32); return i32_; }
+template <> inline u8 WABT_VECTORCALL Value::Get<u8>() const { CheckType(ValueType::I32); return i32_; }
+template <> inline s16 WABT_VECTORCALL Value::Get<s16>() const { CheckType(ValueType::I32); return i32_; }
+template <> inline u16 WABT_VECTORCALL Value::Get<u16>() const { CheckType(ValueType::I32); return i32_; }
+template <> inline s32 WABT_VECTORCALL Value::Get<s32>() const { CheckType(ValueType::I32); return i32_; }
+template <> inline u32 WABT_VECTORCALL Value::Get<u32>() const { CheckType(ValueType::I32); return i32_; }
+template <> inline s64 WABT_VECTORCALL Value::Get<s64>() const { CheckType(ValueType::I64); return i64_; }
+template <> inline u64 WABT_VECTORCALL Value::Get<u64>() const { CheckType(ValueType::I64); return i64_; }
+template <> inline f32 WABT_VECTORCALL Value::Get<f32>() const { CheckType(ValueType::F32); return f32_; }
+template <> inline f64 WABT_VECTORCALL Value::Get<f64>() const { CheckType(ValueType::F64); return f64_; }
+template <> inline v128 WABT_VECTORCALL Value::Get<v128>() const { CheckType(ValueType::V128); return v128_; }
+template <> inline Ref WABT_VECTORCALL Value::Get<Ref>() const { CheckType(ValueType::ExternRef); return ref_; }
+
+template <> inline s8x16 WABT_VECTORCALL Value::Get<s8x16>() const { CheckType(ValueType::V128); return Bitcast<s8x16>(v128_); }
+template <> inline u8x16 WABT_VECTORCALL Value::Get<u8x16>() const { CheckType(ValueType::V128); return Bitcast<u8x16>(v128_); }
+template <> inline s16x8 WABT_VECTORCALL Value::Get<s16x8>() const { CheckType(ValueType::V128); return Bitcast<s16x8>(v128_); }
+template <> inline u16x8 WABT_VECTORCALL Value::Get<u16x8>() const { CheckType(ValueType::V128); return Bitcast<u16x8>(v128_); }
+template <> inline s32x4 WABT_VECTORCALL Value::Get<s32x4>() const { CheckType(ValueType::V128); return Bitcast<s32x4>(v128_); }
+template <> inline u32x4 WABT_VECTORCALL Value::Get<u32x4>() const { CheckType(ValueType::V128); return Bitcast<u32x4>(v128_); }
+template <> inline s64x2 WABT_VECTORCALL Value::Get<s64x2>() const { CheckType(ValueType::V128); return Bitcast<s64x2>(v128_); }
+template <> inline u64x2 WABT_VECTORCALL Value::Get<u64x2>() const { CheckType(ValueType::V128); return Bitcast<u64x2>(v128_); }
+template <> inline f32x4 WABT_VECTORCALL Value::Get<f32x4>() const { CheckType(ValueType::V128); return Bitcast<f32x4>(v128_); }
+template <> inline f64x2 WABT_VECTORCALL Value::Get<f64x2>() const { CheckType(ValueType::V128); return Bitcast<f64x2>(v128_); }
+
+template <> inline void WABT_VECTORCALL Value::Set<s32>(s32 val) { i32_ = val; SetType(ValueType::I32); }
+template <> inline void WABT_VECTORCALL Value::Set<u32>(u32 val) { i32_ = val; SetType(ValueType::I32); }
+template <> inline void WABT_VECTORCALL Value::Set<s64>(s64 val) { i64_ = val; SetType(ValueType::I64); }
+template <> inline void WABT_VECTORCALL Value::Set<u64>(u64 val) { i64_ = val; SetType(ValueType::I64); }
+template <> inline void WABT_VECTORCALL Value::Set<f32>(f32 val) { f32_ = val; SetType(ValueType::F32); }
+template <> inline void WABT_VECTORCALL Value::Set<f64>(f64 val) { f64_ = val; SetType(ValueType::F64); }
+template <> inline void WABT_VECTORCALL Value::Set<v128>(v128 val) { v128_ = val; SetType(ValueType::V128); }
+template <> inline void WABT_VECTORCALL Value::Set<Ref>(Ref val) { ref_ = val; SetType(ValueType::ExternRef); }
//// Store ////
inline bool Store::IsValid(Ref ref) const {
diff --git a/src/interp/interp.cc b/src/interp/interp.cc
index 6ea80279..f73ec35f 100644
--- a/src/interp/interp.cc
+++ b/src/interp/interp.cc
@@ -615,7 +615,7 @@ Global::Global(Store& store, GlobalType type, Value value)
void Global::Mark(Store& store) {
if (IsReference(type_.type)) {
- store.Mark(value_.ref_);
+ store.Mark(value_.Get<Ref>());
}
}
@@ -846,8 +846,8 @@ 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 %u",
- offset, u64{offset} + segment.size(),
+ "out of bounds: [%u, %" PRIu64 ") >= max value %"
+ PRIu64, offset, u64{offset} + segment.size(),
memory->ByteSize()));
return {};
}
@@ -899,7 +899,7 @@ void Thread::Mark(Store& store) {
frame.Mark(store);
}
for (auto index: refs_) {
- store.Mark(values_[index].ref_);
+ store.Mark(values_[index].Get<Ref>());
}
}
@@ -1760,11 +1760,11 @@ template <typename T, typename V>
RunResult Thread::DoStore(Instr instr, Trap::Ptr* out_trap) {
Memory::Ptr memory{store_, inst_->memories()[instr.imm_u32x2.fst]};
V val = static_cast<V>(Pop<T>());
- u32 offset = Pop<u32>();
+ u64 offset = memory->type().limits.is_64 ? Pop<u64>() : Pop<u32>();
TRAP_IF(Failed(memory->Store(offset, instr.imm_u32x2.snd, val)),
StringPrintf("out of bounds memory access: access at %" PRIu64
"+%" PRIzd " >= max value %u",
- u64{offset} + instr.imm_u32x2.snd, sizeof(V),
+ offset + instr.imm_u32x2.snd, sizeof(V),
memory->ByteSize()));
return RunResult::Ok;
}
@@ -2027,7 +2027,7 @@ RunResult Thread::DoSimdShift(BinopFunc<R, T> f) {
using ST = typename Simd128<T>::Type;
using SR = typename Simd128<R>::Type;
static_assert(ST::lanes == SR::lanes, "SIMD lanes don't match");
- auto amount = Pop<T>();
+ auto amount = Pop<u32>();
auto lhs = Pop<ST>();
SR result;
for (u8 i = 0; i < SR::lanes; ++i) {
@@ -2121,10 +2121,10 @@ RunResult Thread::DoSimdLoadExtend(Instr instr, Trap::Ptr* out_trap) {
template <typename T, typename V>
RunResult Thread::DoAtomicLoad(Instr instr, Trap::Ptr* out_trap) {
Memory::Ptr memory{store_, inst_->memories()[instr.imm_u32x2.fst]};
- u32 offset = Pop<u32>();
+ u64 offset = memory->type().limits.is_64 ? Pop<u64>() : Pop<u32>();
V val;
TRAP_IF(Failed(memory->AtomicLoad(offset, instr.imm_u32x2.snd, &val)),
- StringPrintf("invalid atomic access at %u+%u", offset,
+ StringPrintf("invalid atomic access at %lu+%u", offset,
instr.imm_u32x2.snd));
Push(static_cast<T>(val));
return RunResult::Ok;
@@ -2134,9 +2134,9 @@ template <typename T, typename V>
RunResult Thread::DoAtomicStore(Instr instr, Trap::Ptr* out_trap) {
Memory::Ptr memory{store_, inst_->memories()[instr.imm_u32x2.fst]};
V val = static_cast<V>(Pop<T>());
- u32 offset = Pop<u32>();
+ u64 offset = memory->type().limits.is_64 ? Pop<u64>() : Pop<u32>();
TRAP_IF(Failed(memory->AtomicStore(offset, instr.imm_u32x2.snd, val)),
- StringPrintf("invalid atomic access at %u+%u", offset,
+ StringPrintf("invalid atomic access at %lu+%u", offset,
instr.imm_u32x2.snd));
return RunResult::Ok;
}
@@ -2146,11 +2146,11 @@ RunResult Thread::DoAtomicRmw(BinopFunc<T, T> f,
Instr instr,
Trap::Ptr* out_trap) {
Memory::Ptr memory{store_, inst_->memories()[instr.imm_u32x2.fst]};
- T val = Pop<T>();
- u32 offset = Pop<u32>();
+ T val = static_cast<T>(Pop<R>());
+ u64 offset = memory->type().limits.is_64 ? Pop<u64>() : Pop<u32>();
T old;
TRAP_IF(Failed(memory->AtomicRmw(offset, instr.imm_u32x2.snd, val, f, &old)),
- StringPrintf("invalid atomic access at %u+%u", offset,
+ StringPrintf("invalid atomic access at %lu+%u", offset,
instr.imm_u32x2.snd));
Push(static_cast<R>(old));
return RunResult::Ok;
@@ -2162,10 +2162,10 @@ RunResult Thread::DoAtomicRmwCmpxchg(Instr instr, Trap::Ptr* out_trap) {
V replace = static_cast<V>(Pop<T>());
V expect = static_cast<V>(Pop<T>());
V old;
- u32 offset = Pop<u32>();
+ u64 offset = memory->type().limits.is_64 ? Pop<u64>() : Pop<u32>();
TRAP_IF(Failed(memory->AtomicRmwCmpxchg(offset, instr.imm_u32x2.snd, expect,
replace, &old)),
- StringPrintf("invalid atomic access at %u+%u", offset,
+ StringPrintf("invalid atomic access at %lu+%u", offset,
instr.imm_u32x2.snd));
Push(static_cast<T>(old));
return RunResult::Ok;
@@ -2182,8 +2182,19 @@ std::string Thread::TraceSource::Header(Istream::Offset offset) {
std::string Thread::TraceSource::Pick(Index index, Instr instr) {
Value val = thread_->Pick(index);
const char* reftype;
- // TODO: the opcode index and pick index go in opposite directions.
- auto type = instr.op.GetParamType(index);
+ // Estimate number of operands.
+ // TODO: Instead, record this accurately in opcode.def.
+ Index num_operands = 3;
+ for (Index i = 3; i >= 1; i--) {
+ if (instr.op.GetParamType(i) == ValueType::Void) {
+ num_operands--;
+ } else {
+ break;
+ }
+ }
+ auto type = index > num_operands
+ ? Type(ValueType::Void)
+ : instr.op.GetParamType(num_operands - index + 1);
if (type == ValueType::Void) {
// Void should never be displayed normally; we only expect to see it when
// the stack may have different a different type. This is likely to occur
diff --git a/src/interp/interp.h b/src/interp/interp.h
index dcdaaa50..5dfd42a9 100644
--- a/src/interp/interp.h
+++ b/src/interp/interp.h
@@ -507,8 +507,7 @@ class RefPtr {
Store::RootList::Index root_index_;
};
-union Value {
- Value() = default;
+struct Value {
static Value WABT_VECTORCALL Make(s32);
static Value WABT_VECTORCALL Make(u32);
static Value WABT_VECTORCALL Make(s64);
@@ -525,12 +524,31 @@ union Value {
template <typename T>
void WABT_VECTORCALL Set(T);
- u32 i32_;
- u64 i64_;
- f32 f32_;
- f64 f64_;
- v128 v128_;
- Ref ref_;
+ private:
+ union {
+ u32 i32_;
+ u64 i64_;
+ f32 f32_;
+ f64 f64_;
+ v128 v128_;
+ Ref ref_;
+ };
+
+ public:
+#ifndef NDEBUG
+ Value() : v128_(0, 0, 0, 0), type(ValueType::Any) {}
+ void SetType(ValueType t) { type = t; }
+ void CheckType(ValueType t) const {
+ // Sadly we must allow Any here, since locals may be uninitialized.
+ // Alternatively we could modify InterpAlloca to set the type.
+ assert(t == type || type == ValueType::Any);
+ }
+ ValueType type;
+#else
+ Value() : v128_(0, 0, 0, 0) {}
+ void SetType(ValueType) {}
+ void CheckType(ValueType) const {}
+#endif
};
using Values = std::vector<Value>;
diff --git a/src/shared-validator.cc b/src/shared-validator.cc
index 5f429e59..ef1b69e8 100644
--- a/src/shared-validator.cc
+++ b/src/shared-validator.cc
@@ -570,11 +570,11 @@ Result SharedValidator::CheckAlign(const Location& loc,
Address alignment,
Address natural_alignment) {
if (!is_power_of_two(alignment)) {
- PrintError(loc, "alignment (%u) must be a power of 2", alignment);
+ PrintError(loc, "alignment (%lu) must be a power of 2", alignment);
return Result::Error;
}
if (alignment > natural_alignment) {
- PrintError(loc, "alignment must not be larger than natural alignment (%u)",
+ PrintError(loc, "alignment must not be larger than natural alignment (%lu)",
natural_alignment);
return Result::Error;
}
@@ -585,11 +585,11 @@ Result SharedValidator::CheckAtomicAlign(const Location& loc,
Address alignment,
Address natural_alignment) {
if (!is_power_of_two(alignment)) {
- PrintError(loc, "alignment (%u) must be a power of 2", alignment);
+ PrintError(loc, "alignment (%lu) must be a power of 2", alignment);
return Result::Error;
}
if (alignment != natural_alignment) {
- PrintError(loc, "alignment must be equal to natural alignment (%u)",
+ PrintError(loc, "alignment must be equal to natural alignment (%lu)",
natural_alignment);
return Result::Error;
}
diff --git a/src/tools/spectest-interp.cc b/src/tools/spectest-interp.cc
index 693f2eaa..a212053c 100644
--- a/src/tools/spectest-interp.cc
+++ b/src/tools/spectest-interp.cc
@@ -703,7 +703,7 @@ wabt::Result JSONParser::ParseLaneConstValue(Type lane_type,
ExpectedValue* out_value,
string_view value_str,
AllowExpected allow_expected) {
- v128& v = out_value->value.value.v128_;
+ v128 v = out_value->value.value.Get<v128>();
switch (lane_type) {
case Type::I8: {
@@ -758,6 +758,8 @@ wabt::Result JSONParser::ParseLaneConstValue(Type lane_type,
PrintError("unknown concrete type: \"%s\"", lane_type.GetName());
return wabt::Result::Error;
}
+
+ out_value->value.value.Set<v128>(v);
return wabt::Result::Ok;
}
diff --git a/src/wat-writer.cc b/src/wat-writer.cc
index ea46d802..8a94d24f 100644
--- a/src/wat-writer.cc
+++ b/src/wat-writer.cc
@@ -496,10 +496,10 @@ void WatWriter::WriteLoadStoreExpr(const Expr* expr) {
auto typed_expr = cast<T>(expr);
WritePutsSpace(typed_expr->opcode.GetName());
if (typed_expr->offset) {
- Writef("offset=%u", typed_expr->offset);
+ Writef("offset=%lu", typed_expr->offset);
}
if (!typed_expr->opcode.IsNaturallyAligned(typed_expr->align)) {
- Writef("align=%u", typed_expr->align);
+ Writef("align=%lu", typed_expr->align);
}
WriteNewline(NO_FORCE_NEWLINE);
}