summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2020-01-27 09:57:45 (GMT)
committerGitHub <noreply@github.com>2020-01-27 09:57:45 (GMT)
commit8a4cd700a7426341c2074a2b580306d2d60ec839 (patch)
tree64ff9fdc0361fe05e0ef5a2508e832a5de03b830 /Python/ceval.c
parent72b1004657e60c900e4cd031b2635b587f4b280e (diff)
downloadcpython-8a4cd700a7426341c2074a2b580306d2d60ec839.zip
cpython-8a4cd700a7426341c2074a2b580306d2d60ec839.tar.gz
cpython-8a4cd700a7426341c2074a2b580306d2d60ec839.tar.bz2
bpo-39320: Handle unpacking of **values in compiler (GH-18141)
* Add DICT_UPDATE and DICT_MERGE bytecodes. Use them for ** unpacking. * Remove BUILD_MAP_UNPACK and BUILD_MAP_UNPACK_WITH_CALL, as they are now unused. * Update magic number for ** unpacking opcodes. * Update dis.rst to incorporate new bytecodes. * Add blurb entry.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c55
1 files changed, 19 insertions, 36 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 528ad7f..673b401 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -2801,49 +2801,32 @@ main_loop:
DISPATCH();
}
- case TARGET(BUILD_MAP_UNPACK): {
- Py_ssize_t i;
- PyObject *sum = PyDict_New();
- if (sum == NULL)
- goto error;
-
- for (i = oparg; i > 0; i--) {
- PyObject *arg = PEEK(i);
- if (PyDict_Update(sum, arg) < 0) {
- if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
- _PyErr_Format(tstate, PyExc_TypeError,
- "'%.200s' object is not a mapping",
- arg->ob_type->tp_name);
- }
- Py_DECREF(sum);
- goto error;
+ case TARGET(DICT_UPDATE): {
+ PyObject *update = POP();
+ PyObject *dict = PEEK(oparg);
+ if (PyDict_Update(dict, update) < 0) {
+ if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "'%.200s' object is not a mapping",
+ update->ob_type->tp_name);
}
+ Py_DECREF(update);
+ goto error;
}
-
- while (oparg--)
- Py_DECREF(POP());
- PUSH(sum);
+ Py_DECREF(update);
DISPATCH();
}
- case TARGET(BUILD_MAP_UNPACK_WITH_CALL): {
- Py_ssize_t i;
- PyObject *sum = PyDict_New();
- if (sum == NULL)
- goto error;
+ case TARGET(DICT_MERGE): {
+ PyObject *update = POP();
+ PyObject *dict = PEEK(oparg);
- for (i = oparg; i > 0; i--) {
- PyObject *arg = PEEK(i);
- if (_PyDict_MergeEx(sum, arg, 2) < 0) {
- Py_DECREF(sum);
- format_kwargs_error(tstate, PEEK(2 + oparg), arg);
- goto error;
- }
+ if (_PyDict_MergeEx(dict, update, 2) < 0) {
+ format_kwargs_error(tstate, PEEK(2 + oparg), update);
+ Py_DECREF(update);
+ goto error;
}
-
- while (oparg--)
- Py_DECREF(POP());
- PUSH(sum);
+ Py_DECREF(update);
PREDICT(CALL_FUNCTION_EX);
DISPATCH();
}