py: Fix naming of function arguments when function is a closure.
Addresses issue #1226.
This commit is contained in:
parent
cd87d20f46
commit
9a42eb541e
20
py/emitbc.c
20
py/emitbc.c
|
@ -305,8 +305,26 @@ void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
|
||||||
// we store them as full word-sized objects for efficient access in mp_setup_code_state
|
// we store them as full word-sized objects for efficient access in mp_setup_code_state
|
||||||
// this is the start of the prelude and is guaranteed to be aligned on a word boundary
|
// this is the start of the prelude and is guaranteed to be aligned on a word boundary
|
||||||
{
|
{
|
||||||
|
// For a given argument position (indexed by i) we need to find the
|
||||||
|
// corresponding id_info which is a parameter, as it has the correct
|
||||||
|
// qstr name to use as the argument name. Note that it's not a simple
|
||||||
|
// 1-1 mapping (ie i!=j in general) because of possible closed-over
|
||||||
|
// variables. In the case that the argument i has no corresponding
|
||||||
|
// parameter we use "*" as its name (since no argument can ever be named
|
||||||
|
// "*"). We could use a blank qstr but "*" is better for debugging.
|
||||||
|
// Note: there is some wasted RAM here for the case of storing a qstr
|
||||||
|
// for each closed-over variable, and maybe there is a better way to do
|
||||||
|
// it, but that would require changes to mp_setup_code_state.
|
||||||
for (int i = 0; i < scope->num_pos_args + scope->num_kwonly_args; i++) {
|
for (int i = 0; i < scope->num_pos_args + scope->num_kwonly_args; i++) {
|
||||||
emit_write_bytecode_prealigned_ptr(emit, MP_OBJ_NEW_QSTR(scope->id_info[i].qst));
|
qstr qst = MP_QSTR__star_;
|
||||||
|
for (int j = 0; j < scope->id_info_len; ++j) {
|
||||||
|
id_info_t *id = &scope->id_info[j];
|
||||||
|
if ((id->flags & ID_FLAG_IS_PARAM) && id->local_num == i) {
|
||||||
|
qst = id->qst;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit_write_bytecode_prealigned_ptr(emit, MP_OBJ_NEW_QSTR(qst));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -796,8 +796,17 @@ STATIC void emit_native_end_pass(emit_t *emit) {
|
||||||
ASM_DATA(emit->as, 1, emit->code_info_size);
|
ASM_DATA(emit->as, 1, emit->code_info_size);
|
||||||
ASM_ALIGN(emit->as, ASM_WORD_SIZE);
|
ASM_ALIGN(emit->as, ASM_WORD_SIZE);
|
||||||
emit->code_info_size = ASM_GET_CODE_POS(emit->as) - emit->code_info_offset;
|
emit->code_info_size = ASM_GET_CODE_POS(emit->as) - emit->code_info_offset;
|
||||||
|
// see comment in corresponding part of emitbc.c about the logic here
|
||||||
for (int i = 0; i < emit->scope->num_pos_args + emit->scope->num_kwonly_args; i++) {
|
for (int i = 0; i < emit->scope->num_pos_args + emit->scope->num_kwonly_args; i++) {
|
||||||
ASM_DATA(emit->as, ASM_WORD_SIZE, (mp_uint_t)MP_OBJ_NEW_QSTR(emit->scope->id_info[i].qst));
|
qstr qst = MP_QSTR__star_;
|
||||||
|
for (int j = 0; j < emit->scope->id_info_len; ++j) {
|
||||||
|
id_info_t *id = &emit->scope->id_info[j];
|
||||||
|
if ((id->flags & ID_FLAG_IS_PARAM) && id->local_num == i) {
|
||||||
|
qst = id->qst;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ASM_DATA(emit->as, ASM_WORD_SIZE, (mp_uint_t)MP_OBJ_NEW_QSTR(qst));
|
||||||
}
|
}
|
||||||
|
|
||||||
// bytecode prelude: initialise closed over variables
|
// bytecode prelude: initialise closed over variables
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
# test passing named arg to closed-over function
|
||||||
|
|
||||||
|
def f():
|
||||||
|
x = 1
|
||||||
|
def g(z):
|
||||||
|
print(x, z)
|
||||||
|
return g
|
||||||
|
|
||||||
|
f()(z=42)
|
|
@ -354,7 +354,7 @@ File cmdline/cmd_showbc.py, code block '<genexpr>' (descriptor: \.\+, bytecode @
|
||||||
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
||||||
########
|
########
|
||||||
\.\+5b
|
\.\+5b
|
||||||
arg names: c e
|
arg names: * * *
|
||||||
(N_STATE 6)
|
(N_STATE 6)
|
||||||
(N_EXC_STACK 0)
|
(N_EXC_STACK 0)
|
||||||
bc=-\\d\+ line=1
|
bc=-\\d\+ line=1
|
||||||
|
@ -373,7 +373,7 @@ File cmdline/cmd_showbc.py, code block '<listcomp>' (descriptor: \.\+, bytecode
|
||||||
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
||||||
########
|
########
|
||||||
\.\+5b
|
\.\+5b
|
||||||
arg names: c e
|
arg names: * * *
|
||||||
(N_STATE 7)
|
(N_STATE 7)
|
||||||
(N_EXC_STACK 0)
|
(N_EXC_STACK 0)
|
||||||
bc=-\\d\+ line=1
|
bc=-\\d\+ line=1
|
||||||
|
@ -391,7 +391,7 @@ File cmdline/cmd_showbc.py, code block '<dictcomp>' (descriptor: \.\+, bytecode
|
||||||
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
||||||
########
|
########
|
||||||
\.\+5b
|
\.\+5b
|
||||||
arg names: c e
|
arg names: * * *
|
||||||
(N_STATE 8)
|
(N_STATE 8)
|
||||||
(N_EXC_STACK 0)
|
(N_EXC_STACK 0)
|
||||||
bc=-\\d\+ line=1
|
bc=-\\d\+ line=1
|
||||||
|
@ -411,7 +411,7 @@ File cmdline/cmd_showbc.py, code block 'closure' (descriptor: \.\+, bytecode @\.
|
||||||
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
||||||
########
|
########
|
||||||
\.\+5b
|
\.\+5b
|
||||||
arg names: x
|
arg names: *
|
||||||
(N_STATE 4)
|
(N_STATE 4)
|
||||||
(N_EXC_STACK 0)
|
(N_EXC_STACK 0)
|
||||||
bc=-\\d\+ line=1
|
bc=-\\d\+ line=1
|
||||||
|
@ -430,7 +430,7 @@ File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ byt
|
||||||
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
||||||
########
|
########
|
||||||
\.\+5b
|
\.\+5b
|
||||||
arg names: b a
|
arg names: * b
|
||||||
(N_STATE 4)
|
(N_STATE 4)
|
||||||
(N_EXC_STACK 0)
|
(N_EXC_STACK 0)
|
||||||
bc=-\\d\+ line=1
|
bc=-\\d\+ line=1
|
||||||
|
|
Loading…
Reference in New Issue