]> git.saurik.com Git - cycript.git/blame - sig/ffi_type.cpp
Use class extension syntax as part of Object CYON.
[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
5875f632
JF
27#define ffi_type_slonglong ffi_type_sint64
28#define ffi_type_ulonglong ffi_type_uint64
29
ea2d184c
JF
30namespace sig {
31
0559abf8
JF
32template <>
33ffi_type *Primitive<bool>::GetFFI(CYPool &pool) const {
34 return &ffi_type_uchar;
35}
36
37template <>
38ffi_type *Primitive<char>::GetFFI(CYPool &pool) const {
39 return &ffi_type_schar;
40}
41
42template <>
43ffi_type *Primitive<float>::GetFFI(CYPool &pool) const {
44 return &ffi_type_float;
45}
46
47template <>
48ffi_type *Primitive<double>::GetFFI(CYPool &pool) const {
49 return &ffi_type_double;
50}
51
52template <>
53ffi_type *Primitive<signed char>::GetFFI(CYPool &pool) const {
54 return &ffi_type_schar;
55}
56
57template <>
58ffi_type *Primitive<signed int>::GetFFI(CYPool &pool) const {
59 return &ffi_type_sint;
60}
61
62template <>
63ffi_type *Primitive<signed long int>::GetFFI(CYPool &pool) const {
64 return &ffi_type_slong;
65}
66
67template <>
68ffi_type *Primitive<signed long long int>::GetFFI(CYPool &pool) const {
69 return &ffi_type_slonglong;
70}
71
72template <>
73ffi_type *Primitive<signed short int>::GetFFI(CYPool &pool) const {
74 return &ffi_type_sshort;
75}
76
77template <>
78ffi_type *Primitive<unsigned char>::GetFFI(CYPool &pool) const {
79 return &ffi_type_uchar;
80}
81
82template <>
83ffi_type *Primitive<unsigned int>::GetFFI(CYPool &pool) const {
84 return &ffi_type_uint;
85}
86
87template <>
88ffi_type *Primitive<unsigned long int>::GetFFI(CYPool &pool) const {
89 return &ffi_type_ulong;
90}
91
92template <>
93ffi_type *Primitive<unsigned long long int>::GetFFI(CYPool &pool) const {
94 return &ffi_type_ulonglong;
95}
96
97template <>
98ffi_type *Primitive<unsigned short int>::GetFFI(CYPool &pool) const {
99 return &ffi_type_ushort;
100}
101
102ffi_type *Void::GetFFI(CYPool &pool) const {
103 return &ffi_type_void;
104}
105
106ffi_type *Unknown::GetFFI(CYPool &pool) const {
107 _assert(false);
108}
109
110ffi_type *String::GetFFI(CYPool &pool) const {
111 return &ffi_type_pointer;
112}
113
e2ce853b 114#ifdef CY_OBJECTIVEC
0559abf8
JF
115ffi_type *Meta::GetFFI(CYPool &pool) const {
116 return &ffi_type_pointer;
117}
118
119ffi_type *Selector::GetFFI(CYPool &pool) const {
120 return &ffi_type_pointer;
121}
e2ce853b 122#endif
0559abf8
JF
123
124ffi_type *Bits::GetFFI(CYPool &pool) const {
125 /* XXX: we can totally make this work */
126 _assert(false);
127}
128
129ffi_type *Pointer::GetFFI(CYPool &pool) const {
130 return &ffi_type_pointer;
131}
132
133ffi_type *Array::GetFFI(CYPool &pool) const {
134 // XXX: this is really lame
135 ffi_type *ffi(new(pool) ffi_type());
136 ffi->size = 0;
137 ffi->alignment = 0;
138 ffi->type = FFI_TYPE_STRUCT;
139
140 ffi_type *element(type.GetFFI(pool));
141
142 ffi->elements = new(pool) ffi_type *[size + 1];
143 for (size_t i(0); i != size; ++i)
144 ffi->elements[i] = element;
145 ffi->elements[size] = NULL;
146
147 return ffi;
148}
149
e2ce853b 150#ifdef CY_OBJECTIVEC
0559abf8
JF
151ffi_type *Object::GetFFI(CYPool &pool) const {
152 return &ffi_type_pointer;
153}
e2ce853b 154#endif
0559abf8
JF
155
156ffi_type *Aggregate::GetFFI(CYPool &pool) const {
157 // XXX: we can totally make overlap work
158 _assert(!overlap);
159
160 ffi_type *ffi(new(pool) ffi_type());
161 ffi->size = 0;
162 ffi->alignment = 0;
163 ffi->type = FFI_TYPE_STRUCT;
164
255fe37e
JF
165 if (signature.count == 0) {
166 // https://gcc.gnu.org/ml/gcc-patches/2015-01/msg01286.html
167 ffi->elements = new(pool) ffi_type *[2];
168 ffi->elements[0] = &ffi_type_void;
169 ffi->elements[1] = NULL;
170 } else {
171 ffi->elements = new(pool) ffi_type *[signature.count + 1];
172 for (size_t index(0); index != signature.count; ++index)
173 ffi->elements[index] = signature.elements[index].type->GetFFI(pool);
174 ffi->elements[signature.count] = NULL;
175 }
0559abf8
JF
176
177 return ffi;
178}
179
180ffi_type *Function::GetFFI(CYPool &pool) const {
181 _assert(false);
182}
183
e2ce853b 184#ifdef CY_OBJECTIVEC
0559abf8
JF
185ffi_type *Block::GetFFI(CYPool &pool) const {
186 return &ffi_type_pointer;
ea2d184c 187}
e2ce853b 188#endif
ea2d184c 189
574d4720
JF
190void sig_ffi_cif(CYPool &pool, size_t variadic, const Signature &signature, ffi_cif *cif) {
191 _assert(signature.count != 0);
192 size_t count(signature.count - 1);
193 ffi_type *type(signature.elements[0].type->GetFFI(pool));
194
195 ffi_type **types(new(pool) ffi_type *[count]);
196 for (size_t index(0); index != count; ++index)
197 types[index] = signature.elements[index + 1].type->GetFFI(pool);
198
199 ffi_status status;
200#ifdef HAVE_FFI_PREP_CIF_VAR
201 if (variadic == 0)
202#endif
203 status = ffi_prep_cif(cif, FFI_DEFAULT_ABI, count, type, types);
204#ifdef HAVE_FFI_PREP_CIF_VAR
205 else
206 status = ffi_prep_cif_var(cif, FFI_DEFAULT_ABI, variadic - 1, count, type, types);
207#endif
ea2d184c
JF
208 _assert(status == FFI_OK);
209}
210
211}