1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_COMPILER_C_SIGNATURE_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_COMPILER_C_SIGNATURE_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/machine-type.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define FOREACH_CTYPE_MACHINE_TYPE_MAPPING(V) \
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(void, MachineType::None())                \
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(bool, MachineType::Uint8())               \
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(int8_t, MachineType::Int8())              \
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(uint8_t, MachineType::Uint8())            \
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(int16_t, MachineType::Int16())            \
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(uint16_t, MachineType::Uint16())          \
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(int32_t, MachineType::Int32())            \
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(uint32_t, MachineType::Uint32())          \
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(int64_t, MachineType::Int64())            \
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(uint64_t, MachineType::Uint64())          \
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(float, MachineType::Float32())            \
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(double, MachineType::Float64())           \
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(void*, MachineType::Pointer())            \
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(int*, MachineType::Pointer())
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename T>
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline MachineType MachineTypeForC() {
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (false) {
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // All other types T must be assignable to Object*
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *(static_cast<Object* volatile*>(0)) = static_cast<T>(0);
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return MachineType::AnyTagged();
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_TEMPLATE_SPECIALIZATION(ctype, mtype) \
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  template <>                                         \
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline MachineType MachineTypeForC<ctype>() {       \
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return mtype;                                     \
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochFOREACH_CTYPE_MACHINE_TYPE_MAPPING(DECLARE_TEMPLATE_SPECIALIZATION)
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_TEMPLATE_SPECIALIZATION
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Helper for building machine signatures from C types.
48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CSignature : public MachineSignature {
49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch protected:
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CSignature(size_t return_count, size_t parameter_count, MachineType* reps)
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : MachineSignature(return_count, parameter_count, reps) {}
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  template <typename P1 = void, typename P2 = void, typename P3 = void,
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            typename P4 = void, typename P5 = void>
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VerifyParams() {
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Verifies the C signature against the machine types. Maximum {5} params.
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK_LT(parameter_count(), 6u);
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const int kMax = 5;
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MachineType params[] = {MachineTypeForC<P1>(), MachineTypeForC<P2>(),
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            MachineTypeForC<P3>(), MachineTypeForC<P4>(),
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            MachineTypeForC<P5>()};
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int p = kMax - 1; p >= 0; p--) {
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (p < static_cast<int>(parameter_count())) {
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        CHECK_EQ(GetParam(p), params[p]);
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        CHECK_EQ(MachineType::None(), params[p]);
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static CSignature* FromMachine(Zone* zone, MachineSignature* msig) {
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return reinterpret_cast<CSignature*>(msig);
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static CSignature* New(Zone* zone, MachineType ret,
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         MachineType p1 = MachineType::None(),
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         MachineType p2 = MachineType::None(),
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         MachineType p3 = MachineType::None(),
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         MachineType p4 = MachineType::None(),
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         MachineType p5 = MachineType::None()) {
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MachineType* buffer = zone->NewArray<MachineType>(6);
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int pos = 0;
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t return_count = 0;
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (ret != MachineType::None()) {
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      buffer[pos++] = ret;
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return_count++;
88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    buffer[pos++] = p1;
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    buffer[pos++] = p2;
91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    buffer[pos++] = p3;
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    buffer[pos++] = p4;
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    buffer[pos++] = p5;
94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t param_count = 5;
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (p5 == MachineType::None()) param_count--;
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (p4 == MachineType::None()) param_count--;
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (p3 == MachineType::None()) param_count--;
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (p2 == MachineType::None()) param_count--;
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (p1 == MachineType::None()) param_count--;
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < param_count; i++) {
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Check that there are no MachineType::None()'s in the middle of
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // parameters.
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK_NE(MachineType::None(), buffer[return_count + i]);
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) CSignature(return_count, param_count, buffer);
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename Ret, uint16_t kParamCount>
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CSignatureOf : public CSignature {
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MachineType storage_[1 + kParamCount];
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CSignatureOf()
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : CSignature(MachineTypeForC<Ret>() != MachineType::None() ? 1 : 0,
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   kParamCount, reinterpret_cast<MachineType*>(&storage_)) {
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (return_count_ == 1) storage_[0] = MachineTypeForC<Ret>();
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Set(int index, MachineType type) {
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK_LE(0, index);
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK_LT(index, kParamCount);
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    reps_[return_count_ + index] = type;
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Helper classes for instantiating Signature objects to be callable from C.
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename Ret>
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CSignature0 : public CSignatureOf<Ret, 0> {
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CSignature0() : CSignatureOf<Ret, 0>() {}
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename Ret, typename P1>
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CSignature1 : public CSignatureOf<Ret, 1> {
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CSignature1() : CSignatureOf<Ret, 1>() {
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this->Set(0, MachineTypeForC<P1>());
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename Ret, typename P1, typename P2>
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CSignature2 : public CSignatureOf<Ret, 2> {
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CSignature2() : CSignatureOf<Ret, 2>() {
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this->Set(0, MachineTypeForC<P1>());
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this->Set(1, MachineTypeForC<P2>());
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename Ret, typename P1, typename P2, typename P3>
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CSignature3 : public CSignatureOf<Ret, 3> {
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CSignature3() : CSignatureOf<Ret, 3>() {
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this->Set(0, MachineTypeForC<P1>());
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this->Set(1, MachineTypeForC<P2>());
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this->Set(2, MachineTypeForC<P3>());
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef CSignature2<int32_t, int32_t, int32_t> CSignature_i_ii;
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef CSignature2<uint32_t, uint32_t, uint32_t> CSignature_u_uu;
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef CSignature2<float, float, float> CSignature_f_ff;
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef CSignature2<double, double, double> CSignature_d_dd;
165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef CSignature2<Object*, Object*, Object*> CSignature_o_oo;
166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace compiler
167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_COMPILER_C_SIGNATURE_H_
171