v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
wasm-value.h
Go to the documentation of this file.
1// Copyright 2017 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_WASM_WASM_VALUE_H_
6#define V8_WASM_WASM_VALUE_H_
7
8#if !V8_ENABLE_WEBASSEMBLY
9#error This header should only be included if WebAssembly is enabled.
10#endif // !V8_ENABLE_WEBASSEMBLY
11
12#include "src/base/memory.h"
13#include "src/common/simd128.h"
14#include "src/handles/handles.h"
16#include "src/wasm/value-type.h"
17#include "third_party/fp16/src/include/fp16.h"
18
19namespace v8 {
20namespace internal {
21namespace wasm {
22
23struct WasmModule;
24
25// Macro for defining WasmValue methods for different types.
26// Elements:
27// - name (for to_<name>() method)
28// - wasm type
29// - c type
30#define FOREACH_PRIMITIVE_WASMVAL_TYPE(V) \
31 V(i8, kWasmI8, int8_t) \
32 V(i16, kWasmI16, int16_t) \
33 V(i32, kWasmI32, int32_t) \
34 V(u32, kWasmI32, uint32_t) \
35 V(i64, kWasmI64, int64_t) \
36 V(u64, kWasmI64, uint64_t) \
37 V(f16, kWasmF16, uint16_t) \
38 V(f32, kWasmF32, float) \
39 V(f32_boxed, kWasmF32, Float32) \
40 V(f64, kWasmF64, double) \
41 V(f64_boxed, kWasmF64, Float64) \
42 V(s128, kWasmS128, Simd128)
43
45
46// A wasm value with type information.
47class WasmValue {
48 public:
50
51#define DEFINE_TYPE_SPECIFIC_METHODS(name, localtype, ctype) \
52 explicit WasmValue(ctype v) : type_(localtype), bit_pattern_{} { \
53 static_assert(sizeof(ctype) <= sizeof(bit_pattern_), \
54 "size too big for WasmValue"); \
55 base::WriteUnalignedValue<ctype>(reinterpret_cast<Address>(bit_pattern_), \
56 v); \
57 } \
58 ctype to_##name() const { \
59 DCHECK_EQ(localtype, type_); \
60 return to_##name##_unchecked(); \
61 } \
62 ctype to_##name##_unchecked() const { \
63 return base::ReadUnalignedValue<ctype>( \
64 reinterpret_cast<Address>(bit_pattern_)); \
65 }
66
68#undef DEFINE_TYPE_SPECIFIC_METHODS
69
70 WasmValue(const uint8_t* raw_bytes, CanonicalValueType type)
71 : type_(type), bit_pattern_{} {
73 memcpy(bit_pattern_, raw_bytes, type.value_kind_size());
74 }
75
77 : type_(type), bit_pattern_{} {
78 static_assert(sizeof(DirectHandle<Object>) <= sizeof(bit_pattern_),
79 "bit_pattern_ must be large enough to fit a Handle");
80 DCHECK(type.is_reference());
82 reinterpret_cast<Address>(bit_pattern_), ref);
83 }
84
90
91 CanonicalValueType type() const { return type_; }
92
93 const WasmModule* module() const { return module_; }
94
95 // Checks equality of type and bit pattern (also for float and double values).
96 bool operator==(const WasmValue& other) const {
97 return type_ == other.type_ &&
98 !memcmp(bit_pattern_, other.bit_pattern_,
101 }
102
103 void CopyTo(uint8_t* to) const {
104 static_assert(sizeof(float) == sizeof(Float32));
105 static_assert(sizeof(double) == sizeof(Float64));
107 memcpy(to, bit_pattern_, type_.value_kind_size());
108 }
109
110 // If {packed_type.is_packed()}, create a new value of {packed_type()}.
111 // Otherwise, return this object.
112 WasmValue Packed(ValueType packed_type) const {
113 if (packed_type == kWasmI8) {
115 return WasmValue(static_cast<int8_t>(to_i32()));
116 }
117 if (packed_type == kWasmI16) {
119 return WasmValue(static_cast<int16_t>(to_i32()));
120 }
121 return *this;
122 }
123
124 template <typename T>
125 inline T to() const;
126
127 template <typename T>
128 inline T to_unchecked() const;
129
130 static WasmValue ForUintPtr(uintptr_t value) {
131 using type =
132 std::conditional<kSystemPointerSize == 8, uint64_t, uint32_t>::type;
133 return WasmValue{type{value}};
134 }
135
136 inline std::string to_string() const {
137 switch (type_.kind()) {
138 case kI8:
139 return std::to_string(to_i8());
140 case kI16:
141 return std::to_string(to_i16());
142 case kI32:
143 return std::to_string(to_i32());
144 case kI64:
145 return std::to_string(to_i64());
146 case kF16:
147 return std::to_string(fp16_ieee_to_fp32_value(to_f16()));
148 case kF32:
149 return std::to_string(to_f32());
150 case kF64:
151 return std::to_string(to_f64());
152 case kS128: {
153 std::stringstream stream;
154 stream << "0x" << std::hex;
155 for (int8_t uint8_t : bit_pattern_) {
156 if (!(uint8_t & 0xf0)) stream << '0';
157 stream << uint8_t;
158 }
159 return stream.str();
160 }
161 case kRefNull:
162 case kRef:
163 return "DirectHandle [" + std::to_string(to_ref().address()) + "]";
164 case kVoid:
165 case kTop:
166 case kBottom:
167 UNREACHABLE();
168 }
169 }
170
172 DCHECK(type().is_numeric());
173 uint32_t byte_count = type().value_kind_size();
174 return static_cast<uint32_t>(std::count(
175 bit_pattern_, bit_pattern_ + byte_count, 0)) == byte_count;
176 }
177
178 private:
180 uint8_t bit_pattern_[16];
181 const WasmModule* module_ = nullptr;
182};
183
184#define DECLARE_CAST(name, localtype, ctype, ...) \
185 template <> \
186 inline ctype WasmValue::to_unchecked() const { \
187 return to_##name##_unchecked(); \
188 } \
189 template <> \
190 inline ctype WasmValue::to() const { \
191 return to_##name(); \
192 }
194#undef DECLARE_CAST
195
196} // namespace wasm
197} // namespace internal
198} // namespace v8
199
200#endif // V8_WASM_WASM_VALUE_H_
#define DECLARE_CAST(CamelName)
Definition asm-types.h:111
constexpr int value_kind_size() const
Definition value-type.h:485
constexpr ValueKind kind() const
Definition value-type.h:631
constexpr bool is_reference() const
Definition value-type.h:600
constexpr bool is_numeric() const
Definition value-type.h:373
const WasmModule * module_
Definition wasm-value.h:181
DirectHandle< Object > to_ref() const
Definition wasm-value.h:85
void CopyTo(uint8_t *to) const
Definition wasm-value.h:103
CanonicalValueType type_
Definition wasm-value.h:179
bool operator==(const WasmValue &other) const
Definition wasm-value.h:96
std::string to_string() const
Definition wasm-value.h:136
static WasmValue ForUintPtr(uintptr_t value)
Definition wasm-value.h:130
WasmValue Packed(ValueType packed_type) const
Definition wasm-value.h:112
WasmValue(const uint8_t *raw_bytes, CanonicalValueType type)
Definition wasm-value.h:70
WasmValue(DirectHandle< Object > ref, CanonicalValueType type)
Definition wasm-value.h:76
const WasmModule * module() const
Definition wasm-value.h:93
CanonicalValueType type() const
Definition wasm-value.h:91
static V ReadUnalignedValue(Address p)
Definition memory.h:28
static void WriteUnalignedValue(Address p, V value)
Definition memory.h:41
FloatWithBits< 32 > Float32
Definition index.h:233
FloatWithBits< 64 > Float64
Definition index.h:234
constexpr IndependentValueType kWasmI8
constexpr IndependentValueType kWasmI32
constexpr IndependentHeapType kWasmVoid
constexpr IndependentValueType kWasmI16
wasm::WasmModule WasmModule
Definition c-api.cc:87
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define ASSERT_TRIVIALLY_COPYABLE(T)
Definition macros.h:267
#define DEFINE_TYPE_SPECIFIC_METHODS(name, localtype, ctype)
Definition wasm-value.h:51
#define FOREACH_PRIMITIVE_WASMVAL_TYPE(V)
Definition wasm-value.h:30