Line data Source code
1 : // Copyright 2016 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_ASMJS_ASM_TYPES_H_
6 : #define V8_ASMJS_ASM_TYPES_H_
7 :
8 : #include <string>
9 :
10 : #include "src/base/compiler-specific.h"
11 : #include "src/base/macros.h"
12 : #include "src/globals.h"
13 : #include "src/zone/zone-containers.h"
14 : #include "src/zone/zone.h"
15 :
16 : namespace v8 {
17 : namespace internal {
18 : namespace wasm {
19 :
20 : class AsmType;
21 : class AsmFunctionType;
22 : class AsmOverloadedFunctionType;
23 :
24 : // List of V(CamelName, string_name, number, parent_types)
25 : #define FOR_EACH_ASM_VALUE_TYPE_LIST(V) \
26 : /* These tags are not types that are expressable in the asm source. They */ \
27 : /* are used to express semantic information about the types they tag. */ \
28 : V(Heap, "[]", 1, 0) \
29 : V(FloatishDoubleQ, "floatish|double?", 2, 0) \
30 : V(FloatQDoubleQ, "float?|double?", 3, 0) \
31 : /* The following are actual types that appear in the asm source. */ \
32 : V(Void, "void", 4, 0) \
33 : V(Extern, "extern", 5, 0) \
34 : V(DoubleQ, "double?", 6, kAsmFloatishDoubleQ | kAsmFloatQDoubleQ) \
35 : V(Double, "double", 7, kAsmDoubleQ | kAsmExtern) \
36 : V(Intish, "intish", 8, 0) \
37 : V(Int, "int", 9, kAsmIntish) \
38 : V(Signed, "signed", 10, kAsmInt | kAsmExtern) \
39 : V(Unsigned, "unsigned", 11, kAsmInt) \
40 : V(FixNum, "fixnum", 12, kAsmSigned | kAsmUnsigned) \
41 : V(Floatish, "floatish", 13, kAsmFloatishDoubleQ) \
42 : V(FloatQ, "float?", 14, kAsmFloatQDoubleQ | kAsmFloatish) \
43 : V(Float, "float", 15, kAsmFloatQ) \
44 : /* Types used for expressing the Heap accesses. */ \
45 : V(Uint8Array, "Uint8Array", 16, kAsmHeap) \
46 : V(Int8Array, "Int8Array", 17, kAsmHeap) \
47 : V(Uint16Array, "Uint16Array", 18, kAsmHeap) \
48 : V(Int16Array, "Int16Array", 19, kAsmHeap) \
49 : V(Uint32Array, "Uint32Array", 20, kAsmHeap) \
50 : V(Int32Array, "Int32Array", 21, kAsmHeap) \
51 : V(Float32Array, "Float32Array", 22, kAsmHeap) \
52 : V(Float64Array, "Float64Array", 23, kAsmHeap) \
53 : /* None is used to represent errors in the type checker. */ \
54 : V(None, "<none>", 31, 0)
55 :
56 : // List of V(CamelName)
57 : #define FOR_EACH_ASM_CALLABLE_TYPE_LIST(V) \
58 : V(FunctionType) \
59 : V(OverloadedFunctionType)
60 :
61 : class AsmValueType {
62 : public:
63 : typedef uint32_t bitset_t;
64 :
65 : enum : uint32_t {
66 : #define DEFINE_TAG(CamelName, string_name, number, parent_types) \
67 : kAsm##CamelName = ((1u << (number)) | (parent_types)),
68 : FOR_EACH_ASM_VALUE_TYPE_LIST(DEFINE_TAG)
69 : #undef DEFINE_TAG
70 : kAsmUnknown = 0,
71 : kAsmValueTypeTag = 1u
72 : };
73 :
74 : private:
75 : friend class AsmType;
76 :
77 : static AsmValueType* AsValueType(AsmType* type) {
78 31888974 : if ((reinterpret_cast<uintptr_t>(type) & kAsmValueTypeTag) ==
79 : kAsmValueTypeTag) {
80 : return reinterpret_cast<AsmValueType*>(type);
81 : }
82 : return nullptr;
83 : }
84 :
85 : bitset_t Bitset() const {
86 : DCHECK_EQ(reinterpret_cast<uintptr_t>(this) & kAsmValueTypeTag,
87 : kAsmValueTypeTag);
88 : return static_cast<bitset_t>(reinterpret_cast<uintptr_t>(this) &
89 15571406 : ~kAsmValueTypeTag);
90 : }
91 :
92 : static AsmType* New(bitset_t bits) {
93 : DCHECK_EQ((bits & kAsmValueTypeTag), 0u);
94 : return reinterpret_cast<AsmType*>(
95 : static_cast<uintptr_t>(bits | kAsmValueTypeTag));
96 : }
97 :
98 : // AsmValueTypes can't be created except through AsmValueType::New.
99 : DISALLOW_IMPLICIT_CONSTRUCTORS(AsmValueType);
100 : };
101 :
102 : class V8_EXPORT_PRIVATE AsmCallableType : public NON_EXPORTED_BASE(ZoneObject) {
103 : public:
104 : virtual std::string Name() = 0;
105 :
106 : virtual bool CanBeInvokedWith(AsmType* return_type,
107 : const ZoneVector<AsmType*>& args) = 0;
108 :
109 : #define DECLARE_CAST(CamelName) \
110 : virtual Asm##CamelName* As##CamelName() { return nullptr; }
111 35744 : FOR_EACH_ASM_CALLABLE_TYPE_LIST(DECLARE_CAST)
112 : #undef DECLARE_CAST
113 :
114 : protected:
115 108364 : AsmCallableType() = default;
116 0 : virtual ~AsmCallableType() = default;
117 : virtual bool IsA(AsmType* other);
118 :
119 : private:
120 : friend class AsmType;
121 :
122 : DISALLOW_COPY_AND_ASSIGN(AsmCallableType);
123 : };
124 :
125 0 : class V8_EXPORT_PRIVATE AsmFunctionType final : public AsmCallableType {
126 : public:
127 160972 : AsmFunctionType* AsFunctionType() final { return this; }
128 :
129 153595 : void AddArgument(AsmType* type) { args_.push_back(type); }
130 : const ZoneVector<AsmType*> Arguments() const { return args_; }
131 : AsmType* ReturnType() const { return return_type_; }
132 :
133 : bool CanBeInvokedWith(AsmType* return_type,
134 : const ZoneVector<AsmType*>& args) override;
135 :
136 : protected:
137 : AsmFunctionType(Zone* zone, AsmType* return_type)
138 82022 : : return_type_(return_type), args_(zone) {}
139 :
140 : private:
141 : friend AsmType;
142 :
143 : std::string Name() override;
144 : bool IsA(AsmType* other) override;
145 :
146 : AsmType* return_type_;
147 : ZoneVector<AsmType*> args_;
148 :
149 : DISALLOW_COPY_AND_ASSIGN(AsmFunctionType);
150 : };
151 :
152 0 : class V8_EXPORT_PRIVATE AsmOverloadedFunctionType final
153 : : public AsmCallableType {
154 : public:
155 30084 : AsmOverloadedFunctionType* AsOverloadedFunctionType() override {
156 30084 : return this;
157 : }
158 :
159 : void AddOverload(AsmType* overload);
160 :
161 : private:
162 : friend AsmType;
163 :
164 11287 : explicit AsmOverloadedFunctionType(Zone* zone) : overloads_(zone) {}
165 :
166 : std::string Name() override;
167 : bool CanBeInvokedWith(AsmType* return_type,
168 : const ZoneVector<AsmType*>& args) override;
169 :
170 : ZoneVector<AsmType*> overloads_;
171 :
172 : DISALLOW_IMPLICIT_CONSTRUCTORS(AsmOverloadedFunctionType);
173 : };
174 :
175 : class V8_EXPORT_PRIVATE AsmType {
176 : public:
177 : #define DEFINE_CONSTRUCTOR(CamelName, string_name, number, parent_types) \
178 : static AsmType* CamelName() { \
179 : return AsmValueType::New(AsmValueType::kAsm##CamelName); \
180 : }
181 92 : FOR_EACH_ASM_VALUE_TYPE_LIST(DEFINE_CONSTRUCTOR)
182 : #undef DEFINE_CONSTRUCTOR
183 :
184 : #define DEFINE_CAST(CamelCase) \
185 : Asm##CamelCase* As##CamelCase() { \
186 : if (AsValueType() != nullptr) { \
187 : return nullptr; \
188 : } \
189 : return reinterpret_cast<AsmCallableType*>(this)->As##CamelCase(); \
190 : }
191 335290 : FOR_EACH_ASM_CALLABLE_TYPE_LIST(DEFINE_CAST)
192 : #undef DEFINE_CAST
193 : AsmValueType* AsValueType() { return AsmValueType::AsValueType(this); }
194 : AsmCallableType* AsCallableType();
195 :
196 : // A function returning ret. Callers still need to invoke AddArgument with the
197 : // returned type to fully create this type.
198 : static AsmType* Function(Zone* zone, AsmType* ret) {
199 : AsmFunctionType* f = new (zone) AsmFunctionType(zone, ret);
200 : return reinterpret_cast<AsmType*>(f);
201 : }
202 :
203 : // Overloaded function types. Not creatable by asm source, but useful to
204 : // represent the overloaded stdlib functions.
205 : static AsmType* OverloadedFunction(Zone* zone) {
206 : auto* f = new (zone) AsmOverloadedFunctionType(zone);
207 : return reinterpret_cast<AsmType*>(f);
208 : }
209 :
210 : // The type for fround(src).
211 : static AsmType* FroundType(Zone* zone);
212 :
213 : // The (variadic) type for min and max.
214 : static AsmType* MinMaxType(Zone* zone, AsmType* dest, AsmType* src);
215 :
216 : std::string Name();
217 : // IsExactly returns true if x is the exact same type as y. For
218 : // non-value types (e.g., callables), this returns x == y.
219 : static bool IsExactly(AsmType* x, AsmType* y);
220 : // IsA is used to query whether this is an instance of that (i.e., if this is
221 : // a type derived from that.) For non-value types (e.g., callables), this
222 : // returns this == that.
223 : bool IsA(AsmType* that);
224 :
225 : // The following methods are meant to be used for inspecting the traits of
226 : // element types for the heap view types.
227 : enum : int32_t { kNotHeapType = -1 };
228 :
229 : // Returns the element size if this is a heap type. Otherwise returns
230 : // kNotHeapType.
231 : int32_t ElementSizeInBytes();
232 : // Returns the load type if this is a heap type. AsmType::None is returned if
233 : // this is not a heap type.
234 : AsmType* LoadType();
235 : // Returns the store type if this is a heap type. AsmType::None is returned if
236 : // this is not a heap type.
237 : AsmType* StoreType();
238 : };
239 :
240 : } // namespace wasm
241 : } // namespace internal
242 : } // namespace v8
243 :
244 : #endif // V8_ASMJS_ASM_TYPES_H_
|