Line data Source code
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 : #include "src/boxed-float.h"
9 : #include "src/handles.h"
10 : #include "src/v8memory.h"
11 : #include "src/wasm/wasm-opcodes.h"
12 : #include "src/zone/zone-containers.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 : namespace wasm {
17 :
18 : #define FOREACH_SIMD_TYPE(V) \
19 : V(float, float4, f32x4, 4) \
20 : V(int32_t, int4, i32x4, 4) \
21 : V(int16_t, int8, i16x8, 8) \
22 : V(int8_t, int16, i8x16, 16)
23 :
24 : #define DEFINE_SIMD_TYPE(cType, sType, name, kSize) \
25 : struct sType { \
26 : cType val[kSize]; \
27 : };
28 : FOREACH_SIMD_TYPE(DEFINE_SIMD_TYPE)
29 : #undef DEFINE_SIMD_TYPE
30 :
31 : class Simd128 {
32 : public:
33 66742068 : Simd128() : val_() {
34 129558132 : for (size_t i = 0; i < 16; i++) {
35 62816064 : val_[i] = 0;
36 : }
37 : }
38 : #define DEFINE_SIMD_TYPE_SPECIFIC_METHODS(cType, sType, name, size) \
39 : explicit Simd128(sType val) { \
40 : WriteUnalignedValue<sType>(reinterpret_cast<Address>(val_), val); \
41 : } \
42 : sType to_##name() { \
43 : return ReadUnalignedValue<sType>(reinterpret_cast<Address>(val_)); \
44 : }
45 : FOREACH_SIMD_TYPE(DEFINE_SIMD_TYPE_SPECIFIC_METHODS)
46 : #undef DEFINE_SIMD_TYPE_SPECIFIC_METHODS
47 :
48 : private:
49 : uint8_t val_[16];
50 : };
51 :
52 : // Macro for defining WasmValue methods for different types.
53 : // Elements:
54 : // - name (for to_<name>() method)
55 : // - wasm type
56 : // - c type
57 : #define FOREACH_WASMVAL_TYPE(V) \
58 : V(i32, kWasmI32, int32_t) \
59 : V(u32, kWasmI32, uint32_t) \
60 : V(i64, kWasmI64, int64_t) \
61 : V(u64, kWasmI64, uint64_t) \
62 : V(f32, kWasmF32, float) \
63 : V(f32_boxed, kWasmF32, Float32) \
64 : V(f64, kWasmF64, double) \
65 : V(f64_boxed, kWasmF64, Float64) \
66 : V(s128, kWasmS128, Simd128) \
67 : V(anyref, kWasmAnyRef, Handle<Object>)
68 :
69 : ASSERT_TRIVIALLY_COPYABLE(Handle<Object>);
70 :
71 : // A wasm value with type information.
72 : class WasmValue {
73 : public:
74 4688560 : WasmValue() : type_(kWasmStmt), bit_pattern_{} {}
75 :
76 : #define DEFINE_TYPE_SPECIFIC_METHODS(name, localtype, ctype) \
77 : explicit WasmValue(ctype v) : type_(localtype), bit_pattern_{} { \
78 : static_assert(sizeof(ctype) <= sizeof(bit_pattern_), \
79 : "size too big for WasmValue"); \
80 : WriteUnalignedValue<ctype>(reinterpret_cast<Address>(bit_pattern_), v); \
81 : } \
82 : ctype to_##name() const { \
83 : DCHECK_EQ(localtype, type_); \
84 : return to_##name##_unchecked(); \
85 : } \
86 : ctype to_##name##_unchecked() const { \
87 : return ReadUnalignedValue<ctype>(reinterpret_cast<Address>(bit_pattern_)); \
88 : }
89 40685262 : FOREACH_WASMVAL_TYPE(DEFINE_TYPE_SPECIFIC_METHODS)
90 : #undef DEFINE_TYPE_SPECIFIC_METHODS
91 :
92 : ValueType type() const { return type_; }
93 :
94 : // Checks equality of type and bit pattern (also for float and double values).
95 : bool operator==(const WasmValue& other) const {
96 832 : return type_ == other.type_ &&
97 416 : !memcmp(bit_pattern_, other.bit_pattern_, 16);
98 : }
99 :
100 : template <typename T>
101 : inline T to() const;
102 :
103 : template <typename T>
104 : inline T to_unchecked() const;
105 :
106 : private:
107 : ValueType type_;
108 : uint8_t bit_pattern_[16];
109 : };
110 :
111 : #define DECLARE_CAST(name, localtype, ctype, ...) \
112 : template <> \
113 : inline ctype WasmValue::to_unchecked() const { \
114 : return to_##name##_unchecked(); \
115 : } \
116 : template <> \
117 : inline ctype WasmValue::to() const { \
118 : return to_##name(); \
119 : }
120 : FOREACH_WASMVAL_TYPE(DECLARE_CAST)
121 : #undef DECLARE_CAST
122 :
123 : } // namespace wasm
124 : } // namespace internal
125 : } // namespace v8
126 :
127 : #endif // V8_WASM_WASM_VALUE_H_
|