summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/compile.c65
-rw-r--r--py/emitbc.c6
-rw-r--r--py/emitglue.c3
-rw-r--r--py/objfun.c1
-rw-r--r--py/vm.c8
5 files changed, 35 insertions, 48 deletions
diff --git a/py/compile.c b/py/compile.c
index 9f081ebbcf..47cd0c4510 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -53,9 +53,8 @@ typedef struct _compiler_t {
uint16_t n_arg_keyword;
uint8_t star_flags;
uint8_t have_bare_star;
- uint8_t param_pass;
- uint16_t param_pass_num_dict_params;
- uint16_t param_pass_num_default_params;
+ uint16_t num_dict_params;
+ uint16_t num_default_params;
scope_t *scope_head;
scope_t *scope_cur;
@@ -897,7 +896,7 @@ void compile_funcdef_param(compiler_t *comp, mp_parse_node_t pn) {
// this parameter does not have a default value
// check for non-default parameters given after default parameters (allowed by parser, but not syntactically valid)
- if (!comp->have_bare_star && comp->param_pass_num_default_params != 0) {
+ if (!comp->have_bare_star && comp->num_default_params != 0) {
compile_syntax_error(comp, pn, "non-default argument follows default argument");
return;
}
@@ -907,27 +906,23 @@ void compile_funcdef_param(compiler_t *comp, mp_parse_node_t pn) {
// in CPython, None (and True, False?) as default parameters are loaded with LOAD_NAME; don't understandy why
if (comp->have_bare_star) {
- comp->param_pass_num_dict_params += 1;
- if (comp->param_pass == 1) {
+ comp->num_dict_params += 1;
#if !MICROPY_EMIT_CPYTHON
- // in Micro Python we put the default dict parameters into a dictionary using the bytecode
- if (comp->param_pass_num_dict_params == 1) {
- // first default dict param, so make the map
- EMIT_ARG(build_map, 0);
- }
+ // in Micro Python we put the default dict parameters into a dictionary using the bytecode
+ if (comp->num_dict_params == 1) {
+ // first default dict param, so make the map
+ EMIT_ARG(build_map, 0);
+ }
#endif
- EMIT_ARG(load_const_id, MP_PARSE_NODE_LEAF_ARG(pn_id));
- compile_node(comp, pn_equal);
+ EMIT_ARG(load_const_id, MP_PARSE_NODE_LEAF_ARG(pn_id));
+ compile_node(comp, pn_equal);
#if !MICROPY_EMIT_CPYTHON
- // in Micro Python we put the default dict parameters into a dictionary using the bytecode
- EMIT(store_map);
+ // in Micro Python we put the default dict parameters into a dictionary using the bytecode
+ EMIT(store_map);
#endif
- }
} else {
- comp->param_pass_num_default_params += 1;
- if (comp->param_pass == 2) {
- compile_node(comp, pn_equal);
- }
+ comp->num_default_params += 1;
+ compile_node(comp, pn_equal);
}
}
@@ -948,34 +943,23 @@ qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint
// save variables (probably don't need to do this, since we can't have nested definitions..?)
uint old_have_bare_star = comp->have_bare_star;
- uint old_param_pass = comp->param_pass;
- uint old_param_pass_num_dict_params = comp->param_pass_num_dict_params;
- uint old_param_pass_num_default_params = comp->param_pass_num_default_params;
+ uint old_num_dict_params = comp->num_dict_params;
+ uint old_num_default_params = comp->num_default_params;
// compile default parameters
-
- // pass 1 does any default parameters after bare star
comp->have_bare_star = false;
- comp->param_pass = 1;
- comp->param_pass_num_dict_params = 0;
- comp->param_pass_num_default_params = 0;
+ comp->num_dict_params = 0;
+ comp->num_default_params = 0;
apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
if (comp->had_error) {
return MP_QSTR_NULL;
}
- // pass 2 does any default parameters before bare star
- comp->have_bare_star = false;
- comp->param_pass = 2;
- comp->param_pass_num_dict_params = 0;
- comp->param_pass_num_default_params = 0;
- apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
-
#if !MICROPY_EMIT_CPYTHON
// in Micro Python we put the default positional parameters into a tuple using the bytecode
- if (comp->param_pass_num_default_params > 0) {
- EMIT_ARG(build_tuple, comp->param_pass_num_default_params);
+ if (comp->num_default_params > 0) {
+ EMIT_ARG(build_tuple, comp->num_default_params);
}
#endif
@@ -983,13 +967,12 @@ qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint
scope_t *fscope = (scope_t*)pns->nodes[4];
// make the function
- close_over_variables_etc(comp, fscope, comp->param_pass_num_default_params, comp->param_pass_num_dict_params);
+ close_over_variables_etc(comp, fscope, comp->num_default_params, comp->num_dict_params);
// restore variables
comp->have_bare_star = old_have_bare_star;
- comp->param_pass = old_param_pass;
- comp->param_pass_num_dict_params = old_param_pass_num_dict_params;
- comp->param_pass_num_default_params = old_param_pass_num_default_params;
+ comp->num_dict_params = old_num_dict_params;
+ comp->num_default_params = old_num_default_params;
// return its name (the 'f' in "def f(...):")
return fscope->simple_name;
diff --git a/py/emitbc.c b/py/emitbc.c
index fc3e5ed622..a1179a6954 100644
--- a/py/emitbc.c
+++ b/py/emitbc.c
@@ -744,10 +744,10 @@ STATIC void emit_bc_make_function(emit_t *emit, scope_t *scope, uint n_pos_defau
if (n_pos_defaults == 0) {
// load dummy entry for non-existent positional default tuple
emit_bc_load_null(emit);
+ emit_bc_rot_two(emit);
} else if (n_kw_defaults == 0) {
// load dummy entry for non-existent keyword default dict
emit_bc_load_null(emit);
- emit_bc_rot_two(emit);
}
emit_bc_pre(emit, -1);
emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->unique_code_id);
@@ -762,11 +762,11 @@ STATIC void emit_bc_make_closure(emit_t *emit, scope_t *scope, uint n_pos_defaul
if (n_pos_defaults == 0) {
// load dummy entry for non-existent positional default tuple
emit_bc_load_null(emit);
- emit_bc_rot_two(emit);
+ emit_bc_rot_three(emit);
} else if (n_kw_defaults == 0) {
// load dummy entry for non-existent keyword default dict
emit_bc_load_null(emit);
- emit_bc_rot_three(emit);
+ emit_bc_rot_two(emit);
}
emit_bc_pre(emit, -2);
emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->unique_code_id);
diff --git a/py/emitglue.c b/py/emitglue.c
index 48800bbf00..90c9b77cf8 100644
--- a/py/emitglue.c
+++ b/py/emitglue.c
@@ -197,6 +197,9 @@ mp_obj_t mp_make_function_from_id(uint unique_code_id, mp_obj_t def_args, mp_obj
return mp_const_none;
}
+ // def_args must be MP_OBJ_NULL or a tuple
+ assert(def_args == MP_OBJ_NULL || MP_OBJ_IS_TYPE(def_args, &mp_type_tuple));
+
// TODO implement default kw args
assert(def_kw_args == MP_OBJ_NULL);
diff --git a/py/objfun.c b/py/objfun.c
index adf05ce404..dd4b7347ca 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -361,6 +361,7 @@ mp_obj_t mp_obj_new_fun_bc(uint scope_flags, qstr *args, uint n_args, mp_obj_t d
uint n_extra_args = 0;
mp_obj_tuple_t *def_args = def_args_in;
if (def_args != MP_OBJ_NULL) {
+ assert(MP_OBJ_IS_TYPE(def_args, &mp_type_tuple));
n_def_args = def_args->len;
n_extra_args = def_args->len;
}
diff --git a/py/vm.c b/py/vm.c
index 47d6bf8f59..1ea0c5eaa1 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -718,9 +718,9 @@ unwind_jump:
case MP_BC_MAKE_FUNCTION_DEFARGS:
DECODE_UINT;
- // Stack layout: def_dict def_tuple <- TOS
+ // Stack layout: def_tuple def_dict <- TOS
obj1 = POP();
- SET_TOP(mp_make_function_from_id(unum, obj1, TOP()));
+ SET_TOP(mp_make_function_from_id(unum, TOP(), obj1));
break;
case MP_BC_MAKE_CLOSURE:
@@ -731,10 +731,10 @@ unwind_jump:
case MP_BC_MAKE_CLOSURE_DEFARGS:
DECODE_UINT;
- // Stack layout: def_dict def_tuple closure_tuple <- TOS
+ // Stack layout: def_tuple def_dict closure_tuple <- TOS
obj1 = POP();
obj2 = POP();
- SET_TOP(mp_make_closure_from_id(unum, obj1, obj2, TOP()));
+ SET_TOP(mp_make_closure_from_id(unum, obj1, TOP(), obj2));
break;
case MP_BC_CALL_FUNCTION: