LCOV - code coverage report
Current view: top level - src/asmjs - asm-types.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 89 93 95.7 %
Date: 2017-10-20 Functions: 20 24 83.3 %

          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             : #include "src/asmjs/asm-types.h"
       6             : 
       7             : #include <cinttypes>
       8             : 
       9             : #include "src/utils.h"
      10             : #include "src/v8.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : namespace wasm {
      15             : 
      16       43814 : AsmCallableType* AsmType::AsCallableType() {
      17      237316 :   if (AsValueType() != nullptr) {
      18             :     return nullptr;
      19             :   }
      20             : 
      21       43814 :   return reinterpret_cast<AsmCallableType*>(this);
      22             : }
      23             : 
      24          49 : std::string AsmType::Name() {
      25             :   AsmValueType* avt = this->AsValueType();
      26          49 :   if (avt != nullptr) {
      27          41 :     switch (avt->Bitset()) {
      28             : #define RETURN_TYPE_NAME(CamelName, string_name, number, parent_types) \
      29             :   case AsmValueType::kAsm##CamelName:                                  \
      30             :     return string_name;
      31           1 :       FOR_EACH_ASM_VALUE_TYPE_LIST(RETURN_TYPE_NAME)
      32             : #undef RETURN_TYPE_NAME
      33             :       default:
      34           0 :         UNREACHABLE();
      35             :     }
      36             :   }
      37             : 
      38           8 :   return this->AsCallableType()->Name();
      39             : }
      40             : 
      41      312416 : bool AsmType::IsExactly(AsmType* that) {
      42             :   // TODO(jpp): maybe this can become this == that.
      43             :   AsmValueType* avt = this->AsValueType();
      44      390027 :   if (avt != nullptr) {
      45             :     AsmValueType* tavt = that->AsValueType();
      46      104555 :     if (tavt == nullptr) {
      47             :       return false;
      48             :     }
      49      104387 :     return avt->Bitset() == tavt->Bitset();
      50             :   }
      51             : 
      52             :   // TODO(jpp): is it useful to allow non-value types to be tested with
      53             :   // IsExactly?
      54      285472 :   return that == this;
      55             : }
      56             : 
      57     6776329 : bool AsmType::IsA(AsmType* that) {
      58             :   // IsA is used for querying inheritance relationships. Therefore it is only
      59             :   // meaningful for basic types.
      60     6776329 :   if (auto* avt = this->AsValueType()) {
      61     6589893 :     if (auto* tavt = that->AsValueType()) {
      62     6342011 :       return (avt->Bitset() & tavt->Bitset()) == tavt->Bitset();
      63             :     }
      64             :     return false;
      65             :   }
      66             : 
      67      186436 :   if (auto* as_callable = this->AsCallableType()) {
      68      186436 :     return as_callable->IsA(that);
      69             :   }
      70             : 
      71           0 :   UNREACHABLE();
      72             : }
      73             : 
      74      211606 : int32_t AsmType::ElementSizeInBytes() {
      75             :   auto* value = AsValueType();
      76      211606 :   if (value == nullptr) {
      77             :     return AsmType::kNotHeapType;
      78             :   }
      79      211599 :   switch (value->Bitset()) {
      80             :     case AsmValueType::kAsmInt8Array:
      81             :     case AsmValueType::kAsmUint8Array:
      82             :       return 1;
      83             :     case AsmValueType::kAsmInt16Array:
      84             :     case AsmValueType::kAsmUint16Array:
      85        5858 :       return 2;
      86             :     case AsmValueType::kAsmInt32Array:
      87             :     case AsmValueType::kAsmUint32Array:
      88             :     case AsmValueType::kAsmFloat32Array:
      89      178128 :       return 4;
      90             :     case AsmValueType::kAsmFloat64Array:
      91        5984 :       return 8;
      92             :     default:
      93          16 :       return AsmType::kNotHeapType;
      94             :   }
      95             : }
      96             : 
      97      128690 : AsmType* AsmType::LoadType() {
      98             :   auto* value = AsValueType();
      99      128690 :   if (value == nullptr) {
     100             :     return AsmType::None();
     101             :   }
     102      128683 :   switch (value->Bitset()) {
     103             :     case AsmValueType::kAsmInt8Array:
     104             :     case AsmValueType::kAsmUint8Array:
     105             :     case AsmValueType::kAsmInt16Array:
     106             :     case AsmValueType::kAsmUint16Array:
     107             :     case AsmValueType::kAsmInt32Array:
     108             :     case AsmValueType::kAsmUint32Array:
     109             :       return AsmType::Intish();
     110             :     case AsmValueType::kAsmFloat32Array:
     111        8274 :       return AsmType::FloatQ();
     112             :     case AsmValueType::kAsmFloat64Array:
     113        3216 :       return AsmType::DoubleQ();
     114             :     default:
     115          16 :       return AsmType::None();
     116             :   }
     117             : }
     118             : 
     119       82905 : AsmType* AsmType::StoreType() {
     120             :   auto* value = AsValueType();
     121       82905 :   if (value == nullptr) {
     122             :     return AsmType::None();
     123             :   }
     124       82898 :   switch (value->Bitset()) {
     125             :     case AsmValueType::kAsmInt8Array:
     126             :     case AsmValueType::kAsmUint8Array:
     127             :     case AsmValueType::kAsmInt16Array:
     128             :     case AsmValueType::kAsmUint16Array:
     129             :     case AsmValueType::kAsmInt32Array:
     130             :     case AsmValueType::kAsmUint32Array:
     131             :       return AsmType::Intish();
     132             :     case AsmValueType::kAsmFloat32Array:
     133        4895 :       return AsmType::FloatishDoubleQ();
     134             :     case AsmValueType::kAsmFloat64Array:
     135        2769 :       return AsmType::FloatQDoubleQ();
     136             :     default:
     137          16 :       return AsmType::None();
     138             :   }
     139             : }
     140             : 
     141        4370 : bool AsmCallableType::IsA(AsmType* other) {
     142        4370 :   return other->AsCallableType() == this;
     143             : }
     144             : 
     145           3 : std::string AsmFunctionType::Name() {
     146             :   std::string ret;
     147             :   ret += "(";
     148          16 :   for (size_t ii = 0; ii < args_.size(); ++ii) {
     149          18 :     ret += args_[ii]->Name();
     150           5 :     if (ii != args_.size() - 1) {
     151             :       ret += ", ";
     152             :     }
     153             :   }
     154             :   ret += ") -> ";
     155           6 :   ret += return_type_->Name();
     156           3 :   return ret;
     157             : }
     158             : 
     159             : namespace {
     160           0 : class AsmFroundType final : public AsmCallableType {
     161             :  public:
     162             :   friend AsmType;
     163             : 
     164      346055 :   AsmFroundType() : AsmCallableType() {}
     165             : 
     166             :   bool CanBeInvokedWith(AsmType* return_type,
     167             :                         const ZoneVector<AsmType*>& args) override;
     168             : 
     169           1 :   std::string Name() override { return "fround"; }
     170             : };
     171             : }  // namespace
     172             : 
     173      346054 : AsmType* AsmType::FroundType(Zone* zone) {
     174             :   auto* Fround = new (zone) AsmFroundType();
     175      346055 :   return reinterpret_cast<AsmType*>(Fround);
     176             : }
     177             : 
     178           8 : bool AsmFroundType::CanBeInvokedWith(AsmType* return_type,
     179             :                                      const ZoneVector<AsmType*>& args) {
     180          16 :   if (args.size() != 1) {
     181             :     return false;
     182             :   }
     183             : 
     184           8 :   auto* arg = args[0];
     185          24 :   if (!arg->IsA(AsmType::Floatish()) && !arg->IsA(AsmType::DoubleQ()) &&
     186          12 :       !arg->IsA(AsmType::Signed()) && !arg->IsA(AsmType::Unsigned())) {
     187             :     return false;
     188             :   }
     189             : 
     190           8 :   return true;
     191             : }
     192             : 
     193             : namespace {
     194           0 : class AsmMinMaxType final : public AsmCallableType {
     195             :  private:
     196             :   friend AsmType;
     197             : 
     198             :   AsmMinMaxType(AsmType* dest, AsmType* src)
     199     1038153 :       : AsmCallableType(), return_type_(dest), arg_(src) {}
     200             : 
     201         971 :   bool CanBeInvokedWith(AsmType* return_type,
     202             :                         const ZoneVector<AsmType*>& args) override {
     203        1942 :     if (!return_type_->IsExactly(return_type)) {
     204             :       return false;
     205             :     }
     206             : 
     207        1038 :     if (args.size() < 2) {
     208             :       return false;
     209             :     }
     210             : 
     211         830 :     for (size_t ii = 0; ii < args.size(); ++ii) {
     212         808 :       if (!args[ii]->IsA(arg_)) {
     213             :         return false;
     214             :       }
     215             :     }
     216             : 
     217             :     return true;
     218             :   }
     219             : 
     220           3 :   std::string Name() override {
     221          24 :     return "(" + arg_->Name() + ", " + arg_->Name() + "...) -> " +
     222           9 :            return_type_->Name();
     223             :   }
     224             : 
     225             :   AsmType* return_type_;
     226             :   AsmType* arg_;
     227             : };
     228             : }  // namespace
     229             : 
     230     1038149 : AsmType* AsmType::MinMaxType(Zone* zone, AsmType* dest, AsmType* src) {
     231             :   DCHECK_NOT_NULL(dest->AsValueType());
     232             :   DCHECK_NOT_NULL(src->AsValueType());
     233             :   auto* MinMax = new (zone) AsmMinMaxType(dest, src);
     234     1038153 :   return reinterpret_cast<AsmType*>(MinMax);
     235             : }
     236             : 
     237      182066 : bool AsmFunctionType::IsA(AsmType* other) {
     238             :   auto* that = other->AsFunctionType();
     239      182066 :   if (that == nullptr) {
     240             :     return false;
     241             :   }
     242       17768 :   if (!return_type_->IsExactly(that->return_type_)) {
     243             :     return false;
     244             :   }
     245             : 
     246       26613 :   if (args_.size() != that->args_.size()) {
     247             :     return false;
     248             :   }
     249             : 
     250       46259 :   for (size_t ii = 0; ii < args_.size(); ++ii) {
     251       56157 :     if (!args_[ii]->IsExactly(that->args_[ii])) {
     252             :       return false;
     253             :     }
     254             :   }
     255             : 
     256             :   return true;
     257             : }
     258             : 
     259       49037 : bool AsmFunctionType::CanBeInvokedWith(AsmType* return_type,
     260             :                                        const ZoneVector<AsmType*>& args) {
     261       98074 :   if (!return_type_->IsExactly(return_type)) {
     262             :     return false;
     263             :   }
     264             : 
     265      377547 :   if (args_.size() != args.size()) {
     266             :     return false;
     267             :   }
     268             : 
     269      246310 :   for (size_t ii = 0; ii < args_.size(); ++ii) {
     270      202756 :     if (!args[ii]->IsA(args_[ii])) {
     271             :       return false;
     272             :     }
     273             :   }
     274             : 
     275             :   return true;
     276             : }
     277             : 
     278           1 : std::string AsmOverloadedFunctionType::Name() {
     279             :   std::string ret;
     280             : 
     281           6 :   for (size_t ii = 0; ii < overloads_.size(); ++ii) {
     282           2 :     if (ii != 0) {
     283             :       ret += " /\\ ";
     284             :     }
     285           9 :     ret += overloads_[ii]->Name();
     286             :   }
     287             : 
     288           1 :   return ret;
     289             : }
     290             : 
     291        1353 : bool AsmOverloadedFunctionType::CanBeInvokedWith(
     292             :     AsmType* return_type, const ZoneVector<AsmType*>& args) {
     293        6574 :   for (size_t ii = 0; ii < overloads_.size(); ++ii) {
     294        8663 :     if (overloads_[ii]->AsCallableType()->CanBeInvokedWith(return_type, args)) {
     295             :       return true;
     296             :     }
     297             :   }
     298             : 
     299             :   return false;
     300             : }
     301             : 
     302     2768392 : void AsmOverloadedFunctionType::AddOverload(AsmType* overload) {
     303             :   DCHECK_NOT_NULL(overload->AsCallableType());
     304     2768392 :   overloads_.push_back(overload);
     305     2768396 : }
     306             : 
     307             : }  // namespace wasm
     308             : }  // namespace internal
     309             : }  // namespace v8

Generated by: LCOV version 1.10