Commit 64204de0 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #27095: Simplified MAKE_FUNCTION and removed MAKE_CLOSURE opcodes.

Patch by Demur Rumed.
parent 5697c4b6
......@@ -937,27 +937,16 @@ All of the following opcodes use their arguments.
.. opcode:: MAKE_FUNCTION (argc)
Pushes a new function object on the stack. From bottom to top, the consumed
stack must consist of
* ``argc & 0xFF`` default argument objects in positional order
* ``(argc >> 8) & 0xFF`` pairs of name and default argument, with the name
just below the object on the stack, for keyword-only parameters
* ``(argc >> 16) & 0x7FFF`` parameter annotation objects
* a tuple listing the parameter names for the annotations (only if there are
ony annotation objects)
stack must consist of values if the argument carries a specified flag value
* ``0x01`` a tuple of default argument objects in positional order
* ``0x02`` a dictionary of keyword-only parameters' default values
* ``0x04`` an annotation dictionary
* ``0x08`` a tuple containing cells for free variables, making a closure
* the code associated with the function (at TOS1)
* 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)
.. index:: builtin: slice
......
......@@ -102,7 +102,6 @@ extern "C" {
#define CALL_FUNCTION 131
#define MAKE_FUNCTION 132
#define BUILD_SLICE 133
#define MAKE_CLOSURE 134
#define LOAD_CLOSURE 135
#define LOAD_DEREF 136
#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.6a0 3360 (add FORMAT_VALUE opcode #25483
# Python 3.6a0 3361 (lineno delta of code.co_lnotab becomes signed)
# Python 3.6a0 3370 (16 bit wordcode)
# Python 3.6a0 3371 (add BUILD_CONST_KEY_MAP opcode #27140)
# Python 3.6a1 3370 (16 bit wordcode)
# 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
# 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
# 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
_PYCACHE = '__pycache__'
......
......@@ -319,7 +319,7 @@ class GrammarTests(unittest.TestCase):
def f(x) -> list: pass
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
def f(): 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('CALL_FUNCTION', 131) # #args + (#kwargs << 8)
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('MAKE_CLOSURE', 134)
def_op('LOAD_CLOSURE', 135)
hasfree.append(135)
def_op('LOAD_DEREF', 136)
......
This diff is collapsed.
......@@ -345,7 +345,7 @@ class GrammarTests(unittest.TestCase):
def f(x) -> list: pass
self.assertEqual(f.__annotations__, {'return': list})
# test MAKE_CLOSURE with a variety of oparg's
# test closures with a variety of opargs
closure = 1
def f(): 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
-----------------
- 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.
Patch by Dave Sawyer.
......
......@@ -3325,116 +3325,36 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
DISPATCH();
}
TARGET(MAKE_CLOSURE)
TARGET(MAKE_FUNCTION) {
int posdefaults = oparg & 0xff;
int kwdefaults = (oparg>>8) & 0xff;
int num_annotations = (oparg >> 16) & 0x7fff;
PyObject *qualname = POP(); /* qualname */
PyObject *code = POP(); /* code object */
PyObject *func = PyFunction_NewWithQualName(code, f->f_globals, qualname);
Py_DECREF(code);
Py_DECREF(qualname);
PyObject *qualname = POP();
PyObject *codeobj = POP();
PyFunctionObject *func = (PyFunctionObject *)
PyFunction_NewWithQualName(codeobj, f->f_globals, qualname);
if (func == NULL)
Py_DECREF(codeobj);
Py_DECREF(qualname);
if (func == NULL) {
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) {
Py_ssize_t name_ix;
PyObject *names = POP(); /* names of args with annotations */
PyObject *anns = PyDict_New();
if (anns == NULL) {
Py_DECREF(func);
Py_DECREF(names);
goto error;
}
name_ix = PyTuple_Size(names);
assert(num_annotations == name_ix+1);
while (name_ix > 0) {
PyObject *name, *value;
int err;
--name_ix;
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);
if (oparg & 0x08) {
assert(PyTuple_CheckExact(TOP()));
func ->func_closure = POP();
}
/* XXX Maybe this should be a separate opcode? */
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 (oparg & 0x04) {
assert(PyDict_CheckExact(TOP()));
func->func_annotations = POP();
}
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);
if (oparg & 0x02) {
assert(PyDict_CheckExact(TOP()));
func->func_kwdefaults = POP();
}
if (oparg & 0x01) {
assert(PyTuple_CheckExact(TOP()));
func->func_defaults = POP();
}
PUSH(func);
PUSH((PyObject *)func);
DISPATCH();
}
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
......@@ -133,7 +133,7 @@ static void *opcode_targets[256] = {
&&TARGET_CALL_FUNCTION,
&&TARGET_MAKE_FUNCTION,
&&TARGET_BUILD_SLICE,
&&TARGET_MAKE_CLOSURE,
&&_unknown_opcode,
&&TARGET_LOAD_CLOSURE,
&&TARGET_LOAD_DEREF,
&&TARGET_STORE_DEREF,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment