df8127a17e
Attempt to address issue #386. unique_code_id's have been removed and replaced with a pointer to the "raw code" information. This pointer is stored in the actual byte code (aligned, so the GC can trace it), so that raw code (ie byte code, native code and inline assembler) is kept only for as long as it is needed. In memory it's now like a tree: the outer module's byte code points directly to its children's raw code. So when the outer code gets freed, if there are no remaining functions that need the raw code, then the children's code gets freed as well. This is pretty much like CPython does it, except that CPython stores indexes in the byte code rather than machine pointers. These indices index the per-function constant table in order to find the relevant code.
54 lines
2.0 KiB
C
54 lines
2.0 KiB
C
enum {
|
|
ID_INFO_KIND_GLOBAL_IMPLICIT,
|
|
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
|
|
ID_INFO_KIND_FREE, // in a function f, belongs to the parent of f
|
|
};
|
|
|
|
enum {
|
|
ID_FLAG_IS_PARAM = 0x01,
|
|
ID_FLAG_IS_DELETED = 0x02,
|
|
};
|
|
|
|
typedef struct _id_info_t {
|
|
uint8_t kind;
|
|
uint8_t flags;
|
|
// when it's an ID_INFO_KIND_LOCAL this is the unique number of the local
|
|
// whet it's an ID_INFO_KIND_CELL/FREE this is the unique number of the closed over variable
|
|
uint16_t local_num;
|
|
qstr qstr;
|
|
} id_info_t;
|
|
|
|
// scope is a "block" in Python parlance
|
|
typedef enum { SCOPE_MODULE, SCOPE_FUNCTION, SCOPE_LAMBDA, SCOPE_LIST_COMP, SCOPE_DICT_COMP, SCOPE_SET_COMP, SCOPE_GEN_EXPR, SCOPE_CLASS } scope_kind_t;
|
|
typedef struct _scope_t {
|
|
scope_kind_t kind;
|
|
struct _scope_t *parent;
|
|
struct _scope_t *next;
|
|
mp_parse_node_t pn;
|
|
qstr source_file;
|
|
qstr simple_name;
|
|
mp_raw_code_t *raw_code;
|
|
uint8_t scope_flags; // see runtime0.h
|
|
uint8_t emit_options; // see compile.h
|
|
uint16_t num_params;
|
|
uint16_t num_locals;
|
|
uint16_t stack_size; // maximum size of the locals stack
|
|
uint16_t exc_stack_size; // maximum size of the exception stack
|
|
uint16_t id_info_alloc;
|
|
uint16_t id_info_len;
|
|
id_info_t *id_info;
|
|
} scope_t;
|
|
|
|
scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint emit_options);
|
|
void scope_free(scope_t *scope);
|
|
id_info_t *scope_find_or_add_id(scope_t *scope, qstr qstr, bool *added);
|
|
id_info_t *scope_find(scope_t *scope, qstr qstr);
|
|
id_info_t *scope_find_global(scope_t *scope, qstr qstr);
|
|
id_info_t *scope_find_local_in_parent(scope_t *scope, qstr qstr);
|
|
void scope_close_over_in_parents(scope_t *scope, qstr qstr);
|
|
void scope_declare_global(scope_t *scope, qstr qstr);
|
|
void scope_declare_nonlocal(scope_t *scope, qstr qstr);
|
|
void scope_print_info(scope_t *s);
|