Skip to content

Commit bee17b0

Browse files
committed
py: Put n_state for bytecode in the bytecode prelude.
Rationale: setting up the stack (state for locals and exceptions) is really part of the "code", it's the prelude of the function. For example, native code adjusts the stack pointer on entry to the function. Native code doesn't need to know n_state for any other reason. So putting the state size in the bytecode prelude is sensible. It reduced ROM usage on STM by about 30 bytes :) And makes it easier to pass information about the bytecode between functions.
1 parent 8dcc0c7 commit bee17b0

7 files changed

Lines changed: 27 additions & 30 deletions

File tree

py/bc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ typedef struct _mp_exc_stack {
1414
byte opcode;
1515
} mp_exc_stack;
1616

17-
mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, uint n_state, mp_obj_t *ret);
17+
mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, mp_obj_t *ret);
1818
mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **sp_in_out, mp_exc_stack *exc_stack, mp_exc_stack **exc_sp_in_out, volatile mp_obj_t inject_exc);
1919
void mp_byte_code_print(const byte *code, int len);
2020

py/emitbc.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,11 +224,14 @@ STATIC void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
224224
emit_write_code_info_qstr(emit, scope->source_file);
225225
emit_write_code_info_qstr(emit, scope->simple_name);
226226

227-
// bytecode prelude: exception stack size; 16 bit uint for now
227+
// bytecode prelude: local state size and exception stack size; 16 bit uints for now
228228
{
229-
byte* c = emit_get_cur_to_write_byte_code(emit, 2);
230-
c[0] = scope->exc_stack_size & 0xff;
231-
c[1] = (scope->exc_stack_size >> 8) & 0xff;
229+
byte* c = emit_get_cur_to_write_byte_code(emit, 4);
230+
uint n_state = scope->num_locals + scope->stack_size;
231+
c[0] = n_state & 0xff;
232+
c[1] = (n_state >> 8) & 0xff;
233+
c[2] = scope->exc_stack_size & 0xff;
234+
c[3] = (scope->exc_stack_size >> 8) & 0xff;
232235
}
233236

234237
// bytecode prelude: initialise closed over variables

py/obj.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,10 +257,10 @@ mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg
257257
mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!)
258258
mp_obj_t mp_obj_new_range(int start, int stop, int step);
259259
mp_obj_t mp_obj_new_range_iterator(int cur, int stop, int step);
260-
mp_obj_t mp_obj_new_fun_bc(uint scope_flags, qstr *args, uint n_args, mp_obj_t def_args, uint n_state, const byte *code);
260+
mp_obj_t mp_obj_new_fun_bc(uint scope_flags, qstr *args, uint n_args, mp_obj_t def_args, const byte *code);
261261
mp_obj_t mp_obj_new_fun_asm(uint n_args, void *fun);
262262
mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun);
263-
mp_obj_t mp_obj_new_gen_instance(const byte *bytecode, uint n_state, int n_args, const mp_obj_t *args);
263+
mp_obj_t mp_obj_new_gen_instance(const byte *bytecode, int n_args, const mp_obj_t *args);
264264
mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_obj_t closure_tuple);
265265
mp_obj_t mp_obj_new_tuple(uint n, const mp_obj_t *items);
266266
mp_obj_t mp_obj_new_list(uint n, mp_obj_t *items);
@@ -419,7 +419,7 @@ typedef struct _mp_obj_fun_native_t { // need this so we can define const object
419419

420420
extern const mp_obj_type_t fun_native_type;
421421
extern const mp_obj_type_t fun_bc_type;
422-
void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code);
422+
void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, const byte **code);
423423

424424
mp_obj_t mp_identity(mp_obj_t self);
425425
MP_DECLARE_CONST_FUN_OBJ(mp_identity_obj);

py/objfun.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ typedef struct _mp_obj_fun_bc_t {
147147
machine_uint_t n_def_args : 15; // number of default arguments
148148
machine_uint_t takes_var_args : 1; // set if this function takes variable args
149149
machine_uint_t takes_kw_args : 1; // set if this function takes keyword args
150-
uint n_state; // total state size for the executing function (incl args, locals, stack)
151150
const byte *bytecode; // bytecode for the function
152151
qstr *args; // argument names (needed to resolve positional args passed as keywords)
153152
mp_obj_t extra_args[]; // values of default args (if any), plus a slot at the end for var args and/or kw args (if it takes them)
@@ -285,7 +284,7 @@ continue2:;
285284
DEBUG_printf("Calling: args=%p, n_args=%d, extra_args=%p, n_extra_args=%d\n", args, n_args, extra_args, n_extra_args);
286285
dump_args(args, n_args);
287286
dump_args(extra_args, n_extra_args);
288-
mp_vm_return_kind_t vm_return_kind = mp_execute_byte_code(self->bytecode, args, n_args, extra_args, n_extra_args, self->n_state, &result);
287+
mp_vm_return_kind_t vm_return_kind = mp_execute_byte_code(self->bytecode, args, n_args, extra_args, n_extra_args, &result);
289288
rt_globals_set(old_globals);
290289

291290
if (vm_return_kind == MP_VM_RETURN_NORMAL) {
@@ -304,7 +303,7 @@ const mp_obj_type_t fun_bc_type = {
304303
.call = fun_bc_call,
305304
};
306305

307-
mp_obj_t mp_obj_new_fun_bc(uint scope_flags, qstr *args, uint n_args, mp_obj_t def_args_in, uint n_state, const byte *code) {
306+
mp_obj_t mp_obj_new_fun_bc(uint scope_flags, qstr *args, uint n_args, mp_obj_t def_args_in, const byte *code) {
308307
uint n_def_args = 0;
309308
uint n_extra_args = 0;
310309
mp_obj_tuple_t *def_args = def_args_in;
@@ -326,19 +325,17 @@ mp_obj_t mp_obj_new_fun_bc(uint scope_flags, qstr *args, uint n_args, mp_obj_t d
326325
o->n_def_args = n_def_args;
327326
o->takes_var_args = (scope_flags & MP_SCOPE_FLAG_VARARGS) != 0;
328327
o->takes_kw_args = (scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0;
329-
o->n_state = n_state;
330328
o->bytecode = code;
331329
if (def_args != MP_OBJ_NULL) {
332330
memcpy(o->extra_args, def_args->items, n_def_args * sizeof(mp_obj_t));
333331
}
334332
return o;
335333
}
336334

337-
void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code) {
335+
void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, const byte **code) {
338336
assert(MP_OBJ_IS_TYPE(self_in, &fun_bc_type));
339337
mp_obj_fun_bc_t *self = self_in;
340338
*n_args = self->n_args;
341-
*n_state = self->n_state;
342339
*code = self->bytecode;
343340
}
344341

py/objgenerator.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,16 @@ STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp
2424
mp_obj_t self_fun = self->fun;
2525
assert(MP_OBJ_IS_TYPE(self_fun, &fun_bc_type));
2626
int bc_n_args;
27-
uint bc_n_state;
2827
const byte *bc_code;
29-
mp_obj_fun_bc_get(self_fun, &bc_n_args, &bc_n_state, &bc_code);
28+
mp_obj_fun_bc_get(self_fun, &bc_n_args, &bc_code);
3029
if (n_args != bc_n_args) {
3130
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function takes %d positional arguments but %d were given", bc_n_args, n_args));
3231
}
3332
if (n_kw != 0) {
3433
nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
3534
}
3635

37-
return mp_obj_new_gen_instance(bc_code, bc_n_state, n_args, args);
36+
return mp_obj_new_gen_instance(bc_code, n_args, args);
3837
}
3938

4039
const mp_obj_type_t gen_wrap_type = {
@@ -210,14 +209,15 @@ const mp_obj_type_t gen_instance_type = {
210209
.locals_dict = (mp_obj_t)&gen_instance_locals_dict,
211210
};
212211

213-
mp_obj_t mp_obj_new_gen_instance(const byte *bytecode, uint n_state, int n_args, const mp_obj_t *args) {
212+
mp_obj_t mp_obj_new_gen_instance(const byte *bytecode, int n_args, const mp_obj_t *args) {
214213
// get code info size, and skip the line number table
215214
machine_uint_t code_info_size = bytecode[0] | (bytecode[1] << 8) | (bytecode[2] << 16) | (bytecode[3] << 24);
216215
bytecode += code_info_size;
217216

218-
// bytecode prelude: get exception stack size
219-
machine_uint_t n_exc_stack = bytecode[0] | (bytecode[1] << 8);
220-
bytecode += 2;
217+
// bytecode prelude: get state size and exception stack size
218+
machine_uint_t n_state = bytecode[0] | (bytecode[1] << 8);
219+
machine_uint_t n_exc_stack = bytecode[2] | (bytecode[3] << 8);
220+
bytecode += 4;
221221

222222
// bytecode prelude: initialise closed over variables
223223
// TODO

py/runtime.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ typedef struct _mp_code_t {
4848
mp_code_kind_t kind : 8;
4949
uint scope_flags : 8;
5050
uint n_args : 16;
51-
uint n_state : 16;
5251
union {
5352
struct {
5453
byte *code;
@@ -147,7 +146,6 @@ void rt_assign_byte_code(uint unique_code_id, byte *code, uint len, int n_args,
147146
unique_codes[unique_code_id].kind = MP_CODE_BYTE;
148147
unique_codes[unique_code_id].scope_flags = scope_flags;
149148
unique_codes[unique_code_id].n_args = n_args;
150-
unique_codes[unique_code_id].n_state = n_locals + n_stack;
151149
unique_codes[unique_code_id].u_byte.code = code;
152150
unique_codes[unique_code_id].u_byte.len = len;
153151
unique_codes[unique_code_id].arg_names = arg_names;
@@ -176,7 +174,6 @@ void rt_assign_native_code(uint unique_code_id, void *fun, uint len, int n_args)
176174
unique_codes[unique_code_id].kind = MP_CODE_NATIVE;
177175
unique_codes[unique_code_id].scope_flags = 0;
178176
unique_codes[unique_code_id].n_args = n_args;
179-
unique_codes[unique_code_id].n_state = 0;
180177
unique_codes[unique_code_id].u_native.fun = fun;
181178

182179
//printf("native code: %d bytes\n", len);
@@ -208,7 +205,6 @@ void rt_assign_inline_asm_code(uint unique_code_id, void *fun, uint len, int n_a
208205
unique_codes[unique_code_id].kind = MP_CODE_INLINE_ASM;
209206
unique_codes[unique_code_id].scope_flags = 0;
210207
unique_codes[unique_code_id].n_args = n_args;
211-
unique_codes[unique_code_id].n_state = 0;
212208
unique_codes[unique_code_id].u_inline_asm.fun = fun;
213209

214210
#ifdef DEBUG_PRINT
@@ -662,7 +658,7 @@ mp_obj_t rt_make_function_from_id(int unique_code_id, mp_obj_t def_args) {
662658
mp_obj_t fun;
663659
switch (c->kind) {
664660
case MP_CODE_BYTE:
665-
fun = mp_obj_new_fun_bc(c->scope_flags, c->arg_names, c->n_args, def_args, c->n_state, c->u_byte.code);
661+
fun = mp_obj_new_fun_bc(c->scope_flags, c->arg_names, c->n_args, def_args, c->u_byte.code);
666662
break;
667663
case MP_CODE_NATIVE:
668664
fun = rt_make_function_n(c->n_args, c->u_native.fun);

py/vm.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,17 @@ typedef enum {
4444
#define TOP() (*sp)
4545
#define SET_TOP(val) *sp = (val)
4646

47-
mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, uint n_state, mp_obj_t *ret) {
47+
mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, mp_obj_t *ret) {
4848
const byte *ip = code;
4949

5050
// get code info size, and skip line number table
5151
machine_uint_t code_info_size = ip[0] | (ip[1] << 8) | (ip[2] << 16) | (ip[3] << 24);
5252
ip += code_info_size;
5353

54-
// bytecode prelude: exception stack size; 16 bit uint for now
55-
machine_uint_t n_exc_stack = ip[0] | (ip[1] << 8);
56-
ip += 2;
54+
// bytecode prelude: state size and exception stack size; 16 bit uints
55+
machine_uint_t n_state = ip[0] | (ip[1] << 8);
56+
machine_uint_t n_exc_stack = ip[2] | (ip[3] << 8);
57+
ip += 4;
5758

5859
// allocate state for locals and stack
5960
mp_obj_t temp_state[10];

0 commit comments

Comments
 (0)