Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 832 lines (669 sloc) 29.452 kb
c64e58f pmc docs update 3
Michael Scott authored
1 /*
e69d2a4 @petdance Made pcc_params be static. Removed unused arg from build_func. Headerizi...
petdance authored
2 Copyright (C) 2001-2010, Parrot Foundation.
c64e58f pmc docs update 3
Michael Scott authored
3 $Id$
4
5 =head1 NAME
6
f474cd7 @bschmalhofer [perl #38235] Rename (dyn)?classes to (dyn)?pmc
bschmalhofer authored
7 src/pmc/nci.pmc - Native Call Interface
c64e58f pmc docs update 3
Michael Scott authored
8
9 =head1 DESCRIPTION
10
11 The vtable functions for the native C call functions.
12
13 =head2 Methods
14
15 =over 4
16
17 =cut
18
19 */
2a2c19b Added in code to properly do native calls to library routines loaded via
Dan Sugalski authored
20
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
21 /* Cheat with this include, for whatever reason the space is required */
22 # include "ffi.h"
23
6bdd5f9 @petdance headerizer now runs on PMC files
petdance authored
24 /* HEADERIZER HFILE: none */
25 /* HEADERIZER BEGIN: static */
e69d2a4 @petdance Made pcc_params be static. Removed unused arg from build_func. Headerizi...
petdance authored
26 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
27
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
28 static void build_libffi_func(PARROT_INTERP,
29 ARGMOD(Parrot_NCI_attributes *nci))
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
30 __attribute__nonnull__(1)
31 __attribute__nonnull__(2)
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
32 FUNC_MODIFIES(*nci);
33
34 static ffi_type * nci_to_ffi_type(PARROT_INTERP, nci_sig_elem_t nci_t)
35 __attribute__nonnull__(1);
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
36
7723c62 @plobsing kill dead code
plobsing authored
37 #define ASSERT_ARGS_build_libffi_func __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
38 PARROT_ASSERT_ARG(interp) \
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
39 , PARROT_ASSERT_ARG(nci))
40 #define ASSERT_ARGS_nci_to_ffi_type __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
41 PARROT_ASSERT_ARG(interp))
e69d2a4 @petdance Made pcc_params be static. Removed unused arg from build_func. Headerizi...
petdance authored
42 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
6bdd5f9 @petdance headerizer now runs on PMC files
petdance authored
43 /* HEADERIZER END: static */
44
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
45 #if (INTVAL_SIZE == 4)
46 # define ffi_type_parrot_intval ffi_type_sint32
47 #elif (INTVAL_SIZE == 8)
48 # define ffi_type_parrot_intval ffi_type_sint64
49 #else
50 # error "unhandled INTVAL_SIZE value"
51 #endif
52
53 #if (NUMVAL_SIZE == 4)
54 # define ffi_type_parrot_numval ffi_type_float
55 #elif (NUMVAL_SIZE == 8)
56 # define ffi_type_parrot_numval ffi_type_double
57 #else
58 # error "unhandled NUMVAL_SIZE value"
59 #endif
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
60
61 typedef struct pmc_holder_t {
62 PMC* p;
63 union {
64 INTVAL* ival;
65 void** pval;
66 };
67 } pmc_holder_t;
68
69
70 /*
71
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
72 =item C<static ffi_cif *sig_to_cif(PARROT_INTERP, Parrot_NCI_attributes *nci)>
73
74 =cut
75
76 */
77
78 static void
79 sig_to_cif(PARROT_INTERP, ARGMOD(Parrot_NCI_attributes *nci)) {
80 int i;
81 PMC *sig = nci->signature;
82 INTVAL argc = VTABLE_elements(interp, sig) - 1;
83 ffi_type *ret_t = nci_to_ffi_type(interp, VTABLE_get_integer_keyed_int(interp, sig, 0));
84 ffi_type **arg_t = mem_gc_allocate_n_zeroed_typed(interp, argc, ffi_type *);
85 ffi_cif *cif = mem_gc_allocate_zeroed_typed(interp, ffi_cif);
86
87 for (i = 0; i < argc; i++) {
88 arg_t[i] = nci_to_ffi_type(interp, VTABLE_get_integer_keyed_int(interp, sig, i + 1));
89 }
90
91 if (ffi_prep_cif(cif, FFI_DEFAULT_ABI, argc, ret_t, arg_t) == FFI_OK) {
92 nci->cif = cif;
93 nci->arg_types = arg_t;
94 return;
95 }
96
97 mem_gc_free(interp, arg_t);
98 mem_gc_free(interp, cif);
99
100 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, "invalid ffi signature");
101 }
102
103
104 /*
105
106 =item C<static ffi_type * nci_to_ffi_type(PARROT_INTERP, nci_sig_elem_t nci_t)>
107
108 =cut
109
110 */
111
112 static ffi_type *
113 nci_to_ffi_type(PARROT_INTERP, nci_sig_elem_t nci_t) {
114 switch (nci_t) {
115 case enum_nci_sig_void: return &ffi_type_void;
116 case enum_nci_sig_null: return &ffi_type_pointer;
117 case enum_nci_sig_interp: return &ffi_type_pointer;
118
119 case enum_nci_sig_float: return &ffi_type_float;
120 case enum_nci_sig_double: return &ffi_type_double;
121 case enum_nci_sig_numval: return &ffi_type_parrot_numval;
122
123 case enum_nci_sig_char: return &ffi_type_schar;
124 case enum_nci_sig_short: return &ffi_type_sshort;
125 case enum_nci_sig_int: return &ffi_type_sint;
126 case enum_nci_sig_long: return &ffi_type_slong;
127 case enum_nci_sig_intval: return &ffi_type_parrot_intval;
128
129 case enum_nci_sig_string:
130 case enum_nci_sig_cstring:
131 case enum_nci_sig_cstringref:
132 case enum_nci_sig_bufref:
133 return &ffi_type_pointer;
134
135 case enum_nci_sig_ptr:
136 case enum_nci_sig_pmc:
137 case enum_nci_sig_pmcinv:
138 case enum_nci_sig_pmcslurp:
139 case enum_nci_sig_ptrref:
140 case enum_nci_sig_shortref:
141 case enum_nci_sig_intref:
142 case enum_nci_sig_longref:
143 return &ffi_type_pointer;
144 }
145 }
146
147 static void
148 build_libffi_func(PARROT_INTERP, ARGMOD(Parrot_NCI_attributes *nci))
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
149 {
7723c62 @plobsing kill dead code
plobsing authored
150 ASSERT_ARGS(build_libffi_func)
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
151
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
152 nci->signature = Parrot_nci_parse_signature(interp, nci->sig_str);
153
154 Parrot_nci_sig_to_pcc(interp, nci->signature,
155 &nci->pcc_params_signature,
156 &nci->pcc_return_signature);
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
157
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
158 /* Arity is length of the signature minus one (the return type). */
159 nci->arity = VTABLE_elements(interp, nci->signature) - 1;
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
160
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
161 sig_to_cif(interp, nci);
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
162 }
163
336b07c @bacek Add 'does invokable' to all PMCs with VTABLE_invoke (except Object). Par...
bacek authored
164 pmclass NCI auto_attrs provides invokable {
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param and r...
plobsing authored
165 /* NCI thunk handling attributes */
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
166 ATTR PMC *signature;
2d5eeb8 @plobsing eliminate some unnecessary attributes
plobsing authored
167 ATTR STRING *sig_str;
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
168 ATTR void *func; /* Function pointer to call. */
169 ATTR void *orig_func;
170 ATTR PMC *fb_info; /* Frame-builder info */
171 ATTR void *cif; /* Function interface */
172 ATTR void *arg_types; /* Used for building the libffi call interface */
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
173
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param and r...
plobsing authored
174 /* Parrot Sub-ish attributes */
175 ATTR STRING *pcc_params_signature;
176 ATTR STRING *pcc_return_signature;
2d5eeb8 @plobsing eliminate some unnecessary attributes
plobsing authored
177 ATTR INTVAL arity;
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param and r...
plobsing authored
178
179 /* MMD fields */
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
180 ATTR STRING *long_signature; /* The full signature. */
181 ATTR PMC *multi_sig; /* type tuple array (?) */
2a2c19b Added in code to properly do native calls to library routines loaded via
Dan Sugalski authored
182
c64e58f pmc docs update 3
Michael Scott authored
183 /*
184
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
185 =item C<METHOD get_multisig()>
1415cda add introspection method get_multisig
Leopold Toetsch authored
186
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
187 Return the MMD signature PMC, if any or a Null PMC.
1415cda add introspection method get_multisig
Leopold Toetsch authored
188
189 =cut
190
191 */
192
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
193 METHOD get_multisig() {
26f7d7b @cotto [PMC] replace PMC_pmc_val with an ATTR in the NCI PMC
cotto authored
194 PMC *sig;
195 GET_ATTR_multi_sig(INTERP, SELF, sig);
83dd9f2 @NotFound [core] partial fix for TT #667, examples/namespace/namespace_dump.pir d...
NotFound authored
196 if (PMC_IS_NULL(sig))
26f7d7b @cotto [PMC] replace PMC_pmc_val with an ATTR in the NCI PMC
cotto authored
197 sig = PMCNULL;
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
198 RETURN(PMC *sig);
1415cda add introspection method get_multisig
Leopold Toetsch authored
199 }
200
201 /*
202
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
203 =item C<METHOD set_raw_nci_ptr(void *func)>
204
205 Sets the specified function pointer and raw flag.
206
207 =cut
208
209 */
210
211 METHOD make_raw_nci(PMC *func) {
212 VTABLE_set_pointer(interp, SELF, (void *)func);
213 }
214
215 /*
216
c64e58f pmc docs update 3
Michael Scott authored
217 =item C<void init()>
218
219 Initializes the NCI with a C<NULL> function pointer.
220
221 =cut
222
223 */
224
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
225 VTABLE void init() {
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
226 PObj_custom_mark_SET(SELF);
f7fc86b nci
Leopold Toetsch authored
227 }
228
c64e58f pmc docs update 3
Michael Scott authored
229 /*
230
380c0ba fix NCI related DOD problem
Leopold Toetsch authored
231 =item C<void set_pointer_keyed_str(STRING *key, void *func)>
c64e58f pmc docs update 3
Michael Scott authored
232
380c0ba fix NCI related DOD problem
Leopold Toetsch authored
233 Sets the specified function pointer and signature (C<*key>).
c64e58f pmc docs update 3
Michael Scott authored
234
235 =cut
236
237 */
238
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
239 VTABLE void *get_pointer() {
240 return PARROT_NCI(SELF)->orig_func;
241 }
242
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
243 VTABLE void set_pointer_keyed_str(STRING *key, void *func) {
1764f4c @chromatic [PMC] Optimized NCI registration signature handling slightly by avoiding
chromatic authored
244 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
637246f @jnthn Refactor the NCI PMC to have an underlying structure, in preparation for...
jnthn authored
245
62e3049 @petdance consting, and fixed embedded tabs
petdance authored
246 /* Store the original function and signature. */
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
247 SET_ATTR_func(INTERP, SELF, func);
c4cd281 @chromatic [PMC] Avoided an unnecessary STRING copying and creation in NCI's
chromatic authored
248
249 /* ensure that the STRING signature is constant */
250 if (!PObj_constant_TEST(key)) {
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
251 char * const key_c = Parrot_str_to_cstring(INTERP, key);
e69d2a4 @petdance Made pcc_params be static. Removed unused arg from build_func. Headerizi...
petdance authored
252 const size_t key_length = Parrot_str_byte_length(interp, key);
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
253 key = string_make(interp, key_c, key_length, NULL, 0);
c4cd281 @chromatic [PMC] Avoided an unnecessary STRING copying and creation in NCI's
chromatic authored
254 Parrot_str_free_cstring(key_c);
255 }
256
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
257 nci_info->sig_str = key;
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
258 }
03918bc @chromatic [PMC] Fixed a read of unitialized memory in NCI PMC reported by Valgrind...
chromatic authored
259
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
260 /*
261
262 =item C<void mark()>
263
264 Mark any referenced strings and PMCs.
265
266 =cut
267
268 */
269 VTABLE void mark() {
270 if (PARROT_NCI(SELF)) {
971e997 @NotFound rename pmc attributes struct from Parrot_<type> to Parrot_<type>_attribu...
NotFound authored
271 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
272
3b094c7 @plobsing add NCI.fb_info for frame buffer info
plobsing authored
273 Parrot_gc_mark_PMC_alive(interp, nci_info->fb_info);
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
274 Parrot_gc_mark_STRING_alive(interp, nci_info->sig_str);
c64fa8d @plobsing split NCI signature parser out from nci.pmc
plobsing authored
275 Parrot_gc_mark_STRING_alive(interp, nci_info->pcc_params_signature);
276 Parrot_gc_mark_STRING_alive(interp, nci_info->pcc_return_signature);
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
277 Parrot_gc_mark_STRING_alive(interp, nci_info->long_signature);
278 Parrot_gc_mark_PMC_alive(interp, nci_info->multi_sig);
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
279 }
280 }
281
282 /*
283
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
284 =item C<void destroy()>
285
286 Free all of the memory used internally to store various things, like libffi call signatures.
287
288 =cut
289
290 */
291
292 VTABLE void destroy() {
293 if (PARROT_NCI(SELF)) {
294 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
295 mem_sys_free(nci_info->cif);
296 mem_sys_free(nci_info->arg_types);
297 }
298 }
299
300
301 /*
302
c64e58f pmc docs update 3
Michael Scott authored
303 =item C<PMC *clone()>
304
305 Creates and returns a clone of the NCI.
306
307 =cut
308
309 */
310
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
311 VTABLE PMC *clone() {
971e997 @NotFound rename pmc attributes struct from Parrot_<type> to Parrot_<type>_attribu...
NotFound authored
312 Parrot_NCI_attributes * const nci_info_self = PARROT_NCI(SELF);
313 Parrot_NCI_attributes *nci_info_ret;
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
314 void *cif;
62e3049 @petdance consting, and fixed embedded tabs
petdance authored
315
083213a @Whiteknight start rename of pmc_new to Parrot_pmc_new
Whiteknight authored
316 PMC * const ret = Parrot_pmc_new(INTERP, SELF->vtable->base_type);
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
317 nci_info_ret = PARROT_NCI(ret);
82c7cf6 @chromatic [PMC] Minor cleanups and tidyings.
chromatic authored
318
c64e58f pmc docs update 3
Michael Scott authored
319 /* FIXME if data is malloced (JIT/i386!) then we need
320 * the length of data here, to memcpy it
321 * ManagedStruct or Buffer?
322 */
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
323 nci_info_ret->func = nci_info_self->func;
3b094c7 @plobsing add NCI.fb_info for frame buffer info
plobsing authored
324 nci_info_ret->fb_info = nci_info_self->fb_info;
811a7df @cotto [PMC] make NCI PMCs use ATTRs, with one temporary workaround for i386 ji...
cotto authored
325 nci_info_ret->orig_func = nci_info_self->orig_func;
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
326 nci_info_ret->cif = nci_info_self->cif;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
327 nci_info_ret->sig_str = nci_info_self->sig_str;
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
328 nci_info_ret->pcc_params_signature = nci_info_self->pcc_params_signature;
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param and r...
plobsing authored
329 nci_info_ret->pcc_return_signature = nci_info_self->pcc_params_signature;
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
330 nci_info_ret->arity = nci_info_self->arity;
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
331 PObj_get_FLAGS(ret) |= (PObj_get_FLAGS(SELF) & 0x7);
82c7cf6 @chromatic [PMC] Minor cleanups and tidyings.
chromatic authored
332
c64e58f pmc docs update 3
Michael Scott authored
333 return ret;
2a2c19b Added in code to properly do native calls to library routines loaded via
Dan Sugalski authored
334 }
335
c64e58f pmc docs update 3
Michael Scott authored
336 /*
337
338 =item C<INTVAL defined()>
339
340 Returns whether the NCI is defined.
341
342 =cut
343
344 */
345
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
346 VTABLE INTVAL defined() {
971e997 @NotFound rename pmc attributes struct from Parrot_<type> to Parrot_<type>_attribu...
NotFound authored
347 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
348 return nci_info->orig_func != NULL;
2a2c19b Added in code to properly do native calls to library routines loaded via
Dan Sugalski authored
349 }
350
c64e58f pmc docs update 3
Michael Scott authored
351 /*
352
0ae5d55 @paultcochrane Patch courtesy of Steve Peters <steve at fisharerojo dot org>, his comme...
paultcochrane authored
353 =item C<opcode_t *invoke(void *next)>
c64e58f pmc docs update 3
Michael Scott authored
354
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
355 Calls the associated C function, returning C<*next>. If the invocant is a
356 class, the PMC arguments are shifted down.
c64e58f pmc docs update 3
Michael Scott authored
357
358 =cut
359
360 */
361
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
362 VTABLE opcode_t *invoke(void *next) {
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
363 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
bbd8ef4 @cotto [strings] first of many patches from darbelo++ getting rid of ->strstart...
cotto authored
364 char *sig_str;
811a7df @cotto [PMC] make NCI PMCs use ATTRs, with one temporary workaround for i386 ji...
cotto authored
365 PMC *cont;
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
366 INTVAL return_size = sizeof (void*);
367 PMC *ctx = CURRENT_CONTEXT(interp);
368 PMC *call_object = Parrot_pcc_get_signature(interp, ctx);
369 void (*func)(void*,void*,void*); /* a function pointer for our function to call */
370
371 PMC *positional, *arg_iter;
372 STRING *void_return;
373 void **values;
374 void **pcc_ptr;
375 void **translation_pointers = NULL; /* Data translation pointers, used to hold values
376 that are passed by reference so we can update
377 the objects after the FFI call is over */
378 void **pcc_val = NULL; /* A holder for the values passed to pcc */
379 void **middle_man = NULL; /* An array to hold various pointers so they are not lost if
380 the function changes values by reference */
381 void *return_data; /* Holds return data from FFI call */
382 size_t count, i, j_offset;
383 char *tmp_sig;
384 ffi_cif *cif, pcc_cif;
385 ffi_type **pcc_args;
386
387 cif = (ffi_cif*)nci_info->cif;
388 func = (void (*)(void*, void*, void*))nci_info->func;
389
390 if (!cif) {
c64fa8d @plobsing split NCI signature parser out from nci.pmc
plobsing authored
391 /* build the thunk only when necessary */
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
392 build_libffi_func(interp, nci_info);
393 cif = nci_info->cif;
82c7cf6 @chromatic [PMC] Minor cleanups and tidyings.
chromatic authored
394
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
395 if (!cif && !func)
c64fa8d @plobsing split NCI signature parser out from nci.pmc
plobsing authored
396 Parrot_ex_throw_from_c_args(INTERP, NULL,
397 EXCEPTION_INVALID_OPERATION,
398 "attempt to call NULL function");
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
399 }
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
400
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
401 if (nci_info->arity > 0) {
402 size_t pcc_argc, pcc_values_offset, pcc_values_size, values_size;
403 /* Function has arguments */
404 pcc_args = mem_internal_allocate_n_zeroed_typed(nci_info->arity + 4, ffi_type*);
405 tmp_sig = Parrot_str_to_cstring(interp, nci_info->pcc_params_signature);
406
407 pcc_args[0] = &ffi_type_pointer;
408 pcc_args[1] = &ffi_type_pointer;
409 pcc_args[2] = &ffi_type_pointer;
410 pcc_values_size = 0;
411 values_size = 0;
412 pcc_argc = Parrot_str_length(interp, nci_info->pcc_params_signature);
413
414 /* Add up the size of memory needed for the actual call */
415 for (i = 0; i < (size_t)nci_info->arity; i++) {
416 values_size += cif->arg_types[i]->size;
417 }
418
419 pcc_ptr = (void**)mem_internal_allocate_n_zeroed_typed(pcc_argc + 4, void*);
420
421 /* Setup Parrot_pcc_fill_params_from_c_args required arguments */
422 pcc_ptr[0] = &interp;
423 pcc_ptr[1] = &call_object;
424 pcc_ptr[2] = &tmp_sig;
425
426 pcc_val = mem_internal_allocate_n_zeroed_typed(pcc_argc, void*);
427 /* Allocate enough room for the values passed to the ffi function plus add some
428 padding just to be sure we have enough space. */
429 values = mem_internal_allocate_zeroed(values_size + 2 * sizeof(void*));
430 /* Middle man is used to contain */
431 middle_man = mem_internal_allocate_n_zeroed_typed(nci_info->arity, void*);
432
433 /* Add up the size of the pcc arguments */
434 for (i = 0; i < pcc_argc; i++) {
435 pcc_args[i + 3] = &ffi_type_pointer;
436 if (tmp_sig[i] == 'N') {
437 pcc_val[i] = mem_internal_allocate_typed(FLOATVAL);
438 pcc_ptr[i+3] = &pcc_val[i];
439 }
440 else if (tmp_sig[i] == 'I') {
441 pcc_val[i] = mem_internal_allocate_typed(INTVAL);
442 pcc_ptr[i+3] = &pcc_val[i];
443 }
444 else if (tmp_sig[i] == 'P' || tmp_sig[i] == 'S') {
445 pcc_val[i] = mem_internal_allocate_typed(void*);
446 pcc_ptr[i+3] = &pcc_val[i];
447 }
448 }
449
450 if (ffi_prep_cif(&pcc_cif, FFI_DEFAULT_ABI, 3 + pcc_argc,
451 &ffi_type_void, pcc_args) != FFI_OK) {
452 Parrot_ex_throw_from_c_args(INTERP, NULL,
453 EXCEPTION_INVALID_OPERATION,
454 "Bad signature generated for Parrot_pcc_fill_params_from_c_args in NCI");
455 }
456
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
457 {
458 ffi_arg ret;
459 ffi_call(&pcc_cif, FFI_FN(Parrot_pcc_fill_params_from_c_args), &ret, pcc_ptr);
460 }
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
461
462 Parrot_str_free_cstring(tmp_sig);
463
464 /*
465 * Apply Argument Transformations
466 * this is mostly to transform STRING* into char*
467 * and add the parrot interp argument if it needs it
468 * but other transformations might apply later, like packing an
469 * object into a ManagedStruct
470 */
471 j_offset = 0;
472 translation_pointers = mem_internal_allocate_n_zeroed_typed(nci_info->arity, void*);
473 for (i = 0; i < (size_t)nci_info->arity; i++) {
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
474 switch (VTABLE_get_integer_keyed_int(interp, nci_info->signature, i + 1)) {
475 case enum_nci_sig_interp:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
476 values[i] = &interp;
477 j_offset++;
478 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
479 case enum_nci_sig_cstring:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
480 if (STRING_IS_NULL(*(STRING**)pcc_val[i - j_offset])) {
481 translation_pointers[i] = (char*) NULL;
482 }
483 else {
484 translation_pointers[i] = Parrot_str_to_cstring(interp, *(STRING**)pcc_val[i - j_offset]);
485 }
486 values[i] = &translation_pointers[i];
487 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
488 case enum_nci_sig_bufref:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
489 if (STRING_IS_NULL(*(STRING**)pcc_val[i - j_offset])) {
490 translation_pointers[i] = (char*) NULL;
491 }
492 else {
493 translation_pointers[i] = Parrot_str_to_cstring(interp, *(STRING**)pcc_val[i - j_offset]);
494 }
495 middle_man[i] = &translation_pointers[i];
496 values[i] = &middle_man[i];
497 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
498 case enum_nci_sig_cstringref:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
499 values[i] = &Buffer_bufstart(*(STRING**)pcc_val[i - j_offset]);
500 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
501 case enum_nci_sig_char:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
502 translation_pointers[i] = mem_internal_allocate_zeroed_typed(char);
503 *((char**)translation_pointers)[i] = (char)*(INTVAL*)pcc_val[i - j_offset];
504 values[i] = translation_pointers[i];
505 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
506 case enum_nci_sig_shortref:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
507 translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
508 ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)pcc_val[i - j_offset];
509 ((pmc_holder_t*)translation_pointers[i])->ival = (INTVAL*)mem_internal_allocate_zeroed_typed(short);
510 *((pmc_holder_t*)translation_pointers[i])->ival = (short)VTABLE_get_integer(interp, *(PMC**)pcc_ptr[i - j_offset]);
511 values[i] = &((pmc_holder_t*)translation_pointers[i])->ival;
512 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
513 case enum_nci_sig_short:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
514 translation_pointers[i] = mem_internal_allocate_zeroed_typed(short);
515 *((short**)translation_pointers)[i] = (short)*(INTVAL*)pcc_val[i - j_offset];
516 values[i] = translation_pointers[i];
517 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
518 case enum_nci_sig_intref:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
519 translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
520 ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)pcc_val[i - j_offset];
521 ((pmc_holder_t*)translation_pointers[i])->ival = (INTVAL*)mem_internal_allocate_zeroed_typed(int);
522 *((pmc_holder_t*)translation_pointers[i])->ival = (int)VTABLE_get_integer(interp, *(PMC**)pcc_val[i - j_offset]);
523 values[i] = &((pmc_holder_t*)translation_pointers[i])->ival;
524 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
525 case enum_nci_sig_int:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
526 translation_pointers[i] = mem_internal_allocate_zeroed_typed(int);
527 *((int**)translation_pointers)[i] = (int)*(INTVAL*)pcc_val[i - j_offset];
528 values[i] = translation_pointers[i];
529 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
530 case enum_nci_sig_longref:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
531 translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
532 ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)pcc_val[i - j_offset];
533 ((pmc_holder_t*)translation_pointers[i])->ival = (INTVAL*)mem_internal_allocate_zeroed_typed(long);
534 *((pmc_holder_t*)translation_pointers[i])->ival = (long)VTABLE_get_integer(interp, *(PMC**)pcc_val[i - j_offset]);
535 values[i] = &((pmc_holder_t*)translation_pointers[i])->ival;
536 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
537 case enum_nci_sig_long:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
538 translation_pointers[i] = mem_internal_allocate_zeroed_typed(long);
539 *((long**)translation_pointers)[i] = (long)*(INTVAL*)pcc_val[i - j_offset];
540 values[i] = translation_pointers[i];
541 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
542 case enum_nci_sig_ptrref:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
543 translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
544 ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)pcc_val[i - j_offset];
545 ((pmc_holder_t*)translation_pointers[i])->pval = (void**)mem_internal_allocate_zeroed_typed(void*);
546 *((pmc_holder_t*)translation_pointers[i])->pval = PMC_IS_NULL(*(PMC**)pcc_val[i - j_offset]) ?
547 (void *)NULL : (void*)VTABLE_get_pointer(interp, *(PMC**)pcc_val[i - j_offset]);
548 values[i] = &((pmc_holder_t*)translation_pointers[i])->pval;
549 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
550 case enum_nci_sig_pmc:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
551 translation_pointers[i] = *(PMC**)pcc_val[i - j_offset];
552 values[i] = &translation_pointers[i];
553 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
554 case enum_nci_sig_ptr:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
555 translation_pointers[i] = PMC_IS_NULL(*(PMC**)pcc_val[i - j_offset]) ?
556 (void *)NULL : VTABLE_get_pointer(interp, *(PMC**)pcc_val[i - j_offset]);
557 values[i] = &translation_pointers[i];
558 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
559 case enum_nci_sig_float:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
560 translation_pointers[i] = mem_internal_allocate_zeroed_typed(float);
561 *((float**)translation_pointers)[i] = (float)*(FLOATVAL*)pcc_val[i - j_offset];
562 values[i] = translation_pointers[i];
563 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
564 case enum_nci_sig_double:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
565 translation_pointers[i] = mem_internal_allocate_zeroed_typed(double);
566 *((double**)translation_pointers)[i] = *(FLOATVAL*)pcc_val[i - j_offset];
567 values[i] = translation_pointers[i];
568 break;
569 default:
570 break;
571 }
572 }
573
574 if (pcc_args) {
575 mem_sys_free(pcc_args);
576 }
577 if (pcc_ptr) {
578 mem_sys_free(pcc_ptr);
579 }
580 if (pcc_val) {
581 for (i = 0; i < pcc_argc; i++) {
582 mem_sys_free(pcc_val[i]);
583 }
584 if (pcc_val)
585 mem_sys_free(pcc_val);
586 }
587 }
588 else {
589 /* No arguments */
590 values = NULL;
591 }
592
593 /*
594 * This will allow for any type of datat to be returned.
595 * Including one day Structures
596 */
597 return_data = mem_internal_allocate_zeroed(cif->rtype->size);
598
599 ffi_call(cif, FFI_FN(func), return_data, values);
600
601 if (cif->rtype != &ffi_type_void) {
602 char *s;
603 PMC *ret_object;
604 s = Parrot_str_to_cstring(interp, nci_info->pcc_return_signature);
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
605 switch (VTABLE_get_integer_keyed_int(interp, nci_info->signature, 0)) {
606 case enum_nci_sig_ptr:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
607 {
608 PMC *final_destination = PMCNULL;
609
610 if (*(void**)return_data != NULL) {
611 final_destination = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
612 VTABLE_set_pointer(interp, final_destination, *(void**)return_data);
613 }
614 ret_object = Parrot_pcc_build_call_from_c_args(interp,
615 call_object,
616 s, final_destination);
617 }
618 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
619 case enum_nci_sig_cstring:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
620 {
621 STRING *final_destination = Parrot_str_new(interp, *(char**)return_data, 0);
622 ret_object = Parrot_pcc_build_call_from_c_args(interp,
623 call_object,
624 s, final_destination);
625 }
626 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
627 case enum_nci_sig_float:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
628 {
629 FLOATVAL final_destination = *(float*)return_data;
630
631 ret_object = Parrot_pcc_build_call_from_c_args(interp,
632 call_object,
633 s, final_destination);
634 }
635 break;
636 default:
637 switch (s[0]) {
638 case 'N':
639 ret_object = Parrot_pcc_build_call_from_c_args(interp,
640 call_object,
641 s, *(FLOATVAL*)return_data);
642 case 'I':
643 ret_object = Parrot_pcc_build_call_from_c_args(interp,
644 call_object,
645 s, *(INTVAL*)return_data);
646 case 'P':
647 case 'S':
648 default:
649 ret_object = Parrot_pcc_build_call_from_c_args(interp,
650 call_object,
651 s, *(void**)return_data);
652 }
653 break;
654 }
655 Parrot_str_free_cstring(s);
656 }
657
658 /*
659 * Free memory used for cstrings,
660 * and any other translations that use temporary memory
661 */
662 for (i = 0; i < (size_t)nci_info->arity; i++) {
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
663 switch (VTABLE_get_integer_keyed_int(interp, nci_info->signature, i + 1)) {
664 case enum_nci_sig_bufref:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
665 if (translation_pointers[i]) {
666 Parrot_str_free_cstring((char*)translation_pointers[i]);
667 }
668 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
669 case enum_nci_sig_cstring:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
670 if (translation_pointers[i]) {
671 Parrot_str_free_cstring((char*)translation_pointers[i]);
672 }
673 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
674 case enum_nci_sig_shortref:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
675 VTABLE_set_integer_native(interp,
676 ((pmc_holder_t*)translation_pointers[i])->p,
677 (INTVAL)*(short*)((pmc_holder_t*)translation_pointers[i])->ival);
678 if (translation_pointers[i]) {
679 mem_sys_free(translation_pointers[i]);
680 }
681 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
682 case enum_nci_sig_intref:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
683 VTABLE_set_integer_native(interp,
684 ((pmc_holder_t*)translation_pointers[i])->p,
685 (INTVAL)*(int*)((pmc_holder_t*)translation_pointers[i])->ival);
686 if (translation_pointers[i]) {
687 mem_sys_free(translation_pointers[i]);
688 }
689 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
690 case enum_nci_sig_longref:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
691 VTABLE_set_integer_native(interp,
692 ((pmc_holder_t*)translation_pointers[i])->p,
693 (INTVAL)*(long*)((pmc_holder_t*)translation_pointers[i])->ival);
694 if (translation_pointers[i]) {
695 mem_sys_free(translation_pointers[i]);
696 }
697 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
698 case enum_nci_sig_ptrref:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
699 VTABLE_set_pointer(interp,
700 ((pmc_holder_t*)translation_pointers[i])->p,
701 (PMC*)*((pmc_holder_t*)translation_pointers[i])->pval);
702 if (translation_pointers[i]) {
703 mem_sys_free(translation_pointers[i]);
704 }
705 break;
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
706 case enum_nci_sig_double:
707 case enum_nci_sig_char:
708 case enum_nci_sig_short:
709 case enum_nci_sig_int:
710 case enum_nci_sig_long:
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
711 if (translation_pointers[i]) {
712 mem_sys_free(translation_pointers[i]);
713 }
714 break;
715 default:
716 break;
717 }
718 }
719
720 if (nci_info->arity > 0 && middle_man) {
721 mem_sys_free(middle_man);
722 }
723 if (return_data) {
724 mem_sys_free(return_data);
725 }
726 if (values) {
727 mem_sys_free(values);
728 }
729
92c390d Fix tailcalls to NCI, #38724
Leopold Toetsch authored
730 cont = INTERP->current_cont;
82c7cf6 @chromatic [PMC] Minor cleanups and tidyings.
chromatic authored
731
8838c7f builtins 1 - first shot
Leopold Toetsch authored
732 /*
92c390d Fix tailcalls to NCI, #38724
Leopold Toetsch authored
733 * If the NCI function was tailcalled, the return result
734 * is already passed back to the caller of this frame
735 * - see Parrot_init_ret_nci(). We therefore invoke the
736 * return continuation here, which gets rid of this frame
737 * and returns the real return address
8838c7f builtins 1 - first shot
Leopold Toetsch authored
738 */
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
739 if (cont && cont != NEED_CONTINUATION
740 && (PObj_get_FLAGS(cont) & SUB_FLAG_TAILCALL)) {
540d4c3 @bacek Merge context_pmc3 branch into trunk.
bacek authored
741 cont = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp));
92c390d Fix tailcalls to NCI, #38724
Leopold Toetsch authored
742 next = VTABLE_invoke(INTERP, cont, next);
743 }
82c7cf6 @chromatic [PMC] Minor cleanups and tidyings.
chromatic authored
744
e063e49 @chromatic Continuing Parrot/C++ cleanups (Steve Peters, RT #42746).
chromatic authored
745 return (opcode_t *)next;
2a2c19b Added in code to properly do native calls to library routines loaded via
Dan Sugalski authored
746 }
380c0ba fix NCI related DOD problem
Leopold Toetsch authored
747
c64e58f pmc docs update 3
Michael Scott authored
748 /*
749
750 =item C<INTVAL get_integer()>
751
752 Returns the function pointer as an integer.
753
754 =cut
755
756 */
757
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
758 VTABLE INTVAL get_integer() {
7723c62 @plobsing kill dead code
plobsing authored
759 // XXX: TODO
760 return 0;
3168931 Forth can now generate code for words on the fly and execute them.
Dan Sugalski authored
761 }
762
f35b03c @rubys Initial support for sort
rubys authored
763 /*
764
765 =item C<INTVAL get_bool()>
766
767 Returns the boolean value of the pointer.
768
769 =cut
770
771 */
772
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
773 VTABLE INTVAL get_bool() {
971e997 @NotFound rename pmc attributes struct from Parrot_<type> to Parrot_<type>_attribu...
NotFound authored
774 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
775 return (0 != (INTVAL)nci_info->cif);
f35b03c @rubys Initial support for sort
rubys authored
776 }
777
6586a2c @jnthn Implement arity method on NCI PMCs, plus a test for it.
jnthn authored
778 /*
779
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
780 =item C<METHOD arity()>
6586a2c @jnthn Implement arity method on NCI PMCs, plus a test for it.
jnthn authored
781
01e804c @Util [pmc] Typo corrections
Util authored
782 Return the arity of the NCI (the number of arguments).
6586a2c @jnthn Implement arity method on NCI PMCs, plus a test for it.
jnthn authored
783
784 =cut
785
786 */
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
787 METHOD arity() {
971e997 @NotFound rename pmc attributes struct from Parrot_<type> to Parrot_<type>_attribu...
NotFound authored
788 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
48d2796 @NotFound Another unreachable warning, codingstd in jit_emit ppc
NotFound authored
789 INTVAL arity = 0;
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
790
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
791 if (nci_info) {
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
792 if (!nci_info->cif) {
a90f6d7 @plobsing switch ffi nci.pmc over to standard signature parser
plobsing authored
793 build_libffi_func(interp, nci_info);
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
794 }
795 if (nci_info->cif) {
c64fa8d @plobsing split NCI signature parser out from nci.pmc
plobsing authored
796 arity = nci_info->arity;
797 RETURN(INTVAL arity);
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
798 }
799 }
6586a2c @jnthn Implement arity method on NCI PMCs, plus a test for it.
jnthn authored
800
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
801 Parrot_ex_throw_from_c_args(INTERP, NULL,
802 EXCEPTION_INVALID_OPERATION,
803 "You cannot get the arity of an undefined NCI.");
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
804 }
2a2c19b Added in code to properly do native calls to library routines loaded via
Dan Sugalski authored
805 }
c64e58f pmc docs update 3
Michael Scott authored
806
807 /*
808
809 =back
810
811 =head1 SEE ALSO
812
813 F<docs/pdds/pdd03_calling_conventions.pod>.
814
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
815 =head1 HISTORY
816
817 Initial revision by sean 2002/08/04.
818
819 Updates by John Harrison, Summer 2010, GSoC.
820
c64e58f pmc docs update 3
Michael Scott authored
821 =cut
822
823 */
824
0eb3eb3 added formatting footer and detabbed
Michael Scott authored
825 /*
826 * Local variables:
72575ae @bschmalhofer #40481: [PATCH] C-code coda in pmc files
bschmalhofer authored
827 * c-file-style: "parrot"
0eb3eb3 added formatting footer and detabbed
Michael Scott authored
828 * End:
829 * vim: expandtab shiftwidth=4:
72575ae @bschmalhofer #40481: [PATCH] C-code coda in pmc files
bschmalhofer authored
830 */
f631eb3 @plobsing remove private2 (raw) flag from nci-ffi.pmc
plobsing authored
831
Something went wrong with that request. Please try again.