2 Copyright (C) 2001-2009, Parrot Foundation.
11 B<Arguments and Returns>: Functions in this file handle argument/return value
12 passing to and from subroutines following the Parrot Calling Conventions.
22 #include "parrot/parrot.h"
23 #include "parrot/oplib/ops.h"
24 #include "parrot/runcore_api.h"
26 #include "pmc/pmc_key.h"
27 #include "pmc/pmc_callsignature.h"
28 #include "pmc/pmc_fixedintegerarray.h"
29 #include "pmc/pmc_context.h"
31 /* HEADERIZER HFILE: include/parrot/call.h */
34 Set of functions used in generic versions of fill_params and fill_returns.
36 typedef INTVAL
* (*intval_ptr_func_t
)(PARROT_INTERP
, void *arg_info
, INTVAL index
);
37 typedef FLOATVAL
* (*numval_ptr_func_t
)(PARROT_INTERP
, void *arg_info
, INTVAL index
);
38 typedef STRING
** (*string_ptr_func_t
)(PARROT_INTERP
, void *arg_info
, INTVAL index
);
39 typedef PMC
** (*pmc_ptr_func_t
) (PARROT_INTERP
, void *arg_info
, INTVAL index
);
41 typedef INTVAL (*intval_func_t
)(PARROT_INTERP
, void *arg_info
, INTVAL index
);
42 typedef FLOATVAL (*numval_func_t
)(PARROT_INTERP
, void *arg_info
, INTVAL index
);
43 typedef STRING
* (*string_func_t
)(PARROT_INTERP
, void *arg_info
, INTVAL index
);
44 typedef PMC
* (*pmc_func_t
) (PARROT_INTERP
, void *arg_info
, INTVAL index
);
46 typedef struct pcc_set_funcs
{
47 intval_ptr_func_t intval
;
48 numval_ptr_func_t numval
;
49 string_ptr_func_t string
;
52 intval_func_t intval_constant
;
53 numval_func_t numval_constant
;
54 string_func_t string_constant
;
55 pmc_func_t pmc_constant
;
58 typedef struct pcc_get_funcs
{
64 intval_func_t intval_constant
;
65 numval_func_t numval_constant
;
66 string_func_t string_constant
;
67 pmc_func_t pmc_constant
;
70 /* HEADERIZER BEGIN: static */
71 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
73 static void assign_default_param_value(PARROT_INTERP
,
76 ARGIN(void *arg_info
),
77 ARGIN(struct pcc_set_funcs
*accessor
))
78 __attribute__nonnull__(1)
79 __attribute__nonnull__(4)
80 __attribute__nonnull__(5);
82 static void assign_default_result_value(PARROT_INTERP
,
86 __attribute__nonnull__(1)
87 __attribute__nonnull__(2)
88 FUNC_MODIFIES(*results
);
90 PARROT_CAN_RETURN_NULL
91 static PMC
* clone_key_arg(PARROT_INTERP
, ARGIN(PMC
*key
))
92 __attribute__nonnull__(1)
93 __attribute__nonnull__(2);
95 PARROT_CANNOT_RETURN_NULL
96 static void dissect_aggregate_arg(PARROT_INTERP
,
97 ARGMOD(PMC
*call_object
),
98 ARGIN(PMC
*aggregate
))
99 __attribute__nonnull__(1)
100 __attribute__nonnull__(2)
101 __attribute__nonnull__(3)
102 FUNC_MODIFIES(*call_object
);
104 static void extract_named_arg_from_op(PARROT_INTERP
,
105 ARGMOD(PMC
*call_object
),
107 ARGIN(PMC
* const raw_sig
),
108 ARGIN(opcode_t
* const raw_args
),
110 __attribute__nonnull__(1)
111 __attribute__nonnull__(2)
112 __attribute__nonnull__(3)
113 __attribute__nonnull__(4)
114 __attribute__nonnull__(5)
115 FUNC_MODIFIES(*call_object
);
117 static void fill_params(PARROT_INTERP
,
118 ARGMOD_NULLOK(PMC
*call_object
),
120 ARGIN(void *arg_info
),
121 ARGIN(struct pcc_set_funcs
*accessor
))
122 __attribute__nonnull__(1)
123 __attribute__nonnull__(3)
124 __attribute__nonnull__(4)
125 __attribute__nonnull__(5)
126 FUNC_MODIFIES(*call_object
);
128 static void fill_results(PARROT_INTERP
,
129 ARGMOD_NULLOK(PMC
*call_object
),
131 ARGIN(void *return_info
),
132 ARGIN(struct pcc_get_funcs
*accessor
))
133 __attribute__nonnull__(1)
134 __attribute__nonnull__(3)
135 __attribute__nonnull__(4)
136 __attribute__nonnull__(5)
137 FUNC_MODIFIES(*call_object
);
139 PARROT_CANNOT_RETURN_NULL
140 static INTVAL
intval_arg_from_c_args(PARROT_INTERP
,
141 ARGIN(va_list *args
),
142 SHIM(INTVAL param_index
))
143 __attribute__nonnull__(1)
144 __attribute__nonnull__(2);
146 PARROT_CANNOT_RETURN_NULL
147 static INTVAL
intval_arg_from_continuation(PARROT_INTERP
,
150 __attribute__nonnull__(1)
151 __attribute__nonnull__(2);
153 PARROT_CANNOT_RETURN_NULL
154 static INTVAL
intval_arg_from_op(PARROT_INTERP
,
155 ARGIN(opcode_t
*raw_args
),
157 __attribute__nonnull__(1)
158 __attribute__nonnull__(2);
160 static INTVAL
intval_constant_from_op(PARROT_INTERP
,
161 ARGIN(opcode_t
*raw_params
),
163 __attribute__nonnull__(1)
164 __attribute__nonnull__(2);
166 static INTVAL
intval_constant_from_varargs(PARROT_INTERP
,
169 __attribute__nonnull__(1)
170 __attribute__nonnull__(2);
172 PARROT_CANNOT_RETURN_NULL
173 static INTVAL
* intval_param_from_c_args(PARROT_INTERP
,
174 ARGIN(va_list *args
),
175 SHIM(INTVAL param_index
))
176 __attribute__nonnull__(1)
177 __attribute__nonnull__(2);
179 PARROT_CANNOT_RETURN_NULL
180 static INTVAL
* intval_param_from_op(PARROT_INTERP
,
181 ARGIN(opcode_t
*raw_params
),
183 __attribute__nonnull__(1)
184 __attribute__nonnull__(2);
186 PARROT_CANNOT_RETURN_NULL
187 static FLOATVAL
numval_arg_from_c_args(PARROT_INTERP
,
188 ARGIN(va_list *args
),
189 SHIM(INTVAL param_index
))
190 __attribute__nonnull__(1)
191 __attribute__nonnull__(2);
193 PARROT_CANNOT_RETURN_NULL
194 static FLOATVAL
numval_arg_from_continuation(PARROT_INTERP
,
197 __attribute__nonnull__(1)
198 __attribute__nonnull__(2);
200 PARROT_CANNOT_RETURN_NULL
201 static FLOATVAL
numval_arg_from_op(PARROT_INTERP
,
202 ARGIN(opcode_t
*raw_args
),
204 __attribute__nonnull__(1)
205 __attribute__nonnull__(2);
207 static FLOATVAL
numval_constant_from_op(PARROT_INTERP
,
208 ARGIN(opcode_t
*raw_params
),
210 __attribute__nonnull__(1)
211 __attribute__nonnull__(2);
213 static FLOATVAL
numval_constant_from_varargs(PARROT_INTERP
,
216 __attribute__nonnull__(1)
217 __attribute__nonnull__(2);
219 PARROT_CANNOT_RETURN_NULL
220 static FLOATVAL
* numval_param_from_c_args(PARROT_INTERP
,
221 ARGIN(va_list *args
),
222 SHIM(INTVAL param_index
))
223 __attribute__nonnull__(1)
224 __attribute__nonnull__(2);
226 PARROT_CANNOT_RETURN_NULL
227 static FLOATVAL
* numval_param_from_op(PARROT_INTERP
,
228 ARGIN(opcode_t
*raw_params
),
230 __attribute__nonnull__(1)
231 __attribute__nonnull__(2);
233 PARROT_CAN_RETURN_NULL
234 static void parse_signature_string(PARROT_INTERP
,
235 ARGIN(const char *signature
),
236 ARGMOD(PMC
**arg_flags
),
237 ARGMOD(PMC
**return_flags
))
238 __attribute__nonnull__(1)
239 __attribute__nonnull__(2)
240 __attribute__nonnull__(3)
241 __attribute__nonnull__(4)
242 FUNC_MODIFIES(*arg_flags
)
243 FUNC_MODIFIES(*return_flags
);
245 PARROT_CANNOT_RETURN_NULL
246 static PMC
* pmc_arg_from_c_args(PARROT_INTERP
,
247 ARGIN(va_list *args
),
248 SHIM(INTVAL param_index
))
249 __attribute__nonnull__(1)
250 __attribute__nonnull__(2);
252 PARROT_CANNOT_RETURN_NULL
253 static PMC
* pmc_arg_from_continuation(PARROT_INTERP
,
256 __attribute__nonnull__(1)
257 __attribute__nonnull__(2);
259 PARROT_CANNOT_RETURN_NULL
260 static PMC
* pmc_arg_from_op(PARROT_INTERP
,
261 ARGIN(opcode_t
*raw_args
),
263 __attribute__nonnull__(1)
264 __attribute__nonnull__(2);
266 PARROT_CAN_RETURN_NULL
267 static PMC
* pmc_constant_from_op(PARROT_INTERP
,
268 ARGIN(opcode_t
*raw_params
),
270 __attribute__nonnull__(1)
271 __attribute__nonnull__(2);
273 PARROT_CAN_RETURN_NULL
274 static PMC
* pmc_constant_from_varargs(PARROT_INTERP
,
277 __attribute__nonnull__(1)
278 __attribute__nonnull__(2);
280 PARROT_CANNOT_RETURN_NULL
281 static PMC
** pmc_param_from_c_args(PARROT_INTERP
,
282 ARGIN(va_list *args
),
283 SHIM(INTVAL param_index
))
284 __attribute__nonnull__(1)
285 __attribute__nonnull__(2);
287 PARROT_CANNOT_RETURN_NULL
288 static PMC
** pmc_param_from_op(PARROT_INTERP
,
289 ARGIN(opcode_t
*raw_params
),
291 __attribute__nonnull__(1)
292 __attribute__nonnull__(2);
294 PARROT_CANNOT_RETURN_NULL
295 static STRING
* string_arg_from_c_args(PARROT_INTERP
,
296 ARGIN(va_list *args
),
297 SHIM(INTVAL param_index
))
298 __attribute__nonnull__(1)
299 __attribute__nonnull__(2);
301 PARROT_CANNOT_RETURN_NULL
302 static STRING
* string_arg_from_continuation(PARROT_INTERP
,
305 __attribute__nonnull__(1)
306 __attribute__nonnull__(2);
308 PARROT_CANNOT_RETURN_NULL
309 static STRING
* string_arg_from_op(PARROT_INTERP
,
310 ARGIN(opcode_t
*raw_args
),
312 __attribute__nonnull__(1)
313 __attribute__nonnull__(2);
315 PARROT_CAN_RETURN_NULL
316 static STRING
* string_constant_from_op(PARROT_INTERP
,
317 ARGIN(opcode_t
*raw_params
),
319 __attribute__nonnull__(1)
320 __attribute__nonnull__(2);
322 PARROT_CAN_RETURN_NULL
323 static STRING
* string_constant_from_varargs(PARROT_INTERP
,
326 __attribute__nonnull__(1)
327 __attribute__nonnull__(2);
329 PARROT_CANNOT_RETURN_NULL
330 static STRING
** string_param_from_c_args(PARROT_INTERP
,
331 ARGIN(va_list *args
),
332 SHIM(INTVAL param_index
))
333 __attribute__nonnull__(1)
334 __attribute__nonnull__(2);
336 PARROT_CANNOT_RETURN_NULL
337 static STRING
** string_param_from_op(PARROT_INTERP
,
338 ARGIN(opcode_t
*raw_params
),
340 __attribute__nonnull__(1)
341 __attribute__nonnull__(2);
343 #define ASSERT_ARGS_assign_default_param_value __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
344 PARROT_ASSERT_ARG(interp) \
345 , PARROT_ASSERT_ARG(arg_info) \
346 , PARROT_ASSERT_ARG(accessor))
347 #define ASSERT_ARGS_assign_default_result_value __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
348 PARROT_ASSERT_ARG(interp) \
349 , PARROT_ASSERT_ARG(results))
350 #define ASSERT_ARGS_clone_key_arg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
351 PARROT_ASSERT_ARG(interp) \
352 , PARROT_ASSERT_ARG(key))
353 #define ASSERT_ARGS_dissect_aggregate_arg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
354 PARROT_ASSERT_ARG(interp) \
355 , PARROT_ASSERT_ARG(call_object) \
356 , PARROT_ASSERT_ARG(aggregate))
357 #define ASSERT_ARGS_extract_named_arg_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
358 PARROT_ASSERT_ARG(interp) \
359 , PARROT_ASSERT_ARG(call_object) \
360 , PARROT_ASSERT_ARG(name) \
361 , PARROT_ASSERT_ARG(raw_sig) \
362 , PARROT_ASSERT_ARG(raw_args))
363 #define ASSERT_ARGS_fill_params __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
364 PARROT_ASSERT_ARG(interp) \
365 , PARROT_ASSERT_ARG(raw_sig) \
366 , PARROT_ASSERT_ARG(arg_info) \
367 , PARROT_ASSERT_ARG(accessor))
368 #define ASSERT_ARGS_fill_results __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
369 PARROT_ASSERT_ARG(interp) \
370 , PARROT_ASSERT_ARG(raw_sig) \
371 , PARROT_ASSERT_ARG(return_info) \
372 , PARROT_ASSERT_ARG(accessor))
373 #define ASSERT_ARGS_intval_arg_from_c_args __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
374 PARROT_ASSERT_ARG(interp) \
375 , PARROT_ASSERT_ARG(args))
376 #define ASSERT_ARGS_intval_arg_from_continuation __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
377 PARROT_ASSERT_ARG(interp) \
378 , PARROT_ASSERT_ARG(cs))
379 #define ASSERT_ARGS_intval_arg_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
380 PARROT_ASSERT_ARG(interp) \
381 , PARROT_ASSERT_ARG(raw_args))
382 #define ASSERT_ARGS_intval_constant_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
383 PARROT_ASSERT_ARG(interp) \
384 , PARROT_ASSERT_ARG(raw_params))
385 #define ASSERT_ARGS_intval_constant_from_varargs __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
386 PARROT_ASSERT_ARG(interp) \
387 , PARROT_ASSERT_ARG(data))
388 #define ASSERT_ARGS_intval_param_from_c_args __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
389 PARROT_ASSERT_ARG(interp) \
390 , PARROT_ASSERT_ARG(args))
391 #define ASSERT_ARGS_intval_param_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
392 PARROT_ASSERT_ARG(interp) \
393 , PARROT_ASSERT_ARG(raw_params))
394 #define ASSERT_ARGS_numval_arg_from_c_args __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
395 PARROT_ASSERT_ARG(interp) \
396 , PARROT_ASSERT_ARG(args))
397 #define ASSERT_ARGS_numval_arg_from_continuation __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
398 PARROT_ASSERT_ARG(interp) \
399 , PARROT_ASSERT_ARG(cs))
400 #define ASSERT_ARGS_numval_arg_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
401 PARROT_ASSERT_ARG(interp) \
402 , PARROT_ASSERT_ARG(raw_args))
403 #define ASSERT_ARGS_numval_constant_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
404 PARROT_ASSERT_ARG(interp) \
405 , PARROT_ASSERT_ARG(raw_params))
406 #define ASSERT_ARGS_numval_constant_from_varargs __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
407 PARROT_ASSERT_ARG(interp) \
408 , PARROT_ASSERT_ARG(data))
409 #define ASSERT_ARGS_numval_param_from_c_args __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
410 PARROT_ASSERT_ARG(interp) \
411 , PARROT_ASSERT_ARG(args))
412 #define ASSERT_ARGS_numval_param_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
413 PARROT_ASSERT_ARG(interp) \
414 , PARROT_ASSERT_ARG(raw_params))
415 #define ASSERT_ARGS_parse_signature_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
416 PARROT_ASSERT_ARG(interp) \
417 , PARROT_ASSERT_ARG(signature) \
418 , PARROT_ASSERT_ARG(arg_flags) \
419 , PARROT_ASSERT_ARG(return_flags))
420 #define ASSERT_ARGS_pmc_arg_from_c_args __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
421 PARROT_ASSERT_ARG(interp) \
422 , PARROT_ASSERT_ARG(args))
423 #define ASSERT_ARGS_pmc_arg_from_continuation __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
424 PARROT_ASSERT_ARG(interp) \
425 , PARROT_ASSERT_ARG(cs))
426 #define ASSERT_ARGS_pmc_arg_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
427 PARROT_ASSERT_ARG(interp) \
428 , PARROT_ASSERT_ARG(raw_args))
429 #define ASSERT_ARGS_pmc_constant_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
430 PARROT_ASSERT_ARG(interp) \
431 , PARROT_ASSERT_ARG(raw_params))
432 #define ASSERT_ARGS_pmc_constant_from_varargs __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
433 PARROT_ASSERT_ARG(interp) \
434 , PARROT_ASSERT_ARG(data))
435 #define ASSERT_ARGS_pmc_param_from_c_args __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
436 PARROT_ASSERT_ARG(interp) \
437 , PARROT_ASSERT_ARG(args))
438 #define ASSERT_ARGS_pmc_param_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
439 PARROT_ASSERT_ARG(interp) \
440 , PARROT_ASSERT_ARG(raw_params))
441 #define ASSERT_ARGS_string_arg_from_c_args __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
442 PARROT_ASSERT_ARG(interp) \
443 , PARROT_ASSERT_ARG(args))
444 #define ASSERT_ARGS_string_arg_from_continuation __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
445 PARROT_ASSERT_ARG(interp) \
446 , PARROT_ASSERT_ARG(cs))
447 #define ASSERT_ARGS_string_arg_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
448 PARROT_ASSERT_ARG(interp) \
449 , PARROT_ASSERT_ARG(raw_args))
450 #define ASSERT_ARGS_string_constant_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
451 PARROT_ASSERT_ARG(interp) \
452 , PARROT_ASSERT_ARG(raw_params))
453 #define ASSERT_ARGS_string_constant_from_varargs __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
454 PARROT_ASSERT_ARG(interp) \
455 , PARROT_ASSERT_ARG(data))
456 #define ASSERT_ARGS_string_param_from_c_args __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
457 PARROT_ASSERT_ARG(interp) \
458 , PARROT_ASSERT_ARG(args))
459 #define ASSERT_ARGS_string_param_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
460 PARROT_ASSERT_ARG(interp) \
461 , PARROT_ASSERT_ARG(raw_params))
462 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
463 /* HEADERIZER END: static */
467 =item C<PMC* Parrot_pcc_build_sig_object_from_op(PARROT_INTERP, PMC *signature,
468 PMC * const raw_sig, opcode_t * const raw_args)>
470 Take a raw signature and argument list from a set_args opcode and
471 convert it to a CallSignature PMC.
478 PARROT_WARN_UNUSED_RESULT
479 PARROT_CANNOT_RETURN_NULL
481 Parrot_pcc_build_sig_object_from_op(PARROT_INTERP
, ARGIN_NULLOK(PMC
*signature
),
482 ARGIN(PMC
* const raw_sig
), ARGIN(opcode_t
* const raw_args
))
484 ASSERT_ARGS(Parrot_pcc_build_sig_object_from_op
)
486 PMC
*ctx
= CURRENT_CONTEXT(interp
);
491 if (PMC_IS_NULL(signature
))
492 call_object
= pmc_new(interp
, enum_class_CallSignature
);
494 call_object
= signature
;
496 /* this macro is much, much faster than the VTABLE STRING comparisons */
497 SETATTR_CallSignature_arg_flags(interp
, call_object
, raw_sig
);
498 GETATTR_FixedIntegerArray_size(interp
, raw_sig
, arg_count
);
499 GETATTR_FixedIntegerArray_int_array(interp
, raw_sig
, int_array
);
501 for (arg_index
= 0; arg_index
< arg_count
; arg_index
++) {
502 INTVAL arg_flags
= int_array
[arg_index
];
504 const INTVAL constant
= PARROT_ARG_CONSTANT_ISSET(arg_flags
);
505 const INTVAL raw_index
= raw_args
[arg_index
+ 2];
507 switch (PARROT_ARG_TYPE_MASK_MASK(arg_flags
)) {
508 case PARROT_ARG_INTVAL
:
510 VTABLE_push_integer(interp
, call_object
, raw_index
);
512 const INTVAL int_value
= CTX_REG_INT(ctx
, raw_index
);
513 VTABLE_push_integer(interp
, call_object
, int_value
);
516 case PARROT_ARG_FLOATVAL
:
518 VTABLE_push_float(interp
, call_object
,
519 Parrot_pcc_get_num_constant(interp
, ctx
, raw_index
));
521 const FLOATVAL float_value
= CTX_REG_NUM(ctx
, raw_index
);
522 VTABLE_push_float(interp
, call_object
, float_value
);
525 case PARROT_ARG_STRING
:
527 STRING
*string_value
;
529 /* ensure that callees don't modify constant caller strings */
530 string_value
= Parrot_str_new_COW(interp
,
531 Parrot_pcc_get_string_constant(interp
, ctx
, raw_index
));
533 string_value
= CTX_REG_STR(ctx
, raw_index
);
535 if (arg_flags
& PARROT_ARG_NAME
) {
537 if (!PMC_IS_NULL(call_object
)
538 && VTABLE_exists_keyed_str(interp
, call_object
, string_value
)) {
539 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
540 "duplicate named argument in call");
543 extract_named_arg_from_op(interp
, call_object
, string_value
,
544 raw_sig
, raw_args
, arg_index
);
547 VTABLE_push_string(interp
, call_object
, string_value
);
555 pmc_value
= Parrot_pcc_get_pmc_constant(interp
, ctx
, raw_index
);
557 pmc_value
= CTX_REG_PMC(ctx
, raw_index
);
559 if (arg_flags
& PARROT_ARG_FLATTEN
) {
560 dissect_aggregate_arg(interp
, call_object
, pmc_value
);
563 VTABLE_push_pmc(interp
, call_object
, clone_key_arg(interp
, pmc_value
));
579 =item C<static void extract_named_arg_from_op(PARROT_INTERP, PMC *call_object,
580 STRING *name, PMC * const raw_sig, opcode_t * const raw_args, INTVAL arg_index)>
582 Pulls in the next argument from a set_args opcode, and sets it as the
583 value of a named argument in the CallSignature PMC.
590 extract_named_arg_from_op(PARROT_INTERP
, ARGMOD(PMC
*call_object
), ARGIN(STRING
*name
),
591 ARGIN(PMC
* const raw_sig
), ARGIN(opcode_t
* const raw_args
),
594 ASSERT_ARGS(extract_named_arg_from_op
)
595 PMC
*ctx
= CURRENT_CONTEXT(interp
);
596 INTVAL arg_flags
= VTABLE_get_integer_keyed_int(interp
,
599 const INTVAL constant
= PARROT_ARG_CONSTANT_ISSET(arg_flags
);
600 const INTVAL raw_index
= raw_args
[arg_index
+ 2];
602 switch (PARROT_ARG_TYPE_MASK_MASK(arg_flags
)) {
603 case PARROT_ARG_INTVAL
:
605 VTABLE_set_integer_keyed_str(interp
, call_object
, name
, raw_index
);
607 VTABLE_set_integer_keyed_str(interp
, call_object
, name
,
608 CTX_REG_INT(ctx
, raw_index
));
610 case PARROT_ARG_FLOATVAL
:
612 VTABLE_set_number_keyed_str(interp
, call_object
, name
,
613 Parrot_pcc_get_num_constant(interp
, ctx
, raw_index
));
615 VTABLE_set_number_keyed_str(interp
, call_object
, name
,
616 CTX_REG_NUM(ctx
, raw_index
));
618 case PARROT_ARG_STRING
:
620 /* ensure that callees don't modify constant caller strings */
621 VTABLE_set_string_keyed_str(interp
, call_object
, name
,
622 Parrot_str_new_COW(interp
,
623 Parrot_pcc_get_string_constant(interp
, ctx
, raw_index
)));
625 VTABLE_set_string_keyed_str(interp
, call_object
, name
,
626 CTX_REG_STR(ctx
, raw_index
));
630 VTABLE_set_pmc_keyed_str(interp
, call_object
, name
,
631 Parrot_pcc_get_pmc_constant(interp
, ctx
, raw_index
));
633 VTABLE_set_pmc_keyed_str(interp
, call_object
, name
,
634 CTX_REG_PMC(ctx
, raw_index
));
643 =item C<static void dissect_aggregate_arg(PARROT_INTERP, PMC *call_object, PMC
646 Takes an aggregate PMC and splits it up into individual arguments,
647 adding each one to the CallSignature PMC. If the aggregate is an array,
648 its elements are added as positional arguments. If the aggregate is a
649 hash, its key/value pairs are added as named arguments.
655 PARROT_CANNOT_RETURN_NULL
657 dissect_aggregate_arg(PARROT_INTERP
, ARGMOD(PMC
*call_object
), ARGIN(PMC
*aggregate
))
659 ASSERT_ARGS(dissect_aggregate_arg
)
660 if (VTABLE_does(interp
, aggregate
, CONST_STRING(interp
, "array"))) {
661 INTVAL elements
= VTABLE_elements(interp
, aggregate
);
663 for (index
= 0; index
< elements
; index
++) {
664 VTABLE_push_pmc(interp
, call_object
,
665 VTABLE_get_pmc_keyed_int(interp
, aggregate
, index
));
668 else if (VTABLE_does(interp
, aggregate
, CONST_STRING(interp
, "hash"))) {
669 INTVAL elements
= VTABLE_elements(interp
, aggregate
);
671 PMC
*key
= pmc_new(interp
, enum_class_Key
);
672 VTABLE_set_integer_native(interp
, key
, 0);
673 SETATTR_Key_next_key(interp
, key
, (PMC
*)INITBucketIndex
);
675 /* Low-level hash iteration. */
676 for (index
= 0; index
< elements
; index
++) {
677 if (!PMC_IS_NULL(key
)) {
678 STRING
*name
= (STRING
*)parrot_hash_get_idx(interp
,
679 (Hash
*)VTABLE_get_pointer(interp
, aggregate
), key
);
681 VTABLE_set_pmc_keyed_str(interp
, call_object
, name
,
682 VTABLE_get_pmc_keyed_str(interp
, aggregate
, name
));
687 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
688 "flattened parameters must be a hash or array");
694 =item C<PMC* Parrot_pcc_build_sig_object_returns_from_op(PARROT_INTERP, PMC
695 *signature, PMC *raw_sig, opcode_t *raw_args)>
697 Take a raw signature and argument list from a set_results opcode and
698 convert it to a CallSignature PMC. Uses an existing CallSignature PMC if
699 one was already created for set_args. Otherwise, creates a new one.
706 PARROT_WARN_UNUSED_RESULT
707 PARROT_CAN_RETURN_NULL
709 Parrot_pcc_build_sig_object_returns_from_op(PARROT_INTERP
, ARGIN_NULLOK(PMC
*signature
),
710 ARGIN(PMC
*raw_sig
), ARGIN(opcode_t
*raw_args
))
712 ASSERT_ARGS(Parrot_pcc_build_sig_object_returns_from_op
)
715 PMC
*ctx
= CURRENT_CONTEXT(interp
);
716 PMC
*returns
= pmc_new(interp
, enum_class_CallSignatureReturns
);
717 INTVAL returns_pos
= 0;
721 if (PMC_IS_NULL(signature
))
722 call_object
= pmc_new(interp
, enum_class_CallSignature
);
723 /* A hack to support 'get_results' as the way of fetching the
724 * exception object inside an exception handler. The first argument
725 * in the call object is the exception, stick it directly into the
726 * destination register. */
727 else if (CALLSIGNATURE_is_exception_TEST(signature
)) {
728 const INTVAL raw_index
= raw_args
[2];
729 CTX_REG_PMC(ctx
, raw_index
) =
730 VTABLE_get_pmc_keyed_int(interp
, signature
, 0);
734 call_object
= signature
;
736 /* a little encapsulation violation for great speed */
737 SETATTR_CallSignature_return_flags(interp
, call_object
, raw_sig
);
738 SETATTR_CallSignature_results(interp
, call_object
, returns
);
740 GETATTR_FixedIntegerArray_size(interp
, raw_sig
, arg_count
);
741 GETATTR_FixedIntegerArray_int_array(interp
, raw_sig
, int_array
);
743 for (arg_index
= 0; arg_index
< arg_count
; arg_index
++) {
744 STRING
* const signature
= CONST_STRING(interp
, "signature");
745 const INTVAL arg_flags
= int_array
[arg_index
];
746 const INTVAL raw_index
= raw_args
[arg_index
+ 2];
748 /* Returns store a pointer to the register, so they can pass
749 * the result back to the caller. */
750 switch (PARROT_ARG_TYPE_MASK_MASK(arg_flags
)) {
751 case PARROT_ARG_INTVAL
:
752 VTABLE_set_pointer_keyed_int(interp
, returns
, returns_pos
++,
753 &(CTX_REG_INT(ctx
, raw_index
)));
754 VTABLE_push_integer(interp
, returns
, PARROT_ARG_INTVAL
);
756 case PARROT_ARG_FLOATVAL
:
757 VTABLE_set_pointer_keyed_int(interp
, returns
, returns_pos
++,
758 &(CTX_REG_NUM(ctx
, raw_index
)));
759 VTABLE_push_integer(interp
, returns
, PARROT_ARG_FLOATVAL
);
761 case PARROT_ARG_STRING
:
762 if (arg_flags
& PARROT_ARG_NAME
) {
763 STRING
* string_val
= arg_flags
& PARROT_ARG_CONSTANT
764 ? Parrot_pcc_get_string_constant(interp
, ctx
, raw_index
)
765 : CTX_REG_STR(ctx
, raw_index
);
766 VTABLE_set_pointer_keyed_int(interp
, returns
, returns_pos
++,
770 VTABLE_set_pointer_keyed_int(interp
, returns
, returns_pos
++,
771 &(CTX_REG_STR(ctx
, raw_index
)));
772 VTABLE_push_integer(interp
, returns
, PARROT_ARG_STRING
);
776 VTABLE_set_pointer_keyed_int(interp
, returns
, returns_pos
++,
777 &(CTX_REG_PMC(ctx
, raw_index
)));
778 VTABLE_push_integer(interp
, returns
, PARROT_ARG_PMC
);
791 =item C<PMC* Parrot_pcc_build_sig_object_from_varargs(PARROT_INTERP, PMC *obj,
792 const char *sig, va_list args)>
794 Converts a varargs list into a CallSignature PMC. The CallSignature stores the
795 original short signature string and an array of integer types to pass on to the
796 multiple dispatch search.
803 PARROT_WARN_UNUSED_RESULT
804 PARROT_CANNOT_RETURN_NULL
806 Parrot_pcc_build_sig_object_from_varargs(PARROT_INTERP
, ARGIN_NULLOK(PMC
*obj
),
807 ARGIN(const char *sig
), va_list args
)
809 ASSERT_ARGS(Parrot_pcc_build_sig_object_from_varargs
)
810 PMC
*type_tuple
= PMCNULL
;
811 PMC
*returns
= PMCNULL
;
812 PMC
*arg_flags
= PMCNULL
;
813 PMC
*return_flags
= PMCNULL
;
814 PMC
* const call_object
= pmc_new(interp
, enum_class_CallSignature
);
815 const INTVAL sig_len
= strlen(sig
);
816 INTVAL in_return_sig
= 0;
819 INTVAL returns_pos
= 0;
824 parse_signature_string(interp
, sig
, &arg_flags
, &return_flags
);
825 VTABLE_set_attr_str(interp
, call_object
, CONST_STRING(interp
, "arg_flags"), arg_flags
);
826 VTABLE_set_attr_str(interp
, call_object
, CONST_STRING(interp
, "return_flags"), return_flags
);
828 /* Process the varargs list */
829 for (i
= 0; i
< sig_len
; ++i
) {
830 const INTVAL type
= sig
[i
];
832 /* Only create the returns array if it's needed */
833 if (in_return_sig
&& PMC_IS_NULL(returns
)) {
834 returns
= pmc_new(interp
, enum_class_CallSignatureReturns
);
835 VTABLE_set_attr_str(interp
, call_object
, CONST_STRING(interp
, "returns"), returns
);
839 STRING
* const signature
= CONST_STRING(interp
, "signature");
840 /* Returns store the original passed-in pointer so they can pass
841 * the result back to the caller. */
844 VTABLE_set_pointer_keyed_int(interp
, returns
, returns_pos
++,
845 (void *)va_arg(args
, INTVAL
*));
846 VTABLE_push_integer(interp
, returns
, PARROT_ARG_INTVAL
);
849 VTABLE_set_pointer_keyed_int(interp
, returns
, returns_pos
++,
850 (void *)va_arg(args
, FLOATVAL
*));
851 VTABLE_push_integer(interp
, returns
, PARROT_ARG_FLOATVAL
);
854 VTABLE_set_pointer_keyed_int(interp
, returns
, returns_pos
++,
855 (void *)va_arg(args
, STRING
**));
856 VTABLE_push_integer(interp
, returns
, PARROT_ARG_STRING
);
859 VTABLE_set_pointer_keyed_int(interp
, returns
, returns_pos
++,
860 (void *)va_arg(args
, PMC
**));
861 VTABLE_push_integer(interp
, returns
, PARROT_ARG_PMC
);
864 Parrot_ex_throw_from_c_args(interp
, NULL
,
865 EXCEPTION_INVALID_OPERATION
,
866 "Dispatch: invalid argument type %c!", type
);
870 /* Regular arguments just set the value */
873 VTABLE_push_integer(interp
, call_object
, va_arg(args
, INTVAL
));
876 VTABLE_push_float(interp
, call_object
, va_arg(args
, FLOATVAL
));
879 VTABLE_push_string(interp
, call_object
, va_arg(args
, STRING
*));
883 INTVAL type_lookahead
= sig
[i
+1];
884 PMC
* const pmc_arg
= va_arg(args
, PMC
*);
885 if (type_lookahead
== 'f') {
886 dissect_aggregate_arg(interp
, call_object
, pmc_arg
);
890 VTABLE_push_pmc(interp
, call_object
, clone_key_arg(interp
, pmc_arg
));
891 if (type_lookahead
== 'i') {
893 Parrot_ex_throw_from_c_args(interp
, NULL
,
894 EXCEPTION_INVALID_OPERATION
,
895 "Dispatch: only the first argument can be an invocant");
897 append_pi
= 0; /* Don't append Pi in front of signature */
907 Parrot_ex_throw_from_c_args(interp
, NULL
,
908 EXCEPTION_INVALID_OPERATION
,
909 "Dispatch: invalid argument type %c!", type
);
914 /* Check if we have an invocant, and add it to the front of the arguments iff needed */
915 if (!PMC_IS_NULL(obj
) && append_pi
) {
916 VTABLE_unshift_pmc(interp
, call_object
, obj
);
924 =item C<static void fill_params(PARROT_INTERP, PMC *call_object, PMC *raw_sig,
925 void *arg_info, struct pcc_set_funcs *accessor)>
927 Gets args for the current function call and puts them into position.
928 First it gets the positional non-slurpy parameters, then the positional
929 slurpy parameters, then the named parameters, and finally the named
937 fill_params(PARROT_INTERP
, ARGMOD_NULLOK(PMC
*call_object
),
938 ARGIN(PMC
*raw_sig
), ARGIN(void *arg_info
), ARGIN(struct pcc_set_funcs
*accessor
))
940 ASSERT_ARGS(fill_params
)
941 PMC
*named_used_list
= PMCNULL
;
944 INTVAL param_count
= VTABLE_elements(interp
, raw_sig
);
945 INTVAL param_index
= 0;
946 INTVAL arg_index
= 0;
947 INTVAL named_count
= 0;
948 INTVAL err_check
= 0;
949 INTVAL positional_args
;
951 /* Check if we should be throwing errors. This is configured separately
952 * for parameters and return values. */
953 if (PARROT_ERRORS_test(interp
, PARROT_ERRORS_PARAM_COUNT_FLAG
))
956 /* A null call object is fine if there are no arguments and no returns. */
957 if (PMC_IS_NULL(call_object
)) {
958 if (param_count
> 0 && err_check
)
959 Parrot_ex_throw_from_c_args(interp
, NULL
,
960 EXCEPTION_INVALID_OPERATION
,
961 "too few arguments: 0 passed, %d expected", param_count
);
966 positional_args
= VTABLE_elements(interp
, call_object
);
967 GETATTR_CallSignature_arg_flags(interp
, call_object
, arg_sig
);
968 GETATTR_FixedIntegerArray_int_array(interp
, raw_sig
, raw_params
);
970 /* EXPERIMENTAL! This block adds provisional :call_sig param support on the
971 callee side only. Does not add :call_sig arg support on the caller side.
972 This is not the final form of the algorithm, but should provide the
973 tools that HLL designers need in the interim. */
974 if (param_count
== 1) {
975 const INTVAL first_flag
= raw_params
[0];
977 if (first_flag
& PARROT_ARG_CALL_SIG
) {
978 *accessor
->pmc(interp
, arg_info
, 0) = call_object
;
982 else if (param_count
== 2) {
983 const INTVAL second_flag
= raw_params
[1];
984 if (second_flag
& PARROT_ARG_CALL_SIG
)
985 *accessor
->pmc(interp
, arg_info
, 1) = call_object
;
988 /* First iterate over positional args and positional parameters. */
994 /* Check if we've used up all the parameters. */
995 if (param_index
>= param_count
) {
996 if (arg_index
>= positional_args
) {
997 /* We've used up all the arguments and parameters, we're done. */
1000 else if (err_check
) {
1001 /* We've used up all the parameters, but have extra positional
1002 * args left over. */
1003 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1004 "too many positional arguments: %d passed, %d expected",
1005 positional_args
, param_index
);
1010 param_flags
= raw_params
[param_index
];
1012 /* If it's a call_sig, we're done. */
1013 if (param_flags
& PARROT_ARG_CALL_SIG
)
1016 /* If the parameter is slurpy, collect all remaining positional
1017 * arguments into an array.*/
1018 if (param_flags
& PARROT_ARG_SLURPY_ARRAY
) {
1019 PMC
*collect_positional
;
1021 /* Can't handle named slurpy here, go on to named argument handling. */
1022 if (param_flags
& PARROT_ARG_NAME
)
1025 if (named_count
> 0)
1026 Parrot_ex_throw_from_c_args(interp
, NULL
,
1027 EXCEPTION_INVALID_OPERATION
,
1028 "named parameters must follow all positional parameters");
1030 collect_positional
= pmc_new(interp
,
1031 Parrot_get_ctx_HLL_type(interp
, enum_class_ResizablePMCArray
));
1032 for (; arg_index
< positional_args
; arg_index
++) {
1033 VTABLE_push_pmc(interp
, collect_positional
,
1034 VTABLE_get_pmc_keyed_int(interp
, call_object
, arg_index
));
1036 *accessor
->pmc(interp
, arg_info
, param_index
) = collect_positional
;
1038 break; /* Terminate the positional arg loop. */
1041 /* We have a positional argument, fill the parameter with it. */
1042 if (arg_index
< positional_args
) {
1044 /* Fill a named parameter with a positional argument. */
1045 if (param_flags
& PARROT_ARG_NAME
) {
1047 if (!(param_flags
& PARROT_ARG_STRING
))
1048 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1049 "named parameters must have a name specified");
1050 param_name
= PARROT_ARG_CONSTANT_ISSET(param_flags
)
1051 ? accessor
->string_constant(interp
, arg_info
, param_index
)
1052 : *accessor
->string(interp
, arg_info
, param_index
);
1055 if (param_index
>= param_count
)
1058 param_flags
= raw_params
[param_index
];
1060 /* Mark the name as used, cannot be filled again. */
1061 if (PMC_IS_NULL(named_used_list
)) /* Only created if needed. */
1062 named_used_list
= pmc_new(interp
, enum_class_Hash
);
1064 VTABLE_set_integer_keyed_str(interp
, named_used_list
, param_name
, 1);
1066 else if (named_count
> 0) {
1067 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1068 "named parameters must follow all positional parameters");
1071 /* Check for :lookahead parameter goes here. */
1073 /* Go ahead and fill the parameter with a positional argument. */
1074 switch (PARROT_ARG_TYPE_MASK_MASK(param_flags
)) {
1075 case PARROT_ARG_INTVAL
:
1076 *accessor
->intval(interp
, arg_info
, param_index
) =
1077 VTABLE_get_integer_keyed_int(interp
, call_object
, arg_index
);
1079 case PARROT_ARG_FLOATVAL
:
1080 *accessor
->numval(interp
, arg_info
, param_index
) =
1081 VTABLE_get_number_keyed_int(interp
, call_object
, arg_index
);
1083 case PARROT_ARG_STRING
:
1084 *accessor
->string(interp
, arg_info
, param_index
) =
1085 VTABLE_get_string_keyed_int(interp
, call_object
, arg_index
);
1087 case PARROT_ARG_PMC
:
1088 *accessor
->pmc(interp
, arg_info
, param_index
) =
1089 VTABLE_get_pmc_keyed_int(interp
, call_object
, arg_index
);
1092 Parrot_ex_throw_from_c_args(interp
, NULL
,
1093 EXCEPTION_INVALID_OPERATION
, "invalid parameter type");
1097 /* Mark the option flag for the filled parameter. */
1098 if (param_flags
& PARROT_ARG_OPTIONAL
) {
1099 INTVAL next_param_flags
;
1101 if (param_index
+ 1 < param_count
) {
1102 next_param_flags
= raw_params
[param_index
+ 1];
1104 if (next_param_flags
& PARROT_ARG_OPT_FLAG
) {
1106 *accessor
->intval(interp
, arg_info
, param_index
) = 1;
1111 /* We have no more positional arguments, fill the optional parameter
1112 * with a default value. */
1113 else if (param_flags
& PARROT_ARG_OPTIONAL
) {
1114 INTVAL next_param_flags
;
1116 /* We don't handle optional named params here, handle them in the
1118 if (param_flags
& PARROT_ARG_NAME
)
1121 assign_default_param_value(interp
, param_index
, param_flags
,
1122 arg_info
, accessor
);
1124 /* Mark the option flag for the parameter to FALSE, it was filled
1125 * with a default value. */
1126 if (param_index
+ 1 < param_count
) {
1127 next_param_flags
= raw_params
[param_index
+ 1];
1129 if (next_param_flags
& PARROT_ARG_OPT_FLAG
) {
1131 *accessor
->intval(interp
, arg_info
, param_index
) = 0;
1135 /* We don't have an argument for the parameter, and it's not optional,
1136 * so it's an error. */
1138 /* We don't handle named params here, go to the next loop. */
1139 if (param_flags
& PARROT_ARG_NAME
)
1143 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1144 "too few positional arguments: %d passed, %d (or more) expected",
1145 positional_args
, param_index
+ 1);
1148 /* Go on to next argument and parameter. */
1153 /* Now iterate over the named arguments and parameters. */
1155 STRING
*param_name
= NULL
;
1158 /* Check if we've used up all the parameters. We'll check for leftover
1159 * named args after the loop. */
1160 if (param_index
>= param_count
)
1163 param_flags
= raw_params
[param_index
];
1165 /* All remaining parameters must be named. */
1166 if (!(param_flags
& PARROT_ARG_NAME
)) {
1167 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1168 "named parameters must follow all positional parameters");
1171 if (arg_index
< positional_args
) {
1172 /* We've used up all the positional parameters, but have extra
1173 * positional args left over. */
1174 if (VTABLE_get_integer_keyed_int(interp
, arg_sig
, arg_index
) & PARROT_ARG_NAME
) {
1175 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1176 "named arguments must follow all positional arguments");
1178 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1179 "too many positional arguments: %d passed, %d expected",
1180 positional_args
, param_index
);
1183 /* Collected ("slurpy") named parameter */
1184 if (param_flags
& PARROT_ARG_SLURPY_ARRAY
) {
1185 PMC
* const collect_named
= pmc_new(interp
,
1186 Parrot_get_ctx_HLL_type(interp
, enum_class_Hash
));
1187 PMC
*named_arg_list
= VTABLE_get_attr_str(interp
, call_object
, CONST_STRING(interp
, "named"));
1188 if (!PMC_IS_NULL(named_arg_list
)) {
1189 INTVAL named_arg_count
= VTABLE_elements(interp
, named_arg_list
);
1190 INTVAL named_arg_index
;
1192 /* Named argument iteration. */
1193 for (named_arg_index
= 0; named_arg_index
< named_arg_count
; named_arg_index
++) {
1194 STRING
*name
= VTABLE_get_string_keyed_int(interp
,
1195 named_arg_list
, named_arg_index
);
1197 if ((PMC_IS_NULL(named_used_list
)) ||
1198 !VTABLE_exists_keyed_str(interp
, named_used_list
, name
)) {
1199 VTABLE_set_pmc_keyed_str(interp
, collect_named
, name
,
1200 VTABLE_get_pmc_keyed_str(interp
, call_object
, name
));
1201 /* Mark the name as used, cannot be filled again. */
1202 if (PMC_IS_NULL(named_used_list
)) /* Only created if needed. */
1203 named_used_list
= pmc_new(interp
, enum_class_Hash
);
1204 VTABLE_set_integer_keyed_str(interp
, named_used_list
, name
, 1);
1210 *accessor
->pmc(interp
, arg_info
, param_index
) = collect_named
;
1211 break; /* End of named parameters. */
1214 /* Store the name. */
1215 if (!(param_flags
& PARROT_ARG_STRING
))
1216 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1217 "named parameters must have a name specified");
1218 param_name
= PARROT_ARG_CONSTANT_ISSET(param_flags
)
1219 ? accessor
->string_constant(interp
, arg_info
, param_index
)
1220 : *accessor
->string(interp
, arg_info
, param_index
);
1222 if (!STRING_IS_NULL(param_name
)) {
1223 /* The next parameter is the actual value. */
1225 if (param_index
>= param_count
)
1228 param_flags
= raw_params
[param_index
];
1230 if (VTABLE_exists_keyed_str(interp
, call_object
, param_name
)) {
1232 /* Mark the name as used, cannot be filled again. */
1233 if (PMC_IS_NULL(named_used_list
)) /* Only created if needed. */
1234 named_used_list
= pmc_new(interp
, enum_class_Hash
);
1235 VTABLE_set_integer_keyed_str(interp
, named_used_list
, param_name
, 1);
1238 /* Fill the named parameter. */
1239 switch (PARROT_ARG_TYPE_MASK_MASK(param_flags
)) {
1240 case PARROT_ARG_INTVAL
:
1241 *accessor
->intval(interp
, arg_info
, param_index
) =
1242 VTABLE_get_integer_keyed_str(interp
, call_object
, param_name
);
1244 case PARROT_ARG_FLOATVAL
:
1245 *accessor
->numval(interp
, arg_info
, param_index
) =
1246 VTABLE_get_number_keyed_str(interp
, call_object
, param_name
);
1248 case PARROT_ARG_STRING
:
1249 *accessor
->string(interp
, arg_info
, param_index
) =
1250 VTABLE_get_string_keyed_str(interp
, call_object
, param_name
);
1252 case PARROT_ARG_PMC
:
1253 *accessor
->pmc(interp
, arg_info
, param_index
) =
1254 VTABLE_get_pmc_keyed_str(interp
, call_object
, param_name
);
1257 Parrot_ex_throw_from_c_args(interp
, NULL
,
1258 EXCEPTION_INVALID_OPERATION
, "invalid parameter type");
1262 /* Mark the option flag for the filled parameter. */
1263 if (param_flags
& PARROT_ARG_OPTIONAL
) {
1264 INTVAL next_param_flags
;
1266 if (param_index
+ 1 < param_count
) {
1267 next_param_flags
= raw_params
[param_index
+ 1];
1269 if (next_param_flags
& PARROT_ARG_OPT_FLAG
) {
1271 *accessor
->intval(interp
, arg_info
, param_index
) = 1;
1276 else if (param_flags
& PARROT_ARG_OPTIONAL
) {
1277 INTVAL next_param_flags
;
1279 assign_default_param_value(interp
, param_index
, param_flags
,
1280 arg_info
, accessor
);
1282 /* Mark the option flag for the parameter to FALSE, it was filled
1283 * with a default value. */
1284 if (param_index
+ 1 < param_count
) {
1285 next_param_flags
= raw_params
[param_index
+ 1];
1287 if (next_param_flags
& PARROT_ARG_OPT_FLAG
) {
1289 *accessor
->intval(interp
, arg_info
, param_index
) = 0;
1293 /* We don't have an argument for the parameter, and it's not optional,
1294 * so it's an error. */
1297 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1298 "too few named arguments: no argument for required parameter '%S'",
1306 /* Double check that all named arguments were assigned to parameters. */
1308 PMC
*named_arg_list
;
1310 /* Early exit to avoid vtable call */
1311 GETATTR_CallSignature_hash(interp
, call_object
, h
);
1312 if (!h
|| !h
->entries
)
1315 named_arg_list
= VTABLE_get_attr_str(interp
, call_object
, CONST_STRING(interp
, "named"));
1316 if (!PMC_IS_NULL(named_arg_list
)) {
1317 INTVAL named_arg_count
= VTABLE_elements(interp
, named_arg_list
);
1318 if (PMC_IS_NULL(named_used_list
))
1320 /* The 'return' above is a temporary hack to duplicate an old bug,
1321 * and will be replaced by the exception below at the next
1322 * deprecation point, see TT #1103
1324 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
1325 "too many named arguments: %d passed, 0 used",
1328 if (named_arg_count
> named_count
) {
1329 /* At this point we know we have named arguments that weren't
1330 * assigned to parameters. We're going to throw an exception
1331 * anyway, so spend a little extra effort to tell the user *which*
1332 * named argument is extra. */
1333 INTVAL named_arg_index
;
1335 /* Named argument iteration. */
1336 for (named_arg_index
= 0; named_arg_index
< named_arg_count
; named_arg_index
++) {
1337 STRING
*name
= VTABLE_get_string_keyed_int(interp
,
1338 named_arg_list
, named_arg_index
);
1340 if (!VTABLE_exists_keyed_str(interp
, named_used_list
, name
)) {
1341 Parrot_ex_throw_from_c_args(interp
, NULL
,
1342 EXCEPTION_INVALID_OPERATION
,
1343 "too many named arguments: '%S' not used",
1354 =item C<static void assign_default_param_value(PARROT_INTERP, INTVAL
1355 param_index, INTVAL param_flags, void *arg_info, struct pcc_set_funcs
1358 Assign an appropriate default value to the parameter depending on its type
1365 assign_default_param_value(PARROT_INTERP
, INTVAL param_index
, INTVAL param_flags
,
1366 ARGIN(void *arg_info
), ARGIN(struct pcc_set_funcs
*accessor
))
1368 ASSERT_ARGS(assign_default_param_value
)
1369 switch (PARROT_ARG_TYPE_MASK_MASK(param_flags
)) {
1370 case PARROT_ARG_INTVAL
:
1371 *accessor
->intval(interp
, arg_info
, param_index
) = 0;
1373 case PARROT_ARG_FLOATVAL
:
1374 *accessor
->numval(interp
, arg_info
, param_index
) = 0.0;
1376 case PARROT_ARG_STRING
:
1377 *accessor
->string(interp
, arg_info
, param_index
) = NULL
;
1379 case PARROT_ARG_PMC
:
1380 *accessor
->pmc(interp
, arg_info
, param_index
) = PMCNULL
;
1383 Parrot_ex_throw_from_c_args(interp
, NULL
,
1384 EXCEPTION_INVALID_OPERATION
, "invalid parameter type");
1391 =item C<static void assign_default_result_value(PARROT_INTERP, PMC *results,
1392 INTVAL index, INTVAL result_flags)>
1394 Assign an appropriate default value to the result depending on its type
1401 assign_default_result_value(PARROT_INTERP
, ARGMOD(PMC
*results
), INTVAL index
, INTVAL result_flags
)
1403 ASSERT_ARGS(assign_default_result_value
)
1404 switch (PARROT_ARG_TYPE_MASK_MASK(result_flags
)) {
1405 case PARROT_ARG_INTVAL
:
1406 VTABLE_set_integer_keyed_int(interp
, results
, index
, 0);
1408 case PARROT_ARG_FLOATVAL
:
1409 VTABLE_set_number_keyed_int(interp
, results
, index
, 0.0);
1411 case PARROT_ARG_STRING
:
1412 VTABLE_set_string_keyed_int(interp
, results
, index
, NULL
);
1414 case PARROT_ARG_PMC
:
1415 VTABLE_set_pmc_keyed_int(interp
, results
, index
, PMCNULL
);
1418 Parrot_ex_throw_from_c_args(interp
, NULL
,
1419 EXCEPTION_INVALID_OPERATION
, "invalid parameter type");
1426 =item C<void Parrot_pcc_fill_params_from_op(PARROT_INTERP, PMC *call_object, PMC
1427 *raw_sig, opcode_t *raw_params)>
1429 Gets args for the current function call and puts them into position.
1430 First it gets the positional non-slurpy parameters, then the positional
1431 slurpy parameters, then the named parameters, and finally the named
1440 Parrot_pcc_fill_params_from_op(PARROT_INTERP
, ARGMOD_NULLOK(PMC
*call_object
),
1441 ARGIN(PMC
*raw_sig
), ARGIN(opcode_t
*raw_params
))
1443 ASSERT_ARGS(Parrot_pcc_fill_params_from_op
)
1445 static pcc_set_funcs function_pointers
= {
1446 (intval_ptr_func_t
)intval_param_from_op
,
1447 (numval_ptr_func_t
)numval_param_from_op
,
1448 (string_ptr_func_t
)string_param_from_op
,
1449 (pmc_ptr_func_t
)pmc_param_from_op
,
1451 (intval_func_t
)intval_constant_from_op
,
1452 (numval_func_t
)numval_constant_from_op
,
1453 (string_func_t
)string_constant_from_op
,
1454 (pmc_func_t
)pmc_constant_from_op
,
1457 fill_params(interp
, call_object
, raw_sig
, raw_params
, &function_pointers
);
1462 =item C<void Parrot_pcc_fill_params_from_c_args(PARROT_INTERP, PMC *call_object,
1463 const char *signature, ...)>
1465 Gets args for the current function call and puts them into position.
1466 First it gets the positional non-slurpy parameters, then the positional
1467 slurpy parameters, then the named parameters, and finally the named
1470 The signature is a string in the format used for
1471 C<Parrot_pcc_invoke_from_sig_object>, but with no return arguments. The
1472 parameters are passed in as a list of references to the destination
1481 Parrot_pcc_fill_params_from_c_args(PARROT_INTERP
, ARGMOD(PMC
*call_object
),
1482 ARGIN(const char *signature
), ...)
1484 ASSERT_ARGS(Parrot_pcc_fill_params_from_c_args
)
1486 PMC
*raw_sig
= PMCNULL
;
1487 PMC
*invalid_sig
= PMCNULL
;
1488 static pcc_set_funcs function_pointers
= {
1489 (intval_ptr_func_t
)intval_param_from_c_args
,
1490 (numval_ptr_func_t
)numval_param_from_c_args
,
1491 (string_ptr_func_t
)string_param_from_c_args
,
1492 (pmc_ptr_func_t
)pmc_param_from_c_args
,
1494 (intval_func_t
)intval_constant_from_varargs
,
1495 (numval_func_t
)numval_constant_from_varargs
,
1496 (string_func_t
)string_constant_from_varargs
,
1497 (pmc_func_t
)pmc_constant_from_varargs
,
1500 parse_signature_string(interp
, signature
, &raw_sig
, &invalid_sig
);
1501 if (!PMC_IS_NULL(invalid_sig
))
1502 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1503 "returns should not be included in the parameter list");
1505 va_start(args
, signature
);
1506 fill_params(interp
, call_object
, raw_sig
, &args
, &function_pointers
);
1512 =item C<static void fill_results(PARROT_INTERP, PMC *call_object, PMC *raw_sig,
1513 void *return_info, struct pcc_get_funcs *accessor)>
1515 Gets return values for the current return and puts them into position.
1516 First it gets the positional non-slurpy returns, then the positional
1517 slurpy returns, then the named returns, and finally the named
1525 fill_results(PARROT_INTERP
, ARGMOD_NULLOK(PMC
*call_object
),
1526 ARGIN(PMC
*raw_sig
), ARGIN(void *return_info
), ARGIN(struct pcc_get_funcs
*accessor
))
1528 ASSERT_ARGS(fill_results
)
1529 INTVAL
*return_array
;
1530 INTVAL
*result_array
;
1532 PMC
*result_sig
= NULL
;
1533 PMC
*ctx
= CURRENT_CONTEXT(interp
);
1534 PMC
*named_used_list
= PMCNULL
;
1535 PMC
*named_return_list
= PMCNULL
;
1536 INTVAL return_index
= 0;
1537 INTVAL return_subindex
= 0;
1538 INTVAL result_index
= 0;
1539 INTVAL positional_index
= 0;
1540 INTVAL named_count
= 0;
1541 INTVAL err_check
= 0;
1542 INTVAL positional_returns
= 0; /* initialized by a loop later */
1543 INTVAL i
= 0; /* used by the initialization loop */
1544 INTVAL return_count
;
1545 INTVAL result_count
;
1547 /* Check if we should be throwing errors. This is configured separately
1548 * for parameters and return values. */
1549 if (PARROT_ERRORS_test(interp
, PARROT_ERRORS_RESULT_COUNT_FLAG
))
1552 GETATTR_FixedIntegerArray_size(interp
, raw_sig
, return_count
);
1554 /* A null call object is fine if there are no returns and no results. */
1555 if (PMC_IS_NULL(call_object
)) {
1556 /* If the return_count is 0, then there are no return values waiting to
1557 * fill the results, so no error. */
1558 if (return_count
> 0 && (err_check
))
1559 Parrot_ex_throw_from_c_args(interp
, NULL
,
1560 EXCEPTION_INVALID_OPERATION
,
1561 "too few returns: 0 passed, %d expected", return_count
);
1566 GETATTR_CallSignature_results(interp
, call_object
, result_list
);
1567 GETATTR_CallSignature_return_flags(interp
, call_object
, result_sig
);
1569 result_count
= PMC_IS_NULL(result_list
) ? 0 : VTABLE_elements(interp
, result_list
);
1570 PARROT_ASSERT(PMC_IS_NULL(result_list
) || !PMC_IS_NULL(result_sig
));
1572 GETATTR_FixedIntegerArray_int_array(interp
, raw_sig
, return_array
);
1573 if (!PMC_IS_NULL(result_sig
))
1574 GETATTR_FixedIntegerArray_int_array(interp
, result_sig
, result_array
);
1576 /* the call obj doesn't have the returns as positionals.
1577 * instead count number of returns before first named return */
1578 for (i
= 0; i
< return_count
; i
++) {
1579 INTVAL flags
= return_array
[i
];
1580 if (flags
& PARROT_ARG_NAME
)
1583 positional_returns
++;
1587 Parrot_io_eprintf(interp,
1588 "return_count: %d\nresult_count: %d\npositional_returns: %d\nraw_sig: %S\nresult_sig: %S\n",
1589 return_count, result_count, positional_returns, VTABLE_get_repr(interp, raw_sig),
1590 VTABLE_get_repr(interp, result_sig));
1594 INTVAL result_flags
;
1596 /* Check if we've used up all the results. */
1597 if (result_index
>= result_count
) {
1598 if (return_index
>= return_count
) {
1599 /* We've used up all returns and results, we're
1600 * done with the whole process. */
1603 else if (err_check
) {
1604 /* We've used up all the results, but have extra positional
1605 * returns left over. */
1606 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1607 "too many positional returns: %d passed, %d expected",
1608 return_index
, result_count
);
1613 result_flags
= result_array
[result_index
];
1615 /* If the result is slurpy, collect all remaining positional
1616 * returns into an array.*/
1617 if (result_flags
& PARROT_ARG_SLURPY_ARRAY
) {
1618 PMC
*collect_positional
;
1620 /* Can't handle named slurpy here, go on to named return handling. */
1621 if (result_flags
& PARROT_ARG_NAME
)
1624 if (named_count
> 0)
1625 Parrot_ex_throw_from_c_args(interp
, NULL
,
1626 EXCEPTION_INVALID_OPERATION
,
1627 "named results must follow all positional results");
1629 collect_positional
= pmc_new(interp
,
1630 Parrot_get_ctx_HLL_type(interp
, enum_class_ResizablePMCArray
));
1632 /* Iterate over all positional returns in the list. */
1635 INTVAL return_flags
;
1636 if (return_index
>= return_count
)
1637 break; /* no more returns */
1639 return_flags
= return_array
[return_index
];
1641 if (return_flags
& PARROT_ARG_NAME
)
1642 break; /* stop at named returns */
1644 constant
= PARROT_ARG_CONSTANT_ISSET(return_flags
);
1645 switch (PARROT_ARG_TYPE_MASK_MASK(return_flags
)) {
1646 case PARROT_ARG_INTVAL
:
1647 VTABLE_push_integer(interp
, collect_positional
, constant
?
1648 accessor
->intval_constant(interp
, return_info
, return_index
)
1649 :accessor
->intval(interp
, return_info
, return_index
));
1651 case PARROT_ARG_FLOATVAL
:
1652 VTABLE_push_float(interp
, collect_positional
, constant
?
1653 accessor
->numval_constant(interp
, return_info
, return_index
)
1654 :accessor
->numval(interp
, return_info
, return_index
));
1656 case PARROT_ARG_STRING
:
1657 VTABLE_push_string(interp
, collect_positional
, constant
?
1658 accessor
->string_constant(interp
, return_info
, return_index
)
1659 :accessor
->string(interp
, return_info
, return_index
));
1661 case PARROT_ARG_PMC
:
1663 PMC
*return_item
= (constant
)
1664 ? accessor
->pmc_constant(interp
, return_info
, return_index
)
1665 : accessor
->pmc(interp
, return_info
, return_index
);
1666 if (return_flags
& PARROT_ARG_FLATTEN
) {
1669 if (!VTABLE_does(interp
, return_item
, CONST_STRING(interp
, "array"))) {
1670 Parrot_ex_throw_from_c_args(interp
, NULL
,
1671 EXCEPTION_INVALID_OPERATION
,
1672 "flattened return on a non-array");
1674 flat_elems
= VTABLE_elements(interp
, return_item
);
1675 for (flat_pos
= 0; flat_pos
< flat_elems
; flat_pos
++) {
1676 /* fetch an item out of the aggregate */
1677 VTABLE_push_pmc(interp
, collect_positional
,
1678 VTABLE_get_pmc_keyed_int(interp
, return_item
, flat_pos
));
1682 VTABLE_push_pmc(interp
, collect_positional
, return_item
);
1686 Parrot_ex_throw_from_c_args(interp
, NULL
,
1687 EXCEPTION_INVALID_OPERATION
, "invalid return type");
1692 VTABLE_set_pmc_keyed_int(interp
, result_list
, result_index
, collect_positional
);
1694 break; /* Terminate the positional return loop. */
1697 /* We have a positional return, fill the result with it. */
1698 if (return_index
< positional_returns
) {
1699 INTVAL return_flags
= return_array
[return_index
];
1700 INTVAL constant
= PARROT_ARG_CONSTANT_ISSET(return_flags
);
1702 /* Fill a named result with a positional return. */
1703 if (result_flags
& PARROT_ARG_NAME
) {
1704 STRING
*result_name
;
1705 if (!(result_flags
& PARROT_ARG_STRING
))
1706 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1707 "named results must have a name specified 1683");
1708 result_name
= VTABLE_get_string_keyed_int(interp
, result_list
, result_index
);
1711 if (result_index
>= result_count
)
1713 result_flags
= result_array
[result_index
];
1715 /* Mark the name as used, cannot be filled again. */
1716 if (PMC_IS_NULL(named_used_list
)) /* Only created if needed. */
1717 named_used_list
= pmc_new(interp
,
1718 Parrot_get_ctx_HLL_type(interp
, enum_class_Hash
));
1719 VTABLE_set_integer_keyed_str(interp
, named_used_list
, result_name
, 1);
1721 else if (named_count
> 0) {
1722 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1723 "named results must follow all positional results");
1726 /* Check for :lookahead result goes here. */
1728 /* Go ahead and fill the result with a positional return. */
1729 switch (PARROT_ARG_TYPE_MASK_MASK(return_flags
)) {
1730 case PARROT_ARG_INTVAL
:
1732 VTABLE_set_integer_keyed_int(interp
, result_list
, result_index
,
1733 accessor
->intval_constant(interp
, return_info
, return_index
));
1735 VTABLE_set_integer_keyed_int(interp
, result_list
, result_index
,
1736 accessor
->intval(interp
, return_info
, return_index
));
1738 case PARROT_ARG_FLOATVAL
:
1740 VTABLE_set_number_keyed_int(interp
, result_list
, result_index
,
1741 accessor
->numval_constant(interp
, return_info
, return_index
));
1743 VTABLE_set_number_keyed_int(interp
, result_list
, result_index
,
1744 accessor
->numval(interp
, return_info
, return_index
));
1746 case PARROT_ARG_STRING
:
1748 VTABLE_set_string_keyed_int(interp
, result_list
, result_index
,
1749 accessor
->string_constant(interp
, return_info
, return_index
));
1751 VTABLE_set_string_keyed_int(interp
, result_list
, result_index
,
1752 accessor
->string(interp
, return_info
, return_index
));
1754 case PARROT_ARG_PMC
:
1756 PMC
*return_item
= (constant
)
1757 ? accessor
->pmc_constant(interp
, return_info
, return_index
)
1758 : accessor
->pmc(interp
, return_info
, return_index
);
1759 if (return_flags
& PARROT_ARG_FLATTEN
) {
1761 if (!VTABLE_does(interp
, return_item
, CONST_STRING(interp
, "array"))) {
1762 Parrot_ex_throw_from_c_args(interp
, NULL
,
1763 EXCEPTION_INVALID_OPERATION
,
1764 "flattened return on a non-array");
1766 flat_elems
= VTABLE_elements(interp
, return_item
);
1767 if (flat_elems
== 0) {
1768 /* Skip empty aggregate */
1771 if (return_subindex
< flat_elems
) {
1772 /* fetch an item out of the aggregate */
1773 return_item
= VTABLE_get_pmc_keyed_int(interp
, return_item
,
1777 if (return_subindex
>= flat_elems
) {
1778 return_subindex
= 0; /* reset */
1781 return_index
--; /* we want to stay on the same item */
1784 VTABLE_set_pmc_keyed_int(interp
, result_list
, result_index
, return_item
);
1788 Parrot_ex_throw_from_c_args(interp
, NULL
,
1789 EXCEPTION_INVALID_OPERATION
, "invalid return type");
1793 /* Mark the option flag for the filled result. */
1794 if (result_flags
& PARROT_ARG_OPTIONAL
) {
1795 INTVAL next_result_flags
;
1797 if (result_index
+ 1 < result_count
) {
1798 next_result_flags
= result_array
[result_index
+ 1];
1799 if (next_result_flags
& PARROT_ARG_OPT_FLAG
) {
1801 VTABLE_set_integer_keyed_int(interp
, result_list
, result_index
, 1);
1806 /* We have no more positional returns, fill the optional result
1807 * with a default value. */
1808 else if (result_flags
& PARROT_ARG_OPTIONAL
) {
1809 INTVAL next_result_flags
;
1811 /* We don't handle optional named results here, handle them in the
1813 if (result_flags
& PARROT_ARG_NAME
)
1816 assign_default_result_value(interp
, result_list
, result_index
, result_flags
);
1818 /* Mark the option flag for the result to FALSE, it was filled
1819 * with a default value. */
1820 if (result_index
+ 1 < result_count
) {
1821 next_result_flags
= result_array
[result_index
+ 1];
1822 if (next_result_flags
& PARROT_ARG_OPT_FLAG
) {
1824 VTABLE_set_integer_keyed_int(interp
, result_list
, result_index
, 0);
1828 /* We don't have an return for the result, and it's not optional,
1829 * so it's an error. */
1831 /* We don't handle named results here, go to the next loop. */
1832 if (result_flags
& PARROT_ARG_NAME
)
1836 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1837 "too few positional returns: %d passed, %d (or more) expected",
1838 positional_returns
, result_index
+ 1);
1841 /* Go on to next return and result. */
1846 for (; return_index
< return_count
; return_index
++) {
1847 STRING
*return_name
;
1848 INTVAL return_flags
;
1851 return_flags
= return_array
[return_index
];
1853 /* All remaining returns must be named. */
1854 if (!(return_flags
& PARROT_ARG_NAME
))
1855 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1856 "named returns must follow all positional returns");
1858 if (!(return_flags
& PARROT_ARG_STRING
))
1859 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1860 "named results must have a name specified 1836");
1862 return_name
= PARROT_ARG_CONSTANT_ISSET(return_flags
)
1863 ? accessor
->string_constant(interp
, return_info
, return_index
)
1864 : accessor
->string(interp
, return_info
, return_index
);
1867 if (result_index
>= result_count
)
1868 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1869 "named returns must have a value");
1871 return_flags
= return_array
[return_index
];
1873 if (PMC_IS_NULL(named_return_list
)) /* Only created if needed. */
1874 named_return_list
= pmc_new(interp
,
1875 Parrot_get_ctx_HLL_type(interp
, enum_class_Hash
));
1877 if (VTABLE_exists_keyed_str(interp
, named_return_list
, return_name
))
1880 constant
= PARROT_ARG_CONSTANT_ISSET(return_flags
);
1881 switch (PARROT_ARG_TYPE_MASK_MASK(return_flags
)) {
1882 case PARROT_ARG_INTVAL
:
1883 VTABLE_set_integer_keyed_str(interp
, named_return_list
, return_name
,
1885 ? accessor
->intval_constant(interp
, return_info
, return_index
)
1886 : accessor
->intval(interp
, return_info
, return_index
));
1888 case PARROT_ARG_FLOATVAL
:
1889 VTABLE_set_number_keyed_str(interp
, named_return_list
, return_name
,
1891 ? accessor
->numval_constant(interp
, return_info
, return_index
)
1892 : accessor
->numval(interp
, return_info
, return_index
));
1894 case PARROT_ARG_STRING
:
1895 VTABLE_set_string_keyed_str(interp
, named_return_list
, return_name
,
1897 ? accessor
->string_constant(interp
, return_info
, return_index
)
1898 : accessor
->string(interp
, return_info
, return_index
));
1900 case PARROT_ARG_PMC
:
1902 PMC
*return_item
= (constant
)
1903 ? accessor
->pmc_constant(interp
, return_info
, return_index
)
1904 : accessor
->pmc(interp
, return_info
, return_index
);
1905 if (return_flags
& PARROT_ARG_FLATTEN
) {
1906 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1907 "named flattened returns not yet implemented");
1909 VTABLE_set_pmc_keyed_str(interp
, named_return_list
, return_name
, return_item
);
1913 Parrot_ex_throw_from_c_args(interp
, NULL
,
1914 EXCEPTION_INVALID_OPERATION
, "invalid return type");
1919 /* Now iterate over the named results, filling them from the
1920 * temporary hash of named returns. */
1922 STRING
*result_name
= NULL
;
1923 INTVAL result_flags
;
1925 /* Check if we've used up all the results. We'll check for leftover
1926 * named returns after the loop. */
1927 if (result_index
>= result_count
)
1930 result_flags
= result_array
[result_index
];
1932 /* All remaining results must be named. */
1933 if (!(result_flags
& PARROT_ARG_NAME
))
1934 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1935 "named results must follow all positional results");
1937 /* Collected ("slurpy") named result */
1938 if (result_flags
& PARROT_ARG_SLURPY_ARRAY
) {
1939 if (PMC_IS_NULL(named_return_list
))
1940 named_return_list
= pmc_new(interp
,
1941 Parrot_get_ctx_HLL_type(interp
, enum_class_Hash
));
1943 VTABLE_set_pmc_keyed_int(interp
, result_list
, result_index
, named_return_list
);
1944 break; /* End of named results. */
1947 /* Store the name. */
1948 if (!(result_flags
& PARROT_ARG_STRING
))
1949 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
1950 "named results must have a name specified 1926");
1951 result_name
= VTABLE_get_string_keyed_int(interp
, result_list
, result_index
);
1953 if (!STRING_IS_NULL(result_name
)) {
1954 /* The next result is the actual value. */
1956 if (result_index
>= result_count
)
1958 result_flags
= result_array
[result_index
];
1960 if (VTABLE_exists_keyed_str(interp
, named_return_list
, result_name
)) {
1964 /* Fill the named result. */
1965 switch (PARROT_ARG_TYPE_MASK_MASK(result_flags
)) {
1966 case PARROT_ARG_INTVAL
:
1967 VTABLE_set_integer_keyed_int(interp
, result_list
, result_index
,
1968 VTABLE_get_integer_keyed_str(interp
, named_return_list
, result_name
));
1970 case PARROT_ARG_FLOATVAL
:
1971 VTABLE_set_number_keyed_int(interp
, result_list
, result_index
,
1972 VTABLE_get_number_keyed_str(interp
, named_return_list
, result_name
));
1974 case PARROT_ARG_STRING
:
1975 VTABLE_set_string_keyed_int(interp
, result_list
, result_index
,
1976 VTABLE_get_string_keyed_str(interp
, named_return_list
, result_name
));
1978 case PARROT_ARG_PMC
:
1979 VTABLE_set_pmc_keyed_int(interp
, result_list
, result_index
,
1980 VTABLE_get_pmc_keyed_str(interp
, named_return_list
, result_name
));
1983 Parrot_ex_throw_from_c_args(interp
, NULL
,
1984 EXCEPTION_INVALID_OPERATION
, "invalid result type");
1987 VTABLE_delete_keyed_str(interp
, named_return_list
, result_name
);
1989 /* Mark the option flag for the filled result. */
1990 if (result_flags
& PARROT_ARG_OPTIONAL
) {
1991 INTVAL next_result_flags
;
1993 if (result_index
+ 1 < result_count
) {
1994 next_result_flags
= return_array
[result_index
+ 1];
1995 if (next_result_flags
& PARROT_ARG_OPT_FLAG
) {
1997 VTABLE_set_integer_keyed_int(interp
, result_list
, result_index
, 1);
2002 else if (result_flags
& PARROT_ARG_OPTIONAL
) {
2003 INTVAL next_result_flags
;
2005 assign_default_result_value(interp
, result_list
, result_index
, result_flags
);
2007 /* Mark the option flag for the result to FALSE, it was filled
2008 * with a default value. */
2009 if (result_index
+ 1 < result_count
) {
2010 next_result_flags
= result_array
[result_index
+ 1];
2011 if (next_result_flags
& PARROT_ARG_OPT_FLAG
) {
2013 VTABLE_set_integer_keyed_int(interp
, result_list
, result_index
, 1);
2017 /* We don't have a return for the result, and it's not optional,
2018 * so it's an error. */
2021 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
2022 "too few named returns: no return for required result '%S'",
2030 /* Double check that all named returns were assigned to results. */
2032 if (!PMC_IS_NULL(named_return_list
)) {
2033 INTVAL named_return_count
= VTABLE_elements(interp
, named_return_list
);
2034 if (named_return_count
> 0)
2035 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
2036 "too many named returns: %d passed, %d used",
2037 named_return_count
+ named_count
, named_count
);
2045 =item C<void Parrot_pcc_fill_returns_from_op(PARROT_INTERP, PMC *call_object,
2046 PMC *raw_sig, opcode_t *raw_returns)>
2048 Sets return values for the current function call. First it sets the
2049 positional returns, then the named returns.
2057 Parrot_pcc_fill_returns_from_op(PARROT_INTERP
, ARGMOD_NULLOK(PMC
*call_object
),
2058 ARGIN(PMC
*raw_sig
), ARGIN(opcode_t
*raw_returns
))
2060 ASSERT_ARGS(Parrot_pcc_fill_returns_from_op
)
2061 INTVAL raw_return_count
= VTABLE_elements(interp
, raw_sig
);
2062 INTVAL err_check
= 0;
2063 static pcc_get_funcs function_pointers
= {
2064 (intval_func_t
)intval_arg_from_op
,
2065 (numval_func_t
)numval_arg_from_op
,
2066 (string_func_t
)string_arg_from_op
,
2067 (pmc_func_t
)pmc_arg_from_op
,
2069 (intval_func_t
)intval_constant_from_op
,
2070 (numval_func_t
)numval_constant_from_op
,
2071 (string_func_t
)string_constant_from_op
,
2072 (pmc_func_t
)pmc_constant_from_op
,
2076 /* Check if we should be throwing errors. This is configured separately
2077 * for parameters and return values. */
2078 if (PARROT_ERRORS_test(interp
, PARROT_ERRORS_RESULT_COUNT_FLAG
))
2081 /* A null call object is fine if there are no arguments and no returns. */
2082 if (PMC_IS_NULL(call_object
)) {
2083 if (raw_return_count
> 0) {
2085 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
2086 "too many return values: %d passed, 0 expected",
2092 fill_results(interp
, call_object
, raw_sig
, raw_returns
, &function_pointers
);
2098 =item C<void Parrot_pcc_fill_returns_from_continuation(PARROT_INTERP, PMC
2099 *call_object, PMC *raw_sig, PMC *from_call_obj)>
2101 Evil function. Fill results from arguments passed to a continuation.
2102 Only works for positional arguments.
2110 Parrot_pcc_fill_returns_from_continuation(PARROT_INTERP
, ARGMOD_NULLOK(PMC
*call_object
),
2111 ARGIN(PMC
*raw_sig
), ARGIN(PMC
*from_call_obj
))
2113 ASSERT_ARGS(Parrot_pcc_fill_returns_from_continuation
)
2114 INTVAL raw_return_count
= VTABLE_elements(interp
, raw_sig
);
2115 INTVAL err_check
= 0;
2116 static pcc_get_funcs function_pointers
= {
2117 (intval_func_t
)intval_arg_from_continuation
,
2118 (numval_func_t
)numval_arg_from_continuation
,
2119 (string_func_t
)string_arg_from_continuation
,
2120 (pmc_func_t
)pmc_arg_from_continuation
,
2122 (intval_func_t
)intval_arg_from_continuation
,
2123 (numval_func_t
)numval_arg_from_continuation
,
2124 (string_func_t
)string_arg_from_continuation
,
2125 (pmc_func_t
)pmc_arg_from_continuation
,
2129 /* Check if we should be throwing errors. This is configured separately
2130 * for parameters and return values. */
2131 if (PARROT_ERRORS_test(interp
, PARROT_ERRORS_RESULT_COUNT_FLAG
))
2134 /* A null call object is fine if there are no arguments and no returns. */
2135 if (PMC_IS_NULL(call_object
)) {
2136 if (raw_return_count
> 0) {
2138 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
2139 "too many return values: %d passed, 0 expected",
2145 fill_results(interp
, call_object
, raw_sig
, from_call_obj
, &function_pointers
);
2152 =item C<void Parrot_pcc_fill_returns_from_c_args(PARROT_INTERP, PMC
2153 *call_object, const char *signature, ...)>
2155 Sets return values for the current function call. First it sets the
2156 positional returns, then the named returns.
2158 The signature is a string in the format used for
2159 C<Parrot_pcc_invoke_from_sig_object>, but with only return arguments.
2160 The parameters are passed in as a list of INTVAL, FLOATVAL, STRING *, or
2170 Parrot_pcc_fill_returns_from_c_args(PARROT_INTERP
, ARGMOD_NULLOK(PMC
*call_object
),
2171 ARGIN(const char *signature
), ...)
2173 ASSERT_ARGS(Parrot_pcc_fill_returns_from_c_args
)
2175 INTVAL raw_return_count
= 0;
2176 INTVAL err_check
= 0;
2177 PMC
*raw_sig
= PMCNULL
;
2178 PMC
*invalid_sig
= PMCNULL
;
2180 static pcc_get_funcs function_pointers
= {
2181 (intval_func_t
)intval_arg_from_c_args
,
2182 (numval_func_t
)numval_arg_from_c_args
,
2183 (string_func_t
)string_arg_from_c_args
,
2184 (pmc_func_t
)pmc_arg_from_c_args
,
2186 (intval_func_t
)intval_constant_from_varargs
,
2187 (numval_func_t
)numval_constant_from_varargs
,
2188 (string_func_t
)string_constant_from_varargs
,
2189 (pmc_func_t
)pmc_constant_from_varargs
,
2192 parse_signature_string(interp
, signature
, &raw_sig
, &invalid_sig
);
2193 if (!PMC_IS_NULL(invalid_sig
))
2194 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
2195 "parameters should not be included in the return signature");
2197 raw_return_count
= VTABLE_elements(interp
, raw_sig
);
2199 /* Check if we should be throwing errors. This is configured separately
2200 * for parameters and return values. */
2201 if (PARROT_ERRORS_test(interp
, PARROT_ERRORS_RESULT_COUNT_FLAG
))
2204 /* A null call object is fine if there are no arguments and no returns. */
2205 if (PMC_IS_NULL(call_object
)) {
2206 if (raw_return_count
> 0)
2208 Parrot_ex_throw_from_c_args(interp
, NULL
,
2209 EXCEPTION_INVALID_OPERATION
,
2210 "too many return values: %d passed, 0 expected",
2215 va_start(args
, signature
);
2216 fill_results(interp
, call_object
, raw_sig
, &args
, &function_pointers
);
2222 =item C<static void parse_signature_string(PARROT_INTERP, const char *signature,
2223 PMC **arg_flags, PMC **return_flags)>
2225 Parses a signature string and creates call and return signature integer
2226 arrays. The two integer arrays should be passed in as references to a
2233 PARROT_CAN_RETURN_NULL
2235 parse_signature_string(PARROT_INTERP
, ARGIN(const char *signature
),
2236 ARGMOD(PMC
**arg_flags
), ARGMOD(PMC
**return_flags
))
2238 ASSERT_ARGS(parse_signature_string
)
2244 if (PMC_IS_NULL(*arg_flags
))
2245 *arg_flags
= pmc_new(interp
, enum_class_ResizableIntegerArray
);
2246 current_array
= *arg_flags
;
2248 for (x
= signature
; *x
!= '\0'; x
++) {
2250 /* detect -> separator */
2255 /* Starting a new argument, so store the previous argument,
2256 * if there was one. */
2258 VTABLE_push_integer(interp
, current_array
, flags
);
2262 /* Switch to the return argument flags. */
2263 if (PMC_IS_NULL(*return_flags
))
2264 *return_flags
= pmc_new(interp
, enum_class_ResizableIntegerArray
);
2265 current_array
= *return_flags
;
2267 /* parse arg type */
2268 else if (isupper((unsigned char)*x
)) {
2269 /* Starting a new argument, so store the previous argument,
2270 * if there was one. */
2272 VTABLE_push_integer(interp
, current_array
, flags
);
2277 case 'I': flags
= PARROT_ARG_INTVAL
; set
++; break;
2278 case 'N': flags
= PARROT_ARG_FLOATVAL
; set
++; break;
2279 case 'S': flags
= PARROT_ARG_STRING
; set
++; break;
2280 case 'P': flags
= PARROT_ARG_PMC
; set
++; break;
2282 Parrot_ex_throw_from_c_args(interp
, NULL
,
2283 EXCEPTION_INVALID_OPERATION
,
2284 "invalid signature string element %c!", *x
);
2288 /* parse arg adverbs */
2289 else if (islower((unsigned char)*x
)) {
2291 case 'c': flags
|= PARROT_ARG_CONSTANT
; break;
2292 case 'f': flags
|= PARROT_ARG_FLATTEN
; break;
2293 case 'i': flags
|= PARROT_ARG_INVOCANT
; break;
2294 case 'l': flags
|= PARROT_ARG_LOOKAHEAD
; break;
2295 case 'n': flags
|= PARROT_ARG_NAME
; break;
2296 case 'o': flags
|= PARROT_ARG_OPTIONAL
; break;
2297 case 'p': flags
|= PARROT_ARG_OPT_FLAG
; break;
2298 case 's': flags
|= PARROT_ARG_SLURPY_ARRAY
; break;
2300 Parrot_ex_throw_from_c_args(interp
, NULL
,
2301 EXCEPTION_INVALID_OPERATION
,
2302 "invalid signature string element %c!", *x
);
2307 /* Store the final argument, if there was one. */
2309 VTABLE_push_integer(interp
, current_array
, flags
);
2314 =item C<void Parrot_pcc_parse_signature_string(PARROT_INTERP, STRING *signature,
2315 PMC **arg_flags, PMC **return_flags)>
2317 Parses a signature string and creates call and return signature integer
2318 arrays. The two integer arrays should be passed in as references to a
2325 PARROT_CAN_RETURN_NULL
2327 Parrot_pcc_parse_signature_string(PARROT_INTERP
, ARGIN(STRING
*signature
),
2328 ARGMOD(PMC
**arg_flags
), ARGMOD(PMC
**return_flags
))
2330 ASSERT_ARGS(Parrot_pcc_parse_signature_string
)
2331 char *s
= Parrot_str_to_cstring(interp
, signature
);
2332 *arg_flags
= PMCNULL
;
2333 *return_flags
= PMCNULL
;
2334 parse_signature_string(interp
, s
, arg_flags
, return_flags
);
2335 Parrot_str_free_cstring(s
);
2340 =item C<void Parrot_pcc_merge_signature_for_tailcall(PARROT_INTERP, PMC *
2341 parent, PMC * tailcall)>
2343 merge in signatures for tailcall
2350 Parrot_pcc_merge_signature_for_tailcall(PARROT_INTERP
,
2351 ARGMOD_NULLOK(PMC
* parent
), ARGMOD_NULLOK(PMC
* tailcall
))
2353 ASSERT_ARGS(Parrot_pcc_merge_signature_for_tailcall
)
2354 if (PMC_IS_NULL(parent
) || PMC_IS_NULL(tailcall
))
2357 /* Broke encapuslation. Direct poking into CallSignature is much faster */
2360 GETATTR_CallSignature_results(interp
, parent
, results
);
2361 GETATTR_CallSignature_return_flags(interp
, parent
, return_flags
);
2362 SETATTR_CallSignature_results(interp
, tailcall
, results
);
2363 SETATTR_CallSignature_return_flags(interp
, tailcall
, return_flags
);
2369 Get the appropriate argument value from the continuation
2371 =item C<static INTVAL intval_arg_from_continuation(PARROT_INTERP, PMC *cs,
2374 =item C<static FLOATVAL numval_arg_from_continuation(PARROT_INTERP, PMC *cs,
2377 =item C<static STRING* string_arg_from_continuation(PARROT_INTERP, PMC *cs,
2380 =item C<static PMC* pmc_arg_from_continuation(PARROT_INTERP, PMC *cs, INTVAL
2383 Get the appropriate argument value from the op.
2385 =item C<static INTVAL intval_arg_from_op(PARROT_INTERP, opcode_t *raw_args,
2388 =item C<static FLOATVAL numval_arg_from_op(PARROT_INTERP, opcode_t *raw_args,
2391 =item C<static STRING* string_arg_from_op(PARROT_INTERP, opcode_t *raw_args,
2394 =item C<static PMC* pmc_arg_from_op(PARROT_INTERP, opcode_t *raw_args, INTVAL
2397 Get the appropriate parameter value from the op (these are pointers, so the
2398 argument value can be stored into them.)
2400 =item C<static INTVAL* intval_param_from_op(PARROT_INTERP, opcode_t *raw_params,
2401 INTVAL param_index)>
2403 =item C<static FLOATVAL* numval_param_from_op(PARROT_INTERP, opcode_t
2404 *raw_params, INTVAL param_index)>
2406 =item C<static STRING** string_param_from_op(PARROT_INTERP, opcode_t
2407 *raw_params, INTVAL param_index)>
2409 =item C<static PMC** pmc_param_from_op(PARROT_INTERP, opcode_t *raw_params,
2410 INTVAL param_index)>
2412 =item C<static INTVAL intval_constant_from_op(PARROT_INTERP, opcode_t
2413 *raw_params, INTVAL param_index)>
2415 =item C<static FLOATVAL numval_constant_from_op(PARROT_INTERP, opcode_t
2416 *raw_params, INTVAL param_index)>
2418 =item C<static STRING* string_constant_from_op(PARROT_INTERP, opcode_t
2419 *raw_params, INTVAL param_index)>
2421 =item C<static PMC* pmc_constant_from_op(PARROT_INTERP, opcode_t *raw_params,
2422 INTVAL param_index)>
2424 Get the appropriate argument value from varargs.
2426 =item C<static INTVAL intval_arg_from_c_args(PARROT_INTERP, va_list *args,
2427 INTVAL param_index)>
2429 =item C<static FLOATVAL numval_arg_from_c_args(PARROT_INTERP, va_list *args,
2430 INTVAL param_index)>
2432 =item C<static STRING* string_arg_from_c_args(PARROT_INTERP, va_list *args,
2433 INTVAL param_index)>
2435 =item C<static PMC* pmc_arg_from_c_args(PARROT_INTERP, va_list *args, INTVAL
2438 Get the appropriate parameter value from varargs (these are pointers, so they
2439 can be set with the argument value).
2441 =item C<static INTVAL* intval_param_from_c_args(PARROT_INTERP, va_list *args,
2442 INTVAL param_index)>
2444 =item C<static FLOATVAL* numval_param_from_c_args(PARROT_INTERP, va_list *args,
2445 INTVAL param_index)>
2447 =item C<static STRING** string_param_from_c_args(PARROT_INTERP, va_list *args,
2448 INTVAL param_index)>
2450 =item C<static PMC** pmc_param_from_c_args(PARROT_INTERP, va_list *args, INTVAL
2453 Parrot constants cannot be passed from varargs, so these functions are dummies
2454 that throw exceptions.
2456 =item C<static INTVAL intval_constant_from_varargs(PARROT_INTERP, void *data,
2459 =item C<static FLOATVAL numval_constant_from_varargs(PARROT_INTERP, void *data,
2462 =item C<static STRING* string_constant_from_varargs(PARROT_INTERP, void *data,
2465 =item C<static PMC* pmc_constant_from_varargs(PARROT_INTERP, void *data, INTVAL
2468 - More specific comments can be added later
2474 PARROT_CANNOT_RETURN_NULL
2476 intval_arg_from_continuation(PARROT_INTERP
, ARGIN(PMC
*cs
), INTVAL arg_index
)
2478 ASSERT_ARGS(intval_arg_from_continuation
)
2479 const INTVAL ret
= VTABLE_get_integer_keyed_int(interp
, cs
, arg_index
);
2483 PARROT_CANNOT_RETURN_NULL
2485 numval_arg_from_continuation(PARROT_INTERP
, ARGIN(PMC
*cs
), INTVAL arg_index
)
2487 ASSERT_ARGS(numval_arg_from_continuation
)
2488 const FLOATVAL ret
= VTABLE_get_number_keyed_int(interp
, cs
, arg_index
);
2492 PARROT_CANNOT_RETURN_NULL
2494 string_arg_from_continuation(PARROT_INTERP
, ARGIN(PMC
*cs
), INTVAL arg_index
)
2496 ASSERT_ARGS(string_arg_from_continuation
)
2497 STRING
*ret
= VTABLE_get_string_keyed_int(interp
, cs
, arg_index
);
2501 PARROT_CANNOT_RETURN_NULL
2503 pmc_arg_from_continuation(PARROT_INTERP
, ARGIN(PMC
*cs
), INTVAL arg_index
)
2505 ASSERT_ARGS(pmc_arg_from_continuation
)
2506 PMC
*ret
= VTABLE_get_pmc_keyed_int(interp
, cs
, arg_index
);
2510 PARROT_CANNOT_RETURN_NULL
2512 intval_arg_from_op(PARROT_INTERP
, ARGIN(opcode_t
*raw_args
), INTVAL arg_index
)
2514 ASSERT_ARGS(intval_arg_from_op
)
2515 const INTVAL raw_index
= raw_args
[arg_index
+ 2];
2516 return REG_INT(interp
, raw_index
);
2519 PARROT_CANNOT_RETURN_NULL
2521 numval_arg_from_op(PARROT_INTERP
, ARGIN(opcode_t
*raw_args
), INTVAL arg_index
)
2523 ASSERT_ARGS(numval_arg_from_op
)
2524 const INTVAL raw_index
= raw_args
[arg_index
+ 2];
2525 return REG_NUM(interp
, raw_index
);
2528 PARROT_CANNOT_RETURN_NULL
2530 string_arg_from_op(PARROT_INTERP
, ARGIN(opcode_t
*raw_args
), INTVAL arg_index
)
2532 ASSERT_ARGS(string_arg_from_op
)
2533 const INTVAL raw_index
= raw_args
[arg_index
+ 2];
2534 return REG_STR(interp
, raw_index
);
2537 PARROT_CANNOT_RETURN_NULL
2539 pmc_arg_from_op(PARROT_INTERP
, ARGIN(opcode_t
*raw_args
), INTVAL arg_index
)
2541 ASSERT_ARGS(pmc_arg_from_op
)
2542 const INTVAL raw_index
= raw_args
[arg_index
+ 2];
2543 return REG_PMC(interp
, raw_index
);
2546 PARROT_CANNOT_RETURN_NULL
2548 intval_param_from_op(PARROT_INTERP
, ARGIN(opcode_t
*raw_params
), INTVAL param_index
)
2550 ASSERT_ARGS(intval_param_from_op
)
2551 const INTVAL raw_index
= raw_params
[param_index
+ 2];
2552 return ®_INT(interp
, raw_index
);
2555 PARROT_CANNOT_RETURN_NULL
2557 numval_param_from_op(PARROT_INTERP
, ARGIN(opcode_t
*raw_params
), INTVAL param_index
)
2559 ASSERT_ARGS(numval_param_from_op
)
2560 const INTVAL raw_index
= raw_params
[param_index
+ 2];
2561 return ®_NUM(interp
, raw_index
);
2564 PARROT_CANNOT_RETURN_NULL
2566 string_param_from_op(PARROT_INTERP
, ARGIN(opcode_t
*raw_params
), INTVAL param_index
)
2568 ASSERT_ARGS(string_param_from_op
)
2569 const INTVAL raw_index
= raw_params
[param_index
+ 2];
2570 return ®_STR(interp
, raw_index
);
2573 PARROT_CANNOT_RETURN_NULL
2575 pmc_param_from_op(PARROT_INTERP
, ARGIN(opcode_t
*raw_params
), INTVAL param_index
)
2577 ASSERT_ARGS(pmc_param_from_op
)
2578 const INTVAL raw_index
= raw_params
[param_index
+ 2];
2579 return ®_PMC(interp
, raw_index
);
2583 intval_constant_from_op(PARROT_INTERP
, ARGIN(opcode_t
*raw_params
), INTVAL param_index
)
2585 ASSERT_ARGS(intval_constant_from_op
)
2586 const INTVAL raw_index
= raw_params
[param_index
+ 2];
2591 numval_constant_from_op(PARROT_INTERP
, ARGIN(opcode_t
*raw_params
), INTVAL param_index
)
2593 ASSERT_ARGS(numval_constant_from_op
)
2594 const INTVAL raw_index
= raw_params
[param_index
+ 2];
2595 return Parrot_pcc_get_num_constant(interp
, CURRENT_CONTEXT(interp
), raw_index
);
2598 PARROT_CAN_RETURN_NULL
2600 string_constant_from_op(PARROT_INTERP
, ARGIN(opcode_t
*raw_params
), INTVAL param_index
)
2602 ASSERT_ARGS(string_constant_from_op
)
2603 const INTVAL raw_index
= raw_params
[param_index
+ 2];
2604 return Parrot_pcc_get_string_constant(interp
, CURRENT_CONTEXT(interp
), raw_index
);
2607 PARROT_CAN_RETURN_NULL
2609 pmc_constant_from_op(PARROT_INTERP
, ARGIN(opcode_t
*raw_params
), INTVAL param_index
)
2611 ASSERT_ARGS(pmc_constant_from_op
)
2612 const INTVAL raw_index
= raw_params
[param_index
+ 2];
2613 return Parrot_pcc_get_pmc_constant(interp
, CURRENT_CONTEXT(interp
), raw_index
);
2616 PARROT_CANNOT_RETURN_NULL
2618 intval_arg_from_c_args(PARROT_INTERP
, ARGIN(va_list *args
), SHIM(INTVAL param_index
))
2620 ASSERT_ARGS(intval_arg_from_c_args
)
2621 return va_arg(*args
, INTVAL
);
2624 PARROT_CANNOT_RETURN_NULL
2626 numval_arg_from_c_args(PARROT_INTERP
, ARGIN(va_list *args
), SHIM(INTVAL param_index
))
2628 ASSERT_ARGS(numval_arg_from_c_args
)
2629 return va_arg(*args
, FLOATVAL
);
2632 PARROT_CANNOT_RETURN_NULL
2634 string_arg_from_c_args(PARROT_INTERP
, ARGIN(va_list *args
), SHIM(INTVAL param_index
))
2636 ASSERT_ARGS(string_arg_from_c_args
)
2637 return va_arg(*args
, STRING
*);
2640 PARROT_CANNOT_RETURN_NULL
2642 pmc_arg_from_c_args(PARROT_INTERP
, ARGIN(va_list *args
), SHIM(INTVAL param_index
))
2644 ASSERT_ARGS(pmc_arg_from_c_args
)
2645 return va_arg(*args
, PMC
*);
2648 PARROT_CANNOT_RETURN_NULL
2650 intval_param_from_c_args(PARROT_INTERP
, ARGIN(va_list *args
), SHIM(INTVAL param_index
))
2652 ASSERT_ARGS(intval_param_from_c_args
)
2653 return va_arg(*args
, INTVAL
*);
2656 PARROT_CANNOT_RETURN_NULL
2658 numval_param_from_c_args(PARROT_INTERP
, ARGIN(va_list *args
), SHIM(INTVAL param_index
))
2660 ASSERT_ARGS(numval_param_from_c_args
)
2661 return va_arg(*args
, FLOATVAL
*);
2664 PARROT_CANNOT_RETURN_NULL
2666 string_param_from_c_args(PARROT_INTERP
, ARGIN(va_list *args
), SHIM(INTVAL param_index
))
2668 ASSERT_ARGS(string_param_from_c_args
)
2669 return va_arg(*args
, STRING
**);
2672 PARROT_CANNOT_RETURN_NULL
2674 pmc_param_from_c_args(PARROT_INTERP
, ARGIN(va_list *args
), SHIM(INTVAL param_index
))
2676 ASSERT_ARGS(pmc_param_from_c_args
)
2677 return va_arg(*args
, PMC
**);
2681 intval_constant_from_varargs(PARROT_INTERP
, ARGIN(void *data
), INTVAL index
)
2683 ASSERT_ARGS(intval_constant_from_varargs
)
2684 PARROT_ASSERT(!"Wrong call");
2689 numval_constant_from_varargs(PARROT_INTERP
, ARGIN(void *data
), INTVAL index
)
2691 ASSERT_ARGS(numval_constant_from_varargs
)
2692 PARROT_ASSERT(!"Wrong call");
2696 PARROT_CAN_RETURN_NULL
2698 string_constant_from_varargs(PARROT_INTERP
, ARGIN(void *data
), INTVAL index
)
2700 ASSERT_ARGS(string_constant_from_varargs
)
2701 PARROT_ASSERT(!"Wrong call");
2705 PARROT_CAN_RETURN_NULL
2707 pmc_constant_from_varargs(PARROT_INTERP
, ARGIN(void *data
), INTVAL index
)
2709 ASSERT_ARGS(pmc_constant_from_varargs
)
2710 PARROT_ASSERT(!"Wrong call");
2716 =item C<static PMC* clone_key_arg(PARROT_INTERP, PMC *key)>
2718 Replaces any src registers by their values (done inside clone). This needs a
2719 test for tailcalls too, but I think there is no syntax to pass a key to a
2720 tailcalled function or method.
2726 PARROT_CAN_RETURN_NULL
2728 clone_key_arg(PARROT_INTERP
, ARGIN(PMC
*key
))
2730 ASSERT_ARGS(clone_key_arg
)
2733 if (PMC_IS_NULL(key
))
2736 if (key
->vtable
->base_type
!= enum_class_Key
)
2739 for (t
= key
; t
; t
=key_next(interp
, t
)) {
2740 /* register keys have to be cloned */
2741 if (PObj_get_FLAGS(key
) & KEY_register_FLAG
) {
2742 return VTABLE_clone(interp
, key
);
2755 F<include/parrot/call.h>, F<src/call/ops.c>, F<src/call/pcc.c>.
2763 * c-file-style: "parrot"
2765 * vim: expandtab shiftwidth=4: