py: mp_execute_byte_code has 2 arg arrays, for more efficient default params.
This commit is contained in:
parent
87413a4d0c
commit
fb083ea986
2
py/bc.h
2
py/bc.h
@ -1,3 +1,3 @@
|
||||
mp_obj_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, uint n_state);
|
||||
mp_obj_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);
|
||||
bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **sp_in_out);
|
||||
void mp_byte_code_print(const byte *code, int len);
|
||||
|
55
py/emitbc.c
55
py/emitbc.c
@ -107,6 +107,22 @@ static void emit_write_byte_code_byte_byte(emit_t* emit, byte b1, uint b2) {
|
||||
c[1] = b2;
|
||||
}
|
||||
|
||||
static void emit_write_byte_code_uint(emit_t* emit, uint num) {
|
||||
if (num <= 127) { // fits in 0x7f
|
||||
// fit argument in single byte
|
||||
byte* c = emit_get_cur_to_write_byte_code(emit, 1);
|
||||
c[0] = num;
|
||||
} else if (num <= 16383) { // fits in 0x3fff
|
||||
// fit argument in two bytes
|
||||
byte* c = emit_get_cur_to_write_byte_code(emit, 2);
|
||||
c[0] = (num >> 8) | 0x80;
|
||||
c[1] = num;
|
||||
} else {
|
||||
// larger numbers not implemented/supported
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
// integers (for small ints) are stored as 24 bits, in excess
|
||||
static void emit_write_byte_code_byte_int(emit_t* emit, byte b1, machine_int_t num) {
|
||||
num += 0x800000;
|
||||
@ -118,26 +134,21 @@ static void emit_write_byte_code_byte_int(emit_t* emit, byte b1, machine_int_t n
|
||||
c[3] = num >> 16;
|
||||
}
|
||||
|
||||
static void emit_write_byte_code_byte_uint(emit_t* emit, byte b1, uint num) {
|
||||
if (num <= 127) { // fits in 0x7f
|
||||
// fit argument in single byte
|
||||
byte* c = emit_get_cur_to_write_byte_code(emit, 2);
|
||||
c[0] = b1;
|
||||
c[1] = num;
|
||||
} else if (num <= 16383) { // fits in 0x3fff
|
||||
// fit argument in two bytes
|
||||
byte* c = emit_get_cur_to_write_byte_code(emit, 3);
|
||||
c[0] = b1;
|
||||
c[1] = (num >> 8) | 0x80;
|
||||
c[2] = num;
|
||||
} else {
|
||||
// larger numbers not implemented/supported
|
||||
assert(0);
|
||||
}
|
||||
static void emit_write_byte_code_byte_uint(emit_t* emit, byte b, uint num) {
|
||||
emit_write_byte_code_byte(emit, b);
|
||||
emit_write_byte_code_uint(emit, num);
|
||||
}
|
||||
|
||||
static void emit_write_byte_code_byte_qstr(emit_t* emit, byte b1, qstr qstr) {
|
||||
emit_write_byte_code_byte_uint(emit, b1, qstr);
|
||||
/* currently unused
|
||||
static void emit_write_byte_code_byte_uint_uint(emit_t* emit, byte b, uint num1, uint num2) {
|
||||
emit_write_byte_code_byte(emit, b);
|
||||
emit_write_byte_code_byte_uint(emit, num1);
|
||||
emit_write_byte_code_byte_uint(emit, num2);
|
||||
}
|
||||
*/
|
||||
|
||||
static void emit_write_byte_code_byte_qstr(emit_t* emit, byte b, qstr qstr) {
|
||||
emit_write_byte_code_byte_uint(emit, b, qstr);
|
||||
}
|
||||
|
||||
// unsigned labels are relative to ip following this instruction, stored as 16 bits
|
||||
@ -665,13 +676,13 @@ static void emit_bc_unpack_ex(emit_t *emit, int n_left, int n_right) {
|
||||
|
||||
static void emit_bc_make_function(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
|
||||
assert(n_dict_params == 0);
|
||||
if (n_default_params != 0) {
|
||||
if (n_default_params == 0) {
|
||||
emit_pre(emit, 1);
|
||||
emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION, scope->unique_code_id);
|
||||
} else {
|
||||
emit_bc_build_tuple(emit, n_default_params);
|
||||
emit_pre(emit, 0);
|
||||
emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->unique_code_id);
|
||||
} else {
|
||||
emit_pre(emit, 1);
|
||||
emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION, scope->unique_code_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
25
py/objfun.c
25
py/objfun.c
@ -154,26 +154,13 @@ mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *a
|
||||
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "function does not take keyword arguments"));
|
||||
}
|
||||
|
||||
mp_obj_t full_args[n_args];
|
||||
if (n_args < self->n_args) {
|
||||
memcpy(full_args, args, n_args * sizeof(*args));
|
||||
int use_def_args = self->n_args - n_args;
|
||||
memcpy(full_args + n_args, self->def_args + self->n_def_args - use_def_args, use_def_args * sizeof(*args));
|
||||
args = full_args;
|
||||
n_args = self->n_args;
|
||||
}
|
||||
|
||||
// optimisation: allow the compiler to optimise this tail call for
|
||||
// the common case when the globals don't need to be changed
|
||||
uint use_def_args = self->n_args - n_args;
|
||||
mp_map_t *old_globals = rt_globals_get();
|
||||
if (self->globals == old_globals) {
|
||||
return mp_execute_byte_code(self->bytecode, args, n_args, self->n_state);
|
||||
} else {
|
||||
rt_globals_set(self->globals);
|
||||
mp_obj_t result = mp_execute_byte_code(self->bytecode, args, n_args, self->n_state);
|
||||
rt_globals_set(old_globals);
|
||||
return result;
|
||||
}
|
||||
rt_globals_set(self->globals);
|
||||
mp_obj_t result = mp_execute_byte_code(self->bytecode, args, n_args, self->def_args + self->n_def_args - use_def_args, use_def_args, self->n_state);
|
||||
rt_globals_set(old_globals);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const mp_obj_type_t fun_bc_type = {
|
||||
|
10
py/vm.c
10
py/vm.c
@ -46,7 +46,7 @@ typedef enum {
|
||||
#define TOP() (*sp)
|
||||
#define SET_TOP(val) *sp = (val)
|
||||
|
||||
mp_obj_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, uint n_state) {
|
||||
mp_obj_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) {
|
||||
// allocate state for locals and stack
|
||||
mp_obj_t temp_state[10];
|
||||
mp_obj_t *state = &temp_state[0];
|
||||
@ -56,10 +56,12 @@ mp_obj_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_arg
|
||||
mp_obj_t *sp = &state[0] - 1;
|
||||
|
||||
// init args
|
||||
for (int i = 0; i < n_args; i++) {
|
||||
assert(i < 8);
|
||||
for (uint i = 0; i < n_args; i++) {
|
||||
state[n_state - 1 - i] = args[i];
|
||||
}
|
||||
for (uint i = 0; i < n_args2; i++) {
|
||||
state[n_state - 1 - n_args - i] = args2[i];
|
||||
}
|
||||
|
||||
const byte *ip = code;
|
||||
|
||||
@ -71,7 +73,7 @@ mp_obj_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_arg
|
||||
{
|
||||
for (uint n_local = *ip++; n_local > 0; n_local--) {
|
||||
uint local_num = *ip++;
|
||||
if (local_num < n_args) {
|
||||
if (local_num < n_args + n_args2) {
|
||||
state[n_state - 1 - local_num] = mp_obj_new_cell(state[n_state - 1 - local_num]);
|
||||
} else {
|
||||
state[n_state - 1 - local_num] = mp_obj_new_cell(MP_OBJ_NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user