diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/binary-reader-logging.cc | 4 | ||||
-rw-r--r-- | src/interp/interp-inl.h | 81 | ||||
-rw-r--r-- | src/interp/interp.cc | 47 | ||||
-rw-r--r-- | src/interp/interp.h | 34 | ||||
-rw-r--r-- | src/shared-validator.cc | 8 | ||||
-rw-r--r-- | src/tools/spectest-interp.cc | 4 | ||||
-rw-r--r-- | src/wat-writer.cc | 4 |
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); } |