LCOV - code coverage report
Current view: top level - src/wasm - value-type.h (source / functions) Hit Total Coverage
Test: app.info Lines: 73 88 83.0 %
Date: 2019-04-17 Functions: 15 15 100.0 %

          Line data    Source code
       1             : // Copyright 2018 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 V8_WASM_VALUE_TYPE_H_
       6             : #define V8_WASM_VALUE_TYPE_H_
       7             : 
       8             : #include "src/machine-type.h"
       9             : #include "src/wasm/wasm-constants.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : 
      14             : template <typename T>
      15             : class Signature;
      16             : 
      17             : namespace wasm {
      18             : 
      19             : enum ValueType : uint8_t {
      20             :   kWasmStmt,
      21             :   kWasmI32,
      22             :   kWasmI64,
      23             :   kWasmF32,
      24             :   kWasmF64,
      25             :   kWasmS128,
      26             :   kWasmAnyRef,
      27             :   kWasmAnyFunc,
      28             :   kWasmNullRef,
      29             :   kWasmExceptRef,
      30             :   kWasmVar,
      31             : };
      32             : 
      33             : using FunctionSig = Signature<ValueType>;
      34             : 
      35     2231757 : inline size_t hash_value(ValueType type) { return static_cast<size_t>(type); }
      36             : 
      37             : // TODO(clemensh): Compute memtype and size from ValueType once we have c++14
      38             : // constexpr support.
      39             : #define FOREACH_LOAD_TYPE(V) \
      40             :   V(I32, , Int32, 2)         \
      41             :   V(I32, 8S, Int8, 0)        \
      42             :   V(I32, 8U, Uint8, 0)       \
      43             :   V(I32, 16S, Int16, 1)      \
      44             :   V(I32, 16U, Uint16, 1)     \
      45             :   V(I64, , Int64, 3)         \
      46             :   V(I64, 8S, Int8, 0)        \
      47             :   V(I64, 8U, Uint8, 0)       \
      48             :   V(I64, 16S, Int16, 1)      \
      49             :   V(I64, 16U, Uint16, 1)     \
      50             :   V(I64, 32S, Int32, 2)      \
      51             :   V(I64, 32U, Uint32, 2)     \
      52             :   V(F32, , Float32, 2)       \
      53             :   V(F64, , Float64, 3)       \
      54             :   V(S128, , Simd128, 4)
      55             : 
      56             : class LoadType {
      57             :  public:
      58             :   enum LoadTypeValue : uint8_t {
      59             : #define DEF_ENUM(type, suffix, ...) k##type##Load##suffix,
      60             :     FOREACH_LOAD_TYPE(DEF_ENUM)
      61             : #undef DEF_ENUM
      62             :   };
      63             : 
      64             :   // Allow implicit convertion of the enum value to this wrapper.
      65             :   constexpr LoadType(LoadTypeValue val)  // NOLINT(runtime/explicit)
      66      231129 :       : val_(val) {}
      67             : 
      68      120626 :   constexpr LoadTypeValue value() const { return val_; }
      69      260158 :   constexpr unsigned size_log_2() const { return kLoadSizeLog2[val_]; }
      70       74800 :   constexpr unsigned size() const { return 1 << size_log_2(); }
      71      357384 :   constexpr ValueType value_type() const { return kValueType[val_]; }
      72       97243 :   constexpr MachineType mem_type() const { return kMemType[val_]; }
      73             : 
      74         485 :   static LoadType ForValueType(ValueType type) {
      75         485 :     switch (type) {
      76             :       case kWasmI32:
      77         335 :         return kI32Load;
      78             :       case kWasmI64:
      79          22 :         return kI64Load;
      80             :       case kWasmF32:
      81          64 :         return kF32Load;
      82             :       case kWasmF64:
      83          64 :         return kF64Load;
      84             :       default:
      85           0 :         UNREACHABLE();
      86             :     }
      87             :   }
      88             : 
      89             :  private:
      90             :   const LoadTypeValue val_;
      91             : 
      92             :   static constexpr uint8_t kLoadSizeLog2[] = {
      93             : #define LOAD_SIZE(_, __, ___, size) size,
      94             :       FOREACH_LOAD_TYPE(LOAD_SIZE)
      95             : #undef LOAD_SIZE
      96             :   };
      97             : 
      98             :   static constexpr ValueType kValueType[] = {
      99             : #define VALUE_TYPE(type, ...) kWasm##type,
     100             :       FOREACH_LOAD_TYPE(VALUE_TYPE)
     101             : #undef VALUE_TYPE
     102             :   };
     103             : 
     104             :   static constexpr MachineType kMemType[] = {
     105             : #define MEMTYPE(_, __, memtype, ___) MachineType::memtype(),
     106             :       FOREACH_LOAD_TYPE(MEMTYPE)
     107             : #undef MEMTYPE
     108             :   };
     109             : };
     110             : 
     111             : #define FOREACH_STORE_TYPE(V) \
     112             :   V(I32, , Word32, 2)         \
     113             :   V(I32, 8, Word8, 0)         \
     114             :   V(I32, 16, Word16, 1)       \
     115             :   V(I64, , Word64, 3)         \
     116             :   V(I64, 8, Word8, 0)         \
     117             :   V(I64, 16, Word16, 1)       \
     118             :   V(I64, 32, Word32, 2)       \
     119             :   V(F32, , Float32, 2)        \
     120             :   V(F64, , Float64, 3)        \
     121             :   V(S128, , Simd128, 4)
     122             : 
     123             : class StoreType {
     124             :  public:
     125             :   enum StoreTypeValue : uint8_t {
     126             : #define DEF_ENUM(type, suffix, ...) k##type##Store##suffix,
     127             :     FOREACH_STORE_TYPE(DEF_ENUM)
     128             : #undef DEF_ENUM
     129             :   };
     130             : 
     131             :   // Allow implicit convertion of the enum value to this wrapper.
     132             :   constexpr StoreType(StoreTypeValue val)  // NOLINT(runtime/explicit)
     133      260614 :       : val_(val) {}
     134             : 
     135      105360 :   constexpr StoreTypeValue value() const { return val_; }
     136      365665 :   constexpr unsigned size_log_2() const { return kStoreSizeLog2[val_]; }
     137      105150 :   constexpr unsigned size() const { return 1 << size_log_2(); }
     138      509042 :   constexpr ValueType value_type() const { return kValueType[val_]; }
     139      143239 :   constexpr MachineRepresentation mem_rep() const { return kMemRep[val_]; }
     140             : 
     141         176 :   static StoreType ForValueType(ValueType type) {
     142         176 :     switch (type) {
     143             :       case kWasmI32:
     144         108 :         return kI32Store;
     145             :       case kWasmI64:
     146          13 :         return kI64Store;
     147             :       case kWasmF32:
     148          26 :         return kF32Store;
     149             :       case kWasmF64:
     150          29 :         return kF64Store;
     151             :       default:
     152           0 :         UNREACHABLE();
     153             :     }
     154             :   }
     155             : 
     156             :  private:
     157             :   const StoreTypeValue val_;
     158             : 
     159             :   static constexpr uint8_t kStoreSizeLog2[] = {
     160             : #define STORE_SIZE(_, __, ___, size) size,
     161             :       FOREACH_STORE_TYPE(STORE_SIZE)
     162             : #undef STORE_SIZE
     163             :   };
     164             : 
     165             :   static constexpr ValueType kValueType[] = {
     166             : #define VALUE_TYPE(type, ...) kWasm##type,
     167             :       FOREACH_STORE_TYPE(VALUE_TYPE)
     168             : #undef VALUE_TYPE
     169             :   };
     170             : 
     171             :   static constexpr MachineRepresentation kMemRep[] = {
     172             : #define MEMREP(_, __, memrep, ___) MachineRepresentation::k##memrep,
     173             :       FOREACH_STORE_TYPE(MEMREP)
     174             : #undef MEMREP
     175             :   };
     176             : };
     177             : 
     178             : // A collection of ValueType-related static methods.
     179             : class V8_EXPORT_PRIVATE ValueTypes {
     180             :  public:
     181     8003367 :   static inline bool IsSubType(ValueType expected, ValueType actual) {
     182       77204 :     return (expected == actual) ||
     183      154061 :            (expected == kWasmAnyRef && actual == kWasmNullRef) ||
     184      153673 :            (expected == kWasmAnyRef && actual == kWasmAnyFunc) ||
     185      153632 :            (expected == kWasmAnyRef && actual == kWasmExceptRef) ||
     186     8156782 :            (expected == kWasmAnyFunc && actual == kWasmNullRef) ||
     187             :            // TODO(mstarzinger): For now we treat "null_ref" as a sub-type of
     188             :            // "except_ref", which is correct but might change. See here:
     189             :            // https://github.com/WebAssembly/exception-handling/issues/55
     190     8079966 :            (expected == kWasmExceptRef && actual == kWasmNullRef);
     191             :   }
     192             : 
     193             :   static inline bool IsReferenceType(ValueType type) {
     194             :     // This function assumes at the moment that it is never called with
     195             :     // {kWasmNullRef}. If this assumption is wrong, it should be added to the
     196             :     // result calculation below.
     197             :     DCHECK_NE(type, kWasmNullRef);
     198      950754 :     return type == kWasmAnyRef || type == kWasmAnyFunc ||
     199      950754 :            type == kWasmExceptRef;
     200             :   }
     201             : 
     202             :   static byte MemSize(MachineType type) {
     203     1046523 :     return 1 << i::ElementSizeLog2Of(type.representation());
     204             :   }
     205             : 
     206     1235449 :   static int ElementSizeInBytes(ValueType type) {
     207     1235449 :     switch (type) {
     208             :       case kWasmI32:
     209             :       case kWasmF32:
     210             :         return 4;
     211             :       case kWasmI64:
     212             :       case kWasmF64:
     213       77720 :         return 8;
     214             :       case kWasmS128:
     215           0 :         return 16;
     216             :       case kWasmAnyRef:
     217             :       case kWasmAnyFunc:
     218             :       case kWasmExceptRef:
     219        7842 :         return kSystemPointerSize;
     220             :       default:
     221           0 :         UNREACHABLE();
     222             :     }
     223             :   }
     224             : 
     225      107734 :   static int ElementSizeLog2Of(ValueType type) {
     226      107734 :     switch (type) {
     227             :       case kWasmI32:
     228             :       case kWasmF32:
     229             :         return 2;
     230             :       case kWasmI64:
     231             :       case kWasmF64:
     232           3 :         return 3;
     233             :       case kWasmS128:
     234           0 :         return 4;
     235             :       default:
     236           0 :         UNREACHABLE();
     237             :     }
     238             :   }
     239             : 
     240      107728 :   static byte MemSize(ValueType type) { return 1 << ElementSizeLog2Of(type); }
     241             : 
     242       59964 :   static ValueTypeCode ValueTypeCodeFor(ValueType type) {
     243       59964 :     switch (type) {
     244             :       case kWasmI32:
     245             :         return kLocalI32;
     246             :       case kWasmI64:
     247       17011 :         return kLocalI64;
     248             :       case kWasmF32:
     249        1326 :         return kLocalF32;
     250             :       case kWasmF64:
     251        3808 :         return kLocalF64;
     252             :       case kWasmS128:
     253        3256 :         return kLocalS128;
     254             :       case kWasmAnyRef:
     255          37 :         return kLocalAnyRef;
     256             :       case kWasmAnyFunc:
     257           0 :         return kLocalAnyFunc;
     258             :       case kWasmExceptRef:
     259           1 :         return kLocalExceptRef;
     260             :       case kWasmStmt:
     261          12 :         return kLocalVoid;
     262             :       default:
     263           0 :         UNREACHABLE();
     264             :     }
     265             :   }
     266             : 
     267     1378477 :   static MachineType MachineTypeFor(ValueType type) {
     268     1378477 :     switch (type) {
     269             :       case kWasmI32:
     270             :         return MachineType::Int32();
     271             :       case kWasmI64:
     272             :         return MachineType::Int64();
     273             :       case kWasmF32:
     274             :         return MachineType::Float32();
     275             :       case kWasmF64:
     276             :         return MachineType::Float64();
     277             :       case kWasmAnyRef:
     278             :       case kWasmAnyFunc:
     279             :       case kWasmExceptRef:
     280             :         return MachineType::TaggedPointer();
     281             :       case kWasmS128:
     282             :         return MachineType::Simd128();
     283             :       case kWasmStmt:
     284             :         return MachineType::None();
     285             :       default:
     286           0 :         UNREACHABLE();
     287             :     }
     288             :   }
     289             : 
     290     4815705 :   static MachineRepresentation MachineRepresentationFor(ValueType type) {
     291     4815705 :     switch (type) {
     292             :       case kWasmI32:
     293             :         return MachineRepresentation::kWord32;
     294             :       case kWasmI64:
     295      137913 :         return MachineRepresentation::kWord64;
     296             :       case kWasmF32:
     297      469055 :         return MachineRepresentation::kFloat32;
     298             :       case kWasmF64:
     299      685621 :         return MachineRepresentation::kFloat64;
     300             :       case kWasmAnyRef:
     301             :       case kWasmAnyFunc:
     302             :       case kWasmExceptRef:
     303       25711 :         return MachineRepresentation::kTaggedPointer;
     304             :       case kWasmS128:
     305          32 :         return MachineRepresentation::kSimd128;
     306             :       case kWasmStmt:
     307           0 :         return MachineRepresentation::kNone;
     308             :       default:
     309           0 :         UNREACHABLE();
     310             :     }
     311             :   }
     312             : 
     313     1156656 :   static ValueType ValueTypeFor(MachineType type) {
     314     1156656 :     switch (type.representation()) {
     315             :       case MachineRepresentation::kWord8:
     316             :       case MachineRepresentation::kWord16:
     317             :       case MachineRepresentation::kWord32:
     318             :         return kWasmI32;
     319             :       case MachineRepresentation::kWord64:
     320             :         return kWasmI64;
     321             :       case MachineRepresentation::kFloat32:
     322             :         return kWasmF32;
     323             :       case MachineRepresentation::kFloat64:
     324             :         return kWasmF64;
     325             :       case MachineRepresentation::kTaggedPointer:
     326             :         return kWasmAnyRef;
     327             :       case MachineRepresentation::kSimd128:
     328             :         return kWasmS128;
     329             :       default:
     330           0 :         UNREACHABLE();
     331             :     }
     332             :   }
     333             : 
     334             :   static char ShortNameOf(ValueType type) {
     335             :     switch (type) {
     336             :       case kWasmI32:
     337             :         return 'i';
     338             :       case kWasmI64:
     339             :         return 'l';
     340             :       case kWasmF32:
     341             :         return 'f';
     342             :       case kWasmF64:
     343             :         return 'd';
     344             :       case kWasmAnyRef:
     345             :         return 'r';
     346             :       case kWasmAnyFunc:
     347             :         return 'a';
     348             :       case kWasmS128:
     349             :         return 's';
     350             :       case kWasmStmt:
     351             :         return 'v';
     352             :       case kWasmVar:
     353             :         return '*';
     354             :       default:
     355             :         return '?';
     356             :     }
     357             :   }
     358             : 
     359       80651 :   static const char* TypeName(ValueType type) {
     360       80651 :     switch (type) {
     361             :       case kWasmI32:
     362             :         return "i32";
     363             :       case kWasmI64:
     364       17800 :         return "i64";
     365             :       case kWasmF32:
     366       17089 :         return "f32";
     367             :       case kWasmF64:
     368       14267 :         return "f64";
     369             :       case kWasmAnyRef:
     370        7059 :         return "anyref";
     371             :       case kWasmAnyFunc:
     372          75 :         return "anyfunc";
     373             :       case kWasmNullRef:
     374           0 :         return "nullref";
     375             :       case kWasmExceptRef:
     376          39 :         return "exn";
     377             :       case kWasmS128:
     378           6 :         return "s128";
     379             :       case kWasmStmt:
     380         532 :         return "<stmt>";
     381             :       case kWasmVar:
     382           0 :         return "<var>";
     383             :       default:
     384           0 :         return "<unknown>";
     385             :     }
     386             :   }
     387             : 
     388             :  private:
     389             :   DISALLOW_IMPLICIT_CONSTRUCTORS(ValueTypes);
     390             : };
     391             : 
     392             : }  // namespace wasm
     393             : }  // namespace internal
     394             : }  // namespace v8
     395             : 
     396             : #endif  // V8_WASM_VALUE_TYPE_H_

Generated by: LCOV version 1.10