summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
authorPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-03-26 23:14:59 +0200
committerPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-03-26 23:17:44 +0200
commit2447a5b582503b70936681702062704e2e9f44d3 (patch)
tree6f747fe74cc8400df1a23a74cbb0b9034df5bc60 /py
parentc12b2213c16ba8839981c362c4d5f133a84b374b (diff)
downloadmicropython-2447a5b582503b70936681702062704e2e9f44d3.tar.gz
micropython-2447a5b582503b70936681702062704e2e9f44d3.zip
py: Support closures with default args.
Diffstat (limited to 'py')
-rw-r--r--py/bc0.h1
-rw-r--r--py/compile.c3
-rw-r--r--py/emitbc.c12
-rw-r--r--py/runtime.c4
-rw-r--r--py/runtime.h2
-rw-r--r--py/showbc.c5
-rw-r--r--py/vm.c8
7 files changed, 27 insertions, 8 deletions
diff --git a/py/bc0.h b/py/bc0.h
index 2c8c47bd2e..3d4b106d32 100644
--- a/py/bc0.h
+++ b/py/bc0.h
@@ -95,6 +95,7 @@
#define MP_BC_CALL_METHOD_KW (0x98) // uint
#define MP_BC_CALL_METHOD_VAR_KW (0x99) // uint
#define MP_BC_MAKE_FUNCTION_DEFARGS (0x9a) // uint
+#define MP_BC_MAKE_CLOSURE_DEFARGS (0x9b) // uint
#define MP_BC_IMPORT_NAME (0xe0) // qstr
#define MP_BC_IMPORT_FROM (0xe1) // qstr
diff --git a/py/compile.c b/py/compile.c
index 0a10b81768..dc001cd88f 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -766,6 +766,9 @@ void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_kind) {
// stuff for lambda and comprehensions and generators
void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_dict_params, int n_default_params) {
+ if (n_default_params) {
+ EMIT_ARG(build_tuple, n_default_params);
+ }
// make closed over variables, if any
// ensure they are closed over in the order defined in the outer scope (mainly to agree with CPython)
int nfree = 0;
diff --git a/py/emitbc.c b/py/emitbc.c
index ef5da3a622..653b144875 100644
--- a/py/emitbc.c
+++ b/py/emitbc.c
@@ -722,16 +722,20 @@ STATIC void emit_bc_make_function(emit_t *emit, scope_t *scope, int n_dict_param
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);
}
}
STATIC void emit_bc_make_closure(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
- assert(n_default_params == 0 && n_dict_params == 0);
- emit_pre(emit, 0);
- emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE, scope->unique_code_id);
+ assert(n_dict_params == 0);
+ if (n_default_params == 0) {
+ emit_pre(emit, 0);
+ emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE, scope->unique_code_id);
+ } else {
+ emit_pre(emit, -1);
+ emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->unique_code_id);
+ }
}
STATIC void emit_bc_call_function(emit_t *emit, int n_positional, int n_keyword, bool have_star_arg, bool have_dbl_star_arg) {
diff --git a/py/runtime.c b/py/runtime.c
index 247a78fe1a..eab414c9ee 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -683,10 +683,10 @@ mp_obj_t rt_make_function_from_id(int unique_code_id, mp_obj_t def_args) {
return fun;
}
-mp_obj_t rt_make_closure_from_id(int unique_code_id, mp_obj_t closure_tuple) {
+mp_obj_t rt_make_closure_from_id(int unique_code_id, mp_obj_t closure_tuple, mp_obj_t def_args) {
DEBUG_OP_printf("make_closure_from_id %d\n", unique_code_id);
// make function object
- mp_obj_t ffun = rt_make_function_from_id(unique_code_id, MP_OBJ_NULL);
+ mp_obj_t ffun = rt_make_function_from_id(unique_code_id, def_args);
// wrap function in closure object
return mp_obj_new_closure(ffun, closure_tuple);
}
diff --git a/py/runtime.h b/py/runtime.h
index f5e4a49cf8..553a834689 100644
--- a/py/runtime.h
+++ b/py/runtime.h
@@ -19,7 +19,7 @@ mp_obj_t rt_make_function_from_id(int unique_code_id, mp_obj_t def_args);
mp_obj_t rt_make_function_n(int n_args, void *fun); // fun must have the correct signature for n_args fixed arguments
mp_obj_t rt_make_function_var(int n_args_min, mp_fun_var_t fun);
mp_obj_t rt_make_function_var_between(int n_args_min, int n_args_max, mp_fun_var_t fun); // min and max are inclusive
-mp_obj_t rt_make_closure_from_id(int unique_code_id, mp_obj_t closure_tuple);
+mp_obj_t rt_make_closure_from_id(int unique_code_id, mp_obj_t closure_tuple, mp_obj_t def_args);
mp_obj_t rt_call_function_0(mp_obj_t fun);
mp_obj_t rt_call_function_1(mp_obj_t fun, mp_obj_t arg);
mp_obj_t rt_call_function_2(mp_obj_t fun, mp_obj_t arg1, mp_obj_t arg2);
diff --git a/py/showbc.c b/py/showbc.c
index 9bdf811d9a..eb743bd29e 100644
--- a/py/showbc.c
+++ b/py/showbc.c
@@ -371,6 +371,11 @@ void mp_byte_code_print(const byte *ip, int len) {
printf("MAKE_CLOSURE " UINT_FMT, unum);
break;
+ case MP_BC_MAKE_CLOSURE_DEFARGS:
+ DECODE_UINT;
+ printf("MAKE_CLOSURE_DEFARGS " UINT_FMT, unum);
+ break;
+
case MP_BC_CALL_FUNCTION:
DECODE_UINT;
printf("CALL_FUNCTION n=" UINT_FMT " nkw=" UINT_FMT, unum & 0xff, (unum >> 8) & 0xff);
diff --git a/py/vm.c b/py/vm.c
index e34acb488b..b98781c761 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -561,7 +561,13 @@ unwind_jump:
case MP_BC_MAKE_CLOSURE:
DECODE_UINT;
- SET_TOP(rt_make_closure_from_id(unum, TOP()));
+ SET_TOP(rt_make_closure_from_id(unum, TOP(), MP_OBJ_NULL));
+ break;
+
+ case MP_BC_MAKE_CLOSURE_DEFARGS:
+ DECODE_UINT;
+ obj1 = POP();
+ SET_TOP(rt_make_closure_from_id(unum, obj1, TOP()));
break;
case MP_BC_CALL_FUNCTION: