/home/travis/build/MoarVM/MoarVM/src/core/frame.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* Frame flags; provide some HLLs can alias. */ |
2 | | #define MVM_FRAME_FLAG_STATE_INIT 1 << 0 |
3 | 0 | #define MVM_FRAME_FLAG_EXIT_HAND_RUN 1 << 1 |
4 | | #define MVM_FRAME_FLAG_HLL_1 1 << 3 |
5 | | #define MVM_FRAME_FLAG_HLL_2 1 << 4 |
6 | | #define MVM_FRAME_FLAG_HLL_3 1 << 5 |
7 | | #define MVM_FRAME_FLAG_HLL_4 1 << 6 |
8 | | |
9 | | /* Lexical hash entry for ->lexical_names on a frame. */ |
10 | | struct MVMLexicalRegistry { |
11 | | /* key string */ |
12 | | MVMString *key; |
13 | | |
14 | | /* index of the lexical entry. */ |
15 | | MVMuint32 value; |
16 | | |
17 | | /* the uthash hash handle inline struct. */ |
18 | | UT_hash_handle hash_handle; |
19 | | }; |
20 | | |
21 | | /* Entry in the linked list of continuation tags for the frame. */ |
22 | | struct MVMContinuationTag { |
23 | | /* The tag itself. */ |
24 | | MVMObject *tag; |
25 | | |
26 | | /* The active exception handler at the point the tag was taken. */ |
27 | | MVMActiveHandler *active_handlers; |
28 | | |
29 | | /* The next continuation tag entry. */ |
30 | | MVMContinuationTag *next; |
31 | | }; |
32 | | |
33 | | /* Function pointer type of special return handler. These are used to allow |
34 | | * return to be intercepted in some way, for things that need to do multiple |
35 | | * calls into the runloop in some C-managed process. Essentially, instead of |
36 | | * nested runloops, you just re-work the C code in question into CPS. */ |
37 | | typedef void (* MVMSpecialReturn)(MVMThreadContext *tc, void *data); |
38 | | |
39 | | /* Function pointer for marking the special return handler data. */ |
40 | | typedef void (* MVMSpecialReturnDataMark)(MVMThreadContext *tc, MVMFrame *frame, |
41 | | MVMGCWorklist *worklist); |
42 | | |
43 | | /* This represents an call frame, aka invocation record. It may exist either on |
44 | | * the heap, in which case its header will have the MVM_CF_FRAME flag set, or |
45 | | * in on a thread-local stack, in which case the collectable header will be |
46 | | * fully zeroed. */ |
47 | | struct MVMFrame { |
48 | | /* Commonalities that all collectable entities have. */ |
49 | | MVMCollectable header; |
50 | | |
51 | | /* The environment for this frame, which lives beyond its execution. |
52 | | * Has space for, for instance, lexicals. */ |
53 | | MVMRegister *env; |
54 | | |
55 | | /* The temporary work space for this frame. After a call is over, this |
56 | | * can be freed up. Must be NULLed out when this happens. */ |
57 | | MVMRegister *work; |
58 | | |
59 | | /* The args buffer. Actually a pointer into an area inside of *work, to |
60 | | * decrease number of allocations. */ |
61 | | MVMRegister *args; |
62 | | |
63 | | /* Callsite that indicates how the current args buffer is being used, if |
64 | | * it is. */ |
65 | | MVMCallsite *cur_args_callsite; |
66 | | |
67 | | /* The outer frame, thus forming the static chain. */ |
68 | | MVMFrame *outer; |
69 | | |
70 | | /* The caller frame, thus forming the dynamic chain. */ |
71 | | MVMFrame *caller; |
72 | | |
73 | | /* The static frame information. Holds all we statically know about |
74 | | * this kind of frame, including information needed to GC-trace it. */ |
75 | | MVMStaticFrame *static_info; |
76 | | |
77 | | /* The code ref object for this frame. */ |
78 | | MVMObject *code_ref; |
79 | | |
80 | | /* Parameters received by this frame. */ |
81 | | MVMArgProcContext params; |
82 | | |
83 | | /* Effective bytecode for the frame (either the original bytecode or a |
84 | | * specialization of it). */ |
85 | | MVMuint8 *effective_bytecode; |
86 | | |
87 | | /* Effective set of frame handlers (to go with the effective bytecode). */ |
88 | | MVMFrameHandler *effective_handlers; |
89 | | |
90 | | /* Effective set of spesh slots, if any. */ |
91 | | MVMCollectable **effective_spesh_slots; |
92 | | |
93 | | /* Effective set of spesh logging slots, if any. */ |
94 | | MVMCollectable **spesh_log_slots; |
95 | | |
96 | | /* The spesh candidate information, if we're in one. */ |
97 | | MVMSpeshCandidate *spesh_cand; |
98 | | |
99 | | /* Address of the next op to execute if we return to this frame. */ |
100 | | MVMuint8 *return_address; |
101 | | |
102 | | /* The register we should store the return value in, if any. */ |
103 | | MVMRegister *return_value; |
104 | | |
105 | | /* The type of return value that is expected. */ |
106 | | MVMReturnType return_type; |
107 | | |
108 | | /* If we want to invoke a special handler upon a return to this |
109 | | * frame, this function pointer is set. */ |
110 | | MVMSpecialReturn special_return; |
111 | | |
112 | | /* If we want to invoke a special handler upon unwinding past a |
113 | | * frame, this function pointer is set. */ |
114 | | MVMSpecialReturn special_unwind; |
115 | | |
116 | | /* Data slot for the special return handler function. */ |
117 | | void *special_return_data; |
118 | | |
119 | | /* Flag for if special_return_data need to be GC marked. */ |
120 | | MVMSpecialReturnDataMark mark_special_return_data; |
121 | | |
122 | | /* Address of the last op executed that threw an exeption; used just |
123 | | * for error reporting. */ |
124 | | MVMuint8 *throw_address; |
125 | | |
126 | | /* Linked list of any continuation tags we have. */ |
127 | | MVMContinuationTag *continuation_tags; |
128 | | |
129 | | /* Cache for dynlex lookup; if the name is non-null, the cache is valid |
130 | | * and the register can be accessed directly to find the contextual. */ |
131 | | MVMString *dynlex_cache_name; |
132 | | MVMRegister *dynlex_cache_reg; |
133 | | MVMuint16 dynlex_cache_type; |
134 | | |
135 | | /* The allocated work/env sizes. */ |
136 | | MVMuint16 allocd_work; |
137 | | MVMuint16 allocd_env; |
138 | | |
139 | | /* Assorted frame flags. */ |
140 | | MVMuint8 flags; |
141 | | |
142 | | /* If we're in a logging spesh run, the index to log at in this |
143 | | * invocation. -1 if we're not in a logging spesh run, junk if no |
144 | | * spesh_cand is set in this frame at all. */ |
145 | | MVMint8 spesh_log_idx; |
146 | | |
147 | | /* On Stack Replacement iteration counter; incremented in loops, and will |
148 | | * trigger if the limit is hit. */ |
149 | | MVMuint8 osr_counter; |
150 | | |
151 | | /* A sequence number to indicate our place in the call stack */ |
152 | | MVMint32 sequence_nr; |
153 | | /* The 'entry label' is a sort of indirect return address for the JIT */ |
154 | | void * jit_entry_label; |
155 | | }; |
156 | | |
157 | | /* How do we invoke this thing? Specifies either an attribute to look at for |
158 | | * an invokable thing, a method to call, and maybe a multi-dispatch cache to |
159 | | * look in first for an answer. */ |
160 | | struct MVMInvocationSpec { |
161 | | /* Class handle, name and hint for attribute holding code to invoke. */ |
162 | | MVMObject *class_handle; |
163 | | MVMString *attr_name; |
164 | | MVMint64 hint; |
165 | | |
166 | | /* Thing that handles invocation. */ |
167 | | MVMObject *invocation_handler; |
168 | | |
169 | | /* Multi-dispatch info class handle, and name/hint of attribute that |
170 | | * holds the cache itself and a flag to check if it's allowed to |
171 | | * consider the cache. */ |
172 | | MVMObject *md_class_handle; |
173 | | MVMString *md_cache_attr_name; |
174 | | MVMint64 md_cache_hint; |
175 | | MVMint64 md_valid_hint; |
176 | | MVMString *md_valid_attr_name; |
177 | | }; |
178 | | |
179 | | MVMRegister * MVM_frame_initial_work(MVMThreadContext *tc, MVMuint16 *local_types, |
180 | | MVMuint16 num_locals); |
181 | | void MVM_frame_invoke_code(MVMThreadContext *tc, MVMCode *code, |
182 | | MVMCallsite *callsite, MVMint32 spesh_cand); |
183 | | void MVM_frame_invoke(MVMThreadContext *tc, MVMStaticFrame *static_frame, |
184 | | MVMCallsite *callsite, MVMRegister *args, |
185 | | MVMFrame *outer, MVMObject *code_ref, MVMint32 spesh_cand); |
186 | | MVM_PUBLIC MVMFrame * MVM_frame_force_to_heap(MVMThreadContext *tc, MVMFrame *frame); |
187 | | MVMFrame * MVM_frame_create_context_only(MVMThreadContext *tc, MVMStaticFrame *static_frame, |
188 | | MVMObject *code_ref); |
189 | | MVMFrame * MVM_frame_create_for_deopt(MVMThreadContext *tc, MVMStaticFrame *static_frame, |
190 | | MVMCode *code_ref); |
191 | | MVM_PUBLIC MVMuint64 MVM_frame_try_return(MVMThreadContext *tc); |
192 | | MVM_PUBLIC MVMuint64 MVM_frame_try_return_no_exit_handlers(MVMThreadContext *tc); |
193 | | void MVM_frame_unwind_to(MVMThreadContext *tc, MVMFrame *frame, MVMuint8 *abs_addr, |
194 | | MVMuint32 rel_addr, MVMObject *return_value); |
195 | | MVM_PUBLIC void MVM_frame_destroy(MVMThreadContext *tc, MVMFrame *frame); |
196 | | MVM_PUBLIC MVMObject * MVM_frame_get_code_object(MVMThreadContext *tc, MVMCode *code); |
197 | | MVM_PUBLIC void MVM_frame_capturelex(MVMThreadContext *tc, MVMObject *code); |
198 | | MVM_PUBLIC void MVM_frame_capture_inner(MVMThreadContext *tc, MVMObject *code); |
199 | | MVM_PUBLIC MVMObject * MVM_frame_takeclosure(MVMThreadContext *tc, MVMObject *code); |
200 | | MVM_PUBLIC MVMObject * MVM_frame_vivify_lexical(MVMThreadContext *tc, MVMFrame *f, MVMuint16 idx); |
201 | | MVM_PUBLIC MVMRegister * MVM_frame_find_lexical_by_name(MVMThreadContext *tc, MVMString *name, MVMuint16 type); |
202 | | MVM_PUBLIC void MVM_frame_bind_lexical_by_name(MVMThreadContext *tc, MVMString *name, MVMuint16 type, MVMRegister *value); |
203 | | MVMObject * MVM_frame_find_lexical_by_name_outer(MVMThreadContext *tc, MVMString *name); |
204 | | MVM_PUBLIC MVMRegister * MVM_frame_find_lexical_by_name_rel(MVMThreadContext *tc, MVMString *name, MVMFrame *cur_frame); |
205 | | MVM_PUBLIC MVMRegister * MVM_frame_find_lexical_by_name_rel_caller(MVMThreadContext *tc, MVMString *name, MVMFrame *cur_caller_frame); |
206 | | MVMRegister * MVM_frame_find_contextual_by_name(MVMThreadContext *tc, MVMString *name, MVMuint16 *type, MVMFrame *cur_frame, MVMint32 vivify, MVMFrame **found_frame); |
207 | | MVMObject * MVM_frame_getdynlex(MVMThreadContext *tc, MVMString *name, MVMFrame *cur_frame); |
208 | | void MVM_frame_binddynlex(MVMThreadContext *tc, MVMString *name, MVMObject *value, MVMFrame *cur_frame); |
209 | | MVMRegister * MVM_frame_lexical(MVMThreadContext *tc, MVMFrame *f, MVMString *name); |
210 | | MVM_PUBLIC MVMRegister * MVM_frame_try_get_lexical(MVMThreadContext *tc, MVMFrame *f, MVMString *name, MVMuint16 type); |
211 | | MVMuint16 MVM_frame_lexical_primspec(MVMThreadContext *tc, MVMFrame *f, MVMString *name); |
212 | | MVM_PUBLIC MVMObject * MVM_frame_find_invokee(MVMThreadContext *tc, MVMObject *code, MVMCallsite **tweak_cs); |
213 | | MVMObject * MVM_frame_find_invokee_multi_ok(MVMThreadContext *tc, MVMObject *code, MVMCallsite **tweak_cs, MVMRegister *args); |
214 | | MVM_PUBLIC MVMObject * MVM_frame_context_wrapper(MVMThreadContext *tc, MVMFrame *f); |