Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 1504 lines (1232 sloc) 51.921 kb
c64e58f pmc docs update 3
Michael Scott authored
1 /*
e69d2a4 @petdance Made pcc_params be static. Removed unused arg from build_func. Header…
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
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison 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. Header…
petdance authored
26 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
27
28 PARROT_IGNORABLE_RESULT
29 static nci_thunk_t /*@alt void@*/
30 build_func(PARROT_INTERP,
31 ARGMOD(Parrot_NCI_attributes *nci_info))
32 __attribute__nonnull__(1)
33 __attribute__nonnull__(2)
34 FUNC_MODIFIES(*nci_info);
35
36 static void pcc_params(PARROT_INTERP,
37 ARGIN(STRING *sig),
38 ARGMOD(Parrot_NCI_attributes *nci_info),
39 size_t sig_length)
40 __attribute__nonnull__(1)
41 __attribute__nonnull__(2)
42 __attribute__nonnull__(3)
43 FUNC_MODIFIES(*nci_info);
44
45 #define ASSERT_ARGS_build_func __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
46 PARROT_ASSERT_ARG(interp) \
47 , PARROT_ASSERT_ARG(nci_info))
48 #define ASSERT_ARGS_pcc_params __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
49 PARROT_ASSERT_ARG(interp) \
50 , PARROT_ASSERT_ARG(sig) \
51 , PARROT_ASSERT_ARG(nci_info))
52 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
6bdd5f9 @petdance headerizer now runs on PMC files
petdance authored
53 /* HEADERIZER END: static */
54
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
55 static
56 INTVAL
57 parse_sig(PARROT_INTERP, STRING *sig, size_t sig_length, Parrot_NCI_attributes *nci_info);
58
59 static
60 size_t
61 parse_return(PARROT_INTERP, STRING* sig, size_t sig_length,
62 Parrot_NCI_attributes * nci_info, ffi_type **return_type);
63
64 static
65 size_t
66 parse_args(PARROT_INTERP, STRING* sig, size_t start, size_t sig_length,
67 Parrot_NCI_attributes *nci_info, ffi_type ***arg_types);
68
69 static
70 size_t
71 parse_identifier(PARROT_INTERP,
72 STRING* sig, size_t start, size_t end,
73 ffi_type** sig_obj,
74 char* pmc_type, size_t *pmc_count,
75 char* translation, size_t *translation_length);
76
77 static
78 size_t
79 parse_structure(PARROT_INTERP, STRING* sig, size_t start, size_t end,
80 ffi_type** sig_obj, char* pmc_type);
81
82 static
83 INTVAL
84 parse_prefix(INTVAL c);
85
86 static
87 size_t
88 structure_length(PARROT_INTERP, STRING* sig, size_t start, size_t end);
89
90 static
91 size_t
92 count_args(PARROT_INTERP, STRING* sig, size_t start, size_t end);
93
94 static
95 size_t
96 find_matching(PARROT_INTERP, STRING* sig, size_t start, size_t sig_length,
97 INTVAL start_character, INTVAL end_character);
98
99 #define IS_DIGIT(x) (((x) == '0') || ((x) == '1') || ((x) == '2') || ((x) == '3') \
100 || ((x) == '4') || ((x) == '5') || ((x) == '6') || ((x) == '7') \
101 || ((x) == '8') || ((x) == '9'))
102
103 #define IS_PREFIX(x) (((x) == '*') || ((x) == 'u'))
104
105 #define IS_OLD_TYPE(x) (((x) == 'P') || ((x) == 'J') || ((x) == 'N') || ((x) == 'S') \
106 || ((x) == 'O') || ((x) == '@') || ((x) == 'B') || ((x) == 'p') \
107 || ((x) == '2') || ((x) == '3') || ((x) == '4') || ((x) == 'U') \
108 || ((x) == 'V'))
109
110 #define IS_TYPE(x) (((x) == 'i') || ((x) == 'v') || ((x) == 'l') || ((x) == 't') \
111 || ((x) == 'c') || ((x) == 'b') || ((x) == 'f') || ((x) == 'd') \
112 || ((x) == 's') || IS_OLD_TYPE(x))
113
114 #define IS_POSTFIX(x) ((x) == '{') /* || IS_DIGIT(x)) */
115 #define IS_INFIX(x) ((x) == '|')
116 #define IS_START_CIRCUMFIX(x) ((x) == '(')
117 #define IS_END_CIRCUMFIX(x) ((x) == ')')
118 #define IS_NOT_END_CIRCUMFIX(x) ((x) != ')')
119
120 #define PREFIX_POINTER (1<<0)
121 #define PREFIX_SIGNED ( 0)
122 #define PREFIX_UNSIGNED (1<<1)
123 #define PREFIX_NATIVE (1<<2)
124
125 typedef struct pmc_holder_t {
126 PMC* p;
127 union {
128 INTVAL* ival;
129 void** pval;
130 };
131 } pmc_holder_t;
132
133 /*
134
135 =item C<static INTVAL parse_sig(PARROT_INTERP, STRING *sig,
136 size_t sig_length, Parrot_NCI_attributes *nci_info)>
137
138 Parse a full signature. All signatures should contain a return type and a list of
139 arguments. "vv" Would be the shortest "void fn(void)" signature you can legally make.
140
141 See C<parse_return> and C<parse_args> to see how the signature is broken down.
142
143 =cut
144
145 */
146
147 static INTVAL
148 parse_sig(PARROT_INTERP, STRING *sig, size_t sig_length, Parrot_NCI_attributes *nci_info) {
149 ffi_cif cif;
150 ffi_type *return_type;
151 ffi_type **arg_types;
152
153 if (sig_length) {
154 size_t i = parse_return(interp, sig, sig_length, nci_info, &return_type);
155 if (i < sig_length)
156 parse_args(interp, sig, i, sig_length, nci_info, &arg_types);
157 else {
158 arg_types = mem_internal_allocate_n_zeroed_typed(1, ffi_type*);
159 arg_types[0] = &ffi_type_void;
160 nci_info->pcc_params_signature = string_make(interp, "", 1, NULL, 0);
161 nci_info->arg_translation = NULL;
162 nci_info->arity = 0;
163 }
164 }
165 else {
166 arg_types = mem_internal_allocate_n_zeroed_typed(1, ffi_type*);
167 arg_types[0] = &ffi_type_void;
168 return_type = &ffi_type_void;
169 nci_info->pcc_params_signature = string_make(interp, "", 1, NULL, 0);
170 nci_info->arg_translation = NULL;
171 nci_info->arity = 0;
172 }
173
174 if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
175 nci_info->arity, return_type, arg_types) == FFI_OK) {
176 nci_info->cif = (void*)mem_internal_allocate_typed(ffi_cif);
177 memcpy(nci_info->cif, &cif, sizeof (ffi_cif));
178 nci_info->arg_types = arg_types;
179
180 return 1;
181 }
182
183 if (arg_types) {
184 mem_sys_free(arg_types);
185 }
186
187 /* TODO: Throw Error here. */
188 printf("Bad signature\n");
189
190 return 0;
191 }
192
193 /*
194
195 =item C<static size_t parse_return(PARROT_INTERP, STRING *sig, size_t sig_length,
196 Parrot_NCI_attributes* nci_info, ffi_type **return_type)>
197
198 Parses the return type. This assumes the first identifier is the return type.
199
200 See C<parse_identifier> to see how a single identifer is parsed.
201
202 =cut
203
204 */
205
206 static size_t
207 parse_return(PARROT_INTERP, STRING *sig, size_t sig_length,
208 Parrot_NCI_attributes* nci_info, ffi_type **return_type) {
209 char *t = mem_allocate_n_zeroed_typed(2, char);
210 size_t j = 0, k = 0;
211 /* Should be 1 character plus a NULL" */
212 char * result_sig = mem_allocate_n_zeroed_typed(2, char);
213 size_t result_length = parse_identifier(interp,
214 sig, 0, sig_length,
215 return_type,
216 result_sig, &j,
217 t, &k);
218
219 nci_info->pcc_return_signature = string_make(interp, result_sig, 2, NULL, 0);
220 nci_info->return_translation = (void*)t;
221 mem_sys_free(result_sig);
222 return result_length;
223 }
224
225 /*
226
227 =item C<static size_t parse_args(PARROT_INTERP, STRING* sig, size_t start, size_t sig_length,
228 Parrot_NCI_attributes *nci_info, ffi_type ***arg_types)>
229
230 Parses the signatures arguments. It takes an offset to know where to start looking.
231 This should fill out a list of C<ffi_type*> args.
232
233 See C<parse_identifier> to see how a single identifer is parsed.
234
235 =cut
236
237 */
238
239 static size_t
240 parse_args(PARROT_INTERP, STRING* sig, size_t start, size_t sig_length,
241 Parrot_NCI_attributes *nci_info, ffi_type ***arg_types) {
242 size_t i = start;
243 size_t arg_count = 0;
244 size_t argc = count_args(interp, sig, start, sig_length);
245 char* parrot_types = mem_allocate_n_zeroed_typed(argc + 1, char);
246 size_t parrot_types_length = 0;
247 char* translation_types = mem_allocate_n_zeroed_typed(argc + 1, char);
248 size_t translation_length = 0;
249
250 *arg_types = mem_internal_allocate_n_zeroed_typed(argc + 1, ffi_type*);
251
252 while (i < sig_length) {
253 ffi_type *ident;
254 i = parse_identifier(interp,
255 sig, i, sig_length,
256 &ident,
257 parrot_types, &parrot_types_length,
258 translation_types, &translation_length);
259 (*arg_types)[arg_count] = ident;
260 arg_count++;
261 }
262
263 nci_info->pcc_params_signature = string_make(interp, parrot_types,
264 strlen(parrot_types), NULL, 0);
265 nci_info->arg_translation = translation_types;
266 nci_info->arity = arg_count;
267
268 mem_sys_free(parrot_types);
269
270 return i;
271 }
272
273 /*
274
275 =item C<static size_t parse_identifier(PARROT_INTERP, STRING *sig, size_t start,
276 size_t sig_length, ffi_type **type_obj,
277 char **type, size_t *pmc_count,
278 char **translation, size_t *translation_count)>
279
280 Parse an identifier and build its representation used for PCC and any translations
281 that are needed.
282
283 An example of a transation is "t", it will take a STRING* and convert it to a
284 char* for the function call.
285
286 =cut
287
288 */
289
290 static size_t
291 parse_identifier(PARROT_INTERP,
292 STRING *sig, size_t start, size_t sig_length,
293 ffi_type **type_obj,
294 char *type, size_t *pmc_count,
295 char *translation, size_t *translation_count) {
296 size_t i = start;
297 INTVAL done = 0;
298
299 while (!done && i < sig_length) {
300 INTVAL c = Parrot_str_indexed(interp, sig, i);
301 int prefix = 0;
302 while (IS_PREFIX(c)) {
303 prefix |= parse_prefix(c);
304 i++;
305
306 if (i < sig_length)
307 c = Parrot_str_indexed(interp, sig, i);
308 else
309 return i;
310 }
311
312 if (IS_START_CIRCUMFIX(c)) {
313 i = parse_structure(interp, sig, i + 1, sig_length, type_obj, type);
314 i++;
315
316 if (i < sig_length)
317 c = Parrot_str_indexed(interp, sig, i);
318 else
319 return i;
320 }
321 else if (IS_TYPE(c)) {
322 if (prefix & PREFIX_POINTER) {
323 *type_obj = &ffi_type_pointer;
324 continue;
325 }
326 translation[(*translation_count)++] = ' ';
327 switch (c) {
328 case (INTVAL)' ':
329 case (INTVAL)'0': /* null ptr or such - doesn't consume a reg */
330 break;
331 case (INTVAL)'c':
332 translation[(*translation_count) - 1] = 'c';
333 type[(*pmc_count)++] = 'I';
334 if (prefix & PREFIX_UNSIGNED) {
335 *type_obj = &ffi_type_uchar;
336 }
337 else {
338 *type_obj = &ffi_type_schar;
339 }
340 break;
341 case (INTVAL)'B':
342 translation[(*translation_count) - 1] = 'B';
343 type[(*pmc_count)++] = 'S';
344 *type_obj = &ffi_type_pointer;
345 break;
346 case (INTVAL)'b':
347 translation[(*translation_count) - 1] = 'b';
348 type[(*pmc_count)++] = 'S';
349 *type_obj = &ffi_type_pointer;
350 break;
351 case (INTVAL)'s':
352 translation[(*translation_count) - 1] = 's';
353 type[(*pmc_count)++] = 'I';
354 if (prefix & PREFIX_UNSIGNED) {
355 *type_obj = &ffi_type_ushort;
356 }
357 else {
358 *type_obj = &ffi_type_sshort;
359 }
360 break;
361 case (INTVAL)'I': /* INTVAL */
362 case (INTVAL)'i':
363 translation[(*translation_count) - 1] = 'i';
364 type[(*pmc_count)++] = 'I';
365 if (prefix & PREFIX_UNSIGNED) {
366 *type_obj = &ffi_type_uint;
367 }
368 else {
369 *type_obj = &ffi_type_sint;
370 }
371 break;
372 case (INTVAL)'l':
373 translation[(*translation_count) - 1] = 'l';
374 type[(*pmc_count)++] = 'I';
375 if (prefix & PREFIX_UNSIGNED) {
376 *type_obj = &ffi_type_ulong;
377 }
378 else {
379 *type_obj = &ffi_type_slong;
380 }
381 break;
382 case (INTVAL)'q':
383 translation[(*translation_count) - 1] = 'q';
384 type[(*pmc_count)++] = 'I';
385 if (prefix & PREFIX_UNSIGNED) {
386 *type_obj = &ffi_type_uint64;
387 }
388 else {
389 *type_obj = &ffi_type_sint64;
390 }
391 break;
392 case (INTVAL)'J': /* interpreter */
393 translation[(*translation_count) - 1] = 'J';
394 *type_obj = &ffi_type_pointer;
395 break;
396 case (INTVAL)'p': /* push pmc->data */
397 translation[(*translation_count) - 1] = 'p';
398 type[(*pmc_count)++] = 'P';
399 *type_obj = &ffi_type_pointer;
400 break;
401 case (INTVAL)'2':
402 translation[(*translation_count) - 1] = '2';
403 type[(*pmc_count)++] = 'P';
404 *type_obj = &ffi_type_pointer;
405 break;
406 case (INTVAL)'3':
407 translation[(*translation_count) - 1] = '3';
408 type[(*pmc_count)++] = 'P';
409 *type_obj = &ffi_type_pointer;
410 break;
411 case (INTVAL)'4':
412 translation[(*translation_count) - 1] = '4';
413 type[(*pmc_count)++] = 'P';
414 *type_obj = &ffi_type_pointer;
415 break;
416 case (INTVAL)'P': /* push PMC * */
417 translation[(*translation_count) - 1] = 'P';
418 type[(*pmc_count)++] = 'P';
419 *type_obj = &ffi_type_pointer;
420 break;
421 case (INTVAL)'V': /* push PMC * */
422 translation[(*translation_count) - 1] = 'V';
423 type[(*pmc_count)++] = 'P';
424 *type_obj = &ffi_type_pointer;
425 break;
426 case (INTVAL)'S':
427 type[(*pmc_count)++] = 'S';
428 *type_obj = &ffi_type_pointer;
429 case (INTVAL)'t':
430 translation[(*translation_count) - 1] = 't';
431 type[(*pmc_count)++] = 'S';
432 *type_obj = &ffi_type_pointer;
433 break;
434 case (INTVAL)'v':
435 type[(*pmc_count)++] = 'v';
436 *type_obj = &ffi_type_void;
437 break;
438 #if (DOUBLE_SIZE == 4) /* FLOATVAL is a float */
439 case (INTVAL)'N':
440 #endif
441 case (INTVAL)'f':
442 translation[(*translation_count) - 1] = 'f';
443 type[(*pmc_count)++] = 'N';
444 *type_obj = &ffi_type_float;
445 break;
446 #if (DOUBLE_SIZE == 8) /* FLOATVAL is a double */
447 case (INTVAL)'N':
448 #endif
449 case (INTVAL)'d':
450 translation[(*translation_count) - 1] = 'd';
451 type[(*pmc_count)++] = 'N';
452 *type_obj = &ffi_type_double;
453 break;
454 #if (DOUBLE_SIZE > 8) /* FLOATVAL is a long double */
455 case (INTVAL)'N':
456 #endif
457 case (INTVAL)'D':
458 translation[(*translation_count) - 1] = 'D';
459 type[(*pmc_count)++] = 'N';
460 *type_obj = &ffi_type_longdouble;
461 break;
462 case (INTVAL)'O': /* push PMC * invocant */
463 *type_obj = &ffi_type_pointer;
464 type[(*pmc_count)++] = 'P';
465 type[(*pmc_count)++] = 'i';
466 break;
467 case (INTVAL)'@': /* push PMC * slurpy */
468 *type_obj = &ffi_type_pointer;
469 type[(*pmc_count)++] = 'P';
470 type[(*pmc_count)++] = 's';
471 break;
472 default:
473 Parrot_ex_throw_from_c_args(interp, NULL,
474 EXCEPTION_JIT_ERROR,
475 "Unknown param Signature %c\n", (char)c);
476 break;
477 }
478 i++;
479
480 if (i < sig_length)
481 c = Parrot_str_indexed(interp, sig, i);
482 else
483 return i;
484 }
485 else {
486 Parrot_ex_throw_from_c_args(interp, NULL,
487 EXCEPTION_JIT_ERROR,
488 "Unknown param Signature %c\n", (char)c);
489 }
490
491 /*
492 * Parse postfix ops
493 * TODO: Parse postfix ops, currently I skip them.
494 */
495 while (IS_POSTFIX(c)) {
496 i++;
497 if (i < sig_length)
498 c = Parrot_str_indexed(interp, sig, i);
499 else
500 return i;
501 }
502
503 if ((i < sig_length) && (c == (INTVAL)'|')) {
504 /* Its a union, parse it special. */
505 }
506 else {
507 done = 1;
508 }
509 }
510
511 return i;
512 }
513
514 /*
515
516 =item C<static INTVAL parse_prefix(INTVAL c)>
517
518 Parse a prefix character.
519
520 =cut
521
522 */
523
524 static INTVAL
525 parse_prefix(INTVAL c) {
526 switch (c) {
527 case '*':
528 return PREFIX_POINTER;
529 break;
530 case 'u':
531 return PREFIX_UNSIGNED;
532 break;
533 default:
534 return 0;
535 break;
536 }
537
538 return 0;
539 }
540
541 /*
542
543 =item C<static size_t parse_structure(PARROT_INTERP, STRING* sig, size_t start,
544 size_t sig_length, ffi_type **type_obj, char* pmc_type)>
545
546 Parses a stucture.
547 TODO: This should auto inflate to an UnmanagedStruct or a ManagedStruct in the future.
548
549 =cut
550
551 */
552
553 static size_t
554 parse_structure(PARROT_INTERP, STRING* sig, size_t start, size_t sig_length,
555 ffi_type **type_obj, char* pmc_type) {
556 size_t i = start;
557 size_t struct_len = structure_length(interp, sig, start, sig_length);
558 size_t element_counter = 0;
559 INTVAL c;
560
561 *type_obj = (ffi_type*)mem_internal_allocate_typed(ffi_type*);
562 (*type_obj)->elements = mem_internal_allocate_n_zeroed_typed(struct_len + 1, ffi_type*);
563
564 (*type_obj)->size = (*type_obj)->alignment = 0;
565 (*type_obj)->type = FFI_TYPE_STRUCT;
566
567 c = Parrot_str_indexed(interp, sig, i);
568 while (i < sig_length && IS_NOT_END_CIRCUMFIX(c)) {
569 i = parse_identifier(interp, sig, i, sig_length,
570 &(*type_obj)->elements[element_counter],
571 NULL, 0, NULL, 0);
572 element_counter++;
573 c = Parrot_str_indexed(interp, sig, i);
574 }
575
576 (*type_obj)->elements[struct_len] = NULL;
577
578 return i;
579 }
580
581 /*
582
583 =item C<static size_t structure_length(PARROT_INTERP, STRING* sig,
584 size_t start, size_t sig_length)>
585
586 Calculates the number of items in a stucture for size purposes.
587
588 =cut
589
590 */
591
592 static size_t
593 structure_length(PARROT_INTERP, STRING* sig, size_t start, size_t sig_length) {
594 size_t len = 0;
595 size_t i = start;
596 INTVAL depth = 0;
597 INTVAL c = Parrot_str_indexed(interp, sig, i);
598 while (i < sig_length && depth != -1) {
599 if (IS_START_CIRCUMFIX(c)) depth++;
600 else if (IS_END_CIRCUMFIX(c)) depth--;
601 else if (depth == 0 && (IS_TYPE(c))) len++;
602 i++;
603 c = Parrot_str_indexed(interp, sig, i);
604 }
605
606 return len;
607 }
608
609 /*
610
611 =item C<static size_t find_matching(PARROT_INTERP, STRING* sig, size_t start,
612 size_t sig_length, INTVAL start_character, INTVAL end_character)>
613
614 Find matching symbols, used for finding the start and stop of a stucture, it is
615 also recursive to handle structures inside of structures.
616
617 =cut
618
619 */
620
621 static size_t
622 find_matching(PARROT_INTERP, STRING* sig, size_t start, size_t sig_length,
623 INTVAL start_character, INTVAL end_character) {
624 size_t i = start;
625 INTVAL c = Parrot_str_indexed(interp, sig, i);
626 while (i < sig_length && c != end_character) {
627 if (c == start_character)
628 i = find_matching(interp, sig, i, sig_length, start_character, end_character);
629 i++;
630 c = Parrot_str_indexed(interp, sig, i);
631 }
632
633 return i;
634 }
635
636 /*
637
638 =item C<size_t count_args(PARROT_INTERP, STRING* sig, size_t start, size_t sig_length)>
639
640 Counts the number of arguments from a given starting point. It only counts
641 identiers, not prefix, infix or postfix modifiers. Structures are considered as
642 1 item in most cases.
643
644 =cut
645
646 */
647
648 static size_t
649 count_args(PARROT_INTERP, STRING* sig, size_t start, size_t sig_length) {
650 size_t length = 0;
651 size_t i = start;
652
653 while (i < sig_length) {
654 const INTVAL c = Parrot_str_indexed(interp, sig, i);
655 if (IS_START_CIRCUMFIX(c)) {
656 i = find_matching(interp, sig, i + 1, sig_length, '(', ')');
657 length++;
658 }
659 else if (IS_TYPE(c)) {
660 length++;
661 }
662 i++;
663 }
664
665 return length;
666 }
e69d2a4 @petdance Made pcc_params be static. Removed unused arg from build_func. Header…
petdance authored
667
668 static void
669 pcc_params(PARROT_INTERP, ARGIN(STRING *sig), ARGMOD(Parrot_NCI_attributes *nci_info),
6bdd5f9 @petdance headerizer now runs on PMC files
petdance authored
670 size_t sig_length)
671 {
4d774df @mikehh fix codetest failure - assert args - src/pmc/nci.pmc
mikehh authored
672 ASSERT_ARGS(pcc_params)
673
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param an…
plobsing authored
674 /* NCI and PCC have a 1 to 1 mapping except an
675 extra char in PCC for invocant and slurpy */
7e3583b @plobsing c89 conformance
plobsing authored
676 size_t buf_length = sig_length + 2 + 1;
677
678 /* avoid malloc churn on common signatures */
679 char static_buf[16];
680 char * const sig_buf = sig_length <= sizeof static_buf ?
681 static_buf :
dee1dcb @NotFound c++ conformance
NotFound authored
682 (char *)mem_sys_allocate(buf_length);
7e3583b @plobsing c89 conformance
plobsing authored
683
684 size_t j = 0;
685 size_t i;
c99ac3c @chromatic [PMC] Avoided some relatively expensive C string conversions and mall…
chromatic authored
686
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param an…
plobsing authored
687 for (i = 0; i < sig_length; ++i) {
e69d2a4 @petdance Made pcc_params be static. Removed unused arg from build_func. Header…
petdance authored
688 const INTVAL c = Parrot_str_indexed(interp, sig, i);
c99ac3c @chromatic [PMC] Avoided some relatively expensive C string conversions and mall…
chromatic authored
689
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param an…
plobsing authored
690 PARROT_ASSERT(j < buf_length - 1);
691
c99ac3c @chromatic [PMC] Avoided some relatively expensive C string conversions and mall…
chromatic authored
692 switch (c) {
8a70f13 @fperrad [cage] improve C indentation, see TT #1329
fperrad authored
693 case (INTVAL)'0': /* null ptr or such - doesn't consume a reg */
694 break;
695 case (INTVAL)'f':
696 case (INTVAL)'N':
697 case (INTVAL)'d':
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param an…
plobsing authored
698 sig_buf[j++] = 'N';
8a70f13 @fperrad [cage] improve C indentation, see TT #1329
fperrad authored
699 break;
700 case (INTVAL)'I': /* INTVAL */
701 case (INTVAL)'l': /* long */
702 case (INTVAL)'i': /* int */
703 case (INTVAL)'s': /* short */
704 case (INTVAL)'c': /* char */
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param an…
plobsing authored
705 sig_buf[j++] = 'I';
8a70f13 @fperrad [cage] improve C indentation, see TT #1329
fperrad authored
706 break;
707 case (INTVAL)'S':
708 case (INTVAL)'t': /* string, pass a cstring */
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param an…
plobsing authored
709 sig_buf[j++] = 'S';
8a70f13 @fperrad [cage] improve C indentation, see TT #1329
fperrad authored
710 break;
711 case (INTVAL)'J': /* interpreter */
712 break;
713 case (INTVAL)'p': /* push pmc->data */
714 case (INTVAL)'P': /* push PMC * */
715 case (INTVAL)'V': /* push PMC * */
716 case (INTVAL)'2':
717 case (INTVAL)'3':
718 case (INTVAL)'4':
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param an…
plobsing authored
719 sig_buf[j++] = 'P';
720 break;
721 case (INTVAL)'v':
722 /* null return */
723 if (j == 0)
724 sig_buf[j++] = '\0';
725 break;
726 case (INTVAL)'O': /* push PMC * invocant */
727 sig_buf[j++] = 'P';
728 sig_buf[j++] = 'i';
8a70f13 @fperrad [cage] improve C indentation, see TT #1329
fperrad authored
729 break;
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param an…
plobsing authored
730 case (INTVAL)'@': /* push PMC * slurpy */
731 sig_buf[j++] = 'P';
732 sig_buf[j++] = 's';
8a70f13 @fperrad [cage] improve C indentation, see TT #1329
fperrad authored
733 break;
734 case (INTVAL)'b': /* buffer (void*) pass Buffer_bufstart(SReg) */
735 case (INTVAL)'B': /* buffer (void**) pass &Buffer_bufstart(SReg) */
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param an…
plobsing authored
736 sig_buf[j++] = 'S';
8a70f13 @fperrad [cage] improve C indentation, see TT #1329
fperrad authored
737 break;
738 default:
739 Parrot_ex_throw_from_c_args(interp, NULL,
c99ac3c @chromatic [PMC] Avoided some relatively expensive C string conversions and mall…
chromatic authored
740 EXCEPTION_JIT_ERROR,
741 "Unknown param Signature %c\n", (char)c);
8a70f13 @fperrad [cage] improve C indentation, see TT #1329
fperrad authored
742 break;
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
743 }
c99ac3c @chromatic [PMC] Avoided some relatively expensive C string conversions and mall…
chromatic authored
744 }
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
745
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param an…
plobsing authored
746 PARROT_ASSERT(j < buf_length);
747 sig_buf[j++] = '\0';
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
748
c99ac3c @chromatic [PMC] Avoided some relatively expensive C string conversions and mall…
chromatic authored
749
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param an…
plobsing authored
750 nci_info->pcc_return_signature =
751 Parrot_str_new(interp, sig_buf, 1);
752
753 nci_info->pcc_params_signature = j ?
754 Parrot_str_new(interp, sig_buf + 1, j - 1) :
755 CONST_STRING(interp, "");
7e3583b @plobsing c89 conformance
plobsing authored
756
757 if (sig_buf != static_buf)
758 mem_sys_free(sig_buf);
c99ac3c @chromatic [PMC] Avoided some relatively expensive C string conversions and mall…
chromatic authored
759 }
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
760
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
761 PARROT_IGNORABLE_RESULT
762 static ffi_cif*
763 build_libffi_func(PARROT_INTERP, ARGMOD(Parrot_NCI_attributes *nci_info))
764 {
765 ASSERT_ARGS(build_func)
766
767 STRING * const key = nci_info->signature;
768 const size_t key_length = Parrot_str_byte_length(interp, key);
769
770 INTVAL r = parse_sig(interp, nci_info->signature, key_length, nci_info);
771
772 return (ffi_cif*)nci_info->cif;
773 }
774
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
775 /* actually build the NCI thunk */
776
e69d2a4 @petdance Made pcc_params be static. Removed unused arg from build_func. Header…
petdance authored
777 PARROT_IGNORABLE_RESULT
778 static nci_thunk_t
779 build_func(PARROT_INTERP, ARGMOD(Parrot_NCI_attributes *nci_info))
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
780 {
4d774df @mikehh fix codetest failure - assert args - src/pmc/nci.pmc
mikehh authored
781 ASSERT_ARGS(build_func)
782
e69d2a4 @petdance Made pcc_params be static. Removed unused arg from build_func. Header…
petdance authored
783 STRING * const key = nci_info->signature;
784 const size_t key_length = Parrot_str_byte_length(interp, key);
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
785
786 pcc_params(interp, key, nci_info, key_length);
787
788 /* Arity is length of that string minus one (the return type). */
789 nci_info->arity = key_length - 1;
790
791 /* Build call function. */
3b094c7 @plobsing add NCI.fb_info for frame buffer info
plobsing authored
792 nci_info->fb_info = build_call_func(interp, key);
793 nci_info->func = F2DPTR(VTABLE_get_pointer(interp, nci_info->fb_info));
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
794
1cdfa9b @plobsing nci_sub_t => nci_thunk_t and moves to header file
plobsing authored
795 return (nci_thunk_t)nci_info->func;
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
796 }
797
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
798
336b07c @bacek Add 'does invokable' to all PMCs with VTABLE_invoke (except Object). …
bacek authored
799 pmclass NCI auto_attrs provides invokable {
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param an…
plobsing authored
800 /* NCI thunk handling attributes */
762a0f2 @bacek Merge branch 'ops_pct' back to trunk.
bacek authored
801 /* NCI thunk handling attributes */
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
802 ATTR STRING *signature; /* The signature. */
9ed2bdc @chromatic [MMD] Changed MULTI initialization to delay generating type typles of…
chromatic authored
803 ATTR void *func; /* Function pointer to call. */
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
804 ATTR void *orig_func;
3b094c7 @plobsing add NCI.fb_info for frame buffer info
plobsing authored
805 ATTR PMC *fb_info; /* Frame-builder info */
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
806 ATTR void *cif; /* Function interface */
807 ATTR void *arg_types; /* Used for building the libffi call interface */
808
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param an…
plobsing authored
809 /* Parrot Sub-ish attributes */
810 ATTR STRING *pcc_params_signature;
811 ATTR STRING *pcc_return_signature;
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
812 ATTR void *arg_translation;
813 ATTR void *return_translation;
9d723e0 @plobsing update NCI signature parsing to emit new (half year old) PCC param an…
plobsing authored
814 ATTR INTVAL arity; /* Cached arity of the NCI. */
815
816 /* MMD fields */
9ed2bdc @chromatic [MMD] Changed MULTI initialization to delay generating type typles of…
chromatic authored
817 ATTR STRING *long_signature; /* The full signature. */
818 ATTR PMC *multi_sig; /* type tuple array (?) */
2a2c19b Added in code to properly do native calls to library routines loaded via
Dan Sugalski authored
819
c64e58f pmc docs update 3
Michael Scott authored
820 /*
821
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
822 =item C<METHOD get_multisig()>
1415cda add introspection method get_multisig
Leopold Toetsch authored
823
824 Return the MMD signature PMC, if any or a Null PMC.
825
826 =cut
827
828 */
829
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
830 METHOD get_multisig() {
26f7d7b @cotto [PMC] replace PMC_pmc_val with an ATTR in the NCI PMC
cotto authored
831 PMC *sig;
832 GET_ATTR_multi_sig(INTERP, SELF, sig);
83dd9f2 @NotFound [core] partial fix for TT #667, examples/namespace/namespace_dump.pi…
NotFound authored
833 if (PMC_IS_NULL(sig))
26f7d7b @cotto [PMC] replace PMC_pmc_val with an ATTR in the NCI PMC
cotto authored
834 sig = PMCNULL;
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
835 RETURN(PMC *sig);
1415cda add introspection method get_multisig
Leopold Toetsch authored
836 }
837
838 /*
839
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
840 =item C<METHOD set_raw_nci_ptr(void *func)>
d1c84dd @tewk [IMCC] added full calling conventions to C PMC methods.
tewk authored
841
842 Sets the specified function pointer and raw flag.
843
844 =cut
845
846 */
847
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
848 METHOD make_raw_nci(PMC *func) {
849 VTABLE_set_pointer(interp, SELF, (void *)func);
d1c84dd @tewk [IMCC] added full calling conventions to C PMC methods.
tewk authored
850 }
851
852 /*
853
c64e58f pmc docs update 3
Michael Scott authored
854 =item C<void init()>
855
856 Initializes the NCI with a C<NULL> function pointer.
857
858 =cut
859
860 */
861
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
862 VTABLE void init() {
637246f @jnthn Refactor the NCI PMC to have an underlying structure, in preparation …
jnthn authored
863 /* Mark that we're not a raw NCI. */
d1c84dd @tewk [IMCC] added full calling conventions to C PMC methods.
tewk authored
864 PObj_flag_CLEAR(private2, SELF);
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
865 PObj_custom_mark_SET(SELF);
f7fc86b nci
Leopold Toetsch authored
866 }
867
c64e58f pmc docs update 3
Michael Scott authored
868 /*
869
380c0ba fix NCI related DOD problem
Leopold Toetsch authored
870 =item C<void set_pointer_keyed_str(STRING *key, void *func)>
c64e58f pmc docs update 3
Michael Scott authored
871
380c0ba fix NCI related DOD problem
Leopold Toetsch authored
872 Sets the specified function pointer and signature (C<*key>).
c64e58f pmc docs update 3
Michael Scott authored
873
874 =cut
875
876 */
877
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
878 VTABLE void set_pointer(void *ptr) {
811a7df @cotto [PMC] make NCI PMCs use ATTRs, with one temporary workaround for i386…
cotto authored
879 SET_ATTR_orig_func(INTERP, SELF, ptr);
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
880 PObj_flag_SET(private2, SELF);
881 }
882
4108fd8 @cotto [JIT] remove undocumented dependency of jit code on PMC internals, fi…
cotto authored
883 VTABLE void *get_pointer() {
884 return PARROT_NCI(SELF)->orig_func;
885 }
886
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
887 VTABLE void set_pointer_keyed_str(STRING *key, void *func) {
1764f4c @chromatic [PMC] Optimized NCI registration signature handling slightly by avoiding
chromatic authored
888 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
637246f @jnthn Refactor the NCI PMC to have an underlying structure, in preparation …
jnthn authored
889
62e3049 @petdance consting, and fixed embedded tabs
petdance authored
890 /* Store the original function and signature. */
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
891 SET_ATTR_func(INTERP, SELF, func);
c4cd281 @chromatic [PMC] Avoided an unnecessary STRING copying and creation in NCI's
chromatic authored
892
893 /* ensure that the STRING signature is constant */
894 if (!PObj_constant_TEST(key)) {
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
895 char * const key_c = Parrot_str_to_cstring(INTERP, key);
e69d2a4 @petdance Made pcc_params be static. Removed unused arg from build_func. Header…
petdance authored
896 const size_t key_length = Parrot_str_byte_length(interp, key);
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
897 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
898 Parrot_str_free_cstring(key_c);
899 }
900
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
901 nci_info->signature = key;
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
902 }
03918bc @chromatic [PMC] Fixed a read of unitialized memory in NCI PMC reported by Valgr…
chromatic authored
903
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
904 /*
905
906 =item C<void mark()>
907
908 Mark any referenced strings and PMCs.
909
910 =cut
911
912 */
913 VTABLE void mark() {
914 if (PARROT_NCI(SELF)) {
971e997 @NotFound rename pmc attributes struct from Parrot_<type> to Parrot_<type>_attr…
NotFound authored
915 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
916
3b094c7 @plobsing add NCI.fb_info for frame buffer info
plobsing authored
917 Parrot_gc_mark_PMC_alive(interp, nci_info->fb_info);
18dd147 @NotFound [gc] add new mark_... _alive functions, use it in a lot of mark vtabl…
NotFound authored
918 Parrot_gc_mark_STRING_alive(interp, nci_info->signature);
919 Parrot_gc_mark_STRING_alive(interp, nci_info->pcc_params_signature);
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
920 Parrot_gc_mark_STRING_alive(interp, nci_info->pcc_return_signature);
18dd147 @NotFound [gc] add new mark_... _alive functions, use it in a lot of mark vtabl…
NotFound authored
921 Parrot_gc_mark_STRING_alive(interp, nci_info->long_signature);
922 Parrot_gc_mark_PMC_alive(interp, nci_info->multi_sig);
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
923 }
65bd9bf eval #1
Leopold Toetsch authored
924 }
11b723d fixed memory leak in jitted i386 nci code; clone nci
Leopold Toetsch authored
925
c64e58f pmc docs update 3
Michael Scott authored
926 /*
927
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
928 =item C<void destroy()>
929
930 Free all of the memory used internally to store various things, like libffi call signatures.
931
932 =cut
933
934 */
935
936 VTABLE void destroy() {
937 if (PARROT_NCI(SELF)) {
938 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
939 mem_sys_free(nci_info->cif);
940 mem_sys_free(nci_info->arg_translation);
941 mem_sys_free(nci_info->arg_types);
942 mem_sys_free(nci_info->return_translation);
943 }
944 }
945
946
947 /*
948
c64e58f pmc docs update 3
Michael Scott authored
949 =item C<PMC *clone()>
950
951 Creates and returns a clone of the NCI.
952
953 =cut
954
955 */
956
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
957 VTABLE PMC *clone() {
971e997 @NotFound rename pmc attributes struct from Parrot_<type> to Parrot_<type>_attr…
NotFound authored
958 Parrot_NCI_attributes * const nci_info_self = PARROT_NCI(SELF);
959 Parrot_NCI_attributes *nci_info_ret;
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
960 void *cif;
62e3049 @petdance consting, and fixed embedded tabs
petdance authored
961
083213a @Whiteknight start rename of pmc_new to Parrot_pmc_new
Whiteknight authored
962 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
963 nci_info_ret = PARROT_NCI(ret);
82c7cf6 @chromatic [PMC] Minor cleanups and tidyings.
chromatic authored
964
c64e58f pmc docs update 3
Michael Scott authored
965 /* FIXME if data is malloced (JIT/i386!) then we need
966 * the length of data here, to memcpy it
967 * ManagedStruct or Buffer?
968 */
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
969 nci_info_ret->func = nci_info_self->func;
3b094c7 @plobsing add NCI.fb_info for frame buffer info
plobsing authored
970 nci_info_ret->fb_info = nci_info_self->fb_info;
811a7df @cotto [PMC] make NCI PMCs use ATTRs, with one temporary workaround for i386…
cotto authored
971 nci_info_ret->orig_func = nci_info_self->orig_func;
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
972 nci_info_ret->cif = nci_info_self->cif;
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
973 nci_info_ret->signature = nci_info_self->signature;
974 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 an…
plobsing authored
975 nci_info_ret->pcc_return_signature = nci_info_self->pcc_params_signature;
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
976 nci_info_ret->arity = nci_info_self->arity;
4108fd8 @cotto [JIT] remove undocumented dependency of jit code on PMC internals, fi…
cotto authored
977 PObj_get_FLAGS(ret) |= (PObj_get_FLAGS(SELF) & 0x7);
82c7cf6 @chromatic [PMC] Minor cleanups and tidyings.
chromatic authored
978
c64e58f pmc docs update 3
Michael Scott authored
979 return ret;
2a2c19b Added in code to properly do native calls to library routines loaded via
Dan Sugalski authored
980 }
981
c64e58f pmc docs update 3
Michael Scott authored
982 /*
983
984 =item C<INTVAL defined()>
985
986 Returns whether the NCI is defined.
987
988 =cut
989
990 */
991
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
992 VTABLE INTVAL defined() {
971e997 @NotFound rename pmc attributes struct from Parrot_<type> to Parrot_<type>_attr…
NotFound authored
993 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
994 return nci_info->orig_func != NULL;
2a2c19b Added in code to properly do native calls to library routines loaded via
Dan Sugalski authored
995 }
996
c64e58f pmc docs update 3
Michael Scott authored
997 /*
998
0ae5d55 @paultcochrane Patch courtesy of Steve Peters <steve at fisharerojo dot org>, his co…
paultcochrane authored
999 =item C<opcode_t *invoke(void *next)>
c64e58f pmc docs update 3
Michael Scott authored
1000
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
1001 Calls the associated C function, returning C<*next>. If the invocant is a
1002 class, the PMC arguments are shifted down.
c64e58f pmc docs update 3
Michael Scott authored
1003
1004 =cut
1005
1006 */
1007
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
1008 VTABLE opcode_t *invoke(void *next) {
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
1009 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
bbd8ef4 @cotto [strings] first of many patches from darbelo++ getting rid of ->strst…
cotto authored
1010 char *sig_str;
811a7df @cotto [PMC] make NCI PMCs use ATTRs, with one temporary workaround for i386…
cotto authored
1011 PMC *cont;
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
1012 INTVAL return_size = sizeof (void*);
1013 PMC *ctx = CURRENT_CONTEXT(interp);
1014 PMC *call_object = Parrot_pcc_get_signature(interp, ctx);
1015 void (*func)(void*,void*,void*); /* a function pointer for our function to call */
1016
1017 if (PObj_flag_TEST(private2, SELF)) {
1018 void *orig_func;
1019 PMC *fb_info;
1020 GET_ATTR_orig_func(INTERP, SELF, orig_func);
1021 GET_ATTR_fb_info(INTERP, SELF, fb_info);
1022
1023 func = (void (*)(void*, void*, void*))orig_func;
1024
1025 if (!func) {
1026 /* build the thunk only when necessary */
1027 func = (void (*)(void*, void*, void*))build_func(interp, nci_info);
1028
1029 if (!func)
1030 Parrot_ex_throw_from_c_args(INTERP, NULL,
1031 EXCEPTION_INVALID_OPERATION,
1032 "attempt to call NULL function");
1033 }
82c7cf6 @chromatic [PMC] Minor cleanups and tidyings.
chromatic authored
1034
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
1035 func = (void (*)(void*, void*, void*))(orig_func);
1036 func(INTERP, SELF, fb_info);
1037 }
1038 else {
1039 PMC *positional, *arg_iter;
1040 STRING *void_return;
1041 void **values, **middle_man = NULL, **pcc_ptr, **translation_pointers = NULL, **pcc_val = NULL;
1042 void *return_data;
1043 size_t count, i, j_offset;
1044 char *tmp_sig;
1045 ffi_cif *cif, pcc_cif;
1046 ffi_type **pcc_args;
1047
1048 cif = (ffi_cif*)nci_info->cif;
1049 func = (void (*)(void*, void*, void*))nci_info->func;
1050
1051 if (!cif) {
1052 /* build the thunk only when necessary */
1053 cif = build_libffi_func(interp, nci_info);
1054
1055 if (!cif && !func)
1056 Parrot_ex_throw_from_c_args(INTERP, NULL,
1057 EXCEPTION_INVALID_OPERATION,
1058
1059 "attempt to call NULL function");
1060 }
82c7cf6 @chromatic [PMC] Minor cleanups and tidyings.
chromatic authored
1061
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
1062 if (nci_info->arity > 0) {
1063 size_t pcc_argc, pcc_values_offset, pcc_values_size, values_size;
1064 /* Function has arguments */
1065 pcc_args = mem_internal_allocate_n_zeroed_typed(nci_info->arity + 4, ffi_type*);
1066 tmp_sig = Parrot_str_to_cstring(interp, nci_info->pcc_params_signature);
1067
1068 pcc_args[0] = &ffi_type_pointer;
1069 pcc_args[1] = &ffi_type_pointer;
1070 pcc_args[2] = &ffi_type_pointer;
1071 pcc_values_size = 0;
1072 values_size = 0;
1073 pcc_argc = Parrot_str_length(interp, nci_info->pcc_params_signature);
1074
1075 /* Add up the size of memory needed for the actual call */
1076 for (i = 0; i < (size_t)nci_info->arity; i++) {
1077 values_size += cif->arg_types[i]->size;
1078 }
1079
1080 pcc_ptr = (void**)mem_internal_allocate_n_zeroed_typed(pcc_argc + 4, void*);
1081
1082 /* Setup Parrot_pcc_fill_params_from_c_args required arguments */
1083 pcc_ptr[0] = &interp;
1084 pcc_ptr[1] = &call_object;
1085 pcc_ptr[2] = &tmp_sig;
1086
1087 pcc_val = (void**)mem_internal_allocate_n_zeroed_typed(pcc_argc, void*);
1088 values = (void**)mem_internal_allocate_zeroed(values_size + sizeof(void*));
1089 /* Middle man is used to contain */
1090 middle_man = mem_internal_allocate_n_zeroed_typed(nci_info->arity, void*);
1091
1092 /* Add up the size of the pcc arguments */
1093 for (i = 0; i < pcc_argc; i++) {
1094 pcc_args[i + 3] = &ffi_type_pointer;
1095 if (tmp_sig[i] == 'N') {
1096 pcc_val[i] = malloc(sizeof(FLOATVAL));
1097 pcc_ptr[i+3] = &pcc_val[i];
1098 }
1099 else if (tmp_sig[i] == 'I') {
1100 pcc_val[i] = malloc(sizeof(INTVAL));
1101 pcc_ptr[i+3] = &pcc_val[i];
1102 }
1103 else if (tmp_sig[i] == 'P' || tmp_sig[i] == 'S') {
1104 pcc_val[i] = malloc(sizeof(void*));
1105 pcc_ptr[i+3] = &pcc_val[i];
1106 }
1107 }
1108
1109 if (ffi_prep_cif(&pcc_cif, FFI_DEFAULT_ABI, 3 + pcc_argc,
1110 &ffi_type_void, pcc_args) != FFI_OK) {
1111 Parrot_ex_throw_from_c_args(INTERP, NULL,
1112 EXCEPTION_INVALID_OPERATION,
1113 "Bad signature generated for Parrot_pcc_fill_params_from_c_args in NCI");
1114 }
1115
1116 ffi_call(&pcc_cif, FFI_FN(Parrot_pcc_fill_params_from_c_args), NULL, pcc_ptr);
1117
1118 Parrot_str_free_cstring(tmp_sig);
1119
1120 /*
1121 * Apply Argument Transformations
1122 * this is mostly to transform STRING* into char*
1123 * and add the parrot interp argument if it needs it
1124 * but other transformations might apply later, like packing an
1125 * object into a ManagedStruct
1126 */
1127 j_offset = 0;
1128 translation_pointers = mem_internal_allocate_n_zeroed_typed(nci_info->arity, void*);
1129 for (i = 0; i < (size_t)nci_info->arity; i++) {
1130 switch ((INTVAL)((char*)nci_info->arg_translation)[i]) {
1131 case 'J':
1132 values[i] = &interp;
1133 j_offset++;
1134 break;
1135 case 't':
1136 if (STRING_IS_NULL(*(STRING**)pcc_val[i - j_offset])) {
1137 translation_pointers[i] = (char*) NULL;
1138 }
1139 else {
1140 translation_pointers[i] = Parrot_str_to_cstring(interp, *(STRING**)pcc_val[i - j_offset]);
1141 }
1142 values[i] = &translation_pointers[i];
1143 break;
1144 case 'B':
1145 if (STRING_IS_NULL(*(STRING**)pcc_val[i - j_offset])) {
1146 translation_pointers[i] = (char*) NULL;
1147 }
1148 else {
1149 translation_pointers[i] = Parrot_str_to_cstring(interp, *(STRING**)pcc_val[i - j_offset]);
1150 }
1151 middle_man[i] = &translation_pointers[i];
1152 values[i] = &middle_man[i];
1153 break;
1154 case 'b':
1155 values[i] = &Buffer_bufstart(*(STRING**)pcc_val[i - j_offset]);
1156 break;
1157 case 'c':
1158 translation_pointers[i] = mem_internal_allocate_zeroed_typed(char);
1159 *((char**)translation_pointers)[i] = (char)*(INTVAL*)pcc_val[i - j_offset];
1160 values[i] = translation_pointers[i];
1161 break;
1162 case '2':
1163 translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
1164 ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)pcc_val[i - j_offset];
1165 ((pmc_holder_t*)translation_pointers[i])->ival = (INTVAL*)mem_internal_allocate_zeroed_typed(short);
1166 *((pmc_holder_t*)translation_pointers[i])->ival = (short)VTABLE_get_integer(interp, *(PMC**)pcc_ptr[i - j_offset]);
1167 values[i] = &((pmc_holder_t*)translation_pointers[i])->ival;
1168 break;
1169 case 's':
1170 translation_pointers[i] = mem_internal_allocate_zeroed_typed(short);
1171 *((short**)translation_pointers)[i] = (short)*(INTVAL*)pcc_val[i - j_offset];
1172 values[i] = translation_pointers[i];
1173 break;
1174 case '3':
1175 translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
1176 ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)pcc_val[i - j_offset];
1177 ((pmc_holder_t*)translation_pointers[i])->ival = (INTVAL*)mem_internal_allocate_zeroed_typed(int);
1178 *((pmc_holder_t*)translation_pointers[i])->ival = (int)VTABLE_get_integer(interp, *(PMC**)pcc_val[i - j_offset]);
1179 values[i] = &((pmc_holder_t*)translation_pointers[i])->ival;
1180 break;
1181 case 'i':
1182 translation_pointers[i] = mem_internal_allocate_zeroed_typed(int);
1183 *((int**)translation_pointers)[i] = (int)*(INTVAL*)pcc_val[i - j_offset];
1184 values[i] = translation_pointers[i];
1185 break;
1186 case '4':
1187 translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
1188 ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)pcc_val[i - j_offset];
1189 ((pmc_holder_t*)translation_pointers[i])->ival = (INTVAL*)mem_internal_allocate_zeroed_typed(long);
1190 *((pmc_holder_t*)translation_pointers[i])->ival = (long)VTABLE_get_integer(interp, *(PMC**)pcc_val[i - j_offset]);
1191 values[i] = &((pmc_holder_t*)translation_pointers[i])->ival;
1192 break;
1193 case 'l':
1194 translation_pointers[i] = mem_internal_allocate_zeroed_typed(long);
1195 *((long**)translation_pointers)[i] = (long)*(INTVAL*)pcc_val[i - j_offset];
1196 values[i] = translation_pointers[i];
1197 break;
1198 case 'q':
1199 translation_pointers[i] = mem_internal_allocate_zeroed_typed(long long);
1200 *((long long**)translation_pointers)[i] = (long long)*(INTVAL*)pcc_val[i - j_offset];
1201 values[i] = translation_pointers[i];
1202 break;
1203 case 'V':
1204 translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
1205 ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)pcc_val[i - j_offset];
1206 ((pmc_holder_t*)translation_pointers[i])->pval = (void**)mem_internal_allocate_zeroed_typed(void*);
1207 *((pmc_holder_t*)translation_pointers[i])->pval = PMC_IS_NULL(*(PMC**)pcc_val[i - j_offset]) ?
1208 (void *)NULL : (void*)VTABLE_get_pointer(interp, *(PMC**)pcc_val[i - j_offset]);
1209 values[i] = &((pmc_holder_t*)translation_pointers[i])->pval;
1210 break;
1211 case 'P':
1212 translation_pointers[i] = *(PMC**)pcc_val[i - j_offset];
1213 values[i] = &translation_pointers[i];
1214 break;
1215 case 'p':
1216 translation_pointers[i] = PMC_IS_NULL(*(PMC**)pcc_val[i - j_offset]) ?
1217 (void *)NULL : VTABLE_get_pointer(interp, *(PMC**)pcc_val[i - j_offset]);
1218 values[i] = &translation_pointers[i];
1219 break;
1220 case 'f':
1221 translation_pointers[i] = mem_internal_allocate_zeroed_typed(float);
1222 *((float**)translation_pointers)[i] = (float)*(FLOATVAL*)pcc_val[i - j_offset];
1223 values[i] = translation_pointers[i];
1224 break;
1225 case 'd':
1226 translation_pointers[i] = mem_internal_allocate_zeroed_typed(double);
1227 *((double**)translation_pointers)[i] = *(FLOATVAL*)pcc_val[i - j_offset];
1228 values[i] = translation_pointers[i];
1229 break;
1230 case ' ':
1231 default:
1232 break;
1233 }
1234 }
1235
1236 if (pcc_args) {
1237 mem_sys_free(pcc_args);
1238 }
1239 if (pcc_ptr) {
1240 mem_sys_free(pcc_ptr);
1241 }
1242 if (pcc_val) {
1243 for (i = 0; i < pcc_argc; i++) {
1244 mem_sys_free(pcc_val[i]);
1245 }
1246 mem_sys_free(pcc_val);
1247 }
1248 }
1249 else {
1250 /* No arguments */
1251 values = NULL;
1252 }
158fbfa @plobsing add fb_info parameter to nci_thunk_t signature
plobsing authored
1253
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
1254 /*
1255 * This will allow for any type of datat to be returned.
1256 * Including one day Structures
1257 */
1258 return_data = mem_internal_allocate_zeroed(cif->rtype->size);
1259
1260 ffi_call(cif, FFI_FN(func), return_data, values);
1261
1262 if (cif->rtype != &ffi_type_void) {
1263 char *s;
1264 PMC *ret_object;
1265 s = Parrot_str_to_cstring(interp, nci_info->pcc_return_signature);
1266 switch (*(char*)nci_info->return_translation) {
1267 case 'p':
1268 {
1269 PMC *final_destination = PMCNULL;
1270
1271 if (*(void**)return_data != NULL) {
1272 final_destination = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
1273 VTABLE_set_pointer(interp, final_destination, *(void**)return_data);
1274 }
1275 ret_object = Parrot_pcc_build_call_from_c_args(interp,
1276 call_object,
1277 s, final_destination);
1278
1279 }
1280 break;
1281 case 't':
1282 {
1283 STRING *final_destination = Parrot_str_new(interp, *(char**)return_data, 0);
1284 ret_object = Parrot_pcc_build_call_from_c_args(interp,
1285 call_object,
1286 s, final_destination);
1287 }
1288 break;
1289 case 'f':
1290 {
1291 FLOATVAL final_destination = *(float*)return_data;
1292
1293 ret_object = Parrot_pcc_build_call_from_c_args(interp,
1294 call_object,
1295 s, final_destination);
1296 }
1297 break;
1298 default:
1299 switch (s[0]) {
1300 case 'N':
1301 ret_object = Parrot_pcc_build_call_from_c_args(interp,
1302 call_object,
1303 s, *(FLOATVAL*)return_data);
1304 case 'I':
1305 ret_object = Parrot_pcc_build_call_from_c_args(interp,
1306 call_object,
1307 s, *(INTVAL*)return_data);
1308 case 'P':
1309 case 'S':
1310 default:
1311 ret_object = Parrot_pcc_build_call_from_c_args(interp,
1312 call_object,
1313 s, *(void**)return_data);
1314 }
1315 break;
1316 }
1317 Parrot_str_free_cstring(s);
1318 }
1319
1320 /*
1321 * Free memory used for cstrings,
1322 * and any other translations that use temporary memory
1323 */
1324 for (i = 0; i < (size_t)nci_info->arity; i++) {
1325 switch ((INTVAL)((char*)nci_info->arg_translation)[i]) {
1326 case (INTVAL)'B':
1327 if (translation_pointers[i]) {
1328 Parrot_str_free_cstring((char*)translation_pointers[i]);
1329 }
1330 break;
1331 case (INTVAL)'t':
1332 if (translation_pointers[i]) {
1333 Parrot_str_free_cstring((char*)translation_pointers[i]);
1334 }
1335 break;
1336 case (INTVAL)'2':
1337 VTABLE_set_integer_native(interp,
1338 ((pmc_holder_t*)translation_pointers[i])->p,
1339 (INTVAL)*(short*)((pmc_holder_t*)translation_pointers[i])->ival);
1340 if (translation_pointers[i]) {
1341 mem_sys_free(translation_pointers[i]);
1342 }
1343 break;
1344 case (INTVAL)'3':
1345 VTABLE_set_integer_native(interp,
1346 ((pmc_holder_t*)translation_pointers[i])->p,
1347 (INTVAL)*(int*)((pmc_holder_t*)translation_pointers[i])->ival);
1348 if (translation_pointers[i]) {
1349 mem_sys_free(translation_pointers[i]);
1350 }
1351 break;
1352 case (INTVAL)'4':
1353 VTABLE_set_integer_native(interp,
1354 ((pmc_holder_t*)translation_pointers[i])->p,
1355 (INTVAL)*(long*)((pmc_holder_t*)translation_pointers[i])->ival);
1356 if (translation_pointers[i]) {
1357 mem_sys_free(translation_pointers[i]);
1358 }
1359 break;
1360 case (INTVAL)'V':
1361 VTABLE_set_pointer(interp,
1362 ((pmc_holder_t*)translation_pointers[i])->p,
1363 (PMC*)*((pmc_holder_t*)translation_pointers[i])->pval);
1364 if (translation_pointers[i]) {
1365 mem_sys_free(translation_pointers[i]);
1366 }
1367 break;
1368 case (INTVAL)'d':
1369 case (INTVAL)'c':
1370 case (INTVAL)'s':
1371 case (INTVAL)'i':
1372 case (INTVAL)'l':
1373 case (INTVAL)'q':
1374 if (translation_pointers[i]) {
1375 mem_sys_free(translation_pointers[i]);
1376 }
1377 break;
1378 default:
1379 break;
1380 }
1381 }
82c7cf6 @chromatic [PMC] Minor cleanups and tidyings.
chromatic authored
1382
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
1383 if (nci_info->arity > 0 && middle_man) {
1384 mem_sys_free(middle_man);
1385 }
1386 if (return_data) {
1387 mem_sys_free(return_data);
1388 }
1389 if (values) {
1390 mem_sys_free(values);
1391 }
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
1392 }
2646951 @tewk [gsoc_nci] gsoc_nci_001 merge
tewk authored
1393
92c390d Fix tailcalls to NCI, #38724
Leopold Toetsch authored
1394 cont = INTERP->current_cont;
82c7cf6 @chromatic [PMC] Minor cleanups and tidyings.
chromatic authored
1395
8838c7f builtins 1 - first shot
Leopold Toetsch authored
1396 /*
92c390d Fix tailcalls to NCI, #38724
Leopold Toetsch authored
1397 * If the NCI function was tailcalled, the return result
1398 * is already passed back to the caller of this frame
1399 * - see Parrot_init_ret_nci(). We therefore invoke the
1400 * return continuation here, which gets rid of this frame
1401 * and returns the real return address
8838c7f builtins 1 - first shot
Leopold Toetsch authored
1402 */
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
1403 if (cont && cont != NEED_CONTINUATION
1404 && (PObj_get_FLAGS(cont) & SUB_FLAG_TAILCALL)) {
540d4c3 @bacek Merge context_pmc3 branch into trunk.
bacek authored
1405 cont = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp));
92c390d Fix tailcalls to NCI, #38724
Leopold Toetsch authored
1406 next = VTABLE_invoke(INTERP, cont, next);
1407 }
82c7cf6 @chromatic [PMC] Minor cleanups and tidyings.
chromatic authored
1408
e063e49 @chromatic Continuing Parrot/C++ cleanups (Steve Peters, RT #42746).
chromatic authored
1409 return (opcode_t *)next;
2a2c19b Added in code to properly do native calls to library routines loaded via
Dan Sugalski authored
1410 }
380c0ba fix NCI related DOD problem
Leopold Toetsch authored
1411
c64e58f pmc docs update 3
Michael Scott authored
1412 /*
1413
1414 =item C<INTVAL get_integer()>
1415
1416 Returns the function pointer as an integer.
1417
1418 =cut
1419
1420 */
1421
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
1422 VTABLE INTVAL get_integer() {
971e997 @NotFound rename pmc attributes struct from Parrot_<type> to Parrot_<type>_attr…
NotFound authored
1423 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
1424 if (!nci_info->func)
e69d2a4 @petdance Made pcc_params be static. Removed unused arg from build_func. Header…
petdance authored
1425 build_func(INTERP, nci_info);
637246f @jnthn Refactor the NCI PMC to have an underlying structure, in preparation …
jnthn authored
1426 return (INTVAL)nci_info->func;
3168931 Forth can now generate code for words on the fly and execute them.
Dan Sugalski authored
1427 }
1428
f35b03c @rubys Initial support for sort
rubys authored
1429 /*
1430
1431 =item C<INTVAL get_bool()>
1432
1433 Returns the boolean value of the pointer.
1434
1435 =cut
1436
1437 */
1438
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
1439 VTABLE INTVAL get_bool() {
971e997 @NotFound rename pmc attributes struct from Parrot_<type> to Parrot_<type>_attr…
NotFound authored
1440 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
1441 return (0 != (INTVAL)nci_info->cif);
f35b03c @rubys Initial support for sort
rubys authored
1442 }
1443
6586a2c @jnthn Implement arity method on NCI PMCs, plus a test for it.
jnthn authored
1444 /*
1445
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
1446 =item C<METHOD arity()>
6586a2c @jnthn Implement arity method on NCI PMCs, plus a test for it.
jnthn authored
1447
01e804c @Util [pmc] Typo corrections
Util authored
1448 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
1449
1450 =cut
1451
1452 */
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
1453 METHOD arity() {
971e997 @NotFound rename pmc attributes struct from Parrot_<type> to Parrot_<type>_attr…
NotFound authored
1454 Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
48d2796 @NotFound Another unreachable warning, codingstd in jit_emit ppc
NotFound authored
1455 INTVAL arity = 0;
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
1456
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
1457 if (nci_info) {
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
1458 if (PObj_flag_TEST(private2, SELF)) {
1459 }
1460 else {
1461 if (!nci_info->cif) {
1462 nci_info->cif = build_libffi_func(interp, nci_info);
1463 }
1464 if (nci_info->cif) {
1465 arity = nci_info->arity;
1466 RETURN(INTVAL arity);
1467 }
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
1468 }
1469 }
6586a2c @jnthn Implement arity method on NCI PMCs, plus a test for it.
jnthn authored
1470
8832378 @chromatic [PMC] Delayed NCI thunk initialization until absolutely necessary. This
chromatic authored
1471 Parrot_ex_throw_from_c_args(INTERP, NULL,
1472 EXCEPTION_INVALID_OPERATION,
1473 "You cannot get the arity of an undefined NCI.");
59661f1 @allisonrandal [pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).
allisonrandal authored
1474 }
2a2c19b Added in code to properly do native calls to library routines loaded via
Dan Sugalski authored
1475 }
c64e58f pmc docs update 3
Michael Scott authored
1476
1477 /*
1478
1479 =back
1480
1481 =head1 SEE ALSO
1482
1483 F<docs/pdds/pdd03_calling_conventions.pod>.
1484
1485 =head1 HISTORY
1486
1487 Initial revision by sean 2002/08/04.
1488
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
1489 Updates by John Harrison, Summer 2010, GSoC.
1490
c64e58f pmc docs update 3
Michael Scott authored
1491 =cut
1492
1493 */
1494
0eb3eb3 added formatting footer and detabbed
Michael Scott authored
1495 /*
1496 * Local variables:
72575ae @bschmalhofer #40481: [PATCH] C-code coda in pmc files
bschmalhofer authored
1497 * c-file-style: "parrot"
0eb3eb3 added formatting footer and detabbed
Michael Scott authored
1498 * End:
1499 * vim: expandtab shiftwidth=4:
72575ae @bschmalhofer #40481: [PATCH] C-code coda in pmc files
bschmalhofer authored
1500 */
0c5f9c3 GSoC: The majority of my NCI changes in 1 commit.
John Harrison authored
1501
1502
1503
Something went wrong with that request. Please try again.