LCOV - code coverage report
Current view: top level - src/asmjs - asm-types.h (source / functions) Hit Total Coverage
Test: app.info Lines: 27 33 81.8 %
Date: 2017-04-26 Functions: 11 22 50.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             : #ifndef SRC_ASMJS_ASM_TYPES_H_
       6             : #define SRC_ASMJS_ASM_TYPES_H_
       7             : 
       8             : #include <string>
       9             : 
      10             : #include "src/base/compiler-specific.h"
      11             : #include "src/base/macros.h"
      12             : #include "src/globals.h"
      13             : #include "src/zone/zone-containers.h"
      14             : #include "src/zone/zone.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : namespace wasm {
      19             : 
      20             : class AsmType;
      21             : class AsmFFIType;
      22             : class AsmFunctionType;
      23             : class AsmOverloadedFunctionType;
      24             : class AsmFunctionTableType;
      25             : 
      26             : // List of V(CamelName, string_name, number, parent_types)
      27             : #define FOR_EACH_ASM_VALUE_TYPE_LIST(V)                                       \
      28             :   /* These tags are not types that are expressable in the asm source. They */ \
      29             :   /* are used to express semantic information about the types they tag.    */ \
      30             :   V(Heap, "[]", 1, 0)                                                         \
      31             :   V(FloatishDoubleQ, "floatish|double?", 2, 0)                                \
      32             :   V(FloatQDoubleQ, "float?|double?", 3, 0)                                    \
      33             :   /* The following are actual types that appear in the asm source. */         \
      34             :   V(Void, "void", 4, 0)                                                       \
      35             :   V(Extern, "extern", 5, 0)                                                   \
      36             :   V(DoubleQ, "double?", 6, kAsmFloatishDoubleQ | kAsmFloatQDoubleQ)           \
      37             :   V(Double, "double", 7, kAsmDoubleQ | kAsmExtern)                            \
      38             :   V(Intish, "intish", 8, 0)                                                   \
      39             :   V(Int, "int", 9, kAsmIntish)                                                \
      40             :   V(Signed, "signed", 10, kAsmInt | kAsmExtern)                               \
      41             :   V(Unsigned, "unsigned", 11, kAsmInt)                                        \
      42             :   V(FixNum, "fixnum", 12, kAsmSigned | kAsmUnsigned)                          \
      43             :   V(Floatish, "floatish", 13, kAsmFloatishDoubleQ)                            \
      44             :   V(FloatQ, "float?", 14, kAsmFloatQDoubleQ | kAsmFloatish)                   \
      45             :   V(Float, "float", 15, kAsmFloatQ)                                           \
      46             :   /* Types used for expressing the Heap accesses. */                          \
      47             :   V(Uint8Array, "Uint8Array", 16, kAsmHeap)                                   \
      48             :   V(Int8Array, "Int8Array", 17, kAsmHeap)                                     \
      49             :   V(Uint16Array, "Uint16Array", 18, kAsmHeap)                                 \
      50             :   V(Int16Array, "Int16Array", 19, kAsmHeap)                                   \
      51             :   V(Uint32Array, "Uint32Array", 20, kAsmHeap)                                 \
      52             :   V(Int32Array, "Int32Array", 21, kAsmHeap)                                   \
      53             :   V(Float32Array, "Float32Array", 22, kAsmHeap)                               \
      54             :   V(Float64Array, "Float64Array", 23, kAsmHeap)                               \
      55             :   /* None is used to represent errors in the type checker. */                 \
      56             :   V(None, "<none>", 31, 0)
      57             : 
      58             : // List of V(CamelName)
      59             : #define FOR_EACH_ASM_CALLABLE_TYPE_LIST(V) \
      60             :   V(FunctionType)                          \
      61             :   V(FFIType)                               \
      62             :   V(OverloadedFunctionType)                \
      63             :   V(FunctionTableType)
      64             : 
      65             : class AsmValueType {
      66             :  public:
      67             :   typedef uint32_t bitset_t;
      68             : 
      69             :   enum : uint32_t {
      70             : #define DEFINE_TAG(CamelName, string_name, number, parent_types) \
      71             :   kAsm##CamelName = ((1u << (number)) | (parent_types)),
      72             :     FOR_EACH_ASM_VALUE_TYPE_LIST(DEFINE_TAG)
      73             : #undef DEFINE_TAG
      74             :         kAsmUnknown = 0,
      75             :     kAsmValueTypeTag = 1u
      76             :   };
      77             : 
      78             :  private:
      79             :   friend class AsmType;
      80             : 
      81             :   static AsmValueType* AsValueType(AsmType* type) {
      82    23930350 :     if ((reinterpret_cast<uintptr_t>(type) & kAsmValueTypeTag) ==
      83             :         kAsmValueTypeTag) {
      84             :       return reinterpret_cast<AsmValueType*>(type);
      85             :     }
      86             :     return nullptr;
      87             :   }
      88             : 
      89             :   bitset_t Bitset() const {
      90             :     DCHECK((reinterpret_cast<uintptr_t>(this) & kAsmValueTypeTag) ==
      91             :            kAsmValueTypeTag);
      92             :     return static_cast<bitset_t>(reinterpret_cast<uintptr_t>(this) &
      93     6146350 :                                  ~kAsmValueTypeTag);
      94             :   }
      95             : 
      96             :   static AsmType* New(bitset_t bits) {
      97             :     DCHECK_EQ((bits & kAsmValueTypeTag), 0u);
      98             :     return reinterpret_cast<AsmType*>(
      99             :         static_cast<uintptr_t>(bits | kAsmValueTypeTag));
     100             :   }
     101             : 
     102             :   // AsmValueTypes can't be created except through AsmValueType::New.
     103             :   DISALLOW_IMPLICIT_CONSTRUCTORS(AsmValueType);
     104             : };
     105             : 
     106             : class V8_EXPORT_PRIVATE AsmCallableType : public NON_EXPORTED_BASE(ZoneObject) {
     107             :  public:
     108             :   virtual std::string Name() = 0;
     109             : 
     110             :   virtual bool CanBeInvokedWith(AsmType* return_type,
     111             :                                 const ZoneVector<AsmType*>& args) = 0;
     112             : 
     113             : #define DECLARE_CAST(CamelName) \
     114             :   virtual Asm##CamelName* As##CamelName() { return nullptr; }
     115       57965 :   FOR_EACH_ASM_CALLABLE_TYPE_LIST(DECLARE_CAST)
     116             : #undef DECLARE_CAST
     117             : 
     118             :  protected:
     119     9611593 :   AsmCallableType() = default;
     120           0 :   virtual ~AsmCallableType() = default;
     121             :   virtual bool IsA(AsmType* other);
     122             : 
     123             :  private:
     124             :   friend class AsmType;
     125             : 
     126             :   DISALLOW_COPY_AND_ASSIGN(AsmCallableType);
     127             : };
     128             : 
     129           0 : class V8_EXPORT_PRIVATE AsmFunctionType final : public AsmCallableType {
     130             :  public:
     131     5751825 :   AsmFunctionType* AsFunctionType() final { return this; }
     132             : 
     133     5718547 :   void AddArgument(AsmType* type) { args_.push_back(type); }
     134             :   const ZoneVector<AsmType*> Arguments() const { return args_; }
     135             :   AsmType* ReturnType() const { return return_type_; }
     136             : 
     137             :   bool CanBeInvokedWith(AsmType* return_type,
     138             :                         const ZoneVector<AsmType*>& args) override;
     139             : 
     140             :  protected:
     141             :   AsmFunctionType(Zone* zone, AsmType* return_type)
     142     4281342 :       : return_type_(return_type), args_(zone) {}
     143             : 
     144             :  private:
     145             :   friend AsmType;
     146             : 
     147             :   std::string Name() override;
     148             :   bool IsA(AsmType* other) override;
     149             : 
     150             :   AsmType* return_type_;
     151             :   ZoneVector<AsmType*> args_;
     152             : 
     153             :   DISALLOW_COPY_AND_ASSIGN(AsmFunctionType);
     154             : };
     155             : 
     156           0 : class V8_EXPORT_PRIVATE AsmOverloadedFunctionType final
     157             :     : public AsmCallableType {
     158             :  public:
     159     5679858 :   AsmOverloadedFunctionType* AsOverloadedFunctionType() override {
     160     5679858 :     return this;
     161             :   }
     162             : 
     163             :   void AddOverload(AsmType* overload);
     164             : 
     165             :  private:
     166             :   friend AsmType;
     167             : 
     168     2129948 :   explicit AsmOverloadedFunctionType(Zone* zone) : overloads_(zone) {}
     169             : 
     170             :   std::string Name() override;
     171             :   bool CanBeInvokedWith(AsmType* return_type,
     172             :                         const ZoneVector<AsmType*>& args) override;
     173             : 
     174             :   ZoneVector<AsmType*> overloads_;
     175             : 
     176             :   DISALLOW_IMPLICIT_CONSTRUCTORS(AsmOverloadedFunctionType);
     177             : };
     178             : 
     179           0 : class V8_EXPORT_PRIVATE AsmFFIType final : public AsmCallableType {
     180             :  public:
     181       16145 :   AsmFFIType* AsFFIType() override { return this; }
     182             : 
     183           1 :   std::string Name() override { return "Function"; }
     184             :   bool CanBeInvokedWith(AsmType* return_type,
     185             :                         const ZoneVector<AsmType*>& args) override;
     186             : 
     187             :  private:
     188             :   friend AsmType;
     189             : 
     190      358819 :   AsmFFIType() = default;
     191             : 
     192             :   DISALLOW_COPY_AND_ASSIGN(AsmFFIType);
     193             : };
     194             : 
     195           0 : class V8_EXPORT_PRIVATE AsmFunctionTableType : public AsmCallableType {
     196             :  public:
     197        1533 :   AsmFunctionTableType* AsFunctionTableType() override { return this; }
     198             : 
     199             :   std::string Name() override;
     200             : 
     201             :   bool CanBeInvokedWith(AsmType* return_type,
     202             :                         const ZoneVector<AsmType*>& args) override;
     203             : 
     204             :   size_t length() const { return length_; }
     205             :   AsmType* signature() { return signature_; }
     206             : 
     207             :  private:
     208             :   friend class AsmType;
     209             : 
     210             :   AsmFunctionTableType(size_t length, AsmType* signature);
     211             : 
     212             :   size_t length_;
     213             :   AsmType* signature_;
     214             : 
     215             :   DISALLOW_IMPLICIT_CONSTRUCTORS(AsmFunctionTableType);
     216             : };
     217             : 
     218             : class V8_EXPORT_PRIVATE AsmType {
     219             :  public:
     220             : #define DEFINE_CONSTRUCTOR(CamelName, string_name, number, parent_types) \
     221             :   static AsmType* CamelName() {                                          \
     222             :     return AsmValueType::New(AsmValueType::kAsm##CamelName);             \
     223             :   }
     224             :   FOR_EACH_ASM_VALUE_TYPE_LIST(DEFINE_CONSTRUCTOR)
     225             : #undef DEFINE_CONSTRUCTOR
     226             : 
     227             : #define DEFINE_CAST(CamelCase)                                        \
     228             :   Asm##CamelCase* As##CamelCase() {                                   \
     229             :     if (AsValueType() != nullptr) {                                   \
     230             :       return nullptr;                                                 \
     231             :     }                                                                 \
     232             :     return reinterpret_cast<AsmCallableType*>(this)->As##CamelCase(); \
     233             :   }
     234    11492890 :   FOR_EACH_ASM_CALLABLE_TYPE_LIST(DEFINE_CAST)
     235             : #undef DEFINE_CAST
     236             :   AsmValueType* AsValueType() { return AsmValueType::AsValueType(this); }
     237             :   AsmCallableType* AsCallableType();
     238             : 
     239             :   // A function returning ret. Callers still need to invoke AddArgument with the
     240             :   // returned type to fully create this type.
     241     4281338 :   static AsmType* Function(Zone* zone, AsmType* ret) {
     242             :     AsmFunctionType* f = new (zone) AsmFunctionType(zone, ret);
     243     4281342 :     return reinterpret_cast<AsmType*>(f);
     244             :   }
     245             : 
     246             :   // Overloaded function types. Not creatable by asm source, but useful to
     247             :   // represent the overloaded stdlib functions.
     248     2129947 :   static AsmType* OverloadedFunction(Zone* zone) {
     249             :     auto* f = new (zone) AsmOverloadedFunctionType(zone);
     250     2129948 :     return reinterpret_cast<AsmType*>(f);
     251             :   }
     252             : 
     253             :   // The type for fround(src).
     254             :   static AsmType* FroundType(Zone* zone);
     255             : 
     256             :   // The (variadic) type for min and max.
     257             :   static AsmType* MinMaxType(Zone* zone, AsmType* dest, AsmType* src);
     258             : 
     259             :   // The type for foreign functions.
     260             :   static AsmType* FFIType(Zone* zone) {
     261      358819 :     auto* f = new (zone) AsmFFIType();
     262             :     return reinterpret_cast<AsmType*>(f);
     263             :   }
     264             : 
     265             :   // The type for function tables.
     266             :   static AsmType* FunctionTableType(Zone* zone, size_t length,
     267             :                                     AsmType* signature) {
     268         292 :     auto* f = new (zone) AsmFunctionTableType(length, signature);
     269             :     return reinterpret_cast<AsmType*>(f);
     270             :   }
     271             : 
     272             :   std::string Name();
     273             :   // IsExactly returns true if this is the exact same type as that. For
     274             :   // non-value types (e.g., callables), this returns this == that.
     275             :   bool IsExactly(AsmType* that);
     276             :   // IsA is used to query whether this is an instance of that (i.e., if this is
     277             :   // a type derived from that.) For non-value types (e.g., callables), this
     278             :   // returns this == that.
     279             :   bool IsA(AsmType* that);
     280             : 
     281             :   // Types allowed in return statements. void is the type for returns without
     282             :   // an expression.
     283             :   bool IsReturnType() {
     284          38 :     return this == AsmType::Void() || this == AsmType::Double() ||
     285          64 :            this == AsmType::Signed() || this == AsmType::Float();
     286             :   }
     287             : 
     288             :   // Converts this to the corresponding valid argument type.
     289             :   AsmType* ToReturnType() {
     290             :     if (this->IsA(AsmType::Signed())) {
     291             :       return AsmType::Signed();
     292             :     }
     293             :     if (this->IsA(AsmType::Double())) {
     294             :       return AsmType::Double();
     295             :     }
     296             :     if (this->IsA(AsmType::Float())) {
     297             :       return AsmType::Float();
     298             :     }
     299             :     if (this->IsA(AsmType::Void())) {
     300             :       return AsmType::Void();
     301             :     }
     302             :     return AsmType::None();
     303             :   }
     304             : 
     305             :   // Types allowed to be parameters in asm functions.
     306             :   bool IsParameterType() {
     307             :     return this == AsmType::Double() || this == AsmType::Int() ||
     308             :            this == AsmType::Float();
     309             :   }
     310             : 
     311             :   // Converts this to the corresponding valid argument type.
     312        6521 :   AsmType* ToParameterType() {
     313        6521 :     if (this->IsA(AsmType::Int())) {
     314             :       return AsmType::Int();
     315             :     }
     316         162 :     if (this->IsA(AsmType::Double())) {
     317             :       return AsmType::Double();
     318             :     }
     319          21 :     if (this->IsA(AsmType::Float())) {
     320             :       return AsmType::Float();
     321             :     }
     322           0 :     return AsmType::None();
     323             :   }
     324             : 
     325             :   // Types allowed to be compared using the comparison operators.
     326             :   bool IsComparableType() {
     327             :     return this == AsmType::Double() || this == AsmType::Signed() ||
     328             :            this == AsmType::Unsigned() || this == AsmType::Float();
     329             :   }
     330             : 
     331             :   // The following methods are meant to be used for inspecting the traits of
     332             :   // element types for the heap view types.
     333             :   enum : int32_t { kNotHeapType = -1 };
     334             : 
     335             :   // Returns the element size if this is a heap type. Otherwise returns
     336             :   // kNotHeapType.
     337             :   int32_t ElementSizeInBytes();
     338             :   // Returns the load type if this is a heap type. AsmType::None is returned if
     339             :   // this is not a heap type.
     340             :   AsmType* LoadType();
     341             :   // Returns the store type if this is a heap type. AsmType::None is returned if
     342             :   // this is not a heap type.
     343             :   AsmType* StoreType();
     344             : };
     345             : 
     346             : }  // namespace wasm
     347             : }  // namespace internal
     348             : }  // namespace v8
     349             : 
     350             : #endif  // SRC_ASMJS_ASM_TYPES_H_

Generated by: LCOV version 1.10