bpo-39320: Handle unpacking of *values in compiler (GH-17984)

* Add three new bytecodes: LIST_TO_TUPLE, LIST_EXTEND, SET_UPDATE. Use them to implement star unpacking expressions.

* Remove four bytecodes BUILD_LIST_UNPACK, BUILD_TUPLE_UNPACK, BUILD_SET_UNPACK and  BUILD_TUPLE_UNPACK_WITH_CALL opcodes as they are now unused.

* Update magic number and dis.rst for new bytecodes.
This commit is contained in:
Mark Shannon 2020-01-23 09:25:17 +00:00 committed by GitHub
parent f9e07e116c
commit 13bc13960c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 2349 additions and 2360 deletions

View file

@ -2621,46 +2621,46 @@ main_loop:
DISPATCH();
}
case TARGET(BUILD_TUPLE_UNPACK_WITH_CALL):
case TARGET(BUILD_TUPLE_UNPACK):
case TARGET(BUILD_LIST_UNPACK): {
int convert_to_tuple = opcode != BUILD_LIST_UNPACK;
Py_ssize_t i;
PyObject *sum = PyList_New(0);
PyObject *return_value;
if (sum == NULL)
case TARGET(LIST_TO_TUPLE): {
PyObject *list = POP();
PyObject *tuple = PyList_AsTuple(list);
Py_DECREF(list);
if (tuple == NULL) {
goto error;
}
PUSH(tuple);
DISPATCH();
}
for (i = oparg; i > 0; i--) {
PyObject *none_val;
none_val = _PyList_Extend((PyListObject *)sum, PEEK(i));
if (none_val == NULL) {
if (opcode == BUILD_TUPLE_UNPACK_WITH_CALL &&
_PyErr_ExceptionMatches(tstate, PyExc_TypeError))
{
check_args_iterable(tstate, PEEK(1 + oparg), PEEK(i));
}
Py_DECREF(sum);
goto error;
case TARGET(LIST_EXTEND): {
PyObject *iterable = POP();
PyObject *list = PEEK(oparg);
PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable);
if (none_val == NULL) {
if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) &&
(iterable->ob_type->tp_iter == NULL && !PySequence_Check(iterable)))
{
PyErr_Clear();
_PyErr_Format(tstate, PyExc_TypeError,
"Value after * must be an iterable, not %.200s",
Py_TYPE(iterable)->tp_name);
}
Py_DECREF(none_val);
Py_DECREF(iterable);
goto error;
}
Py_DECREF(none_val);
Py_DECREF(iterable);
DISPATCH();
}
if (convert_to_tuple) {
return_value = PyList_AsTuple(sum);
Py_DECREF(sum);
if (return_value == NULL)
goto error;
case TARGET(SET_UPDATE): {
PyObject *iterable = POP();
PyObject *set = PEEK(oparg);
int err = _PySet_Update(set, iterable);
Py_DECREF(iterable);
if (err < 0) {
goto error;
}
else {
return_value = sum;
}
while (oparg--)
Py_DECREF(POP());
PUSH(return_value);
DISPATCH();
}
@ -2685,25 +2685,6 @@ main_loop:
DISPATCH();
}
case TARGET(BUILD_SET_UNPACK): {
Py_ssize_t i;
PyObject *sum = PySet_New(NULL);
if (sum == NULL)
goto error;
for (i = oparg; i > 0; i--) {
if (_PySet_Update(sum, PEEK(i)) < 0) {
Py_DECREF(sum);
goto error;
}
}
while (oparg--)
Py_DECREF(POP());
PUSH(sum);
DISPATCH();
}
case TARGET(BUILD_MAP): {
Py_ssize_t i;
PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg);