rather than passing locals to the class body, just execute the class body in the proper environment

This commit is contained in:
Benjamin Peterson 2013-05-16 14:37:25 -05:00
parent e914123d1f
commit e8e14591eb
10 changed files with 3143 additions and 3175 deletions

View File

@ -596,12 +596,6 @@ the stack so that it is available for further iterations of the loop.
.. XXX explain the WHY stuff!
.. opcode:: STORE_LOCALS
Pops TOS from the stack and stores it as the current frame's ``f_locals``.
This is used in class construction.
All of the following opcodes expect arguments. An argument is two bytes, with
the more significant byte last.

View File

@ -49,7 +49,6 @@ extern "C" {
#define BINARY_OR 66
#define INPLACE_POWER 67
#define GET_ITER 68
#define STORE_LOCALS 69
#define PRINT_EXPR 70
#define LOAD_BUILD_CLASS 71
#define YIELD_FROM 72

View File

@ -391,12 +391,13 @@ def _call_with_frames_removed(f, *args, **kwds):
# Python 3.4a1 3260 (add LOAD_CLASSDEREF; allow locals of class to override
# free vars)
# Python 3.4a1 3270 (various tweaks to the __class_ closure)
# Python 3.4a1 3280 (remove implicit class argument)
#
# MAGIC must change whenever the bytecode emitted by the compiler may no
# longer be understood by older implementations of the eval loop (usually
# due to the addition of new opcodes).
_MAGIC_BYTES = (3270).to_bytes(2, 'little') + b'\r\n'
_MAGIC_BYTES = (3280).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(_MAGIC_BYTES, 'little')
_PYCACHE = '__pycache__'

View File

@ -84,7 +84,6 @@ def_op('BINARY_XOR', 65)
def_op('BINARY_OR', 66)
def_op('INPLACE_POWER', 67)
def_op('GET_ITER', 68)
def_op('STORE_LOCALS', 69)
def_op('PRINT_EXPR', 70)
def_op('LOAD_BUILD_CLASS', 71)

View File

@ -57,6 +57,11 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
return NULL;
}
func = PyTuple_GET_ITEM(args, 0); /* Better be callable */
if (!PyFunction_Check(func)) {
PyErr_SetString(PyExc_TypeError,
"__build__class__: func must be a function");
return NULL;
}
name = PyTuple_GET_ITEM(args, 1);
if (!PyUnicode_Check(name)) {
PyErr_SetString(PyExc_TypeError,
@ -155,7 +160,9 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
Py_DECREF(bases);
return NULL;
}
cell = PyObject_CallFunctionObjArgs(func, ns, NULL);
cell = PyEval_EvalCodeEx(PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(func), ns,
NULL, 0, NULL, 0, NULL, 0, NULL,
PyFunction_GET_CLOSURE(func));
if (cell != NULL) {
PyObject *margs;
margs = PyTuple_Pack(3, name, bases, ns);

View File

@ -1873,14 +1873,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
goto error;
}
TARGET(STORE_LOCALS) {
PyObject *locals = POP();
PyObject *old = f->f_locals;
Py_XDECREF(old);
f->f_locals = locals;
DISPATCH();
}
TARGET(RETURN_VALUE) {
retval = POP();
why = WHY_RETURN;

View File

@ -893,8 +893,6 @@ opcode_stack_effect(int opcode, int oparg)
return 7;
case WITH_CLEANUP:
return -1; /* XXX Sometimes more */
case STORE_LOCALS:
return -1;
case RETURN_VALUE:
return -1;
case IMPORT_STAR:
@ -1696,12 +1694,6 @@ compiler_class(struct compiler *c, stmt_ty s)
Py_INCREF(s->v.ClassDef.name);
Py_XDECREF(c->u->u_private);
c->u->u_private = s->v.ClassDef.name;
/* force it to have one mandatory argument */
c->u->u_argcount = 1;
/* load the first argument (__locals__) ... */
ADDOP_I(c, LOAD_FAST, 0);
/* ... and store it into f_locals */
ADDOP_IN_SCOPE(c, STORE_LOCALS);
/* load (global) __name__ ... */
str = PyUnicode_InternFromString("__name__");
if (!str || !compiler_nameop(c, str, Load)) {
@ -4110,9 +4102,8 @@ compute_code_flags(struct compiler *c)
{
PySTEntryObject *ste = c->u->u_ste;
int flags = 0, n;
if (ste->ste_type != ModuleBlock)
flags |= CO_NEWLOCALS;
if (ste->ste_type == FunctionBlock) {
flags |= CO_NEWLOCALS;
if (!ste->ste_unoptimized)
flags |= CO_OPTIMIZED;
if (ste->ste_nested)

File diff suppressed because it is too large Load Diff

View File

@ -68,7 +68,7 @@ static void *opcode_targets[256] = {
&&TARGET_BINARY_OR,
&&TARGET_INPLACE_POWER,
&&TARGET_GET_ITER,
&&TARGET_STORE_LOCALS,
&&_unknown_opcode,
&&TARGET_PRINT_EXPR,
&&TARGET_LOAD_BUILD_CLASS,
&&TARGET_YIELD_FROM,

View File

@ -192,7 +192,7 @@ static int symtable_visit_withitem(struct symtable *st, withitem_ty item);
static identifier top = NULL, lambda = NULL, genexpr = NULL,
listcomp = NULL, setcomp = NULL, dictcomp = NULL,
__class__ = NULL, __locals__ = NULL;
__class__ = NULL;
#define GET_IDENTIFIER(VAR) \
((VAR) ? (VAR) : ((VAR) = PyUnicode_InternFromString(# VAR)))
@ -1185,11 +1185,6 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock,
(void *)s, s->lineno, s->col_offset))
VISIT_QUIT(st, 0);
if (!GET_IDENTIFIER(__locals__) ||
!symtable_add_def(st, __locals__, DEF_PARAM)) {
symtable_exit_block(st, s);
VISIT_QUIT(st, 0);
}
tmp = st->st_private;
st->st_private = s->v.ClassDef.name;
VISIT_SEQ(st, stmt, s->v.ClassDef.body);