]> git.saurik.com Git - cycript.git/blame - sig/ffi_type.cpp
Hold JavaRef<jstring> throughout CYJavaUTF8String.
[cycript.git] / sig / ffi_type.cpp
CommitLineData
7341eedb
JF
1/* Cycript - The Truly Universal Scripting Language
2 * Copyright (C) 2009-2016 Jay Freeman (saurik)
b4aa79af
JF
3*/
4
f95d2598 5/* GNU Affero General Public License, Version 3 {{{ */
b4aa79af 6/*
f95d2598
JF
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
c15969fd 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f95d2598
JF
15 * GNU Affero General Public License for more details.
16
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
b3378a02 19**/
b4aa79af
JF
20/* }}} */
21
37954781 22#include "Error.hpp"
ea2d184c
JF
23
24#include "sig/ffi_type.hpp"
25#include "sig/types.hpp"
26
24ffc58c 27#if FFI_LONG_LONG_MAX == 9223372036854775807LL
5875f632
JF
28#define ffi_type_slonglong ffi_type_sint64
29#define ffi_type_ulonglong ffi_type_uint64
24ffc58c
JF
30#else
31#error need to configure for long long
32#endif
5875f632 33
ea2d184c
JF
34namespace sig {
35
0559abf8
JF
36template <>
37ffi_type *Primitive<bool>::GetFFI(CYPool &pool) const {
38 return &ffi_type_uchar;
39}
40
41template <>
42ffi_type *Primitive<char>::GetFFI(CYPool &pool) const {
43 return &ffi_type_schar;
44}
45
46template <>
47ffi_type *Primitive<float>::GetFFI(CYPool &pool) const {
48 return &ffi_type_float;
49}
50
1e8d8047
JF
51template <>
52ffi_type *Primitive<long double>::GetFFI(CYPool &pool) const {
53 return &ffi_type_longdouble;
54}
55
0559abf8
JF
56template <>
57ffi_type *Primitive<double>::GetFFI(CYPool &pool) const {
58 return &ffi_type_double;
59}
60
61template <>
62ffi_type *Primitive<signed char>::GetFFI(CYPool &pool) const {
63 return &ffi_type_schar;
64}
65
66template <>
67ffi_type *Primitive<signed int>::GetFFI(CYPool &pool) const {
68 return &ffi_type_sint;
69}
70
24ffc58c
JF
71#ifdef __SIZEOF_INT128__
72template <>
73ffi_type *Primitive<signed __int128>::GetFFI(CYPool &pool) const {
74 _assert(false);
75}
76#endif
77
0559abf8
JF
78template <>
79ffi_type *Primitive<signed long int>::GetFFI(CYPool &pool) const {
80 return &ffi_type_slong;
81}
82
83template <>
84ffi_type *Primitive<signed long long int>::GetFFI(CYPool &pool) const {
85 return &ffi_type_slonglong;
86}
87
88template <>
89ffi_type *Primitive<signed short int>::GetFFI(CYPool &pool) const {
90 return &ffi_type_sshort;
91}
92
93template <>
94ffi_type *Primitive<unsigned char>::GetFFI(CYPool &pool) const {
95 return &ffi_type_uchar;
96}
97
98template <>
99ffi_type *Primitive<unsigned int>::GetFFI(CYPool &pool) const {
100 return &ffi_type_uint;
101}
102
24ffc58c
JF
103#ifdef __SIZEOF_INT128__
104template <>
105ffi_type *Primitive<unsigned __int128>::GetFFI(CYPool &pool) const {
106 _assert(false);
107}
108#endif
109
0559abf8
JF
110template <>
111ffi_type *Primitive<unsigned long int>::GetFFI(CYPool &pool) const {
112 return &ffi_type_ulong;
113}
114
115template <>
116ffi_type *Primitive<unsigned long long int>::GetFFI(CYPool &pool) const {
117 return &ffi_type_ulonglong;
118}
119
120template <>
121ffi_type *Primitive<unsigned short int>::GetFFI(CYPool &pool) const {
122 return &ffi_type_ushort;
123}
124
125ffi_type *Void::GetFFI(CYPool &pool) const {
126 return &ffi_type_void;
127}
128
129ffi_type *Unknown::GetFFI(CYPool &pool) const {
130 _assert(false);
131}
132
133ffi_type *String::GetFFI(CYPool &pool) const {
134 return &ffi_type_pointer;
135}
136
e2ce853b 137#ifdef CY_OBJECTIVEC
0559abf8
JF
138ffi_type *Meta::GetFFI(CYPool &pool) const {
139 return &ffi_type_pointer;
140}
141
142ffi_type *Selector::GetFFI(CYPool &pool) const {
143 return &ffi_type_pointer;
144}
e2ce853b 145#endif
0559abf8
JF
146
147ffi_type *Bits::GetFFI(CYPool &pool) const {
148 /* XXX: we can totally make this work */
149 _assert(false);
150}
151
152ffi_type *Pointer::GetFFI(CYPool &pool) const {
153 return &ffi_type_pointer;
154}
155
156ffi_type *Array::GetFFI(CYPool &pool) const {
157 // XXX: this is really lame
158 ffi_type *ffi(new(pool) ffi_type());
159 ffi->size = 0;
160 ffi->alignment = 0;
161 ffi->type = FFI_TYPE_STRUCT;
162
163 ffi_type *element(type.GetFFI(pool));
164
165 ffi->elements = new(pool) ffi_type *[size + 1];
166 for (size_t i(0); i != size; ++i)
167 ffi->elements[i] = element;
168 ffi->elements[size] = NULL;
169
170 return ffi;
171}
172
e2ce853b 173#ifdef CY_OBJECTIVEC
0559abf8
JF
174ffi_type *Object::GetFFI(CYPool &pool) const {
175 return &ffi_type_pointer;
176}
e2ce853b 177#endif
0559abf8 178
aaa29c28
JF
179ffi_type *Enum::GetFFI(CYPool &pool) const {
180 return type.GetFFI(pool);
181}
182
0559abf8 183ffi_type *Aggregate::GetFFI(CYPool &pool) const {
0559abf8 184 _assert(!overlap);
1fdd7c7a 185 _assert(signature.count != _not(size_t));
0559abf8
JF
186
187 ffi_type *ffi(new(pool) ffi_type());
188 ffi->size = 0;
189 ffi->alignment = 0;
190 ffi->type = FFI_TYPE_STRUCT;
191
255fe37e
JF
192 if (signature.count == 0) {
193 // https://gcc.gnu.org/ml/gcc-patches/2015-01/msg01286.html
194 ffi->elements = new(pool) ffi_type *[2];
195 ffi->elements[0] = &ffi_type_void;
196 ffi->elements[1] = NULL;
197 } else {
198 ffi->elements = new(pool) ffi_type *[signature.count + 1];
199 for (size_t index(0); index != signature.count; ++index)
200 ffi->elements[index] = signature.elements[index].type->GetFFI(pool);
201 ffi->elements[signature.count] = NULL;
202 }
0559abf8
JF
203
204 return ffi;
205}
206
207ffi_type *Function::GetFFI(CYPool &pool) const {
208 _assert(false);
209}
210
e2ce853b 211#ifdef CY_OBJECTIVEC
0559abf8
JF
212ffi_type *Block::GetFFI(CYPool &pool) const {
213 return &ffi_type_pointer;
ea2d184c 214}
e2ce853b 215#endif
ea2d184c 216
574d4720
JF
217void sig_ffi_cif(CYPool &pool, size_t variadic, const Signature &signature, ffi_cif *cif) {
218 _assert(signature.count != 0);
219 size_t count(signature.count - 1);
220 ffi_type *type(signature.elements[0].type->GetFFI(pool));
221
222 ffi_type **types(new(pool) ffi_type *[count]);
223 for (size_t index(0); index != count; ++index)
224 types[index] = signature.elements[index + 1].type->GetFFI(pool);
225
226 ffi_status status;
227#ifdef HAVE_FFI_PREP_CIF_VAR
228 if (variadic == 0)
229#endif
230 status = ffi_prep_cif(cif, FFI_DEFAULT_ABI, count, type, types);
231#ifdef HAVE_FFI_PREP_CIF_VAR
232 else
233 status = ffi_prep_cif_var(cif, FFI_DEFAULT_ABI, variadic - 1, count, type, types);
234#endif
ea2d184c
JF
235 _assert(status == FFI_OK);
236}
237
238}