OLD | NEW |
---|---|
(Empty) | |
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 #include "src/v8.h" | |
6 | |
7 #include "src/wasm/asm-types.h" | |
8 | |
9 namespace v8 { | |
10 namespace internal { | |
11 namespace wasm { | |
12 | |
13 AsmCallableType* AsmType::AsCallableType() { | |
14 DCHECK(this->AsFunctionType() != nullptr || | |
15 this->AsOverloadedFunctionType() != nullptr); | |
16 return reinterpret_cast<AsmCallableType*>(this); | |
17 } | |
18 | |
19 std::string AsmType::Name() { | |
20 AsmValueType* avt = this->AsValueType(); | |
21 if (avt != nullptr) { | |
22 switch (avt->Bitset()) { | |
23 #define RETURN_TYPE_NAME(CamelName, string_name, number, parent_types) \ | |
24 case AsmValueType::kAsm##CamelName: \ | |
25 return string_name; | |
26 FOR_EACH_ASM_VALUE_TYPE_LIST(RETURN_TYPE_NAME) | |
27 #undef RETURN_TYPE_NAME | |
28 default: | |
29 UNREACHABLE(); | |
30 } | |
31 } | |
32 return reinterpret_cast<AsmCallableType*>(this)->Name(); | |
ahaas
2016/06/13 16:27:03
AsCallableType()->Name();
John
2016/06/13 17:32:27
Done.
| |
33 } | |
34 | |
35 bool AsmType::IsExactly(AsmType* that) { | |
36 // TODO(jpp): maybe this can become this == that. | |
37 AsmValueType* avt = this->AsValueType(); | |
38 if (avt != nullptr) { | |
39 AsmValueType* tavt = that->AsValueType(); | |
40 if (tavt == nullptr) { | |
41 return false; | |
42 } | |
43 return avt->Bitset() == tavt->Bitset(); | |
44 } | |
45 return that == this; | |
ahaas
2016/06/13 16:27:03
Could you add a comment which explains why callabl
John
2016/06/13 17:32:27
IsExactly is only supposed to be used when queryin
| |
46 } | |
47 | |
48 bool AsmType::IsA(AsmType* that) { | |
49 // IsA is used for querying inheritance relationships. Therefore it is only | |
50 // meaningful for basic types. | |
51 AsmValueType* tavt = that->AsValueType(); | |
52 if (tavt != nullptr) { | |
53 AsmValueType* avt = this->AsValueType(); | |
54 if (avt == nullptr) { | |
55 return false; | |
56 } | |
57 return (avt->Bitset() & tavt->Bitset()) == tavt->Bitset(); | |
58 } | |
59 return that == this; | |
ahaas
2016/06/13 16:27:03
If you say that IsA is only meaningful for basic t
John
2016/06/13 17:32:27
This is a good question, and I don't know the answ
| |
60 } | |
61 | |
62 int32_t AsmType::ElementSizeInBytes() { | |
63 auto* value = AsValueType(); | |
64 if (value == nullptr) { | |
65 return AsmType::kNotHeapType; | |
66 } | |
67 switch (value->Bitset()) { | |
68 case AsmValueType::kAsmInt8Array: | |
69 case AsmValueType::kAsmUint8Array: | |
70 return 1; | |
71 case AsmValueType::kAsmInt16Array: | |
72 case AsmValueType::kAsmUint16Array: | |
73 return 2; | |
74 case AsmValueType::kAsmInt32Array: | |
75 case AsmValueType::kAsmUint32Array: | |
76 case AsmValueType::kAsmFloat32Array: | |
77 return 4; | |
78 case AsmValueType::kAsmFloat64Array: | |
79 return 8; | |
80 default: | |
81 return AsmType::kNotHeapType; | |
82 } | |
83 } | |
84 | |
85 AsmType* AsmType::LoadType() { | |
86 auto* value = AsValueType(); | |
87 if (value == nullptr) { | |
88 return AsmType::None(); | |
89 } | |
90 switch (value->Bitset()) { | |
91 case AsmValueType::kAsmInt8Array: | |
92 case AsmValueType::kAsmUint8Array: | |
93 case AsmValueType::kAsmInt16Array: | |
94 case AsmValueType::kAsmUint16Array: | |
95 case AsmValueType::kAsmInt32Array: | |
96 case AsmValueType::kAsmUint32Array: | |
97 return AsmType::Intish(); | |
98 case AsmValueType::kAsmFloat32Array: | |
99 return AsmType::FloatQ(); | |
100 case AsmValueType::kAsmFloat64Array: | |
101 return AsmType::DoubleQ(); | |
102 default: | |
103 return AsmType::None(); | |
104 } | |
105 } | |
106 | |
107 AsmType* AsmType::StoreType() { | |
108 auto* value = AsValueType(); | |
109 if (value == nullptr) { | |
110 return AsmType::None(); | |
111 } | |
112 switch (value->Bitset()) { | |
113 case AsmValueType::kAsmInt8Array: | |
114 case AsmValueType::kAsmUint8Array: | |
115 case AsmValueType::kAsmInt16Array: | |
116 case AsmValueType::kAsmUint16Array: | |
117 case AsmValueType::kAsmInt32Array: | |
118 case AsmValueType::kAsmUint32Array: | |
119 return AsmType::Intish(); | |
120 case AsmValueType::kAsmFloat32Array: | |
121 return AsmType::FloatishDoubleQ(); | |
ahaas
2016/06/13 16:27:03
Is it intentional that you say FloatishDoubleQ her
John
2016/06/13 17:32:27
yes, http://asmjs.org/spec/latest/#heap-view-types
| |
122 case AsmValueType::kAsmFloat64Array: | |
123 return AsmType::FloatQDoubleQ(); | |
124 default: | |
125 return AsmType::None(); | |
126 } | |
127 } | |
128 | |
129 std::string AsmFunctionType::Name() { | |
130 std::string ret; | |
131 ret += "("; | |
132 for (size_t ii = 0; ii < args_.size(); ++ii) { | |
133 ret += args_[ii]->Name(); | |
134 if (ii != args_.size() - 1) { | |
135 ret += ", "; | |
136 } | |
137 } | |
138 if (IsMinMaxType()) { | |
139 DCHECK_EQ(args_.size(), 2); | |
140 ret += "..."; | |
ahaas
2016/06/13 16:27:03
Is it intentional that this is "..." and not ", ..
John
2016/06/13 17:32:27
yes, http://asmjs.org/spec/latest/#global-types ,
| |
141 } | |
142 ret += ") -> "; | |
143 ret += return_type_->Name(); | |
144 return ret; | |
145 } | |
146 | |
147 namespace { | |
148 class AsmFroundType final : public AsmFunctionType { | |
149 public: | |
150 bool IsFroundType() const override { return true; } | |
151 | |
152 private: | |
153 friend AsmType; | |
154 | |
155 AsmFroundType(Zone* zone, AsmType* src) | |
156 : AsmFunctionType(zone, AsmType::Float()) { | |
157 AddArgument(src); | |
158 } | |
159 }; | |
160 } // namespace | |
161 | |
162 AsmType* AsmType::FroundType(Zone* zone, AsmType* src) { | |
163 DCHECK(src->AsValueType() != nullptr); | |
164 auto* Fround = new (zone) AsmFroundType(zone, src); | |
165 return reinterpret_cast<AsmType*>(Fround); | |
166 } | |
167 | |
168 namespace { | |
169 class AsmMinMaxType final : public AsmFunctionType { | |
170 public: | |
171 bool IsMinMaxType() const override { return true; } | |
172 | |
173 private: | |
174 friend AsmType; | |
175 | |
176 AsmMinMaxType(Zone* zone, AsmType* type) : AsmFunctionType(zone, type) { | |
177 AddArgument(type); | |
178 AddArgument(type); | |
179 } | |
180 | |
181 AsmType* ValidateCall(AsmType* function_type) override { | |
182 auto* callable = function_type->AsFunctionType(); | |
183 if (callable == nullptr) { | |
184 return nullptr; | |
185 } | |
186 | |
187 if (!ReturnType()->IsExactly(callable->ReturnType())) { | |
188 return AsmType::None(); | |
189 } | |
190 | |
191 if (callable->Arguments().size() < 2) { | |
192 return AsmType::None(); | |
193 } | |
194 | |
195 for (size_t ii = 0; ii < Arguments().size(); ++ii) { | |
196 if (!Arguments()[0]->IsExactly(callable->Arguments()[ii])) { | |
197 return AsmType::None(); | |
198 } | |
199 } | |
200 | |
201 return ReturnType(); | |
202 } | |
203 }; | |
204 } // namespace | |
205 | |
206 AsmType* AsmType::MinMaxType(Zone* zone, AsmType* type) { | |
207 DCHECK(type->AsValueType() != nullptr); | |
208 auto* MinMax = new (zone) AsmMinMaxType(zone, type); | |
209 return reinterpret_cast<AsmType*>(MinMax); | |
210 } | |
211 | |
212 AsmType* AsmFunctionType::ValidateCall(AsmType* function_type) { | |
213 auto* callable = function_type->AsFunctionType(); | |
214 if (callable == nullptr) { | |
215 return nullptr; | |
216 } | |
217 | |
218 if (!return_type_->IsExactly(callable->return_type_)) { | |
219 return AsmType::None(); | |
220 } | |
221 | |
222 if (args_.size() != callable->args_.size()) { | |
223 return AsmType::None(); | |
224 } | |
225 | |
226 for (size_t ii = 0; ii < args_.size(); ++ii) { | |
227 if (!args_[ii]->IsExactly(callable->args_[ii])) { | |
228 return AsmType::None(); | |
229 } | |
230 } | |
231 | |
232 return return_type_; | |
233 } | |
234 | |
235 std::string AsmOverloadedFunctionType::Name() { | |
236 std::string ret; | |
237 | |
238 for (size_t ii = 0; ii < overloads_.size(); ++ii) { | |
239 if (ii != 0) { | |
240 ret += " /\\ "; | |
241 } | |
242 ret += overloads_[ii]->Name(); | |
243 } | |
244 | |
245 return ret; | |
246 } | |
247 | |
248 AsmType* AsmOverloadedFunctionType::ValidateCall(AsmType* function_type) { | |
249 auto* callable = function_type->AsFunctionType(); | |
250 if (callable == nullptr) { | |
251 return AsmType::None(); | |
252 } | |
253 | |
254 for (size_t ii = 0; ii < overloads_.size(); ++ii) { | |
255 auto* validated_type = | |
256 overloads_[ii]->AsCallableType()->ValidateCall(function_type); | |
257 if (validated_type != AsmType::None()) { | |
258 return validated_type; | |
259 } | |
260 } | |
261 | |
262 return AsmType::None(); | |
263 } | |
264 | |
265 void AsmOverloadedFunctionType::AddOverload(AsmType* overload) { | |
266 DCHECK(overload->AsFunctionType() != nullptr); | |
267 overloads_.push_back(overload); | |
268 } | |
269 | |
270 } // namespace wasm | |
271 } // namespace internal | |
272 } // namespace v8 | |
OLD | NEW |