2 * Copyright (C) 2001-2008, The Perl Foundation.
6 * Data Structure and Algorithms:
7 * Call argument handling.
9 * Initial version by leo on 2005/07/22
10 * Major changes by mdiep in April 2007
13 * pdd03 - Calling Conventions
16 #ifndef PARROT_INTER_CALL_H_GUARD
17 #define PARROT_INTER_CALL_H_GUARD
19 typedef enum call_state_mode
{
20 /* argument fetching/putting modes */
21 CALL_STATE_SIG
= 0x100, /* runops, nci. In case we're interfacing with
23 CALL_STATE_OP
= 0x200, /* get_, set_ ops. In case we're interfacing
24 with Parrot code and get the signature from
25 call_state_item.u.op. */
26 CALL_S_D_MASK
= 0x300, /* src/dest mask */
28 CALL_STATE_FLATTEN
= 0x400 /* whether we are busy in a :flat argument */
31 typedef struct call_state_item
{
32 /* We have one call_state_item for both the caller (source,
33 arguments/returns) and the callee (destination, parameters/results). */
34 int mode
; /* this specifies:
35 - where we get our arguments from / where we put
36 our parameters (from C code or from set_*,get_*)
37 - if we're in the middle of a :flat */
40 struct { /* In case the caller (or callee? FIXME) is C */
41 void *ap
; /* a ptr to va_list */
42 const char *sig
; /* C string describing the type of each argument */
45 struct { /* In case the caller/callee was Parrot code: */
46 opcode_t
*pc
; /* array of 'indexes' for each argument:
47 - if it's a constant, the constant number
48 - if it's a register, the register number */
49 PMC
*signature
; /* a PMC array holding a Call_bits_enum_t
50 signature for each argument */
54 parrot_context_t
*ctx
; /* the source or destination context */
55 INTVAL used
; /* src: whether this argument has been consumed
56 * (or: whether the previous arg has?) */
57 INTVAL i
; /* number of args/params already processed */
58 INTVAL n
; /* number of args/params to match.
59 * may include :slurpys and :flats */
60 INTVAL sig
; /* type of current arg/param
61 * (counting from 1, the i'th) */
63 /* We might encounter a :flat. */
64 /* FIXME bgeron: is this used for :slurpys?
65 * I can't find a reference in slurpy-filling code. */
67 PMC
*slurp
; /* PMC in which to put the args we slurp up
68 * or source from where to flatten */
69 INTVAL slurp_i
; /* index of :flat/:slurpy arg/param to match */
70 INTVAL slurp_n
; /* number of :flat/:slurpy args/params to match */
73 typedef struct call_state
{
77 int n_actual_args
; /* arguments incl. flatten */
78 int optionals
; /* sum of optionals */
79 int params
; /* sum of params */
80 int first_named
; /* param idx of 1st named */
81 UINTVAL named_done
; /* bit mask, 1 if named was assigned */
82 STRING
*name
; /* name of argument if any */
83 PMC
*key
; /* to iterate a flattening hash */
86 typedef enum arg_pass_t
{
87 PARROT_PASS_PARAMS
= 0x00,
88 PARROT_PASS_RESULTS
= 0x01
91 /* HEADERIZER BEGIN: src/inter_call.c */
92 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
95 void Parrot_convert_arg(PARROT_INTERP
, ARGMOD(call_state
*st
))
96 __attribute__nonnull__(1)
97 __attribute__nonnull__(2)
101 int Parrot_fetch_arg(PARROT_INTERP
, ARGMOD(call_state
*st
))
102 __attribute__nonnull__(1)
103 __attribute__nonnull__(2)
107 int Parrot_fetch_arg_nci(PARROT_INTERP
, ARGMOD(call_state
*st
))
108 __attribute__nonnull__(1)
109 __attribute__nonnull__(2)
113 int Parrot_init_arg_indexes_and_sig_pmc(SHIM_INTERP
,
114 ARGIN(parrot_context_t
*ctx
),
115 ARGIN_NULLOK(opcode_t
*indexes
),
116 ARGIN_NULLOK(PMC
* sig_pmc
),
117 ARGMOD(call_state_item
*sti
))
118 __attribute__nonnull__(2)
119 __attribute__nonnull__(5)
123 void Parrot_init_arg_nci(PARROT_INTERP
,
124 ARGOUT(call_state
*st
),
125 ARGIN(const char *sig
))
126 __attribute__nonnull__(1)
127 __attribute__nonnull__(2)
128 __attribute__nonnull__(3)
132 int Parrot_init_arg_op(PARROT_INTERP
,
133 ARGIN(parrot_context_t
*ctx
),
134 ARGIN_NULLOK(opcode_t
*pc
),
135 ARGIN(call_state_item
*sti
))
136 __attribute__nonnull__(1)
137 __attribute__nonnull__(2)
138 __attribute__nonnull__(4);
141 int Parrot_init_arg_sig(SHIM_INTERP
,
142 ARGIN(parrot_context_t
*ctx
),
143 ARGIN(const char *sig
),
144 ARGIN_NULLOK(void *ap
),
145 ARGMOD(call_state_item
*sti
))
146 __attribute__nonnull__(2)
147 __attribute__nonnull__(3)
148 __attribute__nonnull__(5)
152 void Parrot_init_ret_nci(PARROT_INTERP
,
153 ARGOUT(call_state
*st
),
154 ARGIN(const char *sig
))
155 __attribute__nonnull__(1)
156 __attribute__nonnull__(2)
157 __attribute__nonnull__(3)
161 void parrot_pass_args(PARROT_INTERP
,
162 ARGMOD(parrot_context_t
*src_ctx
),
163 ARGMOD(parrot_context_t
*dest_ctx
),
164 ARGMOD(opcode_t
*src_indexes
),
165 ARGMOD(opcode_t
*dest_indexes
),
166 arg_pass_t param_or_result
)
167 __attribute__nonnull__(1)
168 __attribute__nonnull__(2)
169 __attribute__nonnull__(3)
170 __attribute__nonnull__(4)
171 __attribute__nonnull__(5)
172 FUNC_MODIFIES(*src_ctx
)
173 FUNC_MODIFIES(*dest_ctx
)
174 FUNC_MODIFIES(*src_indexes
)
175 FUNC_MODIFIES(*dest_indexes
);
178 void Parrot_PCCINVOKE(PARROT_INTERP
,
180 ARGMOD(STRING
*method_name
),
181 ARGIN(const char *signature
),
183 __attribute__nonnull__(1)
184 __attribute__nonnull__(2)
185 __attribute__nonnull__(3)
186 __attribute__nonnull__(4)
187 FUNC_MODIFIES(*method_name
);
190 void Parrot_process_args(PARROT_INTERP
,
191 ARGMOD(call_state
*st
),
192 arg_pass_t param_or_result
)
193 __attribute__nonnull__(1)
194 __attribute__nonnull__(2)
197 PARROT_CANNOT_RETURN_NULL
198 PARROT_WARN_UNUSED_RESULT
199 opcode_t
* parrot_pass_args_fromc(PARROT_INTERP
,
200 ARGIN(const char *sig
),
201 ARGMOD(opcode_t
*dest
),
202 ARGIN(parrot_context_t
*old_ctxp
),
204 __attribute__nonnull__(1)
205 __attribute__nonnull__(2)
206 __attribute__nonnull__(3)
207 __attribute__nonnull__(4)
208 FUNC_MODIFIES(*dest
);
210 int Parrot_store_arg(SHIM_INTERP
, ARGIN(const call_state
*st
))
211 __attribute__nonnull__(2);
213 PARROT_WARN_UNUSED_RESULT
214 PARROT_CAN_RETURN_NULL
215 void * set_retval(PARROT_INTERP
, int sig_ret
, ARGIN(parrot_context_t
*ctx
))
216 __attribute__nonnull__(1)
217 __attribute__nonnull__(3);
219 FLOATVAL
set_retval_f(PARROT_INTERP
,
221 ARGIN(parrot_context_t
*ctx
))
222 __attribute__nonnull__(1)
223 __attribute__nonnull__(3);
225 INTVAL
set_retval_i(PARROT_INTERP
,
227 ARGIN(parrot_context_t
*ctx
))
228 __attribute__nonnull__(1)
229 __attribute__nonnull__(3);
231 PARROT_CAN_RETURN_NULL
232 PARROT_WARN_UNUSED_RESULT
233 PMC
* set_retval_p(PARROT_INTERP
, int sig_ret
, ARGIN(parrot_context_t
*ctx
))
234 __attribute__nonnull__(1)
235 __attribute__nonnull__(3);
237 PARROT_CAN_RETURN_NULL
238 PARROT_WARN_UNUSED_RESULT
239 STRING
* set_retval_s(PARROT_INTERP
,
241 ARGIN(parrot_context_t
*ctx
))
242 __attribute__nonnull__(1)
243 __attribute__nonnull__(3);
245 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
246 /* HEADERIZER END: src/inter_call.c */
248 #define ASSERT_SIG_PMC(sig) \
249 PARROT_ASSERT(PObj_is_PMC_TEST(sig)); \
250 PARROT_ASSERT((sig)->vtable->base_type == enum_class_FixedIntegerArray)
252 #define SIG_ELEMS(sig) PMC_int_val(sig)
253 #define SIG_ARRAY(sig) (INTVAL*)PMC_data(sig)
254 #define SIG_ITEM(sig, idx) (SIG_ARRAY(sig))[(idx)]
256 /* XXX Remove interp from this */
257 #define ADD_OP_VAR_PART(interp, seg, pc, n) do { \
258 if (*(pc) == PARROT_OP_set_args_pc || \
259 *(pc) == PARROT_OP_get_results_pc || \
260 *(pc) == PARROT_OP_get_params_pc || \
261 *(pc) == PARROT_OP_set_returns_pc) { \
262 PMC * const sig = (seg)->const_table->constants[(pc)[1]]->u.key; \
263 (n) += SIG_ELEMS(sig); \
268 #endif /* PARROT_INTER_CALL_H_GUARD */
272 * c-file-style: "parrot"
274 * vim: expandtab shiftwidth=4: