]>
git.saurik.com Git - cycript.git/blob - sig/ffi_type.cpp
1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2015 Jay Freeman (saurik)
5 /* GNU Affero General Public License, Version 3 {{{ */
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.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
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/>.
24 #include "sig/ffi_type.hpp"
25 #include "sig/types.hpp"
27 #define ffi_type_slonglong ffi_type_sint64
28 #define ffi_type_ulonglong ffi_type_uint64
34 const struct Signature
*signature
,
39 _assert(signature
->count
>= skip
);
40 for (size_t index
= skip
; index
!= signature
->count
; ++index
)
41 types
[index
- skip
+ offset
] = signature
->elements
[index
].type
->GetFFI(pool
);
45 ffi_type
*Primitive
<bool>::GetFFI(CYPool
&pool
) const {
46 return &ffi_type_uchar
;
50 ffi_type
*Primitive
<char>::GetFFI(CYPool
&pool
) const {
51 return &ffi_type_schar
;
55 ffi_type
*Primitive
<float>::GetFFI(CYPool
&pool
) const {
56 return &ffi_type_float
;
60 ffi_type
*Primitive
<double>::GetFFI(CYPool
&pool
) const {
61 return &ffi_type_double
;
65 ffi_type
*Primitive
<signed char>::GetFFI(CYPool
&pool
) const {
66 return &ffi_type_schar
;
70 ffi_type
*Primitive
<signed int>::GetFFI(CYPool
&pool
) const {
71 return &ffi_type_sint
;
75 ffi_type
*Primitive
<signed long int>::GetFFI(CYPool
&pool
) const {
76 return &ffi_type_slong
;
80 ffi_type
*Primitive
<signed long long int>::GetFFI(CYPool
&pool
) const {
81 return &ffi_type_slonglong
;
85 ffi_type
*Primitive
<signed short int>::GetFFI(CYPool
&pool
) const {
86 return &ffi_type_sshort
;
90 ffi_type
*Primitive
<unsigned char>::GetFFI(CYPool
&pool
) const {
91 return &ffi_type_uchar
;
95 ffi_type
*Primitive
<unsigned int>::GetFFI(CYPool
&pool
) const {
96 return &ffi_type_uint
;
100 ffi_type
*Primitive
<unsigned long int>::GetFFI(CYPool
&pool
) const {
101 return &ffi_type_ulong
;
105 ffi_type
*Primitive
<unsigned long long int>::GetFFI(CYPool
&pool
) const {
106 return &ffi_type_ulonglong
;
110 ffi_type
*Primitive
<unsigned short int>::GetFFI(CYPool
&pool
) const {
111 return &ffi_type_ushort
;
114 ffi_type
*Void::GetFFI(CYPool
&pool
) const {
115 return &ffi_type_void
;
118 ffi_type
*Unknown::GetFFI(CYPool
&pool
) const {
122 ffi_type
*String::GetFFI(CYPool
&pool
) const {
123 return &ffi_type_pointer
;
126 ffi_type
*Meta::GetFFI(CYPool
&pool
) const {
127 return &ffi_type_pointer
;
130 ffi_type
*Selector::GetFFI(CYPool
&pool
) const {
131 return &ffi_type_pointer
;
134 ffi_type
*Bits::GetFFI(CYPool
&pool
) const {
135 /* XXX: we can totally make this work */
139 ffi_type
*Pointer::GetFFI(CYPool
&pool
) const {
140 return &ffi_type_pointer
;
143 ffi_type
*Array::GetFFI(CYPool
&pool
) const {
144 // XXX: this is really lame
145 ffi_type
*ffi(new(pool
) ffi_type());
148 ffi
->type
= FFI_TYPE_STRUCT
;
150 ffi_type
*element(type
.GetFFI(pool
));
152 ffi
->elements
= new(pool
) ffi_type
*[size
+ 1];
153 for (size_t i(0); i
!= size
; ++i
)
154 ffi
->elements
[i
] = element
;
155 ffi
->elements
[size
] = NULL
;
160 ffi_type
*Object::GetFFI(CYPool
&pool
) const {
161 return &ffi_type_pointer
;
164 ffi_type
*Aggregate::GetFFI(CYPool
&pool
) const {
165 // XXX: we can totally make overlap work
168 ffi_type
*ffi(new(pool
) ffi_type());
171 ffi
->type
= FFI_TYPE_STRUCT
;
173 ffi
->elements
= new(pool
) ffi_type
*[signature
.count
+ 1];
174 sig_ffi_types(pool
, &signature
, ffi
->elements
);
175 ffi
->elements
[signature
.count
] = NULL
;
180 ffi_type
*Function::GetFFI(CYPool
&pool
) const {
184 ffi_type
*Block::GetFFI(CYPool
&pool
) const {
185 return &ffi_type_pointer
;
190 struct Signature
*signature
,
197 types
= new(pool
) ffi_type
*[signature
->count
- 1];
198 ffi_type
*type
= signature
->elements
[0].type
->GetFFI(pool
);
199 sig_ffi_types(pool
, signature
, types
, 1 + skip
, offset
);
200 ffi_status status
= ffi_prep_cif(cif
, FFI_DEFAULT_ABI
, signature
->count
- 1 - skip
+ offset
, type
, types
);
201 _assert(status
== FFI_OK
);