OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/asmjs/asm-types.h" | 7 #include "src/asmjs/asm-types.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 bool IsFroundType() const override { return true; } | 166 bool IsFroundType() const override { return true; } |
167 | 167 |
168 private: | 168 private: |
169 friend AsmType; | 169 friend AsmType; |
170 | 170 |
171 explicit AsmFroundType(Zone* zone) | 171 explicit AsmFroundType(Zone* zone) |
172 : AsmFunctionType(zone, AsmType::Float()) {} | 172 : AsmFunctionType(zone, AsmType::Float()) {} |
173 | 173 |
174 AsmType* ValidateCall(AsmType* return_type, | 174 AsmType* ValidateCall(AsmType* return_type, |
175 const ZoneVector<AsmType*>& args) override; | 175 const ZoneVector<AsmType*>& args) override; |
| 176 bool CanBeInvokedWith(AsmType* return_type, |
| 177 const ZoneVector<AsmType*>& args) override; |
176 }; | 178 }; |
177 } // namespace | 179 } // namespace |
178 | 180 |
179 AsmType* AsmType::FroundType(Zone* zone) { | 181 AsmType* AsmType::FroundType(Zone* zone) { |
180 auto* Fround = new (zone) AsmFroundType(zone); | 182 auto* Fround = new (zone) AsmFroundType(zone); |
181 return reinterpret_cast<AsmType*>(Fround); | 183 return reinterpret_cast<AsmType*>(Fround); |
182 } | 184 } |
183 | 185 |
| 186 // TODO(jpp): Remove this method. |
184 AsmType* AsmFroundType::ValidateCall(AsmType* return_type, | 187 AsmType* AsmFroundType::ValidateCall(AsmType* return_type, |
185 const ZoneVector<AsmType*>& args) { | 188 const ZoneVector<AsmType*>& args) { |
186 if (args.size() != 1) { | 189 if (args.size() != 1) { |
187 return AsmType::None(); | 190 return AsmType::None(); |
188 } | 191 } |
189 | 192 |
190 auto* arg = args[0]; | 193 auto* arg = args[0]; |
191 if (!arg->IsA(AsmType::Floatish()) && !arg->IsA(AsmType::DoubleQ()) && | 194 if (!arg->IsA(AsmType::Floatish()) && !arg->IsA(AsmType::DoubleQ()) && |
192 !arg->IsA(AsmType::Signed()) && !arg->IsA(AsmType::Unsigned())) { | 195 !arg->IsA(AsmType::Signed()) && !arg->IsA(AsmType::Unsigned())) { |
193 return AsmType::None(); | 196 return AsmType::None(); |
194 } | 197 } |
195 | 198 |
196 return AsmType::Float(); | 199 return AsmType::Float(); |
197 } | 200 } |
198 | 201 |
| 202 bool AsmFroundType::CanBeInvokedWith(AsmType* return_type, |
| 203 const ZoneVector<AsmType*>& args) { |
| 204 if (args.size() != 1) { |
| 205 return false; |
| 206 } |
| 207 |
| 208 auto* arg = args[0]; |
| 209 if (!arg->IsA(AsmType::Floatish()) && !arg->IsA(AsmType::DoubleQ()) && |
| 210 !arg->IsA(AsmType::Signed()) && !arg->IsA(AsmType::Unsigned())) { |
| 211 return false; |
| 212 } |
| 213 |
| 214 return true; |
| 215 } |
| 216 |
199 namespace { | 217 namespace { |
200 class AsmMinMaxType final : public AsmFunctionType { | 218 class AsmMinMaxType final : public AsmFunctionType { |
201 public: | 219 public: |
202 bool IsMinMaxType() const override { return true; } | 220 bool IsMinMaxType() const override { return true; } |
203 | 221 |
204 private: | 222 private: |
205 friend AsmType; | 223 friend AsmType; |
206 | 224 |
207 AsmMinMaxType(Zone* zone, AsmType* dest, AsmType* src) | 225 AsmMinMaxType(Zone* zone, AsmType* dest, AsmType* src) |
208 : AsmFunctionType(zone, dest) { | 226 : AsmFunctionType(zone, dest) { |
(...skipping 12 matching lines...) Expand all Loading... |
221 } | 239 } |
222 | 240 |
223 for (size_t ii = 0; ii < Arguments().size(); ++ii) { | 241 for (size_t ii = 0; ii < Arguments().size(); ++ii) { |
224 if (!Arguments()[0]->IsExactly(args[ii])) { | 242 if (!Arguments()[0]->IsExactly(args[ii])) { |
225 return AsmType::None(); | 243 return AsmType::None(); |
226 } | 244 } |
227 } | 245 } |
228 | 246 |
229 return ReturnType(); | 247 return ReturnType(); |
230 } | 248 } |
| 249 |
| 250 bool CanBeInvokedWith(AsmType* return_type, |
| 251 const ZoneVector<AsmType*>& args) override { |
| 252 if (!ReturnType()->IsExactly(return_type)) { |
| 253 return false; |
| 254 } |
| 255 |
| 256 if (args.size() < 2) { |
| 257 return false; |
| 258 } |
| 259 |
| 260 auto* arg_type = Arguments()[0]; |
| 261 for (size_t ii = 0; ii < Arguments().size(); ++ii) { |
| 262 if (!args[ii]->IsA(arg_type)) { |
| 263 return false; |
| 264 } |
| 265 } |
| 266 |
| 267 return true; |
| 268 } |
231 }; | 269 }; |
232 } // namespace | 270 } // namespace |
233 | 271 |
234 AsmType* AsmType::MinMaxType(Zone* zone, AsmType* dest, AsmType* src) { | 272 AsmType* AsmType::MinMaxType(Zone* zone, AsmType* dest, AsmType* src) { |
235 DCHECK(dest->AsValueType() != nullptr); | 273 DCHECK(dest->AsValueType() != nullptr); |
236 DCHECK(src->AsValueType() != nullptr); | 274 DCHECK(src->AsValueType() != nullptr); |
237 auto* MinMax = new (zone) AsmMinMaxType(zone, dest, src); | 275 auto* MinMax = new (zone) AsmMinMaxType(zone, dest, src); |
238 return reinterpret_cast<AsmType*>(MinMax); | 276 return reinterpret_cast<AsmType*>(MinMax); |
239 } | 277 } |
240 | 278 |
241 AsmType* AsmFFIType::ValidateCall(AsmType* return_type, | 279 AsmType* AsmFFIType::ValidateCall(AsmType* return_type, |
242 const ZoneVector<AsmType*>& args) { | 280 const ZoneVector<AsmType*>& args) { |
243 for (size_t ii = 0; ii < args.size(); ++ii) { | 281 for (size_t ii = 0; ii < args.size(); ++ii) { |
244 if (!args[ii]->IsA(AsmType::Extern())) { | 282 if (!args[ii]->IsA(AsmType::Extern())) { |
245 return AsmType::None(); | 283 return AsmType::None(); |
246 } | 284 } |
247 } | 285 } |
248 | 286 |
249 return return_type; | 287 return return_type; |
250 } | 288 } |
251 | 289 |
| 290 bool AsmFFIType::CanBeInvokedWith(AsmType* return_type, |
| 291 const ZoneVector<AsmType*>& args) { |
| 292 if (return_type->IsExactly(AsmType::Float())) { |
| 293 return false; |
| 294 } |
| 295 |
| 296 for (size_t ii = 0; ii < args.size(); ++ii) { |
| 297 if (!args[ii]->IsA(AsmType::Extern())) { |
| 298 return false; |
| 299 } |
| 300 } |
| 301 |
| 302 return true; |
| 303 } |
| 304 |
252 AsmType* AsmFunctionType::ValidateCall(AsmType* return_type, | 305 AsmType* AsmFunctionType::ValidateCall(AsmType* return_type, |
253 const ZoneVector<AsmType*>& args) { | 306 const ZoneVector<AsmType*>& args) { |
254 if (!return_type_->IsExactly(return_type)) { | 307 if (!return_type_->IsExactly(return_type)) { |
255 return AsmType::None(); | 308 return AsmType::None(); |
256 } | 309 } |
257 | 310 |
258 if (args_.size() != args.size()) { | 311 if (args_.size() != args.size()) { |
259 return AsmType::None(); | 312 return AsmType::None(); |
260 } | 313 } |
261 | 314 |
262 for (size_t ii = 0; ii < args_.size(); ++ii) { | 315 for (size_t ii = 0; ii < args_.size(); ++ii) { |
263 if (!args_[ii]->IsExactly(args[ii])) { | 316 if (!args_[ii]->IsExactly(args[ii])) { |
264 return AsmType::None(); | 317 return AsmType::None(); |
265 } | 318 } |
266 } | 319 } |
267 | 320 |
268 return return_type_; | 321 return return_type_; |
269 } | 322 } |
270 | 323 |
| 324 bool AsmFunctionType::CanBeInvokedWith(AsmType* return_type, |
| 325 const ZoneVector<AsmType*>& args) { |
| 326 if (!return_type_->IsExactly(return_type)) { |
| 327 return false; |
| 328 } |
| 329 |
| 330 if (args_.size() != args.size()) { |
| 331 return false; |
| 332 } |
| 333 |
| 334 for (size_t ii = 0; ii < args_.size(); ++ii) { |
| 335 if (!args[ii]->IsA(args_[ii])) { |
| 336 return false; |
| 337 } |
| 338 } |
| 339 |
| 340 return true; |
| 341 } |
| 342 |
271 std::string AsmOverloadedFunctionType::Name() { | 343 std::string AsmOverloadedFunctionType::Name() { |
272 std::string ret; | 344 std::string ret; |
273 | 345 |
274 for (size_t ii = 0; ii < overloads_.size(); ++ii) { | 346 for (size_t ii = 0; ii < overloads_.size(); ++ii) { |
275 if (ii != 0) { | 347 if (ii != 0) { |
276 ret += " /\\ "; | 348 ret += " /\\ "; |
277 } | 349 } |
278 ret += overloads_[ii]->Name(); | 350 ret += overloads_[ii]->Name(); |
279 } | 351 } |
280 | 352 |
281 return ret; | 353 return ret; |
282 } | 354 } |
283 | 355 |
284 AsmType* AsmOverloadedFunctionType::ValidateCall( | 356 AsmType* AsmOverloadedFunctionType::ValidateCall( |
285 AsmType* return_type, const ZoneVector<AsmType*>& args) { | 357 AsmType* return_type, const ZoneVector<AsmType*>& args) { |
286 for (size_t ii = 0; ii < overloads_.size(); ++ii) { | 358 for (size_t ii = 0; ii < overloads_.size(); ++ii) { |
287 auto* validated_type = | 359 auto* validated_type = |
288 overloads_[ii]->AsCallableType()->ValidateCall(return_type, args); | 360 overloads_[ii]->AsCallableType()->ValidateCall(return_type, args); |
289 if (validated_type != AsmType::None()) { | 361 if (validated_type != AsmType::None()) { |
290 return validated_type; | 362 return validated_type; |
291 } | 363 } |
292 } | 364 } |
293 | 365 |
294 return AsmType::None(); | 366 return AsmType::None(); |
295 } | 367 } |
296 | 368 |
| 369 bool AsmOverloadedFunctionType::CanBeInvokedWith( |
| 370 AsmType* return_type, const ZoneVector<AsmType*>& args) { |
| 371 for (size_t ii = 0; ii < overloads_.size(); ++ii) { |
| 372 if (overloads_[ii]->AsCallableType()->CanBeInvokedWith(return_type, args)) { |
| 373 return true; |
| 374 } |
| 375 } |
| 376 |
| 377 return false; |
| 378 } |
| 379 |
297 void AsmOverloadedFunctionType::AddOverload(AsmType* overload) { | 380 void AsmOverloadedFunctionType::AddOverload(AsmType* overload) { |
298 DCHECK(overload->AsFunctionType() != nullptr); | 381 DCHECK(overload->AsFunctionType() != nullptr); |
299 overloads_.push_back(overload); | 382 overloads_.push_back(overload); |
300 } | 383 } |
301 | 384 |
302 AsmFunctionTableType::AsmFunctionTableType(size_t length, AsmType* signature) | 385 AsmFunctionTableType::AsmFunctionTableType(size_t length, AsmType* signature) |
303 : length_(length), signature_(signature) { | 386 : length_(length), signature_(signature) { |
304 DCHECK(signature_ != nullptr); | 387 DCHECK(signature_ != nullptr); |
305 DCHECK(signature_->AsFunctionType() != nullptr); | 388 DCHECK(signature_->AsFunctionType() != nullptr); |
306 } | 389 } |
307 | 390 |
308 std::string AsmFunctionTableType::Name() { | 391 std::string AsmFunctionTableType::Name() { |
309 return signature_->Name() + "[" + std::to_string(length_) + "]"; | 392 return signature_->Name() + "[" + std::to_string(length_) + "]"; |
310 } | 393 } |
311 | 394 |
312 AsmType* AsmFunctionTableType::ValidateCall(AsmType* return_type, | 395 AsmType* AsmFunctionTableType::ValidateCall(AsmType* return_type, |
313 const ZoneVector<AsmType*>& args) { | 396 const ZoneVector<AsmType*>& args) { |
314 return signature_->AsCallableType()->ValidateCall(return_type, args); | 397 return signature_->AsCallableType()->ValidateCall(return_type, args); |
315 } | 398 } |
316 | 399 |
| 400 bool AsmFunctionTableType::CanBeInvokedWith(AsmType* return_type, |
| 401 const ZoneVector<AsmType*>& args) { |
| 402 return signature_->AsCallableType()->CanBeInvokedWith(return_type, args); |
| 403 } |
| 404 |
317 } // namespace wasm | 405 } // namespace wasm |
318 } // namespace internal | 406 } // namespace internal |
319 } // namespace v8 | 407 } // namespace v8 |
OLD | NEW |