]> git.saurik.com Git - cycript.git/blame - sig/ffi_type.cpp
Analyze even more headers and added enum typedefs.
[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
51template <>
52ffi_type *Primitive<double>::GetFFI(CYPool &pool) const {
53 return &ffi_type_double;
54}
55
56template <>
57ffi_type *Primitive<signed char>::GetFFI(CYPool &pool) const {
58 return &ffi_type_schar;
59}
60
61template <>
62ffi_type *Primitive<signed int>::GetFFI(CYPool &pool) const {
63 return &ffi_type_sint;
64}
65
24ffc58c
JF
66#ifdef __SIZEOF_INT128__
67template <>
68ffi_type *Primitive<signed __int128>::GetFFI(CYPool &pool) const {
69 _assert(false);
70}
71#endif
72
0559abf8
JF
73template <>
74ffi_type *Primitive<signed long int>::GetFFI(CYPool &pool) const {
75 return &ffi_type_slong;
76}
77
78template <>
79ffi_type *Primitive<signed long long int>::GetFFI(CYPool &pool) const {
80 return &ffi_type_slonglong;
81}
82
83template <>
84ffi_type *Primitive<signed short int>::GetFFI(CYPool &pool) const {
85 return &ffi_type_sshort;
86}
87
88template <>
89ffi_type *Primitive<unsigned char>::GetFFI(CYPool &pool) const {
90 return &ffi_type_uchar;
91}
92
93template <>
94ffi_type *Primitive<unsigned int>::GetFFI(CYPool &pool) const {
95 return &ffi_type_uint;
96}
97
24ffc58c
JF
98#ifdef __SIZEOF_INT128__
99template <>
100ffi_type *Primitive<unsigned __int128>::GetFFI(CYPool &pool) const {
101 _assert(false);
102}
103#endif
104
0559abf8
JF
105template <>
106ffi_type *Primitive<unsigned long int>::GetFFI(CYPool &pool) const {
107 return &ffi_type_ulong;
108}
109
110template <>
111ffi_type *Primitive<unsigned long long int>::GetFFI(CYPool &pool) const {
112 return &ffi_type_ulonglong;
113}
114
115template <>
116ffi_type *Primitive<unsigned short int>::GetFFI(CYPool &pool) const {
117 return &ffi_type_ushort;
118}
119
120ffi_type *Void::GetFFI(CYPool &pool) const {
121 return &ffi_type_void;
122}
123
124ffi_type *Unknown::GetFFI(CYPool &pool) const {
125 _assert(false);
126}
127
128ffi_type *String::GetFFI(CYPool &pool) const {
129 return &ffi_type_pointer;
130}
131
e2ce853b 132#ifdef CY_OBJECTIVEC
0559abf8
JF
133ffi_type *Meta::GetFFI(CYPool &pool) const {
134 return &ffi_type_pointer;
135}
136
137ffi_type *Selector::GetFFI(CYPool &pool) const {
138 return &ffi_type_pointer;
139}
e2ce853b 140#endif
0559abf8
JF
141
142ffi_type *Bits::GetFFI(CYPool &pool) const {
143 /* XXX: we can totally make this work */
144 _assert(false);
145}
146
147ffi_type *Pointer::GetFFI(CYPool &pool) const {
148 return &ffi_type_pointer;
149}
150
151ffi_type *Array::GetFFI(CYPool &pool) const {
152 // XXX: this is really lame
153 ffi_type *ffi(new(pool) ffi_type());
154 ffi->size = 0;
155 ffi->alignment = 0;
156 ffi->type = FFI_TYPE_STRUCT;
157
158 ffi_type *element(type.GetFFI(pool));
159
160 ffi->elements = new(pool) ffi_type *[size + 1];
161 for (size_t i(0); i != size; ++i)
162 ffi->elements[i] = element;
163 ffi->elements[size] = NULL;
164
165 return ffi;
166}
167
e2ce853b 168#ifdef CY_OBJECTIVEC
0559abf8
JF
169ffi_type *Object::GetFFI(CYPool &pool) const {
170 return &ffi_type_pointer;
171}
e2ce853b 172#endif
0559abf8 173
aaa29c28
JF
174ffi_type *Enum::GetFFI(CYPool &pool) const {
175 return type.GetFFI(pool);
176}
177
0559abf8
JF
178ffi_type *Aggregate::GetFFI(CYPool &pool) const {
179 // XXX: we can totally make overlap work
180 _assert(!overlap);
181
182 ffi_type *ffi(new(pool) ffi_type());
183 ffi->size = 0;
184 ffi->alignment = 0;
185 ffi->type = FFI_TYPE_STRUCT;
186
255fe37e
JF
187 if (signature.count == 0) {
188 // https://gcc.gnu.org/ml/gcc-patches/2015-01/msg01286.html
189 ffi->elements = new(pool) ffi_type *[2];
190 ffi->elements[0] = &ffi_type_void;
191 ffi->elements[1] = NULL;
192 } else {
193 ffi->elements = new(pool) ffi_type *[signature.count + 1];
194 for (size_t index(0); index != signature.count; ++index)
195 ffi->elements[index] = signature.elements[index].type->GetFFI(pool);
196 ffi->elements[signature.count] = NULL;
197 }
0559abf8
JF
198
199 return ffi;
200}
201
202ffi_type *Function::GetFFI(CYPool &pool) const {
203 _assert(false);
204}
205
e2ce853b 206#ifdef CY_OBJECTIVEC
0559abf8
JF
207ffi_type *Block::GetFFI(CYPool &pool) const {
208 return &ffi_type_pointer;
ea2d184c 209}
e2ce853b 210#endif
ea2d184c 211
574d4720
JF
212void sig_ffi_cif(CYPool &pool, size_t variadic, const Signature &signature, ffi_cif *cif) {
213 _assert(signature.count != 0);
214 size_t count(signature.count - 1);
215 ffi_type *type(signature.elements[0].type->GetFFI(pool));
216
217 ffi_type **types(new(pool) ffi_type *[count]);
218 for (size_t index(0); index != count; ++index)
219 types[index] = signature.elements[index + 1].type->GetFFI(pool);
220
221 ffi_status status;
222#ifdef HAVE_FFI_PREP_CIF_VAR
223 if (variadic == 0)
224#endif
225 status = ffi_prep_cif(cif, FFI_DEFAULT_ABI, count, type, types);
226#ifdef HAVE_FFI_PREP_CIF_VAR
227 else
228 status = ffi_prep_cif_var(cif, FFI_DEFAULT_ABI, variadic - 1, count, type, types);
229#endif
ea2d184c
JF
230 _assert(status == FFI_OK);
231}
232
233}