Home | History | Annotate | Download | only in compiler
      1 // Copyright 2014 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_COMPILER_C_SIGNATURE_H_
      6 #define V8_COMPILER_C_SIGNATURE_H_
      7 
      8 #include "src/machine-type.h"
      9 
     10 namespace v8 {
     11 namespace internal {
     12 namespace compiler {
     13 
     14 #define FOREACH_CTYPE_MACHINE_TYPE_MAPPING(V) \
     15   V(void, MachineType::None())                \
     16   V(bool, MachineType::Uint8())               \
     17   V(int8_t, MachineType::Int8())              \
     18   V(uint8_t, MachineType::Uint8())            \
     19   V(int16_t, MachineType::Int16())            \
     20   V(uint16_t, MachineType::Uint16())          \
     21   V(int32_t, MachineType::Int32())            \
     22   V(uint32_t, MachineType::Uint32())          \
     23   V(int64_t, MachineType::Int64())            \
     24   V(uint64_t, MachineType::Uint64())          \
     25   V(float, MachineType::Float32())            \
     26   V(double, MachineType::Float64())           \
     27   V(void*, MachineType::Pointer())            \
     28   V(int*, MachineType::Pointer())
     29 
     30 template <typename T>
     31 inline MachineType MachineTypeForC() {
     32   while (false) {
     33     // All other types T must be assignable to Object*
     34     *(static_cast<Object* volatile*>(0)) = static_cast<T>(0);
     35   }
     36   return MachineType::AnyTagged();
     37 }
     38 
     39 #define DECLARE_TEMPLATE_SPECIALIZATION(ctype, mtype) \
     40   template <>                                         \
     41   inline MachineType MachineTypeForC<ctype>() {       \
     42     return mtype;                                     \
     43   }
     44 FOREACH_CTYPE_MACHINE_TYPE_MAPPING(DECLARE_TEMPLATE_SPECIALIZATION)
     45 #undef DECLARE_TEMPLATE_SPECIALIZATION
     46 
     47 // Helper for building machine signatures from C types.
     48 class CSignature : public MachineSignature {
     49  protected:
     50   CSignature(size_t return_count, size_t parameter_count, MachineType* reps)
     51       : MachineSignature(return_count, parameter_count, reps) {}
     52 
     53  public:
     54   template <typename P1 = void, typename P2 = void, typename P3 = void,
     55             typename P4 = void, typename P5 = void>
     56   static void VerifyParams(MachineSignature* sig) {
     57     // Verifies the C signature against the machine types. Maximum {5} params.
     58     CHECK_LT(sig->parameter_count(), 6u);
     59     const int kMax = 5;
     60     MachineType params[] = {MachineTypeForC<P1>(), MachineTypeForC<P2>(),
     61                             MachineTypeForC<P3>(), MachineTypeForC<P4>(),
     62                             MachineTypeForC<P5>()};
     63     for (int p = kMax - 1; p >= 0; p--) {
     64       if (p < static_cast<int>(sig->parameter_count())) {
     65         CHECK_EQ(sig->GetParam(p), params[p]);
     66       } else {
     67         CHECK_EQ(MachineType::None(), params[p]);
     68       }
     69     }
     70   }
     71 
     72   static CSignature* FromMachine(Zone* zone, MachineSignature* msig) {
     73     return reinterpret_cast<CSignature*>(msig);
     74   }
     75 
     76   static CSignature* New(Zone* zone, MachineType ret,
     77                          MachineType p1 = MachineType::None(),
     78                          MachineType p2 = MachineType::None(),
     79                          MachineType p3 = MachineType::None(),
     80                          MachineType p4 = MachineType::None(),
     81                          MachineType p5 = MachineType::None()) {
     82     MachineType* buffer = zone->NewArray<MachineType>(6);
     83     int pos = 0;
     84     size_t return_count = 0;
     85     if (ret != MachineType::None()) {
     86       buffer[pos++] = ret;
     87       return_count++;
     88     }
     89     buffer[pos++] = p1;
     90     buffer[pos++] = p2;
     91     buffer[pos++] = p3;
     92     buffer[pos++] = p4;
     93     buffer[pos++] = p5;
     94     size_t param_count = 5;
     95     if (p5 == MachineType::None()) param_count--;
     96     if (p4 == MachineType::None()) param_count--;
     97     if (p3 == MachineType::None()) param_count--;
     98     if (p2 == MachineType::None()) param_count--;
     99     if (p1 == MachineType::None()) param_count--;
    100     for (size_t i = 0; i < param_count; i++) {
    101       // Check that there are no MachineType::None()'s in the middle of
    102       // parameters.
    103       CHECK_NE(MachineType::None(), buffer[return_count + i]);
    104     }
    105     return new (zone) CSignature(return_count, param_count, buffer);
    106   }
    107 };
    108 
    109 
    110 template <typename Ret, uint16_t kParamCount>
    111 class CSignatureOf : public CSignature {
    112  protected:
    113   MachineType storage_[1 + kParamCount];
    114 
    115   CSignatureOf()
    116       : CSignature(MachineTypeForC<Ret>() != MachineType::None() ? 1 : 0,
    117                    kParamCount, reinterpret_cast<MachineType*>(&storage_)) {
    118     if (return_count_ == 1) storage_[0] = MachineTypeForC<Ret>();
    119   }
    120   void Set(int index, MachineType type) {
    121     CHECK_LE(0, index);
    122     CHECK_LT(index, kParamCount);
    123     reps_[return_count_ + index] = type;
    124   }
    125 };
    126 
    127 // Helper classes for instantiating Signature objects to be callable from C.
    128 template <typename Ret>
    129 class CSignature0 : public CSignatureOf<Ret, 0> {
    130  public:
    131   CSignature0() : CSignatureOf<Ret, 0>() {}
    132 };
    133 
    134 template <typename Ret, typename P1>
    135 class CSignature1 : public CSignatureOf<Ret, 1> {
    136  public:
    137   CSignature1() : CSignatureOf<Ret, 1>() {
    138     this->Set(0, MachineTypeForC<P1>());
    139   }
    140 };
    141 
    142 template <typename Ret, typename P1, typename P2>
    143 class CSignature2 : public CSignatureOf<Ret, 2> {
    144  public:
    145   CSignature2() : CSignatureOf<Ret, 2>() {
    146     this->Set(0, MachineTypeForC<P1>());
    147     this->Set(1, MachineTypeForC<P2>());
    148   }
    149 };
    150 
    151 template <typename Ret, typename P1, typename P2, typename P3>
    152 class CSignature3 : public CSignatureOf<Ret, 3> {
    153  public:
    154   CSignature3() : CSignatureOf<Ret, 3>() {
    155     this->Set(0, MachineTypeForC<P1>());
    156     this->Set(1, MachineTypeForC<P2>());
    157     this->Set(2, MachineTypeForC<P3>());
    158   }
    159 };
    160 
    161 typedef CSignature2<int32_t, int32_t, int32_t> CSignature_i_ii;
    162 typedef CSignature2<uint32_t, uint32_t, uint32_t> CSignature_u_uu;
    163 typedef CSignature2<float, float, float> CSignature_f_ff;
    164 typedef CSignature2<double, double, double> CSignature_d_dd;
    165 typedef CSignature2<Object*, Object*, Object*> CSignature_o_oo;
    166 }  // namespace compiler
    167 }  // namespace internal
    168 }  // namespace v8
    169 
    170 #endif  // V8_COMPILER_C_SIGNATURE_H_
    171