diff options
author | Damien George <damien.p.george@gmail.com> | 2015-10-22 23:45:37 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2015-11-13 12:49:18 +0000 |
commit | 3a3db4dcf0400cffef860f61a84979cb1f7a7541 (patch) | |
tree | cfdcb6931cb120f2f993e10e7db6dc14f40b1ded /py/bc.c | |
parent | 9b7f583b0ca37ee87e5fb82e2d65fcd96a609b2f (diff) |
py: Put all bytecode state (arg count, etc) in bytecode.
Diffstat (limited to 'py/bc.c')
-rw-r--r-- | py/bc.c | 73 |
1 files changed, 40 insertions, 33 deletions
@@ -31,6 +31,7 @@ #include "py/nlr.h" #include "py/objfun.h" +#include "py/runtime0.h" #include "py/bc.h" #if 0 // print debugging info @@ -100,6 +101,12 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t code_state->prev = NULL; #endif + // get params + mp_uint_t scope_flags = *code_state->ip++; + mp_uint_t n_pos_args = *code_state->ip++; + mp_uint_t n_kwonly_args = *code_state->ip++; + mp_uint_t n_def_pos_args = *code_state->ip++; + // align ip code_state->ip = MP_ALIGN(code_state->ip, sizeof(mp_uint_t)); @@ -112,33 +119,33 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t const mp_obj_t *kwargs = args + n_args; // var_pos_kw_args points to the stack where the var-args tuple, and var-kw dict, should go (if they are needed) - mp_obj_t *var_pos_kw_args = &code_state->state[n_state - 1 - self->n_pos_args - self->n_kwonly_args]; + mp_obj_t *var_pos_kw_args = &code_state->state[n_state - 1 - n_pos_args - n_kwonly_args]; // check positional arguments - if (n_args > self->n_pos_args) { + if (n_args > n_pos_args) { // given more than enough arguments - if (!self->takes_var_args) { - fun_pos_args_mismatch(self, self->n_pos_args, n_args); + if ((scope_flags & MP_SCOPE_FLAG_VARARGS) == 0) { + fun_pos_args_mismatch(self, n_pos_args, n_args); } // put extra arguments in varargs tuple - *var_pos_kw_args-- = mp_obj_new_tuple(n_args - self->n_pos_args, args + self->n_pos_args); - n_args = self->n_pos_args; + *var_pos_kw_args-- = mp_obj_new_tuple(n_args - n_pos_args, args + n_pos_args); + n_args = n_pos_args; } else { - if (self->takes_var_args) { + if ((scope_flags & MP_SCOPE_FLAG_VARARGS) != 0) { DEBUG_printf("passing empty tuple as *args\n"); *var_pos_kw_args-- = mp_const_empty_tuple; } // Apply processing and check below only if we don't have kwargs, // otherwise, kw handling code below has own extensive checks. - if (n_kw == 0 && !self->has_def_kw_args) { - if (n_args >= (mp_uint_t)(self->n_pos_args - self->n_def_args)) { + if (n_kw == 0 && (scope_flags & MP_SCOPE_FLAG_DEFKWARGS) == 0) { + if (n_args >= (mp_uint_t)(n_pos_args - n_def_pos_args)) { // given enough arguments, but may need to use some default arguments - for (mp_uint_t i = n_args; i < self->n_pos_args; i++) { - code_state->state[n_state - 1 - i] = self->extra_args[i - (self->n_pos_args - self->n_def_args)]; + for (mp_uint_t i = n_args; i < n_pos_args; i++) { + code_state->state[n_state - 1 - i] = self->extra_args[i - (n_pos_args - n_def_pos_args)]; } } else { - fun_pos_args_mismatch(self, self->n_pos_args - self->n_def_args, n_args); + fun_pos_args_mismatch(self, n_pos_args - n_def_pos_args, n_args); } } } @@ -150,12 +157,12 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t // check keyword arguments - if (n_kw != 0 || self->has_def_kw_args) { + if (n_kw != 0 || (scope_flags & MP_SCOPE_FLAG_DEFKWARGS) != 0) { DEBUG_printf("Initial args: "); - dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args); + dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); mp_obj_t dict = MP_OBJ_NULL; - if (self->takes_kw_args) { + if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) { dict = mp_obj_new_dict(n_kw); // TODO: better go conservative with 0? *var_pos_kw_args = dict; } @@ -165,7 +172,7 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t for (mp_uint_t i = 0; i < n_kw; i++) { mp_obj_t wanted_arg_name = kwargs[2 * i]; - for (mp_uint_t j = 0; j < self->n_pos_args + self->n_kwonly_args; j++) { + for (mp_uint_t j = 0; j < n_pos_args + n_kwonly_args; j++) { if (wanted_arg_name == arg_names[j]) { if (code_state->state[n_state - 1 - j] != MP_OBJ_NULL) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, @@ -176,7 +183,7 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t } } // Didn't find name match with positional args - if (!self->takes_kw_args) { + if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) == 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments")); } mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]); @@ -184,19 +191,19 @@ continue2:; } DEBUG_printf("Args with kws flattened: "); - dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args); + dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); // fill in defaults for positional args - mp_obj_t *d = &code_state->state[n_state - self->n_pos_args]; - mp_obj_t *s = &self->extra_args[self->n_def_args - 1]; - for (mp_uint_t i = self->n_def_args; i > 0; i--, d++, s--) { + mp_obj_t *d = &code_state->state[n_state - n_pos_args]; + mp_obj_t *s = &self->extra_args[n_def_pos_args - 1]; + for (mp_uint_t i = n_def_pos_args; i > 0; i--, d++, s--) { if (*d == MP_OBJ_NULL) { *d = *s; } } DEBUG_printf("Args after filling default positional: "); - dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args); + dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); // Check that all mandatory positional args are specified while (d < &code_state->state[n_state]) { @@ -208,35 +215,35 @@ continue2:; // Check that all mandatory keyword args are specified // Fill in default kw args if we have them - for (mp_uint_t i = 0; i < self->n_kwonly_args; i++) { - if (code_state->state[n_state - 1 - self->n_pos_args - i] == MP_OBJ_NULL) { + for (mp_uint_t i = 0; i < n_kwonly_args; i++) { + if (code_state->state[n_state - 1 - n_pos_args - i] == MP_OBJ_NULL) { mp_map_elem_t *elem = NULL; - if (self->has_def_kw_args) { - elem = mp_map_lookup(&((mp_obj_dict_t*)self->extra_args[self->n_def_args])->map, arg_names[self->n_pos_args + i], MP_MAP_LOOKUP); + if ((scope_flags & MP_SCOPE_FLAG_DEFKWARGS) != 0) { + elem = mp_map_lookup(&((mp_obj_dict_t*)self->extra_args[n_def_pos_args])->map, arg_names[n_pos_args + i], MP_MAP_LOOKUP); } if (elem != NULL) { - code_state->state[n_state - 1 - self->n_pos_args - i] = elem->value; + code_state->state[n_state - 1 - n_pos_args - i] = elem->value; } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "function missing required keyword argument '%q'", MP_OBJ_QSTR_VALUE(arg_names[self->n_pos_args + i]))); + "function missing required keyword argument '%q'", MP_OBJ_QSTR_VALUE(arg_names[n_pos_args + i]))); } } } } else { // no keyword arguments given - if (self->n_kwonly_args != 0) { + if (n_kwonly_args != 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function missing keyword-only argument")); } - if (self->takes_kw_args) { + if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) { *var_pos_kw_args = mp_obj_new_dict(0); } } // get the ip and skip argument names const byte *ip = code_state->ip; - ip += (self->n_pos_args + self->n_kwonly_args) * sizeof(mp_uint_t); + ip += (n_pos_args + n_kwonly_args) * sizeof(mp_uint_t); // store pointer to code_info and jump over it { @@ -256,7 +263,7 @@ continue2:; // now that we skipped over the prelude, set the ip for the VM code_state->ip = ip; - DEBUG_printf("Calling: n_pos_args=%d, n_kwonly_args=%d\n", self->n_pos_args, self->n_kwonly_args); - dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args); + DEBUG_printf("Calling: n_pos_args=%d, n_kwonly_args=%d\n", n_pos_args, n_kwonly_args); + dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); dump_args(code_state->state, n_state); } |