gh-121404: remove some accesses to compiler internals from codegen functions (#121538)

This commit is contained in:
Irit Katriel 2024-07-10 17:09:45 +01:00 committed by GitHub
parent af9f6de6ea
commit 0177a34335
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -71,11 +71,24 @@
((C)->c_flags.cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \
&& ((C)->u->u_ste->ste_type == ModuleBlock))
struct compiler;
typedef _PyInstruction instruction;
typedef _PyInstructionSequence instr_sequence;
static instr_sequence *compiler_instr_sequence(struct compiler *c);
static int compiler_future_features(struct compiler *c);
static struct symtable *compiler_symtable(struct compiler *c);
static PySTEntryObject *compiler_symtable_entry(struct compiler *c);
#define INSTR_SEQUENCE(C) compiler_instr_sequence(C)
#define FUTURE_FEATURES(C) compiler_future_features(C)
#define SYMTABLE(C) compiler_symtable(C)
#define SYMTABLE_ENTRY(C) compiler_symtable_entry(C)
typedef _Py_SourceLocation location;
typedef struct _PyCfgBuilder cfg_builder;
struct compiler;
static PyObject *compiler_maybe_mangle(struct compiler *c, PyObject *name);
#define LOCATION(LNO, END_LNO, COL, END_COL) \
@ -133,12 +146,6 @@ enum {
};
typedef _PyInstruction instruction;
typedef _PyInstructionSequence instr_sequence;
#define INITIAL_INSTR_SEQUENCE_SIZE 100
#define INITIAL_INSTR_SEQUENCE_LABELS_MAP_SIZE 10
static const int compare_masks[] = {
[Py_LT] = COMPARISON_LESS_THAN,
[Py_LE] = COMPARISON_LESS_THAN | COMPARISON_EQUALS,
@ -258,8 +265,6 @@ struct compiler {
*/
};
#define INSTR_SEQUENCE(C) ((C)->u->u_instr_sequence)
typedef struct {
// A list of strings corresponding to name captures. It is used to track:
@ -317,7 +322,6 @@ static int compiler_call_helper(struct compiler *c, location loc,
asdl_keyword_seq *keywords);
static int compiler_try_except(struct compiler *, stmt_ty);
static int compiler_try_star_except(struct compiler *, stmt_ty);
static int compiler_set_qualname(struct compiler *);
static int compiler_sync_comprehension_generator(
struct compiler *c, location loc,
@ -558,8 +562,8 @@ compiler_unit_free(struct compiler_unit *u)
PyMem_Free(u);
}
static struct compiler_unit *
get_class_compiler_unit(struct compiler *c)
static int
compiler_add_static_attribute_to_class(struct compiler *c, PyObject *attr)
{
Py_ssize_t stack_size = PyList_GET_SIZE(c->c_stack);
for (Py_ssize_t i = stack_size - 1; i >= 0; i--) {
@ -568,10 +572,12 @@ get_class_compiler_unit(struct compiler *c)
capsule, CAPSULE_NAME);
assert(u);
if (u->u_scope_type == COMPILER_SCOPE_CLASS) {
return u;
assert(u->u_static_attributes);
RETURN_IF_ERROR(PySet_Add(u->u_static_attributes, attr));
break;
}
}
return NULL;
return SUCCESS;
}
static int
@ -863,38 +869,37 @@ merge_consts_recursive(PyObject *const_cache, PyObject *o)
}
static Py_ssize_t
compiler_add_const(PyObject *const_cache, struct compiler_unit *u, PyObject *o)
compiler_add_const(struct compiler *c, PyObject *o)
{
assert(PyDict_CheckExact(const_cache));
PyObject *key = merge_consts_recursive(const_cache, o);
PyObject *key = merge_consts_recursive(c->c_const_cache, o);
if (key == NULL) {
return ERROR;
}
Py_ssize_t arg = dict_add_o(u->u_metadata.u_consts, key);
Py_ssize_t arg = dict_add_o(c->u->u_metadata.u_consts, key);
Py_DECREF(key);
return arg;
}
static int
compiler_addop_load_const(PyObject *const_cache, struct compiler_unit *u, location loc, PyObject *o)
compiler_addop_load_const(struct compiler *c, location loc, PyObject *o)
{
Py_ssize_t arg = compiler_add_const(const_cache, u, o);
Py_ssize_t arg = compiler_add_const(c, o);
if (arg < 0) {
return ERROR;
}
return codegen_addop_i(u->u_instr_sequence, LOAD_CONST, arg, loc);
return codegen_addop_i(INSTR_SEQUENCE(c), LOAD_CONST, arg, loc);
}
static int
compiler_addop_o(struct compiler_unit *u, location loc,
compiler_addop_o(struct compiler *c, location loc,
int opcode, PyObject *dict, PyObject *o)
{
Py_ssize_t arg = dict_add_o(dict, o);
if (arg < 0) {
return ERROR;
}
return codegen_addop_i(u->u_instr_sequence, opcode, arg, loc);
return codegen_addop_i(INSTR_SEQUENCE(c), opcode, arg, loc);
}
#define LOAD_METHOD -1
@ -984,7 +989,7 @@ codegen_addop_j(instr_sequence *seq, location loc,
#define ADDOP_IN_SCOPE(C, LOC, OP) RETURN_IF_ERROR_IN_SCOPE((C), codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)))
#define ADDOP_LOAD_CONST(C, LOC, O) \
RETURN_IF_ERROR(compiler_addop_load_const((C)->c_const_cache, (C)->u, (LOC), (O)))
RETURN_IF_ERROR(compiler_addop_load_const((C), (LOC), (O)))
/* Same as ADDOP_LOAD_CONST, but steals a reference. */
#define ADDOP_LOAD_CONST_NEW(C, LOC, O) { \
@ -992,7 +997,7 @@ codegen_addop_j(instr_sequence *seq, location loc,
if (__new_const == NULL) { \
return ERROR; \
} \
if (compiler_addop_load_const((C)->c_const_cache, (C)->u, (LOC), __new_const) < 0) { \
if (compiler_addop_load_const((C), (LOC), __new_const) < 0) { \
Py_DECREF(__new_const); \
return ERROR; \
} \
@ -1001,7 +1006,7 @@ codegen_addop_j(instr_sequence *seq, location loc,
#define ADDOP_N(C, LOC, OP, O, TYPE) { \
assert(!OPCODE_HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */ \
if (compiler_addop_o((C)->u, (LOC), (OP), (C)->u->u_metadata.u_ ## TYPE, (O)) < 0) { \
if (compiler_addop_o((C), (LOC), (OP), (C)->u->u_metadata.u_ ## TYPE, (O)) < 0) { \
Py_DECREF((O)); \
return ERROR; \
} \
@ -1514,7 +1519,7 @@ compiler_body(struct compiler *c, location loc, asdl_stmt_seq *stmts)
/* If from __future__ import annotations is active,
* every annotated class and module should have __annotations__.
* Else __annotate__ is created when necessary. */
if ((c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) && c->u->u_ste->ste_annotations_used) {
if ((FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) && SYMTABLE_ENTRY(c)->ste_annotations_used) {
ADDOP(c, loc, SETUP_ANNOTATIONS);
}
if (!asdl_seq_LEN(stmts)) {
@ -1546,7 +1551,7 @@ compiler_body(struct compiler *c, location loc, asdl_stmt_seq *stmts)
// If there are annotations and the future import is not on, we
// collect the annotations in a separate pass and generate an
// __annotate__ function. See PEP 649.
if (!(c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) &&
if (!(FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) &&
c->u->u_deferred_annotations != NULL) {
// It's possible that ste_annotations_block is set but
@ -1554,11 +1559,12 @@ compiler_body(struct compiler *c, location loc, asdl_stmt_seq *stmts)
// set if there are only non-simple annotations (i.e., annotations
// for attributes, subscripts, or parenthesized names). However, the
// reverse should not be possible.
assert(c->u->u_ste->ste_annotation_block != NULL);
PySTEntryObject *ste = SYMTABLE_ENTRY(c);
assert(ste->ste_annotation_block != NULL);
PyObject *deferred_anno = Py_NewRef(c->u->u_deferred_annotations);
void *key = (void *)((uintptr_t)c->u->u_ste->ste_id + 1);
void *key = (void *)((uintptr_t)ste->ste_id + 1);
if (compiler_setup_annotations_scope(c, loc, key,
c->u->u_ste->ste_annotation_block->ste_name) == -1) {
ste->ste_annotation_block->ste_name) == -1) {
Py_DECREF(deferred_anno);
return ERROR;
}
@ -1642,13 +1648,8 @@ finally:
return co;
}
/* The test for LOCAL must come before the test for FREE in order to
handle classes where name is both local and free. The local var is
a method and the free var is a free var referenced within a method.
*/
static int
get_ref_type(struct compiler *c, PyObject *name)
compiler_get_ref_type(struct compiler *c, PyObject *name)
{
int scope;
if (c->u->u_scope_type == COMPILER_SCOPE_CLASS &&
@ -1656,15 +1657,16 @@ get_ref_type(struct compiler *c, PyObject *name)
_PyUnicode_EqualToASCIIString(name, "__classdict__"))) {
return CELL;
}
scope = _PyST_GetScope(c->u->u_ste, name);
PySTEntryObject *ste = SYMTABLE_ENTRY(c);
scope = _PyST_GetScope(ste, name);
if (scope == 0) {
PyErr_Format(PyExc_SystemError,
"_PyST_GetScope(name=%R) failed: "
"unknown scope in unit %S (%R); "
"symbols: %R; locals: %R; globals: %R",
name,
c->u->u_metadata.u_name, c->u->u_ste->ste_id,
c->u->u_ste->ste_symbols, c->u->u_metadata.u_varnames, c->u->u_metadata.u_names);
c->u->u_metadata.u_name, ste->ste_id,
ste->ste_symbols, c->u->u_metadata.u_varnames, c->u->u_metadata.u_names);
return ERROR;
}
return scope;
@ -1698,7 +1700,7 @@ compiler_make_closure(struct compiler *c, location loc,
class. It should be handled by the closure, as
well as by the normal name lookup logic.
*/
int reftype = get_ref_type(c, name);
int reftype = compiler_get_ref_type(c, name);
if (reftype == -1) {
return ERROR;
}
@ -1858,7 +1860,7 @@ compiler_argannotation(struct compiler *c, identifier id,
ADDOP_LOAD_CONST(c, loc, mangled);
Py_DECREF(mangled);
if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) {
if (FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) {
VISIT(c, annexpr, annotation);
}
else {
@ -1940,7 +1942,7 @@ compiler_annotations(struct compiler *c, location loc,
Py_ssize_t annotations_len = 0;
PySTEntryObject *ste;
if (_PySymtable_LookupOptional(c->c_st, args, &ste) < 0) {
if (_PySymtable_LookupOptional(SYMTABLE(c), args, &ste) < 0) {
return ERROR;
}
assert(ste != NULL);
@ -2239,7 +2241,7 @@ compiler_function_body(struct compiler *c, stmt_ty s, int is_async, Py_ssize_t f
docstring = NULL;
}
}
if (compiler_add_const(c->c_const_cache, c->u, docstring ? docstring : Py_None) < 0) {
if (compiler_add_const(c, docstring ? docstring : Py_None) < 0) {
Py_XDECREF(docstring);
compiler_exit_scope(c);
return ERROR;
@ -2252,7 +2254,8 @@ compiler_function_body(struct compiler *c, stmt_ty s, int is_async, Py_ssize_t f
NEW_JUMP_TARGET_LABEL(c, start);
USE_LABEL(c, start);
bool add_stopiteration_handler = c->u->u_ste->ste_coroutine || c->u->u_ste->ste_generator;
PySTEntryObject *ste = SYMTABLE_ENTRY(c);
bool add_stopiteration_handler = ste->ste_coroutine || ste->ste_generator;
if (add_stopiteration_handler) {
/* wrap_in_stopiteration_handler will push a block, so we need to account for that */
RETURN_IF_ERROR(
@ -2463,14 +2466,14 @@ compiler_class_body(struct compiler *c, stmt_ty s, int firstlineno)
return ERROR;
}
}
if (c->u->u_ste->ste_needs_classdict) {
if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
ADDOP(c, loc, LOAD_LOCALS);
// We can't use compiler_nameop here because we need to generate a
// STORE_DEREF in a class namespace, and compiler_nameop() won't do
// that by default.
PyObject *cellvars = c->u->u_metadata.u_cellvars;
if (compiler_addop_o(c->u, loc, STORE_DEREF, cellvars,
if (compiler_addop_o(c, loc, STORE_DEREF, cellvars,
&_Py_ID(__classdict__)) < 0) {
compiler_exit_scope(c);
return ERROR;
@ -2495,7 +2498,7 @@ compiler_class_body(struct compiler *c, stmt_ty s, int firstlineno)
}
/* The following code is artificial */
/* Set __classdictcell__ if necessary */
if (c->u->u_ste->ste_needs_classdict) {
if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
/* Store __classdictcell__ into class namespace */
int i = compiler_lookup_arg(c->u->u_metadata.u_cellvars, &_Py_ID(__classdict__));
if (i < 0) {
@ -2509,7 +2512,7 @@ compiler_class_body(struct compiler *c, stmt_ty s, int firstlineno)
}
}
/* Return __classcell__ if it is referenced, otherwise return None */
if (c->u->u_ste->ste_needs_class_closure) {
if (SYMTABLE_ENTRY(c)->ste_needs_class_closure) {
/* Store __classcell__ into class namespace & return it */
int i = compiler_lookup_arg(c->u->u_metadata.u_cellvars, &_Py_ID(__class__));
if (i < 0) {
@ -2667,7 +2670,7 @@ compiler_typealias_body(struct compiler *c, stmt_ty s)
compiler_enter_scope(c, name, COMPILER_SCOPE_FUNCTION, s, loc.lineno, NULL));
/* Make None the first constant, so the evaluate function can't have a
docstring. */
RETURN_IF_ERROR(compiler_add_const(c->c_const_cache, c->u, Py_None));
RETURN_IF_ERROR(compiler_add_const(c, Py_None));
VISIT_IN_SCOPE(c, expr, s->v.TypeAlias.value);
ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
PyCodeObject *co = optimize_and_assemble(c, 0);
@ -2705,7 +2708,7 @@ compiler_typealias(struct compiler *c, stmt_ty s)
}
Py_DECREF(type_params_name);
RETURN_IF_ERROR_IN_SCOPE(
c, compiler_addop_load_const(c->c_const_cache, c->u, loc, name)
c, compiler_addop_load_const(c, loc, name)
);
RETURN_IF_ERROR_IN_SCOPE(c, compiler_type_params(c, type_params));
}
@ -2972,13 +2975,13 @@ compiler_lambda(struct compiler *c, expr_ty e)
/* Make None the first constant, so the lambda can't have a
docstring. */
RETURN_IF_ERROR(compiler_add_const(c->c_const_cache, c->u, Py_None));
RETURN_IF_ERROR(compiler_add_const(c, Py_None));
c->u->u_metadata.u_argcount = asdl_seq_LEN(args->args);
c->u->u_metadata.u_posonlyargcount = asdl_seq_LEN(args->posonlyargs);
c->u->u_metadata.u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
if (c->u->u_ste->ste_generator) {
if (SYMTABLE_ENTRY(c)->ste_generator) {
co = optimize_and_assemble(c, 0);
}
else {
@ -3154,12 +3157,12 @@ compiler_return(struct compiler *c, stmt_ty s)
location loc = LOC(s);
int preserve_tos = ((s->v.Return.value != NULL) &&
(s->v.Return.value->kind != Constant_kind));
if (!_PyST_IsFunctionLike(c->u->u_ste)) {
PySTEntryObject *ste = SYMTABLE_ENTRY(c);
if (!_PyST_IsFunctionLike(ste)) {
return compiler_error(c, loc, "'return' outside function");
}
if (s->v.Return.value != NULL &&
c->u->u_ste->ste_coroutine && c->u->u_ste->ste_generator)
{
if (s->v.Return.value != NULL && ste->ste_coroutine && ste->ste_generator) {
return compiler_error(c, loc, "'return' with value in async generator");
}
@ -4109,7 +4112,8 @@ addop_binary(struct compiler *c, location loc, operator_ty binop,
static int
addop_yield(struct compiler *c, location loc) {
if (c->u->u_ste->ste_generator && c->u->u_ste->ste_coroutine) {
PySTEntryObject *ste = SYMTABLE_ENTRY(c);
if (ste->ste_generator && ste->ste_coroutine) {
ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_ASYNC_GEN_WRAP);
}
ADDOP_I(c, loc, YIELD_VALUE, 0);
@ -4143,7 +4147,7 @@ compiler_nameop(struct compiler *c, location loc,
op = 0;
optype = OP_NAME;
scope = _PyST_GetScope(c->u->u_ste, mangled);
scope = _PyST_GetScope(SYMTABLE_ENTRY(c), mangled);
switch (scope) {
case FREE:
dict = c->u->u_metadata.u_freevars;
@ -4154,7 +4158,7 @@ compiler_nameop(struct compiler *c, location loc,
optype = OP_DEREF;
break;
case LOCAL:
if (_PyST_IsFunctionLike(c->u->u_ste)) {
if (_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
optype = OP_FAST;
}
else {
@ -4170,7 +4174,7 @@ compiler_nameop(struct compiler *c, location loc,
}
break;
case GLOBAL_IMPLICIT:
if (_PyST_IsFunctionLike(c->u->u_ste))
if (_PyST_IsFunctionLike(SYMTABLE_ENTRY(c)))
optype = OP_GLOBAL;
break;
case GLOBAL_EXPLICIT:
@ -4188,17 +4192,17 @@ compiler_nameop(struct compiler *c, location loc,
case OP_DEREF:
switch (ctx) {
case Load:
if (c->u->u_ste->ste_type == ClassBlock && !c->u->u_in_inlined_comp) {
if (SYMTABLE_ENTRY(c)->ste_type == ClassBlock && !c->u->u_in_inlined_comp) {
op = LOAD_FROM_DICT_OR_DEREF;
// First load the locals
if (codegen_addop_noarg(INSTR_SEQUENCE(c), LOAD_LOCALS, loc) < 0) {
goto error;
}
}
else if (c->u->u_ste->ste_can_see_class_scope) {
else if (SYMTABLE_ENTRY(c)->ste_can_see_class_scope) {
op = LOAD_FROM_DICT_OR_DEREF;
// First load the classdict
if (compiler_addop_o(c->u, loc, LOAD_DEREF,
if (compiler_addop_o(c, loc, LOAD_DEREF,
c->u->u_metadata.u_freevars, &_Py_ID(__classdict__)) < 0) {
goto error;
}
@ -4222,10 +4226,10 @@ compiler_nameop(struct compiler *c, location loc,
case OP_GLOBAL:
switch (ctx) {
case Load:
if (c->u->u_ste->ste_can_see_class_scope && scope == GLOBAL_IMPLICIT) {
if (SYMTABLE_ENTRY(c)->ste_can_see_class_scope && scope == GLOBAL_IMPLICIT) {
op = LOAD_FROM_DICT_OR_GLOBALS;
// First load the classdict
if (compiler_addop_o(c->u, loc, LOAD_DEREF,
if (compiler_addop_o(c, loc, LOAD_DEREF,
c->u->u_metadata.u_freevars, &_Py_ID(__classdict__)) < 0) {
goto error;
}
@ -4240,7 +4244,7 @@ compiler_nameop(struct compiler *c, location loc,
case OP_NAME:
switch (ctx) {
case Load:
op = (c->u->u_ste->ste_type == ClassBlock
op = (SYMTABLE_ENTRY(c)->ste_type == ClassBlock
&& c->u->u_in_inlined_comp)
? LOAD_GLOBAL
: LOAD_NAME;
@ -4745,7 +4749,7 @@ is_import_originated(struct compiler *c, expr_ty e)
return 0;
}
long flags = _PyST_GetSymbol(c->c_st->st_top, e->v.Name.id);
long flags = _PyST_GetSymbol(SYMTABLE(c)->st_top, e->v.Name.id);
return flags & DEF_IMPORT;
}
@ -4764,11 +4768,11 @@ can_optimize_super_call(struct compiler *c, expr_ty attr)
PyObject *super_name = e->v.Call.func->v.Name.id;
// detect statically-visible shadowing of 'super' name
int scope = _PyST_GetScope(c->u->u_ste, super_name);
int scope = _PyST_GetScope(SYMTABLE_ENTRY(c), super_name);
if (scope != GLOBAL_IMPLICIT) {
return 0;
}
scope = _PyST_GetScope(c->c_st->st_top, super_name);
scope = _PyST_GetScope(SYMTABLE(c)->st_top, super_name);
if (scope != 0) {
return 0;
}
@ -4796,7 +4800,7 @@ can_optimize_super_call(struct compiler *c, expr_ty attr)
return 0;
}
// __class__ cell should be available
if (get_ref_type(c, &_Py_ID(__class__)) == FREE) {
if (compiler_get_ref_type(c, &_Py_ID(__class__)) == FREE) {
return 1;
}
return 0;
@ -4818,7 +4822,7 @@ load_args_for_super(struct compiler *c, expr_ty e) {
// load __class__ cell
PyObject *name = &_Py_ID(__class__);
assert(get_ref_type(c, name) == FREE);
assert(compiler_get_ref_type(c, name) == FREE);
RETURN_IF_ERROR(compiler_nameop(c, loc, name, Load));
// load self (first argument)
@ -5490,7 +5494,7 @@ push_inlined_comprehension_state(struct compiler *c, location loc,
PySTEntryObject *entry,
inlined_comprehension_state *state)
{
int in_class_block = (c->u->u_ste->ste_type == ClassBlock) && !c->u->u_in_inlined_comp;
int in_class_block = (SYMTABLE_ENTRY(c)->ste_type == ClassBlock) && !c->u->u_in_inlined_comp;
c->u->u_in_inlined_comp++;
// iterate over names bound in the comprehension and ensure we isolate
// them from the outer scope as needed
@ -5500,7 +5504,7 @@ push_inlined_comprehension_state(struct compiler *c, location loc,
assert(PyLong_Check(v));
long symbol = PyLong_AS_LONG(v);
long scope = (symbol >> SCOPE_OFFSET) & SCOPE_MASK;
PyObject *outv = PyDict_GetItemWithError(c->u->u_ste->ste_symbols, k);
PyObject *outv = PyDict_GetItemWithError(SYMTABLE_ENTRY(c)->ste_symbols, k);
if (outv == NULL) {
if (PyErr_Occurred()) {
return ERROR;
@ -5529,7 +5533,7 @@ push_inlined_comprehension_state(struct compiler *c, location loc,
// the outer version; we'll restore it after running the
// comprehension
Py_INCREF(outv);
if (PyDict_SetItem(c->u->u_ste->ste_symbols, k, v) < 0) {
if (PyDict_SetItem(SYMTABLE_ENTRY(c)->ste_symbols, k, v) < 0) {
Py_DECREF(outv);
return ERROR;
}
@ -5542,7 +5546,7 @@ push_inlined_comprehension_state(struct compiler *c, location loc,
// locals handling for names bound in comprehension (DEF_LOCAL |
// DEF_NONLOCAL occurs in assignment expression to nonlocal)
if ((symbol & DEF_LOCAL && !(symbol & DEF_NONLOCAL)) || in_class_block) {
if (!_PyST_IsFunctionLike(c->u->u_ste)) {
if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
// non-function scope: override this name to use fast locals
PyObject *orig;
if (PyDict_GetItemRef(c->u->u_metadata.u_fasthidden, k, &orig) < 0) {
@ -5644,7 +5648,7 @@ pop_inlined_comprehension_state(struct compiler *c, location loc,
Py_ssize_t pos = 0;
if (state.temp_symbols) {
while (PyDict_Next(state.temp_symbols, &pos, &k, &v)) {
if (PyDict_SetItem(c->u->u_ste->ste_symbols, k, v)) {
if (PyDict_SetItem(SYMTABLE_ENTRY(c)->ste_symbols, k, v)) {
return ERROR;
}
}
@ -5713,7 +5717,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
comprehension_ty outermost;
int scope_type = c->u->u_scope_type;
int is_top_level_await = IS_TOP_LEVEL_AWAIT(c);
PySTEntryObject *entry = _PySymtable_Lookup(c->c_st, (void *)e);
PySTEntryObject *entry = _PySymtable_Lookup(SYMTABLE(c), (void *)e);
if (entry == NULL) {
goto error;
}
@ -6150,7 +6154,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
case DictComp_kind:
return compiler_dictcomp(c, e);
case Yield_kind:
if (!_PyST_IsFunctionLike(c->u->u_ste)) {
if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
return compiler_error(c, loc, "'yield' outside function");
}
if (e->v.Yield.value) {
@ -6162,7 +6166,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
ADDOP_YIELD(c, loc);
break;
case YieldFrom_kind:
if (!_PyST_IsFunctionLike(c->u->u_ste)) {
if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
return compiler_error(c, loc, "'yield' outside function");
}
if (c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION) {
@ -6175,7 +6179,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
break;
case Await_kind:
if (!IS_TOP_LEVEL_AWAIT(c)){
if (!_PyST_IsFunctionLike(c->u->u_ste)) {
if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
return compiler_error(c, loc, "'await' outside function");
}
@ -6215,13 +6219,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
if (e->v.Attribute.value->kind == Name_kind &&
_PyUnicode_EqualToASCIIString(e->v.Attribute.value->v.Name.id, "self"))
{
struct compiler_unit *class_u = get_class_compiler_unit(c);
if (class_u != NULL) {
assert(class_u->u_scope_type == COMPILER_SCOPE_CLASS);
assert(class_u->u_static_attributes);
RETURN_IF_ERROR(
PySet_Add(class_u->u_static_attributes, e->v.Attribute.attr));
}
RETURN_IF_ERROR(compiler_add_static_attribute_to_class(c, e->v.Attribute.attr));
}
VISIT(c, expr, e->v.Attribute.value);
loc = LOC(e);
@ -6368,7 +6366,7 @@ check_annotation(struct compiler *c, stmt_ty s)
{
/* Annotations of complex targets does not produce anything
under annotations future */
if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) {
if (FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) {
return SUCCESS;
}
@ -6415,7 +6413,7 @@ compiler_annassign(struct compiler *c, stmt_ty s)
{
location loc = LOC(s);
expr_ty targ = s->v.AnnAssign.target;
bool future_annotations = c->c_future.ff_features & CO_FUTURE_ANNOTATIONS;
bool future_annotations = FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS;
PyObject *mangled;
assert(s->kind == AnnAssign_kind);
@ -7485,19 +7483,41 @@ compiler_maybe_mangle(struct compiler *c, PyObject *name)
return _Py_MaybeMangle(c->u->u_private, c->u->u_ste, name);
}
static instr_sequence *
compiler_instr_sequence(struct compiler *c)
{
return c->u->u_instr_sequence;
}
static int
compiler_future_features(struct compiler *c)
{
return c->c_future.ff_features;
}
static struct symtable *
compiler_symtable(struct compiler *c)
{
return c->c_st;
}
static PySTEntryObject *
compiler_symtable_entry(struct compiler *c)
{
return c->u->u_ste;
}
static int
compute_code_flags(struct compiler *c)
{
PySTEntryObject *ste = c->u->u_ste;
PySTEntryObject *ste = SYMTABLE_ENTRY(c);
int flags = 0;
if (_PyST_IsFunctionLike(c->u->u_ste)) {
if (_PyST_IsFunctionLike(ste)) {
flags |= CO_NEWLOCALS | CO_OPTIMIZED;
if (ste->ste_nested)
flags |= CO_NESTED;
if (ste->ste_generator && !ste->ste_coroutine)
flags |= CO_GENERATOR;
if (!ste->ste_generator && ste->ste_coroutine)
flags |= CO_COROUTINE;
if (ste->ste_generator && ste->ste_coroutine)
flags |= CO_ASYNC_GENERATOR;
if (ste->ste_varargs)
@ -7506,15 +7526,14 @@ compute_code_flags(struct compiler *c)
flags |= CO_VARKEYWORDS;
}
/* (Only) inherit compilerflags in PyCF_MASK */
flags |= (c->c_flags.cf_flags & PyCF_MASK);
if ((IS_TOP_LEVEL_AWAIT(c)) &&
ste->ste_coroutine &&
!ste->ste_generator) {
if (ste->ste_coroutine && !ste->ste_generator) {
assert (IS_TOP_LEVEL_AWAIT(c) || _PyST_IsFunctionLike(ste));
flags |= CO_COROUTINE;
}
/* (Only) inherit compilerflags in PyCF_MASK */
flags |= (c->c_flags.cf_flags & PyCF_MASK);
return flags;
}