py: Pass all scope flags through to runtime.
This commit is contained in:
parent
c5966128c7
commit
8725f8f7de
18
py/compile.c
18
py/compile.c
|
@ -2595,11 +2595,11 @@ void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn, pn_ki
|
|||
//assert(comp->scope_cur->num_dict_params == 0);
|
||||
} else if (MP_PARSE_NODE_IS_ID(pns->nodes[0])) {
|
||||
// named star
|
||||
comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
|
||||
comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_VARARGS;
|
||||
param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
|
||||
} else if (allow_annotations && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) {
|
||||
// named star with annotation
|
||||
comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
|
||||
comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_VARARGS;
|
||||
pns = (mp_parse_node_struct_t*)pns->nodes[0];
|
||||
param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
|
||||
pn_annotation = pns->nodes[1];
|
||||
|
@ -2613,7 +2613,7 @@ void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn, pn_ki
|
|||
// this parameter has an annotation
|
||||
pn_annotation = pns->nodes[1];
|
||||
}
|
||||
comp->scope_cur->flags |= SCOPE_FLAG_VARKEYWORDS;
|
||||
comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_VARKEYWORDS;
|
||||
} else {
|
||||
// TODO anything to implement?
|
||||
assert(0);
|
||||
|
@ -3032,19 +3032,19 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
|
|||
#endif
|
||||
}
|
||||
|
||||
// compute flags
|
||||
//scope->flags = 0; since we set some things in parameters
|
||||
// compute scope_flags
|
||||
//scope->scope_flags = 0; since we set some things in parameters
|
||||
if (scope->kind != SCOPE_MODULE) {
|
||||
scope->flags |= SCOPE_FLAG_NEWLOCALS;
|
||||
scope->scope_flags |= MP_SCOPE_FLAG_NEWLOCALS;
|
||||
}
|
||||
if (scope->kind == SCOPE_FUNCTION || scope->kind == SCOPE_LAMBDA || scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) {
|
||||
assert(scope->parent != NULL);
|
||||
scope->flags |= SCOPE_FLAG_OPTIMISED;
|
||||
scope->scope_flags |= MP_SCOPE_FLAG_OPTIMISED;
|
||||
|
||||
// TODO possibly other ways it can be nested
|
||||
// Note that we don't actually use this information at the moment (for CPython compat only)
|
||||
if ((SCOPE_FUNCTION <= scope->parent->kind && scope->parent->kind <= SCOPE_SET_COMP) || (scope->parent->kind == SCOPE_CLASS && scope->parent->parent->kind == SCOPE_FUNCTION)) {
|
||||
scope->flags |= SCOPE_FLAG_NESTED;
|
||||
scope->scope_flags |= MP_SCOPE_FLAG_NESTED;
|
||||
}
|
||||
}
|
||||
int num_free = 0;
|
||||
|
@ -3055,7 +3055,7 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
|
|||
}
|
||||
}
|
||||
if (num_free == 0) {
|
||||
scope->flags |= SCOPE_FLAG_NOFREE;
|
||||
scope->scope_flags |= MP_SCOPE_FLAG_NOFREE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -242,7 +242,7 @@ STATIC void emit_bc_end_pass(emit_t *emit) {
|
|||
emit->code_base = m_new(byte, emit->code_info_size + emit->byte_code_size);
|
||||
|
||||
} else if (emit->pass == PASS_3) {
|
||||
rt_assign_byte_code(emit->scope->unique_code_id, emit->code_base, emit->code_info_size + emit->byte_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_info_size + emit->byte_code_size, emit->scope->num_params, emit->scope->num_locals, emit->scope->stack_size, emit->scope->scope_flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -779,7 +779,7 @@ STATIC void emit_bc_raise_varargs(emit_t *emit, int n_args) {
|
|||
STATIC void emit_bc_yield_value(emit_t *emit) {
|
||||
emit_pre(emit, 0);
|
||||
if (emit->pass == PASS_2) {
|
||||
emit->scope->flags |= SCOPE_FLAG_GENERATOR;
|
||||
emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
|
||||
}
|
||||
emit_write_byte_code_byte(emit, MP_BC_YIELD_VALUE);
|
||||
}
|
||||
|
@ -787,7 +787,7 @@ STATIC void emit_bc_yield_value(emit_t *emit) {
|
|||
STATIC void emit_bc_yield_from(emit_t *emit) {
|
||||
emit_pre(emit, -1);
|
||||
if (emit->pass == PASS_2) {
|
||||
emit->scope->flags |= SCOPE_FLAG_GENERATOR;
|
||||
emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
|
||||
}
|
||||
emit_write_byte_code_byte(emit, MP_BC_YIELD_FROM);
|
||||
}
|
||||
|
|
12
py/runtime.c
12
py/runtime.c
|
@ -46,7 +46,7 @@ typedef enum {
|
|||
typedef struct _mp_code_t {
|
||||
struct {
|
||||
mp_code_kind_t kind : 8;
|
||||
bool is_generator : 1;
|
||||
uint scope_flags : 8;
|
||||
};
|
||||
struct {
|
||||
uint n_args : 16;
|
||||
|
@ -242,12 +242,12 @@ STATIC void alloc_unique_codes(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void rt_assign_byte_code(uint unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_stack, bool is_generator) {
|
||||
void rt_assign_byte_code(uint unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_stack, uint scope_flags) {
|
||||
alloc_unique_codes();
|
||||
|
||||
assert(1 <= unique_code_id && unique_code_id < next_unique_code_id && unique_codes[unique_code_id].kind == MP_CODE_NONE);
|
||||
unique_codes[unique_code_id].kind = MP_CODE_BYTE;
|
||||
unique_codes[unique_code_id].is_generator = is_generator;
|
||||
unique_codes[unique_code_id].scope_flags = scope_flags;
|
||||
unique_codes[unique_code_id].n_args = n_args;
|
||||
unique_codes[unique_code_id].n_state = n_locals + n_stack;
|
||||
unique_codes[unique_code_id].u_byte.code = code;
|
||||
|
@ -275,7 +275,7 @@ void rt_assign_native_code(uint unique_code_id, void *fun, uint len, int n_args)
|
|||
|
||||
assert(1 <= unique_code_id && unique_code_id < next_unique_code_id && unique_codes[unique_code_id].kind == MP_CODE_NONE);
|
||||
unique_codes[unique_code_id].kind = MP_CODE_NATIVE;
|
||||
unique_codes[unique_code_id].is_generator = false;
|
||||
unique_codes[unique_code_id].scope_flags = 0;
|
||||
unique_codes[unique_code_id].n_args = n_args;
|
||||
unique_codes[unique_code_id].n_state = 0;
|
||||
unique_codes[unique_code_id].u_native.fun = fun;
|
||||
|
@ -307,7 +307,7 @@ void rt_assign_inline_asm_code(uint unique_code_id, void *fun, uint len, int n_a
|
|||
|
||||
assert(1 <= unique_code_id && unique_code_id < next_unique_code_id && unique_codes[unique_code_id].kind == MP_CODE_NONE);
|
||||
unique_codes[unique_code_id].kind = MP_CODE_INLINE_ASM;
|
||||
unique_codes[unique_code_id].is_generator = false;
|
||||
unique_codes[unique_code_id].scope_flags = 0;
|
||||
unique_codes[unique_code_id].n_args = n_args;
|
||||
unique_codes[unique_code_id].n_state = 0;
|
||||
unique_codes[unique_code_id].u_inline_asm.fun = fun;
|
||||
|
@ -728,7 +728,7 @@ mp_obj_t rt_make_function_from_id(int unique_code_id, mp_obj_t def_args) {
|
|||
}
|
||||
|
||||
// check for generator functions and if so wrap in generator object
|
||||
if (c->is_generator) {
|
||||
if ((c->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) {
|
||||
fun = mp_obj_new_gen_wrap(fun);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
// taken from python source, Include/code.h
|
||||
#define MP_SCOPE_FLAG_OPTIMISED 0x01
|
||||
#define MP_SCOPE_FLAG_NEWLOCALS 0x02
|
||||
#define MP_SCOPE_FLAG_VARARGS 0x04
|
||||
#define MP_SCOPE_FLAG_VARKEYWORDS 0x08
|
||||
#define MP_SCOPE_FLAG_NESTED 0x10
|
||||
#define MP_SCOPE_FLAG_GENERATOR 0x20
|
||||
/* The MP_SCOPE_FLAG_NOFREE flag is set if there are no free or cell variables.
|
||||
This information is redundant, but it allows a single flag test
|
||||
to determine whether there is any extra work to be done when the
|
||||
call frame is setup.
|
||||
*/
|
||||
#define MP_SCOPE_FLAG_NOFREE 0x40
|
||||
|
||||
typedef enum {
|
||||
RT_UNARY_OP_BOOL, // __bool__
|
||||
RT_UNARY_OP_LEN, // __len__
|
||||
|
@ -83,6 +97,6 @@ extern void *const rt_fun_table[RT_F_NUMBER_OF];
|
|||
void rt_init(void);
|
||||
void rt_deinit(void);
|
||||
uint rt_get_unique_code_id(void);
|
||||
void rt_assign_byte_code(uint unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_stack, bool is_generator);
|
||||
void rt_assign_byte_code(uint unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_stack, uint scope_flags);
|
||||
void rt_assign_native_code(uint unique_code_id, void *f, uint len, int n_args);
|
||||
void rt_assign_inline_asm_code(uint unique_code_id, void *f, uint len, int n_args);
|
||||
|
|
|
@ -47,7 +47,7 @@ scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint
|
|||
scope->id_info_len = 0;
|
||||
scope->id_info = m_new(id_info_t, scope->id_info_alloc);
|
||||
|
||||
scope->flags = 0;
|
||||
scope->scope_flags = 0;
|
||||
scope->num_params = 0;
|
||||
/* not needed
|
||||
scope->num_default_params = 0;
|
||||
|
@ -244,7 +244,7 @@ void scope_print_info(scope_t *s) {
|
|||
}
|
||||
printf("\n");
|
||||
*/
|
||||
printf(" flags %04x\n", s->flags);
|
||||
printf(" flags %04x\n", s->scope_flags);
|
||||
printf(" argcount %d\n", s->num_params);
|
||||
printf(" nlocals %d\n", s->num_locals);
|
||||
printf(" stacksize %d\n", s->stack_size);
|
||||
|
|
16
py/scope.h
16
py/scope.h
|
@ -17,20 +17,6 @@ typedef struct _id_info_t {
|
|||
int local_num;
|
||||
} id_info_t;
|
||||
|
||||
// taken from python source, Include/code.h
|
||||
#define SCOPE_FLAG_OPTIMISED 0x0001
|
||||
#define SCOPE_FLAG_NEWLOCALS 0x0002
|
||||
#define SCOPE_FLAG_VARARGS 0x0004
|
||||
#define SCOPE_FLAG_VARKEYWORDS 0x0008
|
||||
#define SCOPE_FLAG_NESTED 0x0010
|
||||
#define SCOPE_FLAG_GENERATOR 0x0020
|
||||
/* The SCOPE_FLAG_NOFREE flag is set if there are no free or cell variables.
|
||||
This information is redundant, but it allows a single flag test
|
||||
to determine whether there is any extra work to be done when the
|
||||
call frame is setup.
|
||||
*/
|
||||
#define SCOPE_FLAG_NOFREE 0x0040
|
||||
|
||||
// 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 {
|
||||
|
@ -43,7 +29,7 @@ typedef struct _scope_t {
|
|||
int id_info_alloc;
|
||||
int id_info_len;
|
||||
id_info_t *id_info;
|
||||
int flags;
|
||||
uint scope_flags; // see runtime0.h
|
||||
int num_params;
|
||||
/* not needed
|
||||
int num_default_params;
|
||||
|
|
Loading…
Reference in New Issue