summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c164
1 files changed, 159 insertions, 5 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 2f3d3ad..5ee9077 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -12,8 +12,10 @@
#include "Python.h"
#include "code.h"
+#include "dictobject.h"
#include "frameobject.h"
#include "opcode.h"
+#include "setobject.h"
#include "structmember.h"
#include <ctype.h>
@@ -2379,6 +2381,43 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
DISPATCH();
}
+ TARGET_WITH_IMPL(BUILD_TUPLE_UNPACK, _build_list_unpack)
+ TARGET(BUILD_LIST_UNPACK)
+ _build_list_unpack: {
+ int convert_to_tuple = opcode == BUILD_TUPLE_UNPACK;
+ int i;
+ PyObject *sum = PyList_New(0);
+ PyObject *return_value;
+ if (sum == NULL)
+ goto error;
+
+ for (i = oparg; i > 0; i--) {
+ PyObject *none_val;
+
+ none_val = _PyList_Extend((PyListObject *)sum, PEEK(i));
+ if (none_val == NULL) {
+ Py_DECREF(sum);
+ goto error;
+ }
+ Py_DECREF(none_val);
+ }
+
+ if (convert_to_tuple) {
+ return_value = PyList_AsTuple(sum);
+ Py_DECREF(sum);
+ if (return_value == NULL)
+ goto error;
+ }
+ else {
+ return_value = sum;
+ }
+
+ while (oparg--)
+ Py_DECREF(POP());
+ PUSH(return_value);
+ DISPATCH();
+ }
+
TARGET(BUILD_SET) {
PyObject *set = PySet_New(NULL);
int err = 0;
@@ -2398,14 +2437,127 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
DISPATCH();
}
+ TARGET(BUILD_SET_UNPACK) {
+ int 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();
+ }
+
TARGET(BUILD_MAP) {
PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg);
if (map == NULL)
goto error;
+ while (--oparg >= 0) {
+ int err;
+ PyObject *key = TOP();
+ PyObject *value = SECOND();
+ STACKADJ(-2);
+ err = PyDict_SetItem(map, key, value);
+ Py_DECREF(value);
+ Py_DECREF(key);
+ if (err != 0) {
+ Py_DECREF(map);
+ goto error;
+ }
+ }
PUSH(map);
DISPATCH();
}
+ TARGET_WITH_IMPL(BUILD_MAP_UNPACK_WITH_CALL, _build_map_unpack)
+ TARGET(BUILD_MAP_UNPACK)
+ _build_map_unpack: {
+ int with_call = opcode == BUILD_MAP_UNPACK_WITH_CALL;
+ int num_maps;
+ int function_location;
+ int i;
+ PyObject *sum = PyDict_New();
+ if (sum == NULL)
+ goto error;
+ if (with_call) {
+ num_maps = oparg & 0xff;
+ function_location = (oparg>>8) & 0xff;
+ }
+ else {
+ num_maps = oparg;
+ }
+
+ for (i = num_maps; i > 0; i--) {
+ PyObject *arg = PEEK(i);
+ if (with_call) {
+ PyObject *intersection = _PyDictView_Intersect(sum, arg);
+
+ if (intersection == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyObject *func = (
+ PEEK(function_location + num_maps));
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%.200s argument after ** "
+ "must be a mapping, not %.200s",
+ PyEval_GetFuncName(func),
+ PyEval_GetFuncDesc(func),
+ arg->ob_type->tp_name);
+ }
+ Py_DECREF(sum);
+ goto error;
+ }
+
+ if (PySet_GET_SIZE(intersection)) {
+ Py_ssize_t idx = 0;
+ PyObject *key;
+ PyObject *func = PEEK(function_location + num_maps);
+ Py_hash_t hash;
+ _PySet_NextEntry(intersection, &idx, &key, &hash);
+ if (!PyUnicode_Check(key)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%.200s keywords must be strings",
+ PyEval_GetFuncName(func),
+ PyEval_GetFuncDesc(func));
+ } else {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%.200s got multiple "
+ "values for keyword argument '%U'",
+ PyEval_GetFuncName(func),
+ PyEval_GetFuncDesc(func),
+ key);
+ }
+ Py_DECREF(intersection);
+ Py_DECREF(sum);
+ goto error;
+ }
+ Py_DECREF(intersection);
+ }
+
+ if (PyDict_Update(sum, arg) < 0) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Format(PyExc_TypeError,
+ "'%.200s' object is not a mapping",
+ arg->ob_type->tp_name);
+ }
+ Py_DECREF(sum);
+ goto error;
+ }
+ }
+
+ while (num_maps--)
+ Py_DECREF(POP());
+ PUSH(sum);
+ DISPATCH();
+ }
+
TARGET(STORE_MAP) {
PyObject *key = TOP();
PyObject *value = SECOND();
@@ -3050,6 +3202,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
goto dispatch_opcode;
}
+
#if USE_COMPUTED_GOTOS
_unknown_opcode:
#endif
@@ -4557,6 +4710,12 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
kwdict = d;
}
}
+ if (nk > 0) {
+ kwdict = update_keyword_args(kwdict, nk, pp_stack, func);
+ if (kwdict == NULL)
+ goto ext_call_fail;
+ }
+
if (flags & CALL_FLAG_VAR) {
stararg = EXT_POP(*pp_stack);
if (!PyTuple_Check(stararg)) {
@@ -4578,11 +4737,6 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
}
nstar = PyTuple_GET_SIZE(stararg);
}
- if (nk > 0) {
- kwdict = update_keyword_args(kwdict, nk, pp_stack, func);
- if (kwdict == NULL)
- goto ext_call_fail;
- }
callargs = update_star_args(na, nstar, stararg, pp_stack);
if (callargs == NULL)
goto ext_call_fail;