Commit 9ecbcfff authored by Damien's avatar Damien
Browse files

py: work towards working closures.

parent 5285155e
......@@ -12,25 +12,28 @@
#define PYBC_LOAD_FAST_1 (0x21)
#define PYBC_LOAD_FAST_2 (0x22)
#define PYBC_LOAD_FAST_N (0x23) // uint
#define PYBC_LOAD_NAME (0x24) // qstr
#define PYBC_LOAD_GLOBAL (0x25) // qstr
#define PYBC_LOAD_ATTR (0x26) // qstr
#define PYBC_LOAD_METHOD (0x27) // qstr
#define PYBC_LOAD_BUILD_CLASS (0x28)
#define PYBC_LOAD_DEREF (0x24) // uint
#define PYBC_LOAD_CLOSURE (0x25) // uint
#define PYBC_LOAD_NAME (0x26) // qstr
#define PYBC_LOAD_GLOBAL (0x27) // qstr
#define PYBC_LOAD_ATTR (0x28) // qstr
#define PYBC_LOAD_METHOD (0x29) // qstr
#define PYBC_LOAD_BUILD_CLASS (0x2a)
#define PYBC_STORE_FAST_0 (0x30)
#define PYBC_STORE_FAST_1 (0x31)
#define PYBC_STORE_FAST_2 (0x32)
#define PYBC_STORE_FAST_N (0x33) // uint
#define PYBC_STORE_NAME (0x34) // qstr
#define PYBC_STORE_GLOBAL (0x35) // qstr
#define PYBC_STORE_ATTR (0x36) // qstr
#define PYBC_STORE_SUBSCR (0x37)
#define PYBC_STORE_DEREF (0x34) // uint
#define PYBC_STORE_NAME (0x35) // qstr
#define PYBC_STORE_GLOBAL (0x36) // qstr
#define PYBC_STORE_ATTR (0x37) // qstr
#define PYBC_STORE_SUBSCR (0x38)
#define PYBC_DELETE_FAST_N (0x39) // uint
#define PYBC_DELETE_NAME (0x3a) // qstr
#define PYBC_DELETE_GLOBAL (0x3b) // qstr
#define PYBC_DELETE_DEREF (0x3c) // qstr
#define PYBC_DELETE_DEREF (0x3a) // uint
#define PYBC_DELETE_NAME (0x3b) // qstr
#define PYBC_DELETE_GLOBAL (0x3c) // qstr
#define PYBC_DELETE_ATTR (0x3d) // qstr
#define PYBC_DELETE_SUBSCR (0x3e)
......@@ -80,7 +83,7 @@
#define PYBC_YIELD_FROM (0x83)
#define PYBC_MAKE_FUNCTION (0x90) // uint
#define PYBC_MAKE_CLOSURE (0x91) // uint?
#define PYBC_MAKE_CLOSURE (0x91) // uint
#define PYBC_CALL_FUNCTION (0x92) // uint
#define PYBC_CALL_FUNCTION_VAR (0x93) // uint
#define PYBC_CALL_FUNCTION_KW (0x94) // uint
......
......@@ -2842,9 +2842,7 @@ void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass
void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
// in functions, turn implicit globals into explicit globals
// compute num_locals, and the index of each local
// compute the index of free and cell vars (freevars[idx] in CPython)
scope->num_locals = 0;
int num_closed = 0;
for (int i = 0; i < scope->id_info_len; i++) {
id_info_t *id = &scope->id_info[i];
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) {
if (scope->kind >= SCOPE_FUNCTION && scope->kind <= SCOPE_GEN_EXPR && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
}
// note: params always count for 1 local, even if they are a cell
if (id->param || id->kind == ID_INFO_KIND_LOCAL) {
id->local_num = scope->num_locals;
scope->num_locals += 1;
} else if (id->kind == ID_INFO_KIND_CELL) {
}
}
// compute the index of cell vars (freevars[idx] in CPython)
int num_closed = 0;
for (int i = 0; i < scope->id_info_len; i++) {
id_info_t *id = &scope->id_info[i];
if (id->kind == ID_INFO_KIND_CELL) {
id->local_num = num_closed;
#if !MICROPY_EMIT_CPYTHON
// the cells come right after the fast locals (CPython doesn't add this offset)
id->local_num += scope->num_locals;
#endif
num_closed += 1;
} else if (id->kind == ID_INFO_KIND_FREE) {
id_info_t *id_parent = scope_find_local_in_parent(scope, id->qstr);
assert(id_parent != NULL); // should never be NULL
id->local_num = id_parent->local_num;
}
}
scope->num_cells = num_closed;
// compute the index of free vars (freevars[idx] in CPython)
// make sure they are in the order of the parent scope
if (scope->parent != NULL) {
int num_free = 0;
for (int i = 0; i < scope->parent->id_info_len; i++) {
id_info_t *id = &scope->parent->id_info[i];
if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
for (int j = 0; j < scope->id_info_len; j++) {
id_info_t *id2 = &scope->id_info[j];
if (id2->kind == ID_INFO_KIND_FREE && id->qstr == id2->qstr) {
id2->local_num = num_closed + num_free;
#if !MICROPY_EMIT_CPYTHON
// the frees come right after the cells (CPython doesn't add this offset)
id2->local_num += scope->num_locals;
#endif
num_free += 1;
}
}
}
}
}
......
......@@ -45,24 +45,24 @@ typedef struct _emit_method_table_t {
void (*load_const_verbatim_quoted_str)(emit_t *emit, qstr qstr, bool bytes);
void (*load_const_verbatim_end)(emit_t *emit);
void (*load_fast)(emit_t *emit, qstr qstr, int local_num);
void (*load_name)(emit_t *emit, qstr qstr);
void (*load_global)(emit_t *emit, qstr qstr);
void (*load_deref)(emit_t *emit, qstr qstr, int local_num);
void (*load_closure)(emit_t *emit, qstr qstr, int local_num);
void (*load_name)(emit_t *emit, qstr qstr);
void (*load_global)(emit_t *emit, qstr qstr);
void (*load_attr)(emit_t *emit, qstr qstr);
void (*load_method)(emit_t *emit, qstr qstr);
void (*load_build_class)(emit_t *emit);
void (*store_fast)(emit_t *emit, qstr qstr, int local_num);
void (*store_deref)(emit_t *emit, qstr qstr, int local_num);
void (*store_name)(emit_t *emit, qstr qstr);
void (*store_global)(emit_t *emit, qstr qstr);
void (*store_deref)(emit_t *emit, qstr qstr, int local_num);
void (*store_attr)(emit_t *emit, qstr qstr);
void (*store_subscr)(emit_t *emit);
void (*store_locals)(emit_t *emit);
void (*delete_fast)(emit_t *emit, qstr qstr, int local_num);
void (*delete_deref)(emit_t *emit, qstr qstr, int local_num);
void (*delete_name)(emit_t *emit, qstr qstr);
void (*delete_global)(emit_t *emit, qstr qstr);
void (*delete_deref)(emit_t *emit, qstr qstr, int local_num);
void (*delete_attr)(emit_t *emit, qstr qstr);
void (*delete_subscr)(emit_t *emit);
void (*dup_top)(emit_t *emit);
......
......@@ -75,7 +75,7 @@ static void emit_bc_end_pass(emit_t *emit) {
emit->code_base = m_new(byte, emit->code_size);
} else if (emit->pass == PASS_3) {
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);
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);
}
}
......@@ -302,24 +302,24 @@ static void emit_bc_load_fast(emit_t *emit, qstr qstr, int local_num) {
}
}
static void emit_bc_load_name(emit_t *emit, qstr qstr) {
static void emit_bc_load_deref(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, 1);
emit_write_byte_1_qstr(emit, PYBC_LOAD_NAME, qstr);
emit_write_byte_1_uint(emit, PYBC_LOAD_DEREF, local_num);
}
static void emit_bc_load_global(emit_t *emit, qstr qstr) {
static void emit_bc_load_closure(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, 1);
emit_write_byte_1_qstr(emit, PYBC_LOAD_GLOBAL, qstr);
emit_write_byte_1_uint(emit, PYBC_LOAD_CLOSURE, local_num);
}
static void emit_bc_load_deref(emit_t *emit, qstr qstr, int local_num) {
static void emit_bc_load_name(emit_t *emit, qstr qstr) {
emit_pre(emit, 1);
assert(0);
emit_write_byte_1_qstr(emit, PYBC_LOAD_NAME, qstr);
}
static void emit_bc_load_closure(emit_t *emit, qstr qstr, int local_num) {
static void emit_bc_load_global(emit_t *emit, qstr qstr) {
emit_pre(emit, 1);
assert(0);
emit_write_byte_1_qstr(emit, PYBC_LOAD_GLOBAL, qstr);
}
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) {
}
}
static void emit_bc_store_deref(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, -1);
emit_write_byte_1_uint(emit, PYBC_STORE_DEREF, local_num);
}
static void emit_bc_store_name(emit_t *emit, qstr qstr) {
emit_pre(emit, -1);
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) {
emit_write_byte_1_qstr(emit, PYBC_STORE_GLOBAL, qstr);
}
static void emit_bc_store_deref(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, -1);
assert(0);
}
static void emit_bc_store_attr(emit_t *emit, qstr qstr) {
emit_pre(emit, -2);
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) {
emit_write_byte_1_uint(emit, PYBC_DELETE_FAST_N, local_num);
}
static void emit_bc_delete_deref(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, 0);
emit_write_byte_1_qstr(emit, PYBC_DELETE_DEREF, local_num);
}
static void emit_bc_delete_name(emit_t *emit, qstr qstr) {
emit_pre(emit, 0);
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) {
emit_write_byte_1_qstr(emit, PYBC_DELETE_GLOBAL, qstr);
}
static void emit_bc_delete_deref(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, 0);
assert(0);
//emit_write_byte_1_qstr(emit, PYBC_DELETE_DEREF, qstr);
}
static void emit_bc_delete_attr(emit_t *emit, qstr qstr) {
emit_pre(emit, -1);
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
}
static void emit_bc_make_closure(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
assert(0);
emit_pre(emit, -2 - n_default_params - 2 * n_dict_params);
if (emit->pass == PASS_3) {
printf("MAKE_CLOSURE %d\n", (n_dict_params << 8) | n_default_params);
}
assert(n_default_params == 0 && n_dict_params == 0);
emit_pre(emit, 0);
emit_write_byte_1_uint(emit, PYBC_MAKE_CLOSURE, 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) {
......@@ -728,24 +725,24 @@ const emit_method_table_t emit_bc_method_table = {
emit_bc_load_const_verbatim_quoted_str,
emit_bc_load_const_verbatim_end,
emit_bc_load_fast,
emit_bc_load_name,
emit_bc_load_global,
emit_bc_load_deref,
emit_bc_load_closure,
emit_bc_load_name,
emit_bc_load_global,
emit_bc_load_attr,
emit_bc_load_method,
emit_bc_load_build_class,
emit_bc_store_fast,
emit_bc_store_deref,
emit_bc_store_name,
emit_bc_store_global,
emit_bc_store_deref,
emit_bc_store_attr,
emit_bc_store_subscr,
emit_bc_store_locals,
emit_bc_delete_fast,
emit_bc_delete_deref,
emit_bc_delete_name,
emit_bc_delete_global,
emit_bc_delete_deref,
emit_bc_delete_attr,
emit_bc_delete_subscr,
emit_bc_dup_top,
......
......@@ -265,31 +265,31 @@ static void emit_cpy_load_fast(emit_t *emit, qstr qstr, int local_num) {
}
}
static void emit_cpy_load_name(emit_t *emit, qstr qstr) {
static void emit_cpy_load_deref(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) {
printf("LOAD_NAME %s\n", qstr_str(qstr));
printf("LOAD_DEREF %d %s\n", local_num, qstr_str(qstr));
}
}
static void emit_cpy_load_global(emit_t *emit, qstr qstr) {
static void emit_cpy_load_closure(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) {
printf("LOAD_GLOBAL %s\n", qstr_str(qstr));
printf("LOAD_CLOSURE %d %s\n", local_num, qstr_str(qstr));
}
}
static void emit_cpy_load_deref(emit_t *emit, qstr qstr, int local_num) {
static void emit_cpy_load_name(emit_t *emit, qstr qstr) {
emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) {
printf("LOAD_DEREF %d %s\n", local_num, qstr_str(qstr));
printf("LOAD_NAME %s\n", qstr_str(qstr));
}
}
static void emit_cpy_load_closure(emit_t *emit, qstr qstr, int local_num) {
static void emit_cpy_load_global(emit_t *emit, qstr qstr) {
emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) {
printf("LOAD_CLOSURE %d %s\n", local_num, qstr_str(qstr));
printf("LOAD_GLOBAL %s\n", qstr_str(qstr));
}
}
......@@ -318,24 +318,24 @@ static void emit_cpy_store_fast(emit_t *emit, qstr qstr, int local_num) {
}
}
static void emit_cpy_store_name(emit_t *emit, qstr qstr) {
static void emit_cpy_store_deref(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) {
printf("STORE_NAME %s\n", qstr_str(qstr));
printf("STORE_DEREF %d %s\n", local_num, qstr_str(qstr));
}
}
static void emit_cpy_store_global(emit_t *emit, qstr qstr) {
static void emit_cpy_store_name(emit_t *emit, qstr qstr) {
emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) {
printf("STORE_GLOBAL %s\n", qstr_str(qstr));
printf("STORE_NAME %s\n", qstr_str(qstr));
}
}
static void emit_cpy_store_deref(emit_t *emit, qstr qstr, int local_num) {
static void emit_cpy_store_global(emit_t *emit, qstr qstr) {
emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) {
printf("STORE_DEREF %d %s\n", local_num, qstr_str(qstr));
printf("STORE_GLOBAL %s\n", qstr_str(qstr));
}
}
......@@ -367,24 +367,24 @@ static void emit_cpy_delete_fast(emit_t *emit, qstr qstr, int local_num) {
}
}
static void emit_cpy_delete_name(emit_t *emit, qstr qstr) {
static void emit_cpy_delete_deref(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, 0, 3);
if (emit->pass == PASS_3) {
printf("DELETE_NAME %s\n", qstr_str(qstr));
printf("DELETE_DEREF %d %s\n", local_num, qstr_str(qstr));
}
}
static void emit_cpy_delete_global(emit_t *emit, qstr qstr) {
static void emit_cpy_delete_name(emit_t *emit, qstr qstr) {
emit_pre(emit, 0, 3);
if (emit->pass == PASS_3) {
printf("DELETE_GLOBAL %s\n", qstr_str(qstr));
printf("DELETE_NAME %s\n", qstr_str(qstr));
}
}
static void emit_cpy_delete_deref(emit_t *emit, qstr qstr, int local_num) {
static void emit_cpy_delete_global(emit_t *emit, qstr qstr) {
emit_pre(emit, 0, 3);
if (emit->pass == PASS_3) {
printf("DELETE_DEREF %d %s\n", local_num, qstr_str(qstr));
printf("DELETE_GLOBAL %s\n", qstr_str(qstr));
}
}
......@@ -852,24 +852,24 @@ const emit_method_table_t emit_cpython_method_table = {
emit_cpy_load_const_verbatim_quoted_str,
emit_cpy_load_const_verbatim_end,
emit_cpy_load_fast,
emit_cpy_load_name,
emit_cpy_load_global,
emit_cpy_load_deref,
emit_cpy_load_closure,
emit_cpy_load_name,
emit_cpy_load_global,
emit_cpy_load_attr,
emit_cpy_load_method,
emit_cpy_load_build_class,
emit_cpy_store_fast,
emit_cpy_store_deref,
emit_cpy_store_name,
emit_cpy_store_global,
emit_cpy_store_deref,
emit_cpy_store_attr,
emit_cpy_store_subscr,
emit_cpy_store_locals,
emit_cpy_delete_fast,
emit_cpy_delete_deref,
emit_cpy_delete_name,
emit_cpy_delete_global,
emit_cpy_delete_deref,
emit_cpy_delete_attr,
emit_cpy_delete_subscr,
emit_cpy_dup_top,
......
......@@ -688,6 +688,17 @@ static void emit_native_load_fast(emit_t *emit, qstr qstr, int local_num) {
#endif
}
static void emit_native_load_deref(emit_t *emit, qstr qstr, int local_num) {
// not implemented
// in principle could support this quite easily (ldr r0, [r0, #0]) and then get closed over variables!
assert(0);
}
static void emit_native_load_closure(emit_t *emit, qstr qstr, int local_num) {
// not implemented
assert(0);
}
static void emit_native_load_name(emit_t *emit, qstr qstr) {
emit_pre(emit);
emit_call_with_imm_arg(emit, RT_F_LOAD_NAME, rt_load_name, qstr, REG_ARG_1);
......@@ -700,17 +711,6 @@ static void emit_native_load_global(emit_t *emit, qstr qstr) {
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
}
static void emit_native_load_deref(emit_t *emit, qstr qstr, int local_num) {
// not implemented
// in principle could support this quite easily (ldr r0, [r0, #0]) and then get closed over variables!
assert(0);
}
static void emit_native_load_closure(emit_t *emit, qstr qstr, int local_num) {
// not implemented
assert(0);
}
static void emit_native_load_attr(emit_t *emit, qstr qstr) {
// depends on type of subject:
// - integer, function, pointer to integers: error
......@@ -771,6 +771,11 @@ static void emit_native_store_fast(emit_t *emit, qstr qstr, int local_num) {
}
}
static void emit_native_store_deref(emit_t *emit, qstr qstr, int local_num) {
// not implemented
assert(0);
}
static void emit_native_store_name(emit_t *emit, qstr qstr) {
// rt_store_name, but needs conversion of object (maybe have rt_viper_store_name(obj, type))
vtype_kind_t vtype;
......@@ -785,11 +790,6 @@ static void emit_native_store_global(emit_t *emit, qstr qstr) {
assert(0);
}
static void emit_native_store_deref(emit_t *emit, qstr qstr, int local_num) {
// not implemented
assert(0);
}
static void emit_native_store_attr(emit_t *emit, qstr qstr) {
vtype_kind_t vtype_base, vtype_val;
emit_pre_pop_reg_reg(emit, &vtype_base, REG_ARG_1, &vtype_val, REG_ARG_3); // arg1 = base, arg3 = value
......@@ -825,6 +825,11 @@ static void emit_native_delete_fast(emit_t *emit, qstr qstr, int local_num) {
assert(0);
}
static void emit_native_delete_deref(emit_t *emit, qstr qstr, int local_num) {
// not supported
assert(0);
}
static void emit_native_delete_name(emit_t *emit, qstr qstr) {
// not implemented
// use rt_delete_name
......@@ -837,11 +842,6 @@ static void emit_native_delete_global(emit_t *emit, qstr qstr) {
assert(0);
}
static void emit_native_delete_deref(emit_t *emit, qstr qstr, int local_num) {
// not supported
assert(0);
}
static void emit_native_delete_attr(emit_t *emit, qstr qstr) {
// not supported
assert(0);
......@@ -1280,24 +1280,24 @@ const emit_method_table_t EXPORT_FUN(method_table) = {
emit_native_load_const_verbatim_quoted_str,
emit_native_load_const_verbatim_end,
emit_native_load_fast,
emit_native_load_name,
emit_native_load_global,
emit_native_load_deref,
emit_native_load_closure,
emit_native_load_name,
emit_native_load_global,
emit_native_load_attr,
emit_native_load_method,
emit_native_load_build_class,
emit_native_store_fast,
emit_native_store_deref,
emit_native_store_name,
emit_native_store_global,
emit_native_store_deref,
emit_native_store_attr,
emit_native_store_subscr,
emit_native_store_locals,
emit_native_delete_fast,
emit_native_delete_deref,
emit_native_delete_name,
emit_native_delete_global,
emit_native_delete_deref,
emit_native_delete_attr,
emit_native_delete_subscr,
emit_native_dup_top,
......
......@@ -43,6 +43,7 @@ typedef enum {
O_FLOAT,
O_COMPLEX,
#endif
O_CELL,
O_EXCEPTION_0,
O_EXCEPTION_N,
O_RANGE,
......@@ -57,6 +58,7 @@ typedef enum {
O_GEN_WRAP,
O_GEN_INSTANCE,
O_BOUND_METH,
O_CLOSURE,
O_TUPLE,
O_LIST,
O_TUPLE_IT,
......@@ -101,6 +103,7 @@ struct _py_obj_base_t {
py_float_t imag;
} u_complex;
#endif
py_obj_t u_cell; // for O_CELL
struct { // for O_EXCEPTION_0
qstr id;
} u_exc0;
......@@ -148,6 +151,10 @@ struct _py_obj_base_t {
py_obj_t meth;
py_obj_t self;
} u_bound_meth;
struct { // for O_CLOSURE
py_obj_t fun;
py_obj_t vars;
} u_closure;
struct { // for O_TUPLE, O_LIST
machine_uint_t alloc;
machine_uint_t len;
......@@ -382,6 +389,13 @@ py_obj_t py_obj_new_complex(py_float_t real, py_float_t imag) {
}
#endif
py_obj_t py_obj_new_cell(py_obj_t val) {
py_obj_base_t *o = m_new(py_obj_base_t, 1);
o->kind = O_CELL;
o->u_cell = val;
return (py_obj_t)o;
}
py_obj_t py_obj_new_exception_0(qstr id) {
py_obj_base_t *o = m_new(py_obj_base_t, 1);
o->kind = O_EXCEPTION_0;
......@@ -585,6 +599,23 @@ qstr py_obj_get_qstr(py_obj_t arg) {
}
}
py_obj_t py_obj_get_cell(py_obj_t cell) {
if (IS_O(cell, O_CELL)) {
return ((py_obj_base_t*)cell)->u_cell;
} else {
assert(0);
return py_const_none;
}
}
void py_obj_set_cell(py_obj_t cell, py_obj_t val) {
if (IS_O(cell, O_CELL)) {
((py_obj_base_t*)cell)->u_cell = val;
} else {
assert(0);
}
}
py_obj_t *py_obj_get_array_fixed_n(py_obj_t o_in, machine_int_t n) {
if (IS_O(o_in, O_TUPLE) || IS_O(o_in, O_LIST)) {
py_obj_base_t *o = o_in;
......@@ -879,6 +910,7 @@ typedef struct _py_code_t {
py_code_kind_t kind;
int n_args;
int n_locals;
int n_cells;
int n_stack;
bool is_generator;
union {
......@@ -1078,19 +1110,20 @@ static void alloc_unique_codes(void) {
}
}
void rt_assign_byte_code(int unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_stack, bool is_generator) {
void rt_assign_byte_code(int unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_cells, int n_stack, bool is_generator) {
alloc_unique_codes();
assert(unique_code_id < next_unique_code_id);
unique_codes[unique_code_id].kind = PY_CODE_BYTE;
unique_codes[unique_code_id].n_args = n_args;
unique_codes[unique_code_id].n_locals = n_locals;
unique_codes[unique_code_id].n_cells = n_cells;
unique_codes[unique_code_id].n_stack = n_stack;
unique_codes[unique_code_id].is_generator = is_generator;
unique_codes[unique_code_id].u_byte.code = code;
unique_codes[unique_code_id].u_byte.len = len;
printf("byte code: %d bytes\n", len);
//printf("byte code: %d bytes\n", len);
#ifdef DEBUG_PRINT
DEBUG_printf("assign byte code: id=%d code=%p len=%u n_args=%d\n", unique_code_id, code, len, n_args);
......@@ -1120,6 +1153,7 @@ void rt_assign_native_code(int unique_code_id, py_fun_t fun, uint len, int n_arg
unique_codes[unique_code_id].kind = PY_CODE_NATIVE;
unique_codes[unique_code_id].n_args = n_args;
unique_codes[unique_code_id].n_locals = 0;
unique_codes[unique_code_id].n_cells = 0;
unique_codes[unique_code_id].n_stack = 0;