4141#include "bc.h"
4242#include "objgenerator.h"
4343
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)
5044#if 0
5145#define TRACE (ip ) mp_bytecode_print2(ip, 1);
5246#else
@@ -103,123 +97,13 @@ typedef enum {
10397 currently_in_except_block = MP_TAGPTR_TAG(exc_sp->val_sp); /* restore previous state */ \
10498 exc_sp -- ; /* pop back to previous exception handler */
10599
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_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-
216100// fastn has items in reverse order (fastn[0] is local[0], fastn[-1] is local[1], etc)
217101// sp points to bottom of stack which grows up
218102// returns:
219103// MP_VM_RETURN_NORMAL, sp valid, return value in *sp
220104// MP_VM_RETURN_YIELD, ip, sp valid, yielded value in *sp
221105// 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 ) {
223107#if MICROPY_OPT_COMPUTED_GOTO
224108 #include "vmentrytable.h"
225109 #define DISPATCH () do { \
@@ -241,7 +125,7 @@ mp_vm_return_kind_t mp_execute_bytecode2(mp_code_state *code_state, volatile mp_
241125 // loop and the exception handler, leading to very obscure bugs.
242126 #define RAISE (o ) do { nlr_pop(); nlr.ret_val = o; goto exception_handler; } while(0)
243127
244- // Pointers which are constant for particular invocation of mp_execute_bytecode2 ()
128+ // Pointers which are constant for particular invocation of mp_execute_bytecode ()
245129 mp_obj_t * const fastn = & code_state -> state [code_state -> n_state - 1 ];
246130 mp_exc_stack_t * const exc_stack = (mp_exc_stack_t * )(code_state -> state + code_state -> n_state );
247131
0 commit comments