LCOV - code coverage report
Current view: top level - src/asmjs - asm-types.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 91 95 95.8 %
Date: 2019-04-19 Functions: 21 25 84.0 %

          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       36289 : AsmCallableType* AsmType::AsCallableType() {
      17      196046 :   if (AsValueType() != nullptr) {
      18             :     return nullptr;
      19             :   }
      20             : 
      21       36289 :   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      252031 : bool AsmType::IsExactly(AsmType* x, AsmType* y) {
      42             :   // TODO(jpp): maybe this can become x == y.
      43      315958 :   if (x == nullptr) return y == nullptr;
      44             :   AsmValueType* avt = x->AsValueType();
      45       86400 :   if (avt != nullptr) {
      46             :     AsmValueType* tavt = y->AsValueType();
      47       86183 :     if (tavt == nullptr) {
      48             :       return false;
      49             :     }
      50       86015 :     return avt->Bitset() == tavt->Bitset();
      51             :   }
      52             : 
      53             :   // TODO(jpp): is it useful to allow non-value types to be tested with
      54             :   // IsExactly?
      55         217 :   return x == y;
      56             : }
      57             : 
      58    15499980 : bool AsmType::IsA(AsmType* that) {
      59             :   // IsA is used for querying inheritance relationships. Therefore it is only
      60             :   // meaningful for basic types.
      61    15499980 :   if (auto* avt = this->AsValueType()) {
      62    15345824 :     if (auto* tavt = that->AsValueType()) {
      63    15146048 :       return (avt->Bitset() & tavt->Bitset()) == tavt->Bitset();
      64             :     }
      65             :     return false;
      66             :   }
      67             : 
      68      154156 :   if (auto* as_callable = this->AsCallableType()) {
      69      154156 :     return as_callable->IsA(that);
      70             :   }
      71             : 
      72           0 :   UNREACHABLE();
      73             : }
      74             : 
      75      169689 : int32_t AsmType::ElementSizeInBytes() {
      76             :   auto* value = AsValueType();
      77      169689 :   if (value == nullptr) {
      78             :     return AsmType::kNotHeapType;
      79             :   }
      80      169682 :   switch (value->Bitset()) {
      81             :     case AsmValueType::kAsmInt8Array:
      82             :     case AsmValueType::kAsmUint8Array:
      83             :       return 1;
      84             :     case AsmValueType::kAsmInt16Array:
      85             :     case AsmValueType::kAsmUint16Array:
      86        4725 :       return 2;
      87             :     case AsmValueType::kAsmInt32Array:
      88             :     case AsmValueType::kAsmUint32Array:
      89             :     case AsmValueType::kAsmFloat32Array:
      90      141985 :       return 4;
      91             :     case AsmValueType::kAsmFloat64Array:
      92        5685 :       return 8;
      93             :     default:
      94          16 :       return AsmType::kNotHeapType;
      95             :   }
      96             : }
      97             : 
      98      103763 : AsmType* AsmType::LoadType() {
      99             :   auto* value = AsValueType();
     100      103763 :   if (value == nullptr) {
     101             :     return AsmType::None();
     102             :   }
     103      103756 :   switch (value->Bitset()) {
     104             :     case AsmValueType::kAsmInt8Array:
     105             :     case AsmValueType::kAsmUint8Array:
     106             :     case AsmValueType::kAsmInt16Array:
     107             :     case AsmValueType::kAsmUint16Array:
     108             :     case AsmValueType::kAsmInt32Array:
     109             :     case AsmValueType::kAsmUint32Array:
     110             :       return AsmType::Intish();
     111             :     case AsmValueType::kAsmFloat32Array:
     112        5914 :       return AsmType::FloatQ();
     113             :     case AsmValueType::kAsmFloat64Array:
     114        3068 :       return AsmType::DoubleQ();
     115             :     default:
     116          16 :       return AsmType::None();
     117             :   }
     118             : }
     119             : 
     120       65932 : AsmType* AsmType::StoreType() {
     121             :   auto* value = AsValueType();
     122       65932 :   if (value == nullptr) {
     123             :     return AsmType::None();
     124             :   }
     125       65925 :   switch (value->Bitset()) {
     126             :     case AsmValueType::kAsmInt8Array:
     127             :     case AsmValueType::kAsmUint8Array:
     128             :     case AsmValueType::kAsmInt16Array:
     129             :     case AsmValueType::kAsmUint16Array:
     130             :     case AsmValueType::kAsmInt32Array:
     131             :     case AsmValueType::kAsmUint32Array:
     132             :       return AsmType::Intish();
     133             :     case AsmValueType::kAsmFloat32Array:
     134        3501 :       return AsmType::FloatishDoubleQ();
     135             :     case AsmValueType::kAsmFloat64Array:
     136        2619 :       return AsmType::FloatQDoubleQ();
     137             :     default:
     138          16 :       return AsmType::None();
     139             :   }
     140             : }
     141             : 
     142        3675 : bool AsmCallableType::IsA(AsmType* other) {
     143        3675 :   return other->AsCallableType() == this;
     144             : }
     145             : 
     146           3 : std::string AsmFunctionType::Name() {
     147             :   std::string ret;
     148             :   ret += "(";
     149          13 :   for (size_t ii = 0; ii < args_.size(); ++ii) {
     150          10 :     ret += args_[ii]->Name();
     151           5 :     if (ii != args_.size() - 1) {
     152             :       ret += ", ";
     153             :     }
     154             :   }
     155             :   ret += ") -> ";
     156           6 :   ret += return_type_->Name();
     157           3 :   return ret;
     158             : }
     159             : 
     160             : namespace {
     161           0 : class AsmFroundType final : public AsmCallableType {
     162             :  public:
     163             :   friend AsmType;
     164             : 
     165        3761 :   AsmFroundType() : AsmCallableType() {}
     166             : 
     167             :   bool CanBeInvokedWith(AsmType* return_type,
     168             :                         const ZoneVector<AsmType*>& args) override;
     169             : 
     170           1 :   std::string Name() override { return "fround"; }
     171             : };
     172             : }  // namespace
     173             : 
     174        3761 : AsmType* AsmType::FroundType(Zone* zone) {
     175             :   auto* Fround = new (zone) AsmFroundType();
     176        3761 :   return reinterpret_cast<AsmType*>(Fround);
     177             : }
     178             : 
     179           8 : bool AsmFroundType::CanBeInvokedWith(AsmType* return_type,
     180             :                                      const ZoneVector<AsmType*>& args) {
     181           8 :   if (args.size() != 1) {
     182             :     return false;
     183             :   }
     184             : 
     185           8 :   auto* arg = args[0];
     186          24 :   if (!arg->IsA(AsmType::Floatish()) && !arg->IsA(AsmType::DoubleQ()) &&
     187          12 :       !arg->IsA(AsmType::Signed()) && !arg->IsA(AsmType::Unsigned())) {
     188             :     return false;
     189             :   }
     190             : 
     191           8 :   return true;
     192             : }
     193             : 
     194             : namespace {
     195           0 : class AsmMinMaxType final : public AsmCallableType {
     196             :  private:
     197             :   friend AsmType;
     198             : 
     199             :   AsmMinMaxType(AsmType* dest, AsmType* src)
     200       11275 :       : AsmCallableType(), return_type_(dest), arg_(src) {}
     201             : 
     202         624 :   bool CanBeInvokedWith(AsmType* return_type,
     203             :                         const ZoneVector<AsmType*>& args) override {
     204        1248 :     if (!AsmType::IsExactly(return_type_, return_type)) {
     205             :       return false;
     206             :     }
     207             : 
     208         181 :     if (args.size() < 2) {
     209             :       return false;
     210             :     }
     211             : 
     212         701 :     for (size_t ii = 0; ii < args.size(); ++ii) {
     213         636 :       if (!args[ii]->IsA(arg_)) {
     214             :         return false;
     215             :       }
     216             :     }
     217             : 
     218             :     return true;
     219             :   }
     220             : 
     221           3 :   std::string Name() override {
     222          21 :     return "(" + arg_->Name() + ", " + arg_->Name() + "...) -> " +
     223           9 :            return_type_->Name();
     224             :   }
     225             : 
     226             :   AsmType* return_type_;
     227             :   AsmType* arg_;
     228             : };
     229             : }  // namespace
     230             : 
     231       11275 : AsmType* AsmType::MinMaxType(Zone* zone, AsmType* dest, AsmType* src) {
     232             :   DCHECK_NOT_NULL(dest->AsValueType());
     233             :   DCHECK_NOT_NULL(src->AsValueType());
     234             :   auto* MinMax = new (zone) AsmMinMaxType(dest, src);
     235       11275 :   return reinterpret_cast<AsmType*>(MinMax);
     236             : }
     237             : 
     238      150481 : bool AsmFunctionType::IsA(AsmType* other) {
     239             :   auto* that = other->AsFunctionType();
     240      150481 :   if (that == nullptr) {
     241             :     return false;
     242             :   }
     243       14392 :   if (!AsmType::IsExactly(return_type_, that->return_type_)) {
     244             :     return false;
     245             :   }
     246             : 
     247        7187 :   if (args_.size() != that->args_.size()) {
     248             :     return false;
     249             :   }
     250             : 
     251       37839 :   for (size_t ii = 0; ii < args_.size(); ++ii) {
     252       46053 :     if (!AsmType::IsExactly(args_[ii], that->args_[ii])) {
     253             :       return false;
     254             :     }
     255             :   }
     256             : 
     257             :   return true;
     258             : }
     259             : 
     260       40756 : bool AsmFunctionType::CanBeInvokedWith(AsmType* return_type,
     261             :                                        const ZoneVector<AsmType*>& args) {
     262       81512 :   if (!AsmType::IsExactly(return_type_, return_type)) {
     263             :     return false;
     264             :   }
     265             : 
     266       36168 :   if (args_.size() != args.size()) {
     267             :     return false;
     268             :   }
     269             : 
     270      203017 :   for (size_t ii = 0; ii < args_.size(); ++ii) {
     271      166916 :     if (!args[ii]->IsA(args_[ii])) {
     272             :       return false;
     273             :     }
     274             :   }
     275             : 
     276             :   return true;
     277             : }
     278             : 
     279           1 : std::string AsmOverloadedFunctionType::Name() {
     280             :   std::string ret;
     281             : 
     282           5 :   for (size_t ii = 0; ii < overloads_.size(); ++ii) {
     283           2 :     if (ii != 0) {
     284             :       ret += " /\\ ";
     285             :     }
     286           4 :     ret += overloads_[ii]->Name();
     287             :   }
     288             : 
     289           1 :   return ret;
     290             : }
     291             : 
     292        1010 : bool AsmOverloadedFunctionType::CanBeInvokedWith(
     293             :     AsmType* return_type, const ZoneVector<AsmType*>& args) {
     294        3544 :   for (size_t ii = 0; ii < overloads_.size(); ++ii) {
     295        3836 :     if (overloads_[ii]->AsCallableType()->CanBeInvokedWith(return_type, args)) {
     296             :       return true;
     297             :     }
     298             :   }
     299             : 
     300             :   return false;
     301             : }
     302             : 
     303       30055 : void AsmOverloadedFunctionType::AddOverload(AsmType* overload) {
     304             :   DCHECK_NOT_NULL(overload->AsCallableType());
     305       30055 :   overloads_.push_back(overload);
     306       30059 : }
     307             : 
     308             : }  // namespace wasm
     309             : }  // namespace internal
     310      122036 : }  // namespace v8

Generated by: LCOV version 1.10