Skip to content

Commit 9ecbcff

Browse files
committed
py: work towards working closures.
1 parent 5285155 commit 9ecbcff

File tree

11 files changed

+214
-108
lines changed

11 files changed

+214
-108
lines changed

py/bc.h

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,28 @@
1212
#define PYBC_LOAD_FAST_1 (0x21)
1313
#define PYBC_LOAD_FAST_2 (0x22)
1414
#define PYBC_LOAD_FAST_N (0x23) // uint
15-
#define PYBC_LOAD_NAME (0x24) // qstr
16-
#define PYBC_LOAD_GLOBAL (0x25) // qstr
17-
#define PYBC_LOAD_ATTR (0x26) // qstr
18-
#define PYBC_LOAD_METHOD (0x27) // qstr
19-
#define PYBC_LOAD_BUILD_CLASS (0x28)
15+
#define PYBC_LOAD_DEREF (0x24) // uint
16+
#define PYBC_LOAD_CLOSURE (0x25) // uint
17+
#define PYBC_LOAD_NAME (0x26) // qstr
18+
#define PYBC_LOAD_GLOBAL (0x27) // qstr
19+
#define PYBC_LOAD_ATTR (0x28) // qstr
20+
#define PYBC_LOAD_METHOD (0x29) // qstr
21+
#define PYBC_LOAD_BUILD_CLASS (0x2a)
2022

2123
#define PYBC_STORE_FAST_0 (0x30)
2224
#define PYBC_STORE_FAST_1 (0x31)
2325
#define PYBC_STORE_FAST_2 (0x32)
2426
#define PYBC_STORE_FAST_N (0x33) // uint
25-
#define PYBC_STORE_NAME (0x34) // qstr
26-
#define PYBC_STORE_GLOBAL (0x35) // qstr
27-
#define PYBC_STORE_ATTR (0x36) // qstr
28-
#define PYBC_STORE_SUBSCR (0x37)
27+
#define PYBC_STORE_DEREF (0x34) // uint
28+
#define PYBC_STORE_NAME (0x35) // qstr
29+
#define PYBC_STORE_GLOBAL (0x36) // qstr
30+
#define PYBC_STORE_ATTR (0x37) // qstr
31+
#define PYBC_STORE_SUBSCR (0x38)
2932

3033
#define PYBC_DELETE_FAST_N (0x39) // uint
31-
#define PYBC_DELETE_NAME (0x3a) // qstr
32-
#define PYBC_DELETE_GLOBAL (0x3b) // qstr
33-
#define PYBC_DELETE_DEREF (0x3c) // qstr
34+
#define PYBC_DELETE_DEREF (0x3a) // uint
35+
#define PYBC_DELETE_NAME (0x3b) // qstr
36+
#define PYBC_DELETE_GLOBAL (0x3c) // qstr
3437
#define PYBC_DELETE_ATTR (0x3d) // qstr
3538
#define PYBC_DELETE_SUBSCR (0x3e)
3639

@@ -80,7 +83,7 @@
8083
#define PYBC_YIELD_FROM (0x83)
8184

8285
#define PYBC_MAKE_FUNCTION (0x90) // uint
83-
#define PYBC_MAKE_CLOSURE (0x91) // uint?
86+
#define PYBC_MAKE_CLOSURE (0x91) // uint
8487
#define PYBC_CALL_FUNCTION (0x92) // uint
8588
#define PYBC_CALL_FUNCTION_VAR (0x93) // uint
8689
#define PYBC_CALL_FUNCTION_KW (0x94) // uint

py/compile.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2842,9 +2842,7 @@ void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass
28422842
void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
28432843
// in functions, turn implicit globals into explicit globals
28442844
// compute num_locals, and the index of each local
2845-
// compute the index of free and cell vars (freevars[idx] in CPython)
28462845
scope->num_locals = 0;
2847-
int num_closed = 0;
28482846
for (int i = 0; i < scope->id_info_len; i++) {
28492847
id_info_t *id = &scope->id_info[i];
28502848
if (scope->kind == SCOPE_CLASS && id->qstr == comp->qstr___class__) {
@@ -2854,16 +2852,47 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
28542852
if (scope->kind >= SCOPE_FUNCTION && scope->kind <= SCOPE_GEN_EXPR && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
28552853
id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
28562854
}
2855+
// note: params always count for 1 local, even if they are a cell
28572856
if (id->param || id->kind == ID_INFO_KIND_LOCAL) {
28582857
id->local_num = scope->num_locals;
28592858
scope->num_locals += 1;
2860-
} else if (id->kind == ID_INFO_KIND_CELL) {
2859+
}
2860+
}
2861+
2862+
// compute the index of cell vars (freevars[idx] in CPython)
2863+
int num_closed = 0;
2864+
for (int i = 0; i < scope->id_info_len; i++) {
2865+
id_info_t *id = &scope->id_info[i];
2866+
if (id->kind == ID_INFO_KIND_CELL) {
28612867
id->local_num = num_closed;
2868+
#if !MICROPY_EMIT_CPYTHON
2869+
// the cells come right after the fast locals (CPython doesn't add this offset)
2870+
id->local_num += scope->num_locals;
2871+
#endif
28622872
num_closed += 1;
2863-
} else if (id->kind == ID_INFO_KIND_FREE) {
2864-
id_info_t *id_parent = scope_find_local_in_parent(scope, id->qstr);
2865-
assert(id_parent != NULL); // should never be NULL
2866-
id->local_num = id_parent->local_num;
2873+
}
2874+
}
2875+
scope->num_cells = num_closed;
2876+
2877+
// compute the index of free vars (freevars[idx] in CPython)
2878+
// make sure they are in the order of the parent scope
2879+
if (scope->parent != NULL) {
2880+
int num_free = 0;
2881+
for (int i = 0; i < scope->parent->id_info_len; i++) {
2882+
id_info_t *id = &scope->parent->id_info[i];
2883+
if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
2884+
for (int j = 0; j < scope->id_info_len; j++) {
2885+
id_info_t *id2 = &scope->id_info[j];
2886+
if (id2->kind == ID_INFO_KIND_FREE && id->qstr == id2->qstr) {
2887+
id2->local_num = num_closed + num_free;
2888+
#if !MICROPY_EMIT_CPYTHON
2889+
// the frees come right after the cells (CPython doesn't add this offset)
2890+
id2->local_num += scope->num_locals;
2891+
#endif
2892+
num_free += 1;
2893+
}
2894+
}
2895+
}
28672896
}
28682897
}
28692898

py/emit.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,24 +45,24 @@ typedef struct _emit_method_table_t {
4545
void (*load_const_verbatim_quoted_str)(emit_t *emit, qstr qstr, bool bytes);
4646
void (*load_const_verbatim_end)(emit_t *emit);
4747
void (*load_fast)(emit_t *emit, qstr qstr, int local_num);
48-
void (*load_name)(emit_t *emit, qstr qstr);
49-
void (*load_global)(emit_t *emit, qstr qstr);
5048
void (*load_deref)(emit_t *emit, qstr qstr, int local_num);
5149
void (*load_closure)(emit_t *emit, qstr qstr, int local_num);
50+
void (*load_name)(emit_t *emit, qstr qstr);
51+
void (*load_global)(emit_t *emit, qstr qstr);
5252
void (*load_attr)(emit_t *emit, qstr qstr);
5353
void (*load_method)(emit_t *emit, qstr qstr);
5454
void (*load_build_class)(emit_t *emit);
5555
void (*store_fast)(emit_t *emit, qstr qstr, int local_num);
56+
void (*store_deref)(emit_t *emit, qstr qstr, int local_num);
5657
void (*store_name)(emit_t *emit, qstr qstr);
5758
void (*store_global)(emit_t *emit, qstr qstr);
58-
void (*store_deref)(emit_t *emit, qstr qstr, int local_num);
5959
void (*store_attr)(emit_t *emit, qstr qstr);
6060
void (*store_subscr)(emit_t *emit);
6161
void (*store_locals)(emit_t *emit);
6262
void (*delete_fast)(emit_t *emit, qstr qstr, int local_num);
63+
void (*delete_deref)(emit_t *emit, qstr qstr, int local_num);
6364
void (*delete_name)(emit_t *emit, qstr qstr);
6465
void (*delete_global)(emit_t *emit, qstr qstr);
65-
void (*delete_deref)(emit_t *emit, qstr qstr, int local_num);
6666
void (*delete_attr)(emit_t *emit, qstr qstr);
6767
void (*delete_subscr)(emit_t *emit);
6868
void (*dup_top)(emit_t *emit);

py/emitbc.c

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ static void emit_bc_end_pass(emit_t *emit) {
7575
emit->code_base = m_new(byte, emit->code_size);
7676

7777
} else if (emit->pass == PASS_3) {
78-
rt_assign_byte_code(emit->scope->unique_code_id, emit->code_base, emit->code_size, emit->scope->num_params, emit->scope->num_locals, emit->scope->stack_size, (emit->scope->flags & SCOPE_FLAG_GENERATOR) != 0);
78+
rt_assign_byte_code(emit->scope->unique_code_id, emit->code_base, emit->code_size, emit->scope->num_params, emit->scope->num_locals, emit->scope->num_cells, emit->scope->stack_size, (emit->scope->flags & SCOPE_FLAG_GENERATOR) != 0);
7979
}
8080
}
8181

@@ -302,24 +302,24 @@ static void emit_bc_load_fast(emit_t *emit, qstr qstr, int local_num) {
302302
}
303303
}
304304

305-
static void emit_bc_load_name(emit_t *emit, qstr qstr) {
305+
static void emit_bc_load_deref(emit_t *emit, qstr qstr, int local_num) {
306306
emit_pre(emit, 1);
307-
emit_write_byte_1_qstr(emit, PYBC_LOAD_NAME, qstr);
307+
emit_write_byte_1_uint(emit, PYBC_LOAD_DEREF, local_num);
308308
}
309309

310-
static void emit_bc_load_global(emit_t *emit, qstr qstr) {
310+
static void emit_bc_load_closure(emit_t *emit, qstr qstr, int local_num) {
311311
emit_pre(emit, 1);
312-
emit_write_byte_1_qstr(emit, PYBC_LOAD_GLOBAL, qstr);
312+
emit_write_byte_1_uint(emit, PYBC_LOAD_CLOSURE, local_num);
313313
}
314314

315-
static void emit_bc_load_deref(emit_t *emit, qstr qstr, int local_num) {
315+
static void emit_bc_load_name(emit_t *emit, qstr qstr) {
316316
emit_pre(emit, 1);
317-
assert(0);
317+
emit_write_byte_1_qstr(emit, PYBC_LOAD_NAME, qstr);
318318
}
319319

320-
static void emit_bc_load_closure(emit_t *emit, qstr qstr, int local_num) {
320+
static void emit_bc_load_global(emit_t *emit, qstr qstr) {
321321
emit_pre(emit, 1);
322-
assert(0);
322+
emit_write_byte_1_qstr(emit, PYBC_LOAD_GLOBAL, qstr);
323323
}
324324

325325
static void emit_bc_load_attr(emit_t *emit, qstr qstr) {
@@ -348,6 +348,11 @@ static void emit_bc_store_fast(emit_t *emit, qstr qstr, int local_num) {
348348
}
349349
}
350350

351+
static void emit_bc_store_deref(emit_t *emit, qstr qstr, int local_num) {
352+
emit_pre(emit, -1);
353+
emit_write_byte_1_uint(emit, PYBC_STORE_DEREF, local_num);
354+
}
355+
351356
static void emit_bc_store_name(emit_t *emit, qstr qstr) {
352357
emit_pre(emit, -1);
353358
emit_write_byte_1_qstr(emit, PYBC_STORE_NAME, qstr);
@@ -358,11 +363,6 @@ static void emit_bc_store_global(emit_t *emit, qstr qstr) {
358363
emit_write_byte_1_qstr(emit, PYBC_STORE_GLOBAL, qstr);
359364
}
360365

361-
static void emit_bc_store_deref(emit_t *emit, qstr qstr, int local_num) {
362-
emit_pre(emit, -1);
363-
assert(0);
364-
}
365-
366366
static void emit_bc_store_attr(emit_t *emit, qstr qstr) {
367367
emit_pre(emit, -2);
368368
emit_write_byte_1_qstr(emit, PYBC_STORE_ATTR, qstr);
@@ -385,6 +385,11 @@ static void emit_bc_delete_fast(emit_t *emit, qstr qstr, int local_num) {
385385
emit_write_byte_1_uint(emit, PYBC_DELETE_FAST_N, local_num);
386386
}
387387

388+
static void emit_bc_delete_deref(emit_t *emit, qstr qstr, int local_num) {
389+
emit_pre(emit, 0);
390+
emit_write_byte_1_qstr(emit, PYBC_DELETE_DEREF, local_num);
391+
}
392+
388393
static void emit_bc_delete_name(emit_t *emit, qstr qstr) {
389394
emit_pre(emit, 0);
390395
emit_write_byte_1_qstr(emit, PYBC_DELETE_NAME, qstr);
@@ -395,12 +400,6 @@ static void emit_bc_delete_global(emit_t *emit, qstr qstr) {
395400
emit_write_byte_1_qstr(emit, PYBC_DELETE_GLOBAL, qstr);
396401
}
397402

398-
static void emit_bc_delete_deref(emit_t *emit, qstr qstr, int local_num) {
399-
emit_pre(emit, 0);
400-
assert(0);
401-
//emit_write_byte_1_qstr(emit, PYBC_DELETE_DEREF, qstr);
402-
}
403-
404403
static void emit_bc_delete_attr(emit_t *emit, qstr qstr) {
405404
emit_pre(emit, -1);
406405
emit_write_byte_1_qstr(emit, PYBC_DELETE_ATTR, qstr);
@@ -612,11 +611,9 @@ static void emit_bc_make_function(emit_t *emit, scope_t *scope, int n_dict_param
612611
}
613612

614613
static void emit_bc_make_closure(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
615-
assert(0);
616-
emit_pre(emit, -2 - n_default_params - 2 * n_dict_params);
617-
if (emit->pass == PASS_3) {
618-
printf("MAKE_CLOSURE %d\n", (n_dict_params << 8) | n_default_params);
619-
}
614+
assert(n_default_params == 0 && n_dict_params == 0);
615+
emit_pre(emit, 0);
616+
emit_write_byte_1_uint(emit, PYBC_MAKE_CLOSURE, scope->unique_code_id);
620617
}
621618

622619
static void emit_bc_call_function(emit_t *emit, int n_positional, int n_keyword, bool have_star_arg, bool have_dbl_star_arg) {
@@ -728,24 +725,24 @@ const emit_method_table_t emit_bc_method_table = {
728725
emit_bc_load_const_verbatim_quoted_str,
729726
emit_bc_load_const_verbatim_end,
730727
emit_bc_load_fast,
731-
emit_bc_load_name,
732-
emit_bc_load_global,
733728
emit_bc_load_deref,
734729
emit_bc_load_closure,
730+
emit_bc_load_name,
731+
emit_bc_load_global,
735732
emit_bc_load_attr,
736733
emit_bc_load_method,
737734
emit_bc_load_build_class,
738735
emit_bc_store_fast,
736+
emit_bc_store_deref,
739737
emit_bc_store_name,
740738
emit_bc_store_global,
741-
emit_bc_store_deref,
742739
emit_bc_store_attr,
743740
emit_bc_store_subscr,
744741
emit_bc_store_locals,
745742
emit_bc_delete_fast,
743+
emit_bc_delete_deref,
746744
emit_bc_delete_name,
747745
emit_bc_delete_global,
748-
emit_bc_delete_deref,
749746
emit_bc_delete_attr,
750747
emit_bc_delete_subscr,
751748
emit_bc_dup_top,

0 commit comments

Comments
 (0)