Line data Source code
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 640883768 : static void VerifyParams(MachineSignature* sig) {
57 : // Verifies the C signature against the machine types. Maximum {5} params.
58 76154854 : CHECK_LT(sig->parameter_count(), 6u);
59 : const int kMax = 5;
60 : MachineType params[] = {MachineTypeForC<P1>(), MachineTypeForC<P2>(),
61 : MachineTypeForC<P3>(), MachineTypeForC<P4>(),
62 76154854 : MachineTypeForC<P5>()};
63 456929124 : for (int p = kMax - 1; p >= 0; p--) {
64 380774270 : if (p < static_cast<int>(sig->parameter_count())) {
65 551863932 : CHECK_EQ(sig->GetParam(p), params[p]);
66 : } else {
67 393639252 : CHECK_EQ(MachineType::None(), params[p]);
68 : }
69 : }
70 76154854 : }
71 :
72 : static CSignature* FromMachine(Zone* zone, MachineSignature* msig) {
73 : return reinterpret_cast<CSignature*>(msig);
74 : }
75 :
76 386538 : 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 386538 : if (ret != MachineType::None()) {
86 386348 : buffer[pos++] = ret;
87 : return_count++;
88 : }
89 386538 : buffer[pos++] = p1;
90 386538 : buffer[pos++] = p2;
91 386538 : buffer[pos++] = p3;
92 386538 : buffer[pos++] = p4;
93 386538 : buffer[pos++] = p5;
94 : size_t param_count = 5;
95 386538 : if (p5 == MachineType::None()) param_count--;
96 386538 : if (p4 == MachineType::None()) param_count--;
97 386538 : if (p3 == MachineType::None()) param_count--;
98 386538 : if (p2 == MachineType::None()) param_count--;
99 386538 : if (p1 == MachineType::None()) param_count--;
100 578716 : 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 384356 : CHECK_NE(MachineType::None(), buffer[return_count + i]);
104 : }
105 386538 : 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 8783 : kParamCount, reinterpret_cast<MachineType*>(&storage_)) {
118 8783 : 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_
|