summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-02-01 18:29:40 +0000
committerDamien George <damien.p.george@gmail.com>2014-02-01 18:29:40 +0000
commitfb083ea986d758c7426fda091c4899f0511aaa8c (patch)
treef63392368dc5140441ab3f0d8a04ec1ca9585871 /py
parent87413a4d0c579ec491cf52ab8d6520430df64c7d (diff)
downloadmicropython-fb083ea986d758c7426fda091c4899f0511aaa8c.tar.gz
micropython-fb083ea986d758c7426fda091c4899f0511aaa8c.zip
py: mp_execute_byte_code has 2 arg arrays, for more efficient default params.
Diffstat (limited to 'py')
-rw-r--r--py/bc.h2
-rw-r--r--py/emitbc.c55
-rw-r--r--py/objfun.c25
-rw-r--r--py/vm.c10
4 files changed, 46 insertions, 46 deletions
diff --git a/py/bc.h b/py/bc.h
index 17f71553e8..814201160b 100644
--- a/py/bc.h
+++ b/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);
diff --git a/py/emitbc.c b/py/emitbc.c
index 10a93d5b6e..117a08cda5 100644
--- a/py/emitbc.c
+++ b/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);
}
}
diff --git a/py/objfun.c b/py/objfun.c
index c60800bfc3..fbc0cab118 100644
--- a/py/objfun.c
+++ b/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 = {
diff --git a/py/vm.c b/py/vm.c
index 18a8a8504f..2c953137cd 100644
--- a/py/vm.c
+++ b/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);