LCOV - code coverage report
Current view: top level - src/asmjs - asm-types.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 104 108 96.3 %
Date: 2017-04-26 Functions: 25 29 86.2 %

          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      405664 : AsmCallableType* AsmType::AsCallableType() {
      17      456554 :   if (AsValueType() != nullptr) {
      18             :     return nullptr;
      19             :   }
      20             : 
      21       32605 :   return reinterpret_cast<AsmCallableType*>(this);
      22             : }
      23             : 
      24          54 : std::string AsmType::Name() {
      25             :   AsmValueType* avt = this->AsValueType();
      26          54 :   if (avt != nullptr) {
      27          43 :     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          11 :   return this->AsCallableType()->Name();
      39             : }
      40             : 
      41       51343 : bool AsmType::IsExactly(AsmType* that) {
      42             :   // TODO(jpp): maybe this can become this == that.
      43             :   AsmValueType* avt = this->AsValueType();
      44      103282 :   if (avt != nullptr) {
      45             :     AsmValueType* tavt = that->AsValueType();
      46       68144 :     if (tavt == nullptr) {
      47             :       return false;
      48             :     }
      49       74927 :     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       28139 :   return that == this;
      55             : }
      56             : 
      57     5713611 : bool AsmType::IsA(AsmType* that) {
      58             :   // IsA is used for querying inheritance relationships. Therefore it is only
      59             :   // meaningful for basic types.
      60     5713611 :   if (auto* avt = this->AsValueType()) {
      61     5674340 :     if (auto* tavt = that->AsValueType()) {
      62     5649932 :       return (avt->Bitset() & tavt->Bitset()) == tavt->Bitset();
      63             :     }
      64             :     return false;
      65             :   }
      66             : 
      67       39271 :   if (auto* as_callable = this->AsCallableType()) {
      68       39271 :     return as_callable->IsA(that);
      69             :   }
      70             : 
      71           0 :   UNREACHABLE();
      72             :   return that == this;
      73             : }
      74             : 
      75      273714 : int32_t AsmType::ElementSizeInBytes() {
      76             :   auto* value = AsValueType();
      77      273714 :   if (value == nullptr) {
      78             :     return AsmType::kNotHeapType;
      79             :   }
      80      273705 :   switch (value->Bitset()) {
      81             :     case AsmValueType::kAsmInt8Array:
      82             :     case AsmValueType::kAsmUint8Array:
      83             :       return 1;
      84             :     case AsmValueType::kAsmInt16Array:
      85             :     case AsmValueType::kAsmUint16Array:
      86        7690 :       return 2;
      87             :     case AsmValueType::kAsmInt32Array:
      88             :     case AsmValueType::kAsmUint32Array:
      89             :     case AsmValueType::kAsmFloat32Array:
      90      235280 :       return 4;
      91             :     case AsmValueType::kAsmFloat64Array:
      92        1995 :       return 8;
      93             :     default:
      94          16 :       return AsmType::kNotHeapType;
      95             :   }
      96             : }
      97             : 
      98       87540 : AsmType* AsmType::LoadType() {
      99             :   auto* value = AsValueType();
     100       87540 :   if (value == nullptr) {
     101             :     return AsmType::None();
     102             :   }
     103       87531 :   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        8273 :       return AsmType::FloatQ();
     113             :     case AsmValueType::kAsmFloat64Array:
     114         550 :       return AsmType::DoubleQ();
     115             :     default:
     116          16 :       return AsmType::None();
     117             :   }
     118             : }
     119             : 
     120       60221 : AsmType* AsmType::StoreType() {
     121             :   auto* value = AsValueType();
     122       60221 :   if (value == nullptr) {
     123             :     return AsmType::None();
     124             :   }
     125       60212 :   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        4919 :       return AsmType::FloatishDoubleQ();
     135             :     case AsmValueType::kAsmFloat64Array:
     136         558 :       return AsmType::FloatQDoubleQ();
     137             :     default:
     138          16 :       return AsmType::None();
     139             :   }
     140             : }
     141             : 
     142       10802 : bool AsmCallableType::IsA(AsmType* other) {
     143       10802 :   return other->AsCallableType() == this;
     144             : }
     145             : 
     146           4 : std::string AsmFunctionType::Name() {
     147             :   std::string ret;
     148             :   ret += "(";
     149          20 :   for (size_t ii = 0; ii < args_.size(); ++ii) {
     150          22 :     ret += args_[ii]->Name();
     151           6 :     if (ii != args_.size() - 1) {
     152             :       ret += ", ";
     153             :     }
     154             :   }
     155             :   ret += ") -> ";
     156           8 :   ret += return_type_->Name();
     157           4 :   return ret;
     158             : }
     159             : 
     160             : namespace {
     161           0 : class AsmFroundType final : public AsmCallableType {
     162             :  public:
     163             :   friend AsmType;
     164             : 
     165      709993 :   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      709994 : AsmType* AsmType::FroundType(Zone* zone) {
     175             :   auto* Fround = new (zone) AsmFroundType();
     176      709993 :   return reinterpret_cast<AsmType*>(Fround);
     177             : }
     178             : 
     179           8 : bool AsmFroundType::CanBeInvokedWith(AsmType* return_type,
     180             :                                      const ZoneVector<AsmType*>& args) {
     181          16 :   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     2129962 :       : AsmCallableType(), return_type_(dest), arg_(src) {}
     201             : 
     202         229 :   bool CanBeInvokedWith(AsmType* return_type,
     203             :                         const ZoneVector<AsmType*>& args) override {
     204         458 :     if (!return_type_->IsExactly(return_type)) {
     205             :       return false;
     206             :     }
     207             : 
     208         544 :     if (args.size() < 2) {
     209             :       return false;
     210             :     }
     211             : 
     212         532 :     for (size_t ii = 0; ii < args.size(); ++ii) {
     213         440 :       if (!args[ii]->IsA(arg_)) {
     214             :         return false;
     215             :       }
     216             :     }
     217             : 
     218             :     return true;
     219             :   }
     220             : 
     221           3 :   std::string Name() override {
     222          24 :     return "(" + arg_->Name() + ", " + arg_->Name() + "...) -> " +
     223           9 :            return_type_->Name();
     224             :   }
     225             : 
     226             :   AsmType* return_type_;
     227             :   AsmType* arg_;
     228             : };
     229             : }  // namespace
     230             : 
     231     2129957 : AsmType* AsmType::MinMaxType(Zone* zone, AsmType* dest, AsmType* src) {
     232             :   DCHECK(dest->AsValueType() != nullptr);
     233             :   DCHECK(src->AsValueType() != nullptr);
     234             :   auto* MinMax = new (zone) AsmMinMaxType(dest, src);
     235     2129962 :   return reinterpret_cast<AsmType*>(MinMax);
     236             : }
     237             : 
     238        6999 : bool AsmFFIType::CanBeInvokedWith(AsmType* return_type,
     239             :                                   const ZoneVector<AsmType*>& args) {
     240        6999 :   if (return_type->IsExactly(AsmType::Float())) {
     241             :     return false;
     242             :   }
     243             : 
     244       21991 :   for (size_t ii = 0; ii < args.size(); ++ii) {
     245       22014 :     if (!args[ii]->IsA(AsmType::Extern())) {
     246             :       return false;
     247             :     }
     248             :   }
     249             : 
     250             :   return true;
     251             : }
     252             : 
     253       28469 : bool AsmFunctionType::IsA(AsmType* other) {
     254             :   auto* that = other->AsFunctionType();
     255       28469 :   if (that == nullptr) {
     256             :     return false;
     257             :   }
     258       12052 :   if (!return_type_->IsExactly(that->return_type_)) {
     259             :     return false;
     260             :   }
     261             : 
     262       18012 :   if (args_.size() != that->args_.size()) {
     263             :     return false;
     264             :   }
     265             : 
     266       29702 :   for (size_t ii = 0; ii < args_.size(); ++ii) {
     267       35643 :     if (!args_[ii]->IsExactly(that->args_[ii])) {
     268             :       return false;
     269             :     }
     270             :   }
     271             : 
     272             :   return true;
     273             : }
     274             : 
     275       26804 : bool AsmFunctionType::CanBeInvokedWith(AsmType* return_type,
     276             :                                        const ZoneVector<AsmType*>& args) {
     277       53608 :   if (!return_type_->IsExactly(return_type)) {
     278             :     return false;
     279             :   }
     280             : 
     281      231212 :   if (args_.size() != args.size()) {
     282             :     return false;
     283             :   }
     284             : 
     285      151795 :   for (size_t ii = 0; ii < args_.size(); ++ii) {
     286      125392 :     if (!args[ii]->IsA(args_[ii])) {
     287             :       return false;
     288             :     }
     289             :   }
     290             : 
     291             :   return true;
     292             : }
     293             : 
     294           1 : std::string AsmOverloadedFunctionType::Name() {
     295             :   std::string ret;
     296             : 
     297           6 :   for (size_t ii = 0; ii < overloads_.size(); ++ii) {
     298           2 :     if (ii != 0) {
     299             :       ret += " /\\ ";
     300             :     }
     301           9 :     ret += overloads_[ii]->Name();
     302             :   }
     303             : 
     304           1 :   return ret;
     305             : }
     306             : 
     307         534 : bool AsmOverloadedFunctionType::CanBeInvokedWith(
     308             :     AsmType* return_type, const ZoneVector<AsmType*>& args) {
     309        1662 :   for (size_t ii = 0; ii < overloads_.size(); ++ii) {
     310        2439 :     if (overloads_[ii]->AsCallableType()->CanBeInvokedWith(return_type, args)) {
     311             :       return true;
     312             :     }
     313             :   }
     314             : 
     315             :   return false;
     316             : }
     317             : 
     318     5679875 : void AsmOverloadedFunctionType::AddOverload(AsmType* overload) {
     319             :   DCHECK(overload->AsCallableType() != nullptr);
     320     5679875 :   overloads_.push_back(overload);
     321     5679877 : }
     322             : 
     323        1529 : AsmFunctionTableType::AsmFunctionTableType(size_t length, AsmType* signature)
     324        1529 :     : length_(length), signature_(signature) {
     325             :   DCHECK(signature_ != nullptr);
     326             :   DCHECK(signature_->AsFunctionType() != nullptr);
     327        1529 : }
     328             : 
     329             : namespace {
     330             : // ToString is used for reporting function tables' names. It converts its
     331             : // argument to uint32_t because asm.js integers are 32-bits, thus effectively
     332             : // limiting the max function table's length.
     333           1 : std::string ToString(size_t s) {
     334           1 :   auto u32 = static_cast<uint32_t>(s);
     335             :   // 16 bytes is more than enough to represent a 32-bit integer as a base 10
     336             :   // string.
     337             :   char digits[16];
     338           1 :   int length = base::OS::SNPrintF(digits, arraysize(digits), "%" PRIu32, u32);
     339             :   DCHECK_NE(length, -1);
     340           1 :   return std::string(digits, length);
     341             : }
     342             : }  // namespace
     343             : 
     344           1 : std::string AsmFunctionTableType::Name() {
     345           7 :   return "(" + signature_->Name() + ")[" + ToString(length_) + "]";
     346             : }
     347             : 
     348           2 : bool AsmFunctionTableType::CanBeInvokedWith(AsmType* return_type,
     349             :                                             const ZoneVector<AsmType*>& args) {
     350           4 :   return signature_->AsCallableType()->CanBeInvokedWith(return_type, args);
     351             : }
     352             : 
     353             : }  // namespace wasm
     354             : }  // namespace internal
     355             : }  // namespace v8

Generated by: LCOV version 1.10