mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
Issue #27095: Simplified MAKE_FUNCTION and removed MAKE_CLOSURE opcodes.
Patch by Demur Rumed.
This commit is contained in:
parent
5697c4b641
commit
64204de04c
13 changed files with 4100 additions and 4160 deletions
|
@ -937,27 +937,16 @@ All of the following opcodes use their arguments.
|
||||||
.. opcode:: MAKE_FUNCTION (argc)
|
.. opcode:: MAKE_FUNCTION (argc)
|
||||||
|
|
||||||
Pushes a new function object on the stack. From bottom to top, the consumed
|
Pushes a new function object on the stack. From bottom to top, the consumed
|
||||||
stack must consist of
|
stack must consist of values if the argument carries a specified flag value
|
||||||
|
|
||||||
* ``argc & 0xFF`` default argument objects in positional order
|
* ``0x01`` a tuple of default argument objects in positional order
|
||||||
* ``(argc >> 8) & 0xFF`` pairs of name and default argument, with the name
|
* ``0x02`` a dictionary of keyword-only parameters' default values
|
||||||
just below the object on the stack, for keyword-only parameters
|
* ``0x04`` an annotation dictionary
|
||||||
* ``(argc >> 16) & 0x7FFF`` parameter annotation objects
|
* ``0x08`` a tuple containing cells for free variables, making a closure
|
||||||
* a tuple listing the parameter names for the annotations (only if there are
|
|
||||||
ony annotation objects)
|
|
||||||
* the code associated with the function (at TOS1)
|
* the code associated with the function (at TOS1)
|
||||||
* the :term:`qualified name` of the function (at TOS)
|
* the :term:`qualified name` of the function (at TOS)
|
||||||
|
|
||||||
|
|
||||||
.. opcode:: MAKE_CLOSURE (argc)
|
|
||||||
|
|
||||||
Creates a new function object, sets its *__closure__* slot, and pushes it on
|
|
||||||
the stack. TOS is the :term:`qualified name` of the function, TOS1 is the
|
|
||||||
code associated with the function, and TOS2 is the tuple containing cells for
|
|
||||||
the closure's free variables. *argc* is interpreted as in ``MAKE_FUNCTION``;
|
|
||||||
the annotations and defaults are also in the same order below TOS2.
|
|
||||||
|
|
||||||
|
|
||||||
.. opcode:: BUILD_SLICE (argc)
|
.. opcode:: BUILD_SLICE (argc)
|
||||||
|
|
||||||
.. index:: builtin: slice
|
.. index:: builtin: slice
|
||||||
|
|
|
@ -102,7 +102,6 @@ extern "C" {
|
||||||
#define CALL_FUNCTION 131
|
#define CALL_FUNCTION 131
|
||||||
#define MAKE_FUNCTION 132
|
#define MAKE_FUNCTION 132
|
||||||
#define BUILD_SLICE 133
|
#define BUILD_SLICE 133
|
||||||
#define MAKE_CLOSURE 134
|
|
||||||
#define LOAD_CLOSURE 135
|
#define LOAD_CLOSURE 135
|
||||||
#define LOAD_DEREF 136
|
#define LOAD_DEREF 136
|
||||||
#define STORE_DEREF 137
|
#define STORE_DEREF 137
|
||||||
|
|
|
@ -222,8 +222,10 @@ _code_type = type(_write_atomic.__code__)
|
||||||
# Python 3.5.2 3351 (fix BUILD_MAP_UNPACK_WITH_CALL opcode #27286)
|
# Python 3.5.2 3351 (fix BUILD_MAP_UNPACK_WITH_CALL opcode #27286)
|
||||||
# Python 3.6a0 3360 (add FORMAT_VALUE opcode #25483
|
# Python 3.6a0 3360 (add FORMAT_VALUE opcode #25483
|
||||||
# Python 3.6a0 3361 (lineno delta of code.co_lnotab becomes signed)
|
# Python 3.6a0 3361 (lineno delta of code.co_lnotab becomes signed)
|
||||||
# Python 3.6a0 3370 (16 bit wordcode)
|
# Python 3.6a1 3370 (16 bit wordcode)
|
||||||
# Python 3.6a0 3371 (add BUILD_CONST_KEY_MAP opcode #27140)
|
# Python 3.6a1 3371 (add BUILD_CONST_KEY_MAP opcode #27140)
|
||||||
|
# Python 3.6a1 3372 (MAKE_FUNCTION simplification, remove MAKE_CLOSURE
|
||||||
|
#27095)
|
||||||
#
|
#
|
||||||
# MAGIC must change whenever the bytecode emitted by the compiler may no
|
# MAGIC must change whenever the bytecode emitted by the compiler may no
|
||||||
# longer be understood by older implementations of the eval loop (usually
|
# longer be understood by older implementations of the eval loop (usually
|
||||||
|
@ -232,7 +234,7 @@ _code_type = type(_write_atomic.__code__)
|
||||||
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
|
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
|
||||||
# in PC/launcher.c must also be updated.
|
# in PC/launcher.c must also be updated.
|
||||||
|
|
||||||
MAGIC_NUMBER = (3371).to_bytes(2, 'little') + b'\r\n'
|
MAGIC_NUMBER = (3372).to_bytes(2, 'little') + b'\r\n'
|
||||||
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
|
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
|
||||||
|
|
||||||
_PYCACHE = '__pycache__'
|
_PYCACHE = '__pycache__'
|
||||||
|
|
|
@ -319,7 +319,7 @@ class GrammarTests(unittest.TestCase):
|
||||||
def f(x) -> list: pass
|
def f(x) -> list: pass
|
||||||
self.assertEquals(f.__annotations__, {'return': list})
|
self.assertEquals(f.__annotations__, {'return': list})
|
||||||
|
|
||||||
# test MAKE_CLOSURE with a variety of oparg's
|
# test closures with a variety of oparg's
|
||||||
closure = 1
|
closure = 1
|
||||||
def f(): return closure
|
def f(): return closure
|
||||||
def f(x=1): return closure
|
def f(x=1): return closure
|
||||||
|
|
|
@ -173,9 +173,8 @@ haslocal.append(126)
|
||||||
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
|
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
|
||||||
def_op('CALL_FUNCTION', 131) # #args + (#kwargs << 8)
|
def_op('CALL_FUNCTION', 131) # #args + (#kwargs << 8)
|
||||||
hasnargs.append(131)
|
hasnargs.append(131)
|
||||||
def_op('MAKE_FUNCTION', 132) # Number of args with default values
|
def_op('MAKE_FUNCTION', 132) # Flags
|
||||||
def_op('BUILD_SLICE', 133) # Number of items
|
def_op('BUILD_SLICE', 133) # Number of items
|
||||||
def_op('MAKE_CLOSURE', 134)
|
|
||||||
def_op('LOAD_CLOSURE', 135)
|
def_op('LOAD_CLOSURE', 135)
|
||||||
hasfree.append(135)
|
hasfree.append(135)
|
||||||
def_op('LOAD_DEREF', 136)
|
def_op('LOAD_DEREF', 136)
|
||||||
|
|
|
@ -649,50 +649,48 @@ expected_jumpy_line = 1
|
||||||
|
|
||||||
Instruction = dis.Instruction
|
Instruction = dis.Instruction
|
||||||
expected_opinfo_outer = [
|
expected_opinfo_outer = [
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=3, argrepr='3', offset=0, starts_line=2, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval=(3, 4), argrepr='(3, 4)', offset=0, starts_line=2, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=2, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=0, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=0, argval='a', argrepr='a', offset=4, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=1, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=1, argval='b', argrepr='b', offset=6, starts_line=None, is_jump_target=False),
|
Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=6, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=8, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_f, argrepr=repr(code_object_f), offset=8, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_f, argrepr=repr(code_object_f), offset=10, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f', argrepr="'outer.<locals>.f'", offset=10, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f', argrepr="'outer.<locals>.f'", offset=12, starts_line=None, is_jump_target=False),
|
Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='', offset=12, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='MAKE_CLOSURE', opcode=134, arg=2, argval=2, argrepr='', offset=14, starts_line=None, is_jump_target=False),
|
Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=14, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=16, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=16, starts_line=7, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=18, starts_line=7, is_jump_target=False),
|
Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='a', argrepr='a', offset=18, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='a', argrepr='a', offset=20, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_DEREF', opcode=136, arg=1, argval='b', argrepr='b', offset=20, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_DEREF', opcode=136, arg=1, argval='b', argrepr='b', offset=22, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval='', argrepr="''", offset=22, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval='', argrepr="''", offset=24, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval=1, argrepr='1', offset=24, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval=1, argrepr='1', offset=26, starts_line=None, is_jump_target=False),
|
Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=26, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=28, starts_line=None, is_jump_target=False),
|
Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=28, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=30, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval='Hello world!', argrepr="'Hello world!'", offset=30, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval='Hello world!', argrepr="'Hello world!'", offset=32, starts_line=None, is_jump_target=False),
|
Instruction(opname='CALL_FUNCTION', opcode=131, arg=7, argval=7, argrepr='7 positional, 0 keyword pair', offset=32, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=7, argval=7, argrepr='7 positional, 0 keyword pair', offset=34, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=34, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=36, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=36, starts_line=8, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=38, starts_line=8, is_jump_target=False),
|
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=38, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=40, starts_line=None, is_jump_target=False),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
expected_opinfo_f = [
|
expected_opinfo_f = [
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=5, argrepr='5', offset=0, starts_line=3, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=(5, 6), argrepr='(5, 6)', offset=0, starts_line=3, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=6, argrepr='6', offset=2, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=2, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=2, argval='a', argrepr='a', offset=4, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=3, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=3, argval='b', argrepr='b', offset=6, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=0, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=0, argval='c', argrepr='c', offset=8, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=1, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=1, argval='d', argrepr='d', offset=10, starts_line=None, is_jump_target=False),
|
Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=10, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=12, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_inner, argrepr=repr(code_object_inner), offset=12, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_inner, argrepr=repr(code_object_inner), offset=14, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f.<locals>.inner', argrepr="'outer.<locals>.f.<locals>.inner'", offset=14, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f.<locals>.inner', argrepr="'outer.<locals>.f.<locals>.inner'", offset=16, starts_line=None, is_jump_target=False),
|
Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='', offset=16, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='MAKE_CLOSURE', opcode=134, arg=2, argval=2, argrepr='', offset=18, starts_line=None, is_jump_target=False),
|
Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=18, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=20, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=20, starts_line=5, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=22, starts_line=5, is_jump_target=False),
|
Instruction(opname='LOAD_DEREF', opcode=136, arg=2, argval='a', argrepr='a', offset=22, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_DEREF', opcode=136, arg=2, argval='a', argrepr='a', offset=24, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='b', argrepr='b', offset=24, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='b', argrepr='b', offset=26, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='c', argrepr='c', offset=26, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='c', argrepr='c', offset=28, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_DEREF', opcode=136, arg=1, argval='d', argrepr='d', offset=28, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_DEREF', opcode=136, arg=1, argval='d', argrepr='d', offset=30, starts_line=None, is_jump_target=False),
|
Instruction(opname='CALL_FUNCTION', opcode=131, arg=4, argval=4, argrepr='4 positional, 0 keyword pair', offset=30, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=4, argval=4, argrepr='4 positional, 0 keyword pair', offset=32, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=32, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=34, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=34, starts_line=6, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=36, starts_line=6, is_jump_target=False),
|
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=36, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=38, starts_line=None, is_jump_target=False),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
expected_opinfo_inner = [
|
expected_opinfo_inner = [
|
||||||
|
|
|
@ -345,7 +345,7 @@ class GrammarTests(unittest.TestCase):
|
||||||
def f(x) -> list: pass
|
def f(x) -> list: pass
|
||||||
self.assertEqual(f.__annotations__, {'return': list})
|
self.assertEqual(f.__annotations__, {'return': list})
|
||||||
|
|
||||||
# test MAKE_CLOSURE with a variety of oparg's
|
# test closures with a variety of opargs
|
||||||
closure = 1
|
closure = 1
|
||||||
def f(): return closure
|
def f(): return closure
|
||||||
def f(x=1): return closure
|
def f(x=1): return closure
|
||||||
|
|
|
@ -10,6 +10,9 @@ What's New in Python 3.6.0 alpha 2
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #27095: Simplified MAKE_FUNCTION and removed MAKE_CLOSURE opcodes.
|
||||||
|
Patch by Demur Rumed.
|
||||||
|
|
||||||
- Issue #27190: Raise NotSupportedError if sqlite3 is older than 3.3.1.
|
- Issue #27190: Raise NotSupportedError if sqlite3 is older than 3.3.1.
|
||||||
Patch by Dave Sawyer.
|
Patch by Dave Sawyer.
|
||||||
|
|
||||||
|
|
124
Python/ceval.c
124
Python/ceval.c
|
@ -3325,116 +3325,36 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
TARGET(MAKE_CLOSURE)
|
|
||||||
TARGET(MAKE_FUNCTION) {
|
TARGET(MAKE_FUNCTION) {
|
||||||
int posdefaults = oparg & 0xff;
|
PyObject *qualname = POP();
|
||||||
int kwdefaults = (oparg>>8) & 0xff;
|
PyObject *codeobj = POP();
|
||||||
int num_annotations = (oparg >> 16) & 0x7fff;
|
PyFunctionObject *func = (PyFunctionObject *)
|
||||||
|
PyFunction_NewWithQualName(codeobj, f->f_globals, qualname);
|
||||||
|
|
||||||
PyObject *qualname = POP(); /* qualname */
|
Py_DECREF(codeobj);
|
||||||
PyObject *code = POP(); /* code object */
|
|
||||||
PyObject *func = PyFunction_NewWithQualName(code, f->f_globals, qualname);
|
|
||||||
Py_DECREF(code);
|
|
||||||
Py_DECREF(qualname);
|
Py_DECREF(qualname);
|
||||||
|
if (func == NULL) {
|
||||||
if (func == NULL)
|
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (opcode == MAKE_CLOSURE) {
|
|
||||||
PyObject *closure = POP();
|
|
||||||
if (PyFunction_SetClosure(func, closure) != 0) {
|
|
||||||
/* Can't happen unless bytecode is corrupt. */
|
|
||||||
Py_DECREF(func);
|
|
||||||
Py_DECREF(closure);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
Py_DECREF(closure);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_annotations > 0) {
|
if (oparg & 0x08) {
|
||||||
Py_ssize_t name_ix;
|
assert(PyTuple_CheckExact(TOP()));
|
||||||
PyObject *names = POP(); /* names of args with annotations */
|
func ->func_closure = POP();
|
||||||
PyObject *anns = PyDict_New();
|
}
|
||||||
if (anns == NULL) {
|
if (oparg & 0x04) {
|
||||||
Py_DECREF(func);
|
assert(PyDict_CheckExact(TOP()));
|
||||||
Py_DECREF(names);
|
func->func_annotations = POP();
|
||||||
goto error;
|
}
|
||||||
}
|
if (oparg & 0x02) {
|
||||||
name_ix = PyTuple_Size(names);
|
assert(PyDict_CheckExact(TOP()));
|
||||||
assert(num_annotations == name_ix+1);
|
func->func_kwdefaults = POP();
|
||||||
while (name_ix > 0) {
|
}
|
||||||
PyObject *name, *value;
|
if (oparg & 0x01) {
|
||||||
int err;
|
assert(PyTuple_CheckExact(TOP()));
|
||||||
--name_ix;
|
func->func_defaults = POP();
|
||||||
name = PyTuple_GET_ITEM(names, name_ix);
|
|
||||||
value = POP();
|
|
||||||
err = PyDict_SetItem(anns, name, value);
|
|
||||||
Py_DECREF(value);
|
|
||||||
if (err != 0) {
|
|
||||||
Py_DECREF(anns);
|
|
||||||
Py_DECREF(func);
|
|
||||||
Py_DECREF(names);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Py_DECREF(names);
|
|
||||||
|
|
||||||
if (PyFunction_SetAnnotations(func, anns) != 0) {
|
|
||||||
/* Can't happen unless
|
|
||||||
PyFunction_SetAnnotations changes. */
|
|
||||||
Py_DECREF(anns);
|
|
||||||
Py_DECREF(func);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
Py_DECREF(anns);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX Maybe this should be a separate opcode? */
|
PUSH((PyObject *)func);
|
||||||
if (kwdefaults > 0) {
|
|
||||||
PyObject *defs = PyDict_New();
|
|
||||||
if (defs == NULL) {
|
|
||||||
Py_DECREF(func);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
while (--kwdefaults >= 0) {
|
|
||||||
PyObject *v = POP(); /* default value */
|
|
||||||
PyObject *key = POP(); /* kw only arg name */
|
|
||||||
int err = PyDict_SetItem(defs, key, v);
|
|
||||||
Py_DECREF(v);
|
|
||||||
Py_DECREF(key);
|
|
||||||
if (err != 0) {
|
|
||||||
Py_DECREF(defs);
|
|
||||||
Py_DECREF(func);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (PyFunction_SetKwDefaults(func, defs) != 0) {
|
|
||||||
/* Can't happen unless
|
|
||||||
PyFunction_SetKwDefaults changes. */
|
|
||||||
Py_DECREF(func);
|
|
||||||
Py_DECREF(defs);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
Py_DECREF(defs);
|
|
||||||
}
|
|
||||||
if (posdefaults > 0) {
|
|
||||||
PyObject *defs = PyTuple_New(posdefaults);
|
|
||||||
if (defs == NULL) {
|
|
||||||
Py_DECREF(func);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
while (--posdefaults >= 0)
|
|
||||||
PyTuple_SET_ITEM(defs, posdefaults, POP());
|
|
||||||
if (PyFunction_SetDefaults(func, defs) != 0) {
|
|
||||||
/* Can't happen unless
|
|
||||||
PyFunction_SetDefaults changes. */
|
|
||||||
Py_DECREF(defs);
|
|
||||||
Py_DECREF(func);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
Py_DECREF(defs);
|
|
||||||
}
|
|
||||||
PUSH(func);
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
253
Python/compile.c
253
Python/compile.c
|
@ -1030,11 +1030,10 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)
|
||||||
return -NARGS(oparg)-1;
|
return -NARGS(oparg)-1;
|
||||||
case CALL_FUNCTION_VAR_KW:
|
case CALL_FUNCTION_VAR_KW:
|
||||||
return -NARGS(oparg)-2;
|
return -NARGS(oparg)-2;
|
||||||
case MAKE_FUNCTION:
|
|
||||||
return -1 -NARGS(oparg) - ((oparg >> 16) & 0xffff);
|
|
||||||
case MAKE_CLOSURE:
|
|
||||||
return -2 - NARGS(oparg) - ((oparg >> 16) & 0xffff);
|
|
||||||
#undef NARGS
|
#undef NARGS
|
||||||
|
case MAKE_FUNCTION:
|
||||||
|
return -1 - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0) -
|
||||||
|
((oparg & 0x04) != 0) - ((oparg & 0x08) != 0);
|
||||||
case BUILD_SLICE:
|
case BUILD_SLICE:
|
||||||
if (oparg == 3)
|
if (oparg == 3)
|
||||||
return -2;
|
return -2;
|
||||||
|
@ -1472,53 +1471,50 @@ compiler_lookup_arg(PyObject *dict, PyObject *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t args, PyObject *qualname)
|
compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, PyObject *qualname)
|
||||||
{
|
{
|
||||||
Py_ssize_t i, free = PyCode_GetNumFree(co);
|
Py_ssize_t i, free = PyCode_GetNumFree(co);
|
||||||
if (qualname == NULL)
|
if (qualname == NULL)
|
||||||
qualname = co->co_name;
|
qualname = co->co_name;
|
||||||
|
|
||||||
if (free == 0) {
|
if (free) {
|
||||||
ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts);
|
for (i = 0; i < free; ++i) {
|
||||||
ADDOP_O(c, LOAD_CONST, qualname, consts);
|
/* Bypass com_addop_varname because it will generate
|
||||||
ADDOP_I(c, MAKE_FUNCTION, args);
|
LOAD_DEREF but LOAD_CLOSURE is needed.
|
||||||
return 1;
|
*/
|
||||||
}
|
PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i);
|
||||||
for (i = 0; i < free; ++i) {
|
int arg, reftype;
|
||||||
/* Bypass com_addop_varname because it will generate
|
|
||||||
LOAD_DEREF but LOAD_CLOSURE is needed.
|
|
||||||
*/
|
|
||||||
PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i);
|
|
||||||
int arg, reftype;
|
|
||||||
|
|
||||||
/* Special case: If a class contains a method with a
|
/* Special case: If a class contains a method with a
|
||||||
free variable that has the same name as a method,
|
free variable that has the same name as a method,
|
||||||
the name will be considered free *and* local in the
|
the name will be considered free *and* local in the
|
||||||
class. It should be handled by the closure, as
|
class. It should be handled by the closure, as
|
||||||
well as by the normal name loookup logic.
|
well as by the normal name loookup logic.
|
||||||
*/
|
*/
|
||||||
reftype = get_ref_type(c, name);
|
reftype = get_ref_type(c, name);
|
||||||
if (reftype == CELL)
|
if (reftype == CELL)
|
||||||
arg = compiler_lookup_arg(c->u->u_cellvars, name);
|
arg = compiler_lookup_arg(c->u->u_cellvars, name);
|
||||||
else /* (reftype == FREE) */
|
else /* (reftype == FREE) */
|
||||||
arg = compiler_lookup_arg(c->u->u_freevars, name);
|
arg = compiler_lookup_arg(c->u->u_freevars, name);
|
||||||
if (arg == -1) {
|
if (arg == -1) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"lookup %s in %s %d %d\n"
|
"lookup %s in %s %d %d\n"
|
||||||
"freevars of %s: %s\n",
|
"freevars of %s: %s\n",
|
||||||
PyUnicode_AsUTF8(PyObject_Repr(name)),
|
PyUnicode_AsUTF8(PyObject_Repr(name)),
|
||||||
PyUnicode_AsUTF8(c->u->u_name),
|
PyUnicode_AsUTF8(c->u->u_name),
|
||||||
reftype, arg,
|
reftype, arg,
|
||||||
PyUnicode_AsUTF8(co->co_name),
|
PyUnicode_AsUTF8(co->co_name),
|
||||||
PyUnicode_AsUTF8(PyObject_Repr(co->co_freevars)));
|
PyUnicode_AsUTF8(PyObject_Repr(co->co_freevars)));
|
||||||
Py_FatalError("compiler_make_closure()");
|
Py_FatalError("compiler_make_closure()");
|
||||||
|
}
|
||||||
|
ADDOP_I(c, LOAD_CLOSURE, arg);
|
||||||
}
|
}
|
||||||
ADDOP_I(c, LOAD_CLOSURE, arg);
|
flags |= 0x08;
|
||||||
|
ADDOP_I(c, BUILD_TUPLE, free);
|
||||||
}
|
}
|
||||||
ADDOP_I(c, BUILD_TUPLE, free);
|
|
||||||
ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts);
|
ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts);
|
||||||
ADDOP_O(c, LOAD_CONST, qualname, consts);
|
ADDOP_O(c, LOAD_CONST, qualname, consts);
|
||||||
ADDOP_I(c, MAKE_CLOSURE, args);
|
ADDOP_I(c, MAKE_FUNCTION, flags);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1536,27 +1532,59 @@ compiler_decorators(struct compiler *c, asdl_seq* decos)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static Py_ssize_t
|
||||||
compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs,
|
compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs,
|
||||||
asdl_seq *kw_defaults)
|
asdl_seq *kw_defaults)
|
||||||
{
|
{
|
||||||
int i, default_count = 0;
|
int i;
|
||||||
|
PyObject *keys = NULL;
|
||||||
|
|
||||||
for (i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
|
for (i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
|
||||||
arg_ty arg = asdl_seq_GET(kwonlyargs, i);
|
arg_ty arg = asdl_seq_GET(kwonlyargs, i);
|
||||||
expr_ty default_ = asdl_seq_GET(kw_defaults, i);
|
expr_ty default_ = asdl_seq_GET(kw_defaults, i);
|
||||||
if (default_) {
|
if (default_) {
|
||||||
PyObject *mangled = _Py_Mangle(c->u->u_private, arg->arg);
|
PyObject *mangled = _Py_Mangle(c->u->u_private, arg->arg);
|
||||||
if (!mangled)
|
if (!mangled) {
|
||||||
return -1;
|
goto error;
|
||||||
ADDOP_O(c, LOAD_CONST, mangled, consts);
|
}
|
||||||
Py_DECREF(mangled);
|
if (keys == NULL) {
|
||||||
if (!compiler_visit_expr(c, default_)) {
|
keys = PyList_New(1);
|
||||||
return -1;
|
if (keys == NULL) {
|
||||||
|
Py_DECREF(mangled);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
PyList_SET_ITEM(keys, 0, mangled);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int res = PyList_Append(keys, mangled);
|
||||||
|
Py_DECREF(mangled);
|
||||||
|
if (res == -1) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!compiler_visit_expr(c, default_)) {
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
default_count++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return default_count;
|
if (keys != NULL) {
|
||||||
|
Py_ssize_t default_count = PyList_GET_SIZE(keys);
|
||||||
|
PyObject *keys_tuple = PyList_AsTuple(keys);
|
||||||
|
Py_DECREF(keys);
|
||||||
|
if (keys_tuple == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ADDOP_N(c, LOAD_CONST, keys_tuple, consts);
|
||||||
|
ADDOP_I(c, BUILD_CONST_KEY_MAP, default_count);
|
||||||
|
return default_count;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
Py_XDECREF(keys);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1595,15 +1623,14 @@ compiler_visit_argannotations(struct compiler *c, asdl_seq* args,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static Py_ssize_t
|
||||||
compiler_visit_annotations(struct compiler *c, arguments_ty args,
|
compiler_visit_annotations(struct compiler *c, arguments_ty args,
|
||||||
expr_ty returns)
|
expr_ty returns)
|
||||||
{
|
{
|
||||||
/* Push arg annotations and a list of the argument names. Return the #
|
/* Push arg annotation dict. Return # of items pushed.
|
||||||
of items pushed. The expressions are evaluated out-of-order wrt the
|
The expressions are evaluated out-of-order wrt the source code.
|
||||||
source code.
|
|
||||||
|
|
||||||
More than 2^16-1 annotations is a SyntaxError. Returns -1 on error.
|
Returns -1 on error.
|
||||||
*/
|
*/
|
||||||
static identifier return_str;
|
static identifier return_str;
|
||||||
PyObject *names;
|
PyObject *names;
|
||||||
|
@ -1635,38 +1662,47 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args,
|
||||||
}
|
}
|
||||||
|
|
||||||
len = PyList_GET_SIZE(names);
|
len = PyList_GET_SIZE(names);
|
||||||
if (len > 65534) {
|
|
||||||
/* len must fit in 16 bits, and len is incremented below */
|
|
||||||
PyErr_SetString(PyExc_SyntaxError,
|
|
||||||
"too many annotations");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (len) {
|
if (len) {
|
||||||
/* convert names to a tuple and place on stack */
|
PyObject *keytuple = PyList_AsTuple(names);
|
||||||
PyObject *elt;
|
Py_DECREF(names);
|
||||||
Py_ssize_t i;
|
if (keytuple == NULL) {
|
||||||
PyObject *s = PyTuple_New(len);
|
return -1;
|
||||||
if (!s)
|
|
||||||
goto error;
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
elt = PyList_GET_ITEM(names, i);
|
|
||||||
Py_INCREF(elt);
|
|
||||||
PyTuple_SET_ITEM(s, i, elt);
|
|
||||||
}
|
}
|
||||||
ADDOP_O(c, LOAD_CONST, s, consts);
|
ADDOP_N(c, LOAD_CONST, keytuple, consts);
|
||||||
Py_DECREF(s);
|
ADDOP_I(c, BUILD_CONST_KEY_MAP, len);
|
||||||
len++; /* include the just-pushed tuple */
|
|
||||||
}
|
}
|
||||||
Py_DECREF(names);
|
else {
|
||||||
|
Py_DECREF(names);
|
||||||
/* We just checked that len <= 65535, see above */
|
}
|
||||||
return Py_SAFE_DOWNCAST(len, Py_ssize_t, int);
|
return len;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
Py_DECREF(names);
|
Py_DECREF(names);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Py_ssize_t
|
||||||
|
compiler_default_arguments(struct compiler *c, arguments_ty args)
|
||||||
|
{
|
||||||
|
Py_ssize_t funcflags = 0;
|
||||||
|
if (args->defaults && asdl_seq_LEN(args->defaults) > 0) {
|
||||||
|
VISIT_SEQ(c, expr, args->defaults);
|
||||||
|
ADDOP_I(c, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
|
||||||
|
funcflags |= 0x01;
|
||||||
|
}
|
||||||
|
if (args->kwonlyargs) {
|
||||||
|
Py_ssize_t res = compiler_visit_kwonlydefaults(c, args->kwonlyargs,
|
||||||
|
args->kw_defaults);
|
||||||
|
if (res < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (res > 0) {
|
||||||
|
funcflags |= 0x02;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return funcflags;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compiler_function(struct compiler *c, stmt_ty s, int is_async)
|
compiler_function(struct compiler *c, stmt_ty s, int is_async)
|
||||||
{
|
{
|
||||||
|
@ -1678,12 +1714,11 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
|
||||||
asdl_seq* decos;
|
asdl_seq* decos;
|
||||||
asdl_seq *body;
|
asdl_seq *body;
|
||||||
stmt_ty st;
|
stmt_ty st;
|
||||||
Py_ssize_t i, n, arglength;
|
Py_ssize_t i, n, funcflags;
|
||||||
int docstring, kw_default_count = 0;
|
int docstring;
|
||||||
int num_annotations;
|
int num_annotations;
|
||||||
int scope_type;
|
int scope_type;
|
||||||
|
|
||||||
|
|
||||||
if (is_async) {
|
if (is_async) {
|
||||||
assert(s->kind == AsyncFunctionDef_kind);
|
assert(s->kind == AsyncFunctionDef_kind);
|
||||||
|
|
||||||
|
@ -1708,24 +1743,23 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
|
||||||
|
|
||||||
if (!compiler_decorators(c, decos))
|
if (!compiler_decorators(c, decos))
|
||||||
return 0;
|
return 0;
|
||||||
if (args->defaults)
|
|
||||||
VISIT_SEQ(c, expr, args->defaults);
|
|
||||||
if (args->kwonlyargs) {
|
|
||||||
int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs,
|
|
||||||
args->kw_defaults);
|
|
||||||
if (res < 0)
|
|
||||||
return 0;
|
|
||||||
kw_default_count = res;
|
|
||||||
}
|
|
||||||
num_annotations = compiler_visit_annotations(c, args, returns);
|
|
||||||
if (num_annotations < 0)
|
|
||||||
return 0;
|
|
||||||
assert((num_annotations & 0xFFFF) == num_annotations);
|
|
||||||
|
|
||||||
if (!compiler_enter_scope(c, name,
|
funcflags = compiler_default_arguments(c, args);
|
||||||
scope_type, (void *)s,
|
if (funcflags == -1) {
|
||||||
s->lineno))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_annotations = compiler_visit_annotations(c, args, returns);
|
||||||
|
if (num_annotations < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (num_annotations > 0) {
|
||||||
|
funcflags |= 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!compiler_enter_scope(c, name, scope_type, (void *)s, s->lineno)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
st = (stmt_ty)asdl_seq_GET(body, 0);
|
st = (stmt_ty)asdl_seq_GET(body, 0);
|
||||||
docstring = compiler_isdocstring(st);
|
docstring = compiler_isdocstring(st);
|
||||||
|
@ -1758,12 +1792,9 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
arglength = asdl_seq_LEN(args->defaults);
|
|
||||||
arglength |= kw_default_count << 8;
|
|
||||||
arglength |= num_annotations << 16;
|
|
||||||
if (is_async)
|
if (is_async)
|
||||||
co->co_flags |= CO_COROUTINE;
|
co->co_flags |= CO_COROUTINE;
|
||||||
compiler_make_closure(c, co, arglength, qualname);
|
compiler_make_closure(c, co, funcflags, qualname);
|
||||||
Py_DECREF(qualname);
|
Py_DECREF(qualname);
|
||||||
Py_DECREF(co);
|
Py_DECREF(co);
|
||||||
|
|
||||||
|
@ -1923,8 +1954,7 @@ compiler_lambda(struct compiler *c, expr_ty e)
|
||||||
PyCodeObject *co;
|
PyCodeObject *co;
|
||||||
PyObject *qualname;
|
PyObject *qualname;
|
||||||
static identifier name;
|
static identifier name;
|
||||||
int kw_default_count = 0;
|
Py_ssize_t funcflags;
|
||||||
Py_ssize_t arglength;
|
|
||||||
arguments_ty args = e->v.Lambda.args;
|
arguments_ty args = e->v.Lambda.args;
|
||||||
assert(e->kind == Lambda_kind);
|
assert(e->kind == Lambda_kind);
|
||||||
|
|
||||||
|
@ -1934,14 +1964,11 @@ compiler_lambda(struct compiler *c, expr_ty e)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args->defaults)
|
funcflags = compiler_default_arguments(c, args);
|
||||||
VISIT_SEQ(c, expr, args->defaults);
|
if (funcflags == -1) {
|
||||||
if (args->kwonlyargs) {
|
return 0;
|
||||||
int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs,
|
|
||||||
args->kw_defaults);
|
|
||||||
if (res < 0) return 0;
|
|
||||||
kw_default_count = res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!compiler_enter_scope(c, name, COMPILER_SCOPE_LAMBDA,
|
if (!compiler_enter_scope(c, name, COMPILER_SCOPE_LAMBDA,
|
||||||
(void *)e, e->lineno))
|
(void *)e, e->lineno))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1967,9 +1994,7 @@ compiler_lambda(struct compiler *c, expr_ty e)
|
||||||
if (co == NULL)
|
if (co == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
arglength = asdl_seq_LEN(args->defaults);
|
compiler_make_closure(c, co, funcflags, qualname);
|
||||||
arglength |= kw_default_count << 8;
|
|
||||||
compiler_make_closure(c, co, arglength, qualname);
|
|
||||||
Py_DECREF(qualname);
|
Py_DECREF(qualname);
|
||||||
Py_DECREF(co);
|
Py_DECREF(co);
|
||||||
|
|
||||||
|
|
3312
Python/importlib.h
3312
Python/importlib.h
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -133,7 +133,7 @@ static void *opcode_targets[256] = {
|
||||||
&&TARGET_CALL_FUNCTION,
|
&&TARGET_CALL_FUNCTION,
|
||||||
&&TARGET_MAKE_FUNCTION,
|
&&TARGET_MAKE_FUNCTION,
|
||||||
&&TARGET_BUILD_SLICE,
|
&&TARGET_BUILD_SLICE,
|
||||||
&&TARGET_MAKE_CLOSURE,
|
&&_unknown_opcode,
|
||||||
&&TARGET_LOAD_CLOSURE,
|
&&TARGET_LOAD_CLOSURE,
|
||||||
&&TARGET_LOAD_DEREF,
|
&&TARGET_LOAD_DEREF,
|
||||||
&&TARGET_STORE_DEREF,
|
&&TARGET_STORE_DEREF,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue