]>
Commit | Line | Data |
---|---|---|
ea2d184c JF |
1 | #include "minimal/stdlib.h" |
2 | ||
3 | #include "sig/ffi_type.hpp" | |
4 | #include "sig/types.hpp" | |
5 | ||
6 | namespace sig { | |
7 | ||
b21525c7 JF |
8 | void 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 | ||
21 | ffi_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 | 81 | ffi_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 |
116 | void 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 | } |