/
sub.h
234 lines (195 loc) · 8.61 KB
/
sub.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/* sub.h
* Copyright (C) 2001-2003, The Perl Foundation.
* SVN Info
* $Id$
* Overview:
* Data Structure and Algorithms:
* Subroutine, coroutine, closure and continuation structures
* and related routines.
* History:
* Initial version by Melvin on on 2002/06/6
* Notes:
* References:
*/
#if !defined(PARROT_SUB_H_GUARD)
#define PARROT_SUB_H_GUARD
#include "parrot/parrot.h"
/*
* Subroutine flags
*/
typedef enum {
/* runtime usage flags */
SUB_FLAG_CORO_FF = PObj_private0_FLAG,
SUB_FLAG_C_HANDLER = PObj_private0_FLAG, /* C exceptions only */
SUB_FLAG_TAILCALL = PObj_private2_FLAG,
SUB_FLAG_GENERATOR = PObj_private3_FLAG, /* unused old python pmcs */
/* compile/loadtime usage flags */
/* from packfile */
SUB_FLAG_IS_OUTER = PObj_private1_FLAG,
SUB_FLAG_PF_ANON = PObj_private3_FLAG,
SUB_FLAG_PF_MAIN = PObj_private4_FLAG,
SUB_FLAG_PF_LOAD = PObj_private5_FLAG,
SUB_FLAG_PF_IMMEDIATE = PObj_private6_FLAG,
SUB_FLAG_PF_POSTCOMP = PObj_private7_FLAG,
SUB_FLAG_PF_MASK = 0xfa /* anon ... postcomp, is_outer*/
} sub_flags_enum;
#define SUB_FLAG_get_FLAGS(o) (PObj_get_FLAGS(o))
#define SUB_FLAG_flag_TEST(flag, o) (SUB_FLAG_get_FLAGS(o) & SUB_FLAG_ ## flag)
#define SUB_FLAG_flag_SET(flag, o) (SUB_FLAG_get_FLAGS(o) |= SUB_FLAG_ ## flag)
#define SUB_FLAG_flag_CLEAR(flag, o) (SUB_FLAG_get_FLAGS(o) &= ~(UINTVAL)(SUB_FLAG_ ## flag))
#define SUB_FLAG_flags_SETTO(o, f) SUB_FLAG_get_FLAGS(o) = (f)
#define SUB_FLAG_flags_CLEARALL(o) SUB_FLAG_flags_SETTO(o, 0)
#define SUB_FLAG_TAILCALL_TEST(o) SUB_FLAG_flag_TEST(TAILCALL, o)
#define SUB_FLAG_TAILCALL_ISSET(o) SUB_FLAG_flag_TEST(TAILCALL, o)
#define SUB_FLAG_TAILCALL_NOTSET(o) (!SUB_FLAG_flag_TEST(TAILCALL, o))
#define SUB_FLAG_TAILCALL_SET(o) SUB_FLAG_flag_SET(TAILCALL, o)
#define SUB_FLAG_TAILCALL_CLEAR(o) SUB_FLAG_flag_CLEAR(TAILCALL, o)
typedef enum {
SUB_COMP_FLAG_BIT_0 = 1 << 0,
SUB_COMP_FLAG_BIT_1 = 1 << 1,
SUB_COMP_FLAG_BIT_2 = 1 << 2,
SUB_COMP_FLAG_BIT_3 = 1 << 3,
SUB_COMP_FLAG_BIT_4 = 1 << 4,
SUB_COMP_FLAG_BIT_5 = 1 << 5,
SUB_COMP_FLAG_BIT_6 = 1 << 6,
SUB_COMP_FLAG_BIT_7 = 1 << 7,
SUB_COMP_FLAG_BIT_8 = 1 << 8,
SUB_COMP_FLAG_BIT_9 = 1 << 9,
SUB_COMP_FLAG_PF_INIT = 1 << 10,
SUB_COMP_FLAG_BIT_10 = 1 << 10,
SUB_COMP_FLAG_BIT_11 = 1 << 11,
SUB_COMP_FLAG_BIT_12 = 1 << 12,
SUB_COMP_FLAG_BIT_13 = 1 << 13,
SUB_COMP_FLAG_BIT_14 = 1 << 14,
SUB_COMP_FLAG_BIT_15 = 1 << 15,
SUB_COMP_FLAG_BIT_16 = 1 << 16,
SUB_COMP_FLAG_BIT_17 = 1 << 17,
SUB_COMP_FLAG_BIT_18 = 1 << 18,
SUB_COMP_FLAG_BIT_19 = 1 << 19,
SUB_COMP_FLAG_BIT_20 = 1 << 20,
SUB_COMP_FLAG_BIT_21 = 1 << 21,
SUB_COMP_FLAG_BIT_22 = 1 << 22,
SUB_COMP_FLAG_BIT_23 = 1 << 23,
SUB_COMP_FLAG_BIT_24 = 1 << 24,
SUB_COMP_FLAG_BIT_25 = 1 << 25,
SUB_COMP_FLAG_BIT_26 = 1 << 26,
SUB_COMP_FLAG_BIT_27 = 1 << 27,
SUB_COMP_FLAG_BIT_28 = 1 << 28,
SUB_COMP_FLAG_BIT_29 = 1 << 29,
SUB_COMP_FLAG_BIT_30 = 1 << 30,
SUB_COMP_FLAG_MASK = 0x00000400
} sub_comp_flags_enum;
#define Sub_comp_get_FLAGS(o) ((PMC_sub(o))->comp_flags)
#define Sub_comp_flag_TEST(flag, o) (Sub_comp_get_FLAGS(o) & SUB_COMP_FLAG_ ## flag)
#define Sub_comp_flag_SET(flag, o) (Sub_comp_get_FLAGS(o) |= SUB_COMP_FLAG_ ## flag)
#define Sub_comp_flag_CLEAR(flag, o) (Sub_comp_get_FLAGS(o) &= ~(UINTVAL)(SUB_COMP_FLAG_ ## flag))
#define Sub_comp_flags_SETTO(o, f) Sub_comp_get_FLAGS(o) = (f)
#define Sub_comp_flags_CLEARALL(o) Sub_comp_flags_SETTO(o, 0)
#define Sub_comp_INIT_TEST(o) Sub_comp_flag_TEST(PF_INIT, o)
#define Sub_comp_INIT_SET(o) Sub_comp_flag_SET(PF_INIT, o)
#define Sub_comp_INIT_CLEAR(o) Sub_comp_flag_CLEAR(PF_INIT, o)
/*
* a flag to signal a Sub that a new RetContinuation should be created
*/
#define NEED_CONTINUATION ((PMC *)1)
/*
* maximum sub recursion depth
*/
#define RECURSION_LIMIT 1000
/*
* Sub and Closure share a Parrot_sub structure.
* Closures have additionally an 'outer_ctx'
*/
typedef struct Parrot_sub {
struct PackFile_ByteCode *seg; /* bytecode segment */
size_t start_offs; /* sub entry in ops from seg->base.data */
size_t end_offs;
INTVAL HLL_id; /* see src/hll.c XXX or per segment? */
PMC *namespace_name; /* where this Sub is in - this is either
* a String or a [Key] and describes
* the relative path in the NameSpace
*/
PMC *namespace_stash; /* the actual hash, HLL::namespace */
STRING *name; /* name of the sub */
INTVAL vtable_index; /* index in Parrot_vtable_slot_names */
PMC *multi_signature; /* list of types for MMD */
INTVAL n_regs_used[4]; /* INSP in PBC */
PMC *lex_info; /* LexInfo PMC */
PMC *outer_sub; /* :outer for closures */
PMC *eval_pmc; /* eval container / NULL */
parrot_context_t *ctx; /* the context this sub is in */
UINTVAL comp_flags; /* compile time and additional flags */
/* - end common */
struct Parrot_Context *outer_ctx; /* outer context, if a closure */
} * parrot_sub_t;
#define PMC_sub(pmc) ((parrot_sub_t)PMC_struct_val(pmc))
/* the first entries must match Parrot_sub, so we can cast
* these two to the other type
*/
typedef struct Parrot_coro {
struct PackFile_ByteCode *seg; /* bytecode segment */
size_t start_offs; /* sub entry in ops from seg->base.data */
size_t end_offs;
INTVAL HLL_id; /* see src/hll.c XXX or per segment? */
PMC *_namespace; /* where this Sub is in - this is either
* a String or a [Key] and describes
* the relative path in the NameSpace
*/
PMC *namespace_stash; /* the actual hash, HLL::namespace */
STRING *name; /* name of the sub */
INTVAL vtable_index; /* index in Parrot_vtable_slot_names */
PMC *multi_signature; /* list of types for MMD */
INTVAL n_regs_used[4]; /* INSP in PBC */
PMC *lex_info; /* LexInfo PMC */
PMC *outer_sub; /* :outer for closures */
PMC *eval_pmc; /* eval container / NULL */
struct Parrot_Context *ctx; /* coroutine context */
UINTVAL comp_flags; /* compile time and additional flags */
/* - end common */
struct PackFile_ByteCode *caller_seg; /* bytecode segment */
opcode_t *address; /* next address to run - toggled each time */
struct Stack_Chunk *dynamic_state; /* next dynamic state */
} * parrot_coro_t;
#define PMC_coro(pmc) ((parrot_coro_t)PMC_struct_val(pmc))
typedef struct Parrot_cont {
/* continuation destination */
struct PackFile_ByteCode *seg; /* bytecode segment */
opcode_t *address; /* start of bytecode, addr to continue */
struct Parrot_Context *to_ctx; /* pointer to dest context */
struct Stack_Chunk *dynamic_state; /* dest dynamic state */
/* a Continuation keeps the from_ctx alive */
struct Parrot_Context *from_ctx; /* sub, this cont is returning from */
opcode_t *current_results; /* ptr into code with get_results opcode
full continuation only */
int runloop_id; /* id of the creating runloop. */
} * parrot_cont_t;
#define PMC_cont(pmc) ((parrot_cont_t)PMC_struct_val(pmc))
struct Parrot_Context_info {
STRING* subname;
STRING* nsname;
STRING* fullname;
int pc;
char *file;
int line;
opcode_t *address;
};
struct Parrot_sub * new_sub(Interp * interp);
struct Parrot_sub * new_closure(Interp * interp);
struct Parrot_coro * new_coroutine(Interp * interp);
struct Parrot_cont * new_continuation(Interp * interp, struct Parrot_cont *to);
struct Parrot_cont * new_ret_continuation(Interp * interp);
PARROT_API PMC * new_ret_continuation_pmc(Interp *, opcode_t * address);
void mark_context(Interp *, parrot_context_t *);
void invalidate_retc_context(Interp *interp, PMC *cont);
PARROT_API STRING* Parrot_full_sub_name(Interp *interp, PMC* sub);
PARROT_API int Parrot_Context_info(Interp *interp, parrot_context_t *, struct Parrot_Context_info *);
PARROT_API STRING* Parrot_Context_infostr(Interp *interp, parrot_context_t *);
PARROT_API PMC* Parrot_find_pad(Interp*, STRING *lex_name, parrot_context_t *);
PARROT_API PMC* parrot_new_closure(Interp*, PMC*);
#endif /* PARROT_SUB_H_GUARD */
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4:
*/