]> git.saurik.com Git - cycript.git/blame - sig/ffi_type.cpp
More interactivity and @selector start.
[cycript.git] / sig / ffi_type.cpp
CommitLineData
ea2d184c
JF
1#include "minimal/stdlib.h"
2
3#include "sig/ffi_type.hpp"
4#include "sig/types.hpp"
5
6namespace sig {
7
b21525c7
JF
8void sig_ffi_types(
9 apr_pool_t *pool,
10 ffi_type *(*sig_ffi_type)(apr_pool_t *, struct Type *),
11 struct Signature *signature,
12 ffi_type **types,
13 size_t skip = 0,
14 size_t offset = 0
15) {
16 _assert(signature->count >= skip);
17 for (size_t index = skip; index != signature->count; ++index)
18 types[index - skip + offset] = (*sig_ffi_type)(pool, signature->elements[index].type);
19}
20
21ffi_type *ObjectiveC(apr_pool_t *pool, struct Type *type) {
ea2d184c
JF
22 switch (type->primitive) {
23 case typename_P: return &ffi_type_pointer;
24
25 case union_P:
26 /* XXX: we can totally make this work */
27 _assert(false);
28 break;
29
30 case string_P: return &ffi_type_pointer;
31 case selector_P: return &ffi_type_pointer;
32 case object_P: return &ffi_type_pointer;
33 case boolean_P: return &ffi_type_uchar;
34 case uchar_P: return &ffi_type_uchar;
35 case uint_P: return &ffi_type_uint;
36 case ulong_P: return &ffi_type_ulong;
37 case ulonglong_P: return &ffi_type_ulong;
38 case ushort_P: return &ffi_type_ushort;
39
40 case array_P:
41 /* XXX: implement */
42 _assert(false);
43 break;
44
45 case pointer_P: return &ffi_type_pointer;
46
47 case bit_P:
48 /* XXX: we can totally make this work */
49 _assert(false);
50 break;
51
52 case char_P: return &ffi_type_schar;
53 case double_P: return &ffi_type_double;
54 case float_P: return &ffi_type_float;
55 case int_P: return &ffi_type_sint;
56 case long_P: return &ffi_type_sint;
57 case longlong_P: return &ffi_type_slong;
58 case short_P: return &ffi_type_sshort;
59
60 case void_P: return &ffi_type_void;
61
62 case struct_P: {
63 ffi_type *aggregate = reinterpret_cast<ffi_type *>(apr_palloc(pool, sizeof(ffi_type)));
64 aggregate->size = 0;
65 aggregate->alignment = 0;
66 aggregate->type = FFI_TYPE_STRUCT;
67
68 aggregate->elements = reinterpret_cast<ffi_type **>(apr_palloc(pool, (type->data.signature.count + 1) * sizeof(ffi_type *)));
b21525c7 69 sig_ffi_types(pool, &ObjectiveC, &type->data.signature, aggregate->elements);
ea2d184c
JF
70 aggregate->elements[type->data.signature.count] = NULL;
71
72 return aggregate;
73 } break;
74
75 default:
76 _assert(false);
77 break;
78 }
79}
80
b21525c7 81ffi_type *Java(apr_pool_t *pool, struct Type *type) {
ea2d184c
JF
82 switch (type->primitive) {
83 case typename_P: return &ffi_type_pointer;
84 case union_P: return &ffi_type_pointer;
85 case string_P: return &ffi_type_pointer;
86 case selector_P: return &ffi_type_pointer;
87 case object_P: return &ffi_type_pointer;
88 case boolean_P: return &ffi_type_uchar;
89 case uchar_P: return &ffi_type_uchar;
90 case uint_P: return &ffi_type_uint;
91 case ulong_P: return &ffi_type_ulong;
92 case ulonglong_P: return &ffi_type_ulong;
93 case ushort_P: return &ffi_type_ushort;
94 case array_P: return &ffi_type_pointer;
95 case pointer_P: return &ffi_type_pointer;
96
97 /* XXX: bit type */
98 case bit_P: return &ffi_type_uint;
99
100 case char_P: return &ffi_type_schar;
101 case double_P: return &ffi_type_double;
102 case float_P: return &ffi_type_double;
103 case int_P: return &ffi_type_sint;
104 case long_P: return &ffi_type_sint;
105 case longlong_P: return &ffi_type_slong;
106 case short_P: return &ffi_type_sshort;
107 case void_P: return &ffi_type_void;
108 case struct_P: return &ffi_type_pointer;
109
110 default:
111 _assert(false);
112 break;
113 }
114}
115
ea2d184c
JF
116void sig_ffi_cif(
117 apr_pool_t *pool,
118 ffi_type *(*sig_ffi_type)(apr_pool_t *, struct Type *),
119 struct Signature *signature,
b21525c7 120 ffi_cif *cif,
ea2d184c
JF
121 size_t skip,
122 ffi_type **types,
123 size_t offset
124) {
125 if (types == NULL)
126 types = reinterpret_cast<ffi_type **>(apr_palloc(pool, (signature->count - 1) * sizeof(ffi_type *)));
127 ffi_type *type = (*sig_ffi_type)(pool, signature->elements[0].type);
128 sig_ffi_types(pool, sig_ffi_type, signature, types, 1 + skip, offset);
b21525c7 129 ffi_status status = ffi_prep_cif(cif, FFI_DEFAULT_ABI, signature->count - 1 - skip + offset, type, types);
ea2d184c
JF
130 _assert(status == FFI_OK);
131}
132
133}