aboutsummaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2022-05-03 10:38:15 +1000
committerDamien George <damien@micropython.org>2022-05-03 16:38:43 +1000
commit590de399f01cd08aa4825b26b91785e07abcf68c (patch)
treee5c2a629ec2f3d032f5d85803625ffdaf109d21e /py
parenta21fd7cc21270c8b286129a6fe79025c57b33102 (diff)
py/emitcommon: Don't implicitly close class vars that are assigned to.
When in a class body or at the module level don't implicitly close over variables that have been assigned to. Fixes issue #8603. Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'py')
-rw-r--r--py/emitcommon.c13
-rw-r--r--py/scope.h1
2 files changed, 10 insertions, 4 deletions
diff --git a/py/emitcommon.c b/py/emitcommon.c
index c1780d2db..647430232 100644
--- a/py/emitcommon.c
+++ b/py/emitcommon.c
@@ -44,9 +44,14 @@ qstr_short_t mp_emit_common_use_qstr(mp_emit_common_t *emit, qstr qst) {
void mp_emit_common_get_id_for_modification(scope_t *scope, qstr qst) {
// name adding/lookup
id_info_t *id = scope_find_or_add_id(scope, qst, ID_INFO_KIND_GLOBAL_IMPLICIT);
- if (SCOPE_IS_FUNC_LIKE(scope->kind) && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
- // rebind as a local variable
- id->kind = ID_INFO_KIND_LOCAL;
+ if (id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
+ if (SCOPE_IS_FUNC_LIKE(scope->kind)) {
+ // rebind as a local variable
+ id->kind = ID_INFO_KIND_LOCAL;
+ } else {
+ // mark this as assigned, to prevent it from being closed over
+ id->kind = ID_INFO_KIND_GLOBAL_IMPLICIT_ASSIGNED;
+ }
}
}
@@ -57,7 +62,7 @@ void mp_emit_common_id_op(emit_t *emit, const mp_emit_method_table_id_ops_t *emi
assert(id != NULL);
// call the emit backend with the correct code
- if (id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
+ if (id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT || id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT_ASSIGNED) {
emit_method_table->global(emit, qst, MP_EMIT_IDOP_GLOBAL_NAME);
} else if (id->kind == ID_INFO_KIND_GLOBAL_EXPLICIT) {
emit_method_table->global(emit, qst, MP_EMIT_IDOP_GLOBAL_GLOBAL);
diff --git a/py/scope.h b/py/scope.h
index 5006deade..b781dde42 100644
--- a/py/scope.h
+++ b/py/scope.h
@@ -32,6 +32,7 @@
typedef enum {
ID_INFO_KIND_UNDECIDED,
ID_INFO_KIND_GLOBAL_IMPLICIT,
+ ID_INFO_KIND_GLOBAL_IMPLICIT_ASSIGNED,
ID_INFO_KIND_GLOBAL_EXPLICIT,
ID_INFO_KIND_LOCAL, // in a function f, written and only referenced by f
ID_INFO_KIND_CELL, // in a function f, read/written by children of f