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 constexpr MachineType MachineTypeForC() {
32 : static_assert(std::is_convertible<T, Object>::value,
33 : "all non-specialized types must be convertible to Object");
34 : return MachineType::AnyTagged();
35 : }
36 :
37 : #define DECLARE_TEMPLATE_SPECIALIZATION(ctype, mtype) \
38 : template <> \
39 : inline MachineType constexpr MachineTypeForC<ctype>() { \
40 : return mtype; \
41 : }
42 : FOREACH_CTYPE_MACHINE_TYPE_MAPPING(DECLARE_TEMPLATE_SPECIALIZATION)
43 : #undef DECLARE_TEMPLATE_SPECIALIZATION
44 :
45 : // Helper for building machine signatures from C types.
46 : class CSignature : public MachineSignature {
47 : protected:
48 : CSignature(size_t return_count, size_t parameter_count, MachineType* reps)
49 : : MachineSignature(return_count, parameter_count, reps) {}
50 :
51 : public:
52 : template <typename... Params>
53 214634656 : static void VerifyParams(MachineSignature* sig) {
54 : // Verifies the C signature against the machine types.
55 : std::array<MachineType, sizeof...(Params)> params{
56 60446320 : {MachineTypeForC<Params>()...}};
57 214634656 : for (size_t p = 0; p < params.size(); ++p) {
58 462565008 : CHECK_EQ(sig->GetParam(p), params[p]);
59 : }
60 60446320 : }
61 :
62 : static CSignature* FromMachine(Zone* zone, MachineSignature* msig) {
63 : return reinterpret_cast<CSignature*>(msig);
64 : }
65 :
66 : template <typename... ParamMachineTypes>
67 345556 : static CSignature* New(Zone* zone, MachineType ret,
68 : ParamMachineTypes... params) {
69 : constexpr size_t param_count = sizeof...(params);
70 125192 : std::array<MachineType, param_count> param_arr{{params...}};
71 : const size_t buffer_size =
72 345556 : param_count + (ret == MachineType::None() ? 0 : 1);
73 : MachineType* buffer = zone->NewArray<MachineType>(buffer_size);
74 : size_t pos = 0;
75 : size_t return_count = 0;
76 345556 : if (ret != MachineType::None()) {
77 345416 : buffer[pos++] = ret;
78 : return_count++;
79 : }
80 294088 : for (MachineType p : param_arr) {
81 : // Check that there are no MachineType::None()'s in the parameters.
82 337792 : CHECK_NE(MachineType::None(), p);
83 168896 : buffer[pos++] = p;
84 : }
85 : DCHECK_EQ(buffer_size, pos);
86 345556 : return new (zone) CSignature(return_count, param_count, buffer);
87 : }
88 : };
89 :
90 : // Helper classes for instantiating Signature objects to be callable from C.
91 : template <typename Ret, typename... Params>
92 : class CSignatureOf : public CSignature {
93 : public:
94 17556 : CSignatureOf() : CSignature(kReturnCount, kParamCount, storage_) {
95 : constexpr std::array<MachineType, kParamCount> param_types{
96 : MachineTypeForC<Params>()...};
97 5852 : if (kReturnCount == 1) storage_[0] = MachineTypeForC<Ret>();
98 : static_assert(
99 : std::is_same<decltype(*reps_), decltype(*param_types.data())>::value,
100 : "type mismatch, cannot memcpy");
101 5852 : memcpy(storage_ + kReturnCount, param_types.data(),
102 : sizeof(*storage_) * kParamCount);
103 5852 : }
104 :
105 : private:
106 : static constexpr size_t kReturnCount =
107 : MachineTypeForC<Ret>() == MachineType::None() ? 0 : 1;
108 : static constexpr size_t kParamCount = sizeof...(Params);
109 :
110 : MachineType storage_[kReturnCount + kParamCount];
111 : };
112 :
113 : typedef CSignatureOf<int32_t, int32_t, int32_t> CSignature_i_ii;
114 : typedef CSignatureOf<uint32_t, uint32_t, uint32_t> CSignature_u_uu;
115 : typedef CSignatureOf<float, float, float> CSignature_f_ff;
116 : typedef CSignatureOf<double, double, double> CSignature_d_dd;
117 : typedef CSignatureOf<Object, Object, Object> CSignature_o_oo;
118 :
119 : } // namespace compiler
120 : } // namespace internal
121 : } // namespace v8
122 :
123 : #endif // V8_COMPILER_C_SIGNATURE_H_
|