41
41
#include "bc.h"
42
42
#include "objgenerator.h"
43
43
44
- // With these macros you can tune the maximum number of function state bytes
45
- // that will be allocated on the stack. Any function that needs more
46
- // than this will use the heap.
47
- #define VM_MAX_STATE_ON_STACK (10 * sizeof(machine_uint_t))
48
-
49
- #define DETECT_VM_STACK_OVERFLOW (0)
50
44
#if 0
51
45
#define TRACE (ip ) mp_bytecode_print2(ip, 1);
52
46
#else
@@ -103,123 +97,13 @@ typedef enum {
103
97
currently_in_except_block = MP_TAGPTR_TAG(exc_sp->val_sp); /* restore previous state */ \
104
98
exc_sp -- ; /* pop back to previous exception handler */
105
99
106
- mp_vm_return_kind_t mp_execute_bytecode (const byte * code , const mp_obj_t * args , uint n_args ,
107
- const mp_obj_t * args2 , uint n_args2 , mp_obj_t * ret ) {
108
- const byte * ip = code ;
109
-
110
- // get code info size, and skip line number table
111
- machine_uint_t code_info_size = ip [0 ] | (ip [1 ] << 8 ) | (ip [2 ] << 16 ) | (ip [3 ] << 24 );
112
- ip += code_info_size ;
113
-
114
- // bytecode prelude: state size and exception stack size; 16 bit uints
115
- machine_uint_t n_state = ip [0 ] | (ip [1 ] << 8 );
116
- machine_uint_t n_exc_stack = ip [2 ] | (ip [3 ] << 8 );
117
- ip += 4 ;
118
-
119
- // allocate state for locals and stack
120
- #if DETECT_VM_STACK_OVERFLOW
121
- n_state += 1 ;
122
- #endif
123
-
124
- int state_size = n_state * sizeof (mp_obj_t ) + n_exc_stack * sizeof (mp_exc_stack_t );
125
- mp_code_state * code_state ;
126
- if (state_size > VM_MAX_STATE_ON_STACK ) {
127
- code_state = m_new_obj_var (mp_code_state , byte , state_size );
128
- } else {
129
- code_state = alloca (sizeof (mp_code_state ) + state_size );
130
- }
131
-
132
- code_state -> code_info = code ;
133
- code_state -> sp = & code_state -> state [0 ] - 1 ;
134
- code_state -> exc_sp = (mp_exc_stack_t * )(code
2851
_state -> state + n_state ) - 1 ;
135
- code_state -> n_state = n_state ;
136
-
137
- // init args
138
- for (uint i = 0 ; i < n_args ; i ++ ) {
139
- code_state -> state [n_state - 1 - i ] = args [i ];
140
- }
141
- for (uint i = 0 ; i < n_args2 ; i ++ ) {
142
- code_state -> state [n_state - 1 - n_args - i ] = args2 [i ];
143
- }
144
-
145
- // set rest of state to MP_OBJ_NULL
146
- for (uint i = 0 ; i < n_state - n_args - n_args2 ; i ++ ) {
147
- code_state -> state [i ] = MP_OBJ_NULL ;
148
- }
149
-
150
- // bytecode prelude: initialise closed over variables
151
- for (uint n_local = * ip ++ ; n_local > 0 ; n_local -- ) {
152
- uint local_num = * ip ++ ;
153
- code_state -> state [n_state - 1 - local_num ] = mp_obj_new_cell (code_state -> state [n_state - 1 - local_num ]);
154
- }
155
-
156
- code_state -> ip = ip ;
157
-
158
- // execute the byte code
159
- mp_vm_return_kind_t vm_return_kind = mp_execute_bytecode2 (code_state , MP_OBJ_NULL );
160
-
161
- #if DETECT_VM_STACK_OVERFLOW
162
- if (vm_return_kind == MP_VM_RETURN_NORMAL ) {
163
- if (code_state -> sp < code_state -> state ) {
164
- printf ("VM stack underflow: " INT_FMT "\n" , code_state -> sp - code_state -> state );
165
- assert (0 );
166
- }
167
- }
168
- // We can't check the case when an exception is returned in state[n_state - 1]
169
- // and there are no arguments, because in this case our detection slot may have
170
- // been overwritten by the returned exception (which is allowed).
171
- if (!(vm_return_kind == MP_VM_RETURN_EXCEPTION && n_args == 0 && n_args2 == 0 )) {
172
- // Just check to see that we have at least 1 null object left in the state.
173
- bool overflow = true;
174
- for (uint i = 0 ; i < n_state - n_args - n_args2 ; i ++ ) {
175
- if (code_state -> state [i ] == MP_OBJ_NULL ) {
176
- overflow = false;
177
- break ;
178
- }
179
- }
180
- if (overflow ) {
181
- printf ("VM stack overflow state=%p n_state+1=" UINT_FMT "\n" , code_state -> state , n_state );
182
- assert (0 );
183
- }
184
- }
185
- #endif
186
-
187
- mp_vm_return_kind_t ret_kind ;
188
- switch (vm_return_kind ) {
189
- case MP_VM_RETURN_NORMAL :
190
- // return value is in *sp
191
- * ret = * code_state -> sp ;
192
- ret_kind = MP_VM_RETURN_NORMAL ;
193
- break ;
194
-
195
- case MP_VM_RETURN_EXCEPTION :
196
- // return value is in state[n_state - 1]
197
- * ret = code_state -> state [n_state - 1 ];
198
- ret_kind = MP_VM_RETURN_EXCEPTION ;
199
- break ;
200
-
201
- case MP_VM_RETURN_YIELD : // byte-code shouldn't yield
202
- default :
203
- assert (0 );
204
- * ret = mp_const_none ;
205
- ret_kind = MP_VM_RETURN_NORMAL ;
206
- break ;
207
- }
208
-
209
- // free the state if it was allocated on the heap
210
- if (state_size > VM_MAX_STATE_ON_STACK ) {
211
- m_del_var (mp_code_state , byte , state_size , code_state );
212
- }
213
- return ret_kind ;
214
- }
215
-
216
100
// fastn has items in reverse order (fastn[0] is local[0], fastn[-1] is local[1], etc)
217
101
// sp points to bottom of stack which grows up
218
102
// returns:
219
103
// MP_VM_RETURN_NORMAL, sp valid, return value in *sp
220
104
// MP_VM_RETURN_YIELD, ip, sp valid, yielded value in *sp
221
105
// MP_VM_RETURN_EXCEPTION, exception in fastn[0]
222
- mp_vm_return_kind_t mp_execute_bytecode2 (mp_code_state * code_state , volatile mp_obj_t inject_exc ) {
106
+ mp_vm_return_kind_t mp_execute_bytecode (mp_code_state * code_state , volatile mp_obj_t inject_exc ) {
223
107
#if MICROPY_OPT_COMPUTED_GOTO
224
108
#include "vmentrytable.h"
225
109
#define DISPATCH () do { \
@@ -241,7 +125,7 @@ mp_vm_return_kind_t mp_execute_bytecode2(mp_code_state *code_state, volatile mp_
241
125
// loop and the exception handler, leading to very obscure bugs.
242
126
#define RAISE (o ) do { nlr_pop(); nlr.ret_val = o; goto exception_handler; } while(0)
243
127
244
- // Pointers which are constant for particular invocation of mp_execute_bytecode2 ()
128
+ // Pointers which are constant for particular invocation of mp_execute_bytecode ()
245
129
mp_obj_t * const fastn = & code_state -> state [code_state -> n_state - 1 ];
246
130
mp_exc_stack_t * const exc_stack = (mp_exc_stack_t * )(code_state -> state + code_state -> n_state );
247
131
0 commit comments