| 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 |