Skip to content

Commit fb083ea

Browse files
committed
py: mp_execute_byte_code has 2 arg arrays, for more efficient default params.
1 parent 87413a4 commit fb083ea

File tree

4 files changed

+46
-46
lines changed

4 files changed

+46
-46
lines changed

py/bc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
mp_obj_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, uint n_state);
1+
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);
22
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);
33
void mp_byte_code_print(const byte *code, int len);

py/emitbc.c

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,22 @@ static void emit_write_byte_code_byte_byte(emit_t* emit, byte b1, uint b2) {
107107
c[1] = b2;
108108
}
109109

110+
static void emit_write_byte_code_uint(emit_t* emit, uint num) {
111+
if (num <= 127) { // fits in 0x7f
112+
// fit argument in single byte
113+
byte* c = emit_get_cur_to_write_byte_code(emit, 1);
114+
c[0] = num;
115+
} else if (num <= 16383) { // fits in 0x3fff
116+
// fit argument in two bytes
117+
byte* c = emit_get_cur_to_write_byte_code(emit, 2);
118+
c[0] = (num >> 8) | 0x80;
119+
c[1] = num;
120+
} else {
121+
// larger numbers not implemented/supported
122+
assert(0);
123+
}
124+
}
125+
110126
// integers (for small ints) are stored as 24 bits, in excess
111127
static void emit_write_byte_code_byte_int(emit_t* emit, byte b1, machine_int_t num) {
112128
num += 0x800000;
@@ -118,26 +134,21 @@ static void emit_write_byte_code_byte_int(emit_t* emit, byte b1, machine_int_t n
118134
c[3] = num >> 16;
119135
}
120136

121-
static void emit_write_byte_code_byte_uint(emit_t* emit, byte b1, uint num) {
122-
if (num <= 127) { // fits in 0x7f
123-
// fit argument in single byte
124-
byte* c = emit_get_cur_to_write_byte_code(emit, 2);
125-
c[0] = b1;
126-
c[1] = num;
127-
} else if (num <= 16383) { // fits in 0x3fff
128-
// fit argument in two bytes
129-
byte* c = emit_get_cur_to_write_byte_code(emit, 3);
130-
c[0] = b1;
131-
c[1] = (num >> 8) | 0x80;
132-
c[2] = num;
133-
} else {
134-
// larger numbers not implemented/supported
135-
assert(0);
136-
}
137+
static void emit_write_byte_code_byte_uint(emit_t* emit, byte b, uint num) {
138+
emit_write_byte_code_byte(emit, b);
139+
emit_write_byte_code_uint(emit, num);
137140
}
138141

139-
static void emit_write_byte_code_byte_qstr(emit_t* emit, byte b1, qstr qstr) {
140-
emit_write_byte_code_byte_uint(emit, b1, qstr);
142+
/* currently unused
143+
static void emit_write_byte_code_byte_uint_uint(emit_t* emit, byte b, uint num1, uint num2) {
144+
emit_write_byte_code_byte(emit, b);
145+
emit_write_byte_code_byte_uint(emit, num1);
146+
emit_write_byte_code_byte_uint(emit, num2);
147+
}
148+
*/
149+
150+
static void emit_write_byte_code_byte_qstr(emit_t* emit, byte b, qstr qstr) {
151+
emit_write_byte_code_byte_uint(emit, b, qstr);
141152
}
142153

143154
// 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) {
665676

666677
static void emit_bc_make_function(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
667678
assert(n_dict_params == 0);
668-
if (n_default_params != 0) {
679+
if (n_default_params == 0) {
680+
emit_pre(emit, 1);
681+
emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION, scope->unique_code_id);
682+
} else {
669683
emit_bc_build_tuple(emit, n_default_params);
670684
emit_pre(emit, 0);
671685
emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->unique_code_id);
672-
} else {
673-
emit_pre(emit, 1);
674-
emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION, scope->unique_code_id);
675686
}
676687
}
677688

py/objfun.c

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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
154154
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "function does not take keyword arguments"));
155155
}
156156

157-
mp_obj_t full_args[n_args];
158-
if (n_args < self->n_args) {
159-
memcpy(full_args, args, n_args * sizeof(*args));
160-
int use_def_args = self->n_args - n_args;
161-
memcpy(full_args + n_args, self->def_args + self->n_def_args - use_def_args, use_def_args * sizeof(*args));
162-
args = full_args;
163-
n_args = self->n_args;
164-
}
165-
166-
// optimisation: allow the compiler to optimise this tail call for
167-
// the common case when the globals don't need to be changed
157+
uint use_def_args = self->n_args - n_args;
168158
mp_map_t *old_globals = rt_globals_get();
169-
if (self->globals == old_globals) {
170-
return mp_execute_byte_code(self->bytecode, args, n_args, self->n_state);
171-
} else {
172-
rt_globals_set(self->globals);
173-
mp_obj_t result = mp_execute_byte_code(self->bytecode, args, n_args, self->n_state);
174-
rt_globals_set(old_globals);
175-
return result;
176-
}
159+
rt_globals_set(self->globals);
160+
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);
161+
rt_globals_set(old_globals);
162+
163+
return result;
177164
}
178165

179166
const mp_obj_type_t fun_bc_type = {

py/vm.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ typedef enum {
4646
#define TOP() (*sp)
4747
#define SET_TOP(val) *sp = (val)
4848

49-
mp_obj_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, uint n_state) {
49+
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) {
5050
// allocate state for locals and stack
5151
mp_obj_t temp_state[10];
5252
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
5656
mp_obj_t *sp = &state[0] - 1;
5757

5858
// init args
59-
for (int i = 0; i < n_args; i++) {
60-
assert(i < 8);
59+
for (uint i = 0; i < n_args; i++) {
6160
state[n_state - 1 - i] = args[i];
6261
}
62+
for (uint i = 0; i < n_args2; i++) {
63+
state[n_state - 1 - n_args - i] = args2[i];
64+
}
6365

6466
const byte *ip = code;
6567

@@ -71,7 +73,7 @@ mp_obj_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_arg
7173
{
7274
for (uint n_local = *ip++; n_local > 0; n_local--) {
7375
uint local_num = *ip++;
74-
if (local_num < n_args) {
76+
if (local_num < n_args + n_args2) {
7577
state[n_state - 1 - local_num] = mp_obj_new_cell(state[n_state - 1 - local_num]);
7678
} else {
7779
state[n_state - 1 - local_num] = mp_obj_new_cell(MP_OBJ_NULL);

0 commit comments

Comments
 (0)