Jiwon Seo's PEP 3102 implementation.

See SF#1549670.
The compiler package has not yet been updated.
This commit is contained in:
Guido van Rossum 2006-10-27 23:31:49 +00:00
parent fc2a0a8e3c
commit 4f72a78684
31 changed files with 739 additions and 227 deletions

View file

@ -494,7 +494,7 @@ PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
(PyObject **)NULL, 0,
(PyObject **)NULL, 0,
(PyObject **)NULL, 0,
NULL);
NULL, NULL);
}
@ -2290,26 +2290,46 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
}
case MAKE_FUNCTION:
{
int posdefaults = oparg & 0xff;
int kwdefaults = (oparg>>8) & 0xff;
v = POP(); /* code object */
x = PyFunction_New(v, f->f_globals);
Py_DECREF(v);
/* XXX Maybe this should be a separate opcode? */
if (x != NULL && oparg > 0) {
v = PyTuple_New(oparg);
if (x != NULL && posdefaults > 0) {
v = PyTuple_New(posdefaults);
if (v == NULL) {
Py_DECREF(x);
x = NULL;
break;
}
while (--oparg >= 0) {
while (--posdefaults >= 0) {
w = POP();
PyTuple_SET_ITEM(v, oparg, w);
PyTuple_SET_ITEM(v, posdefaults, w);
}
err = PyFunction_SetDefaults(x, v);
Py_DECREF(v);
}
if (x != NULL && kwdefaults > 0) {
v = PyDict_New();
if (v == NULL) {
Py_DECREF(x);
x = NULL;
break;
}
while (--kwdefaults >= 0) {
w = POP(); /* default value */
u = POP(); /* kw only arg name */
PyDict_SetItem(v, u, w);
}
err = PyFunction_SetKwDefaults(x, v);
Py_DECREF(v);
}
PUSH(x);
break;
}
case MAKE_CLOSURE:
{
@ -2577,7 +2597,7 @@ fast_yield:
PyObject *
PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
PyObject **args, int argcount, PyObject **kws, int kwcount,
PyObject **defs, int defcount, PyObject *closure)
PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure)
{
register PyFrameObject *f;
register PyObject *retval = NULL;
@ -2601,6 +2621,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
freevars = f->f_localsplus + co->co_nlocals;
if (co->co_argcount > 0 ||
co->co_kwonlyargcount > 0 ||
co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) {
int i;
int n = argcount;
@ -2609,7 +2630,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
kwdict = PyDict_New();
if (kwdict == NULL)
goto fail;
i = co->co_argcount;
i = co->co_argcount + co->co_kwonlyargcount;
if (co->co_flags & CO_VARARGS)
i++;
SETLOCAL(i, kwdict);
@ -2618,7 +2639,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
if (!(co->co_flags & CO_VARARGS)) {
PyErr_Format(PyExc_TypeError,
"%.200s() takes %s %d "
"%sargument%s (%d given)",
"%spositional argument%s (%d given)",
PyString_AsString(co->co_name),
defcount ? "at most" : "exactly",
co->co_argcount,
@ -2638,7 +2659,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
u = PyTuple_New(argcount - n);
if (u == NULL)
goto fail;
SETLOCAL(co->co_argcount, u);
SETLOCAL(co->co_argcount + co->co_kwonlyargcount, u);
for (i = n; i < argcount; i++) {
x = args[i];
Py_INCREF(x);
@ -2656,7 +2677,9 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
goto fail;
}
/* XXX slow -- speed up using dictionary? */
for (j = 0; j < co->co_argcount; j++) {
for (j = 0;
j < co->co_argcount + co->co_kwonlyargcount;
j++) {
PyObject *nm = PyTuple_GET_ITEM(
co->co_varnames, j);
int cmp = PyObject_RichCompareBool(
@ -2669,7 +2692,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
/* Check errors from Compare */
if (PyErr_Occurred())
goto fail;
if (j >= co->co_argcount) {
if (j >= co->co_argcount + co->co_kwonlyargcount) {
if (kwdict == NULL) {
PyErr_Format(PyExc_TypeError,
"%.200s() got an unexpected "
@ -2694,13 +2717,38 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
SETLOCAL(j, value);
}
}
if (co->co_kwonlyargcount > 0) {
for (i = co->co_argcount;
i < co->co_argcount + co->co_kwonlyargcount;
i++) {
if (GETLOCAL(i) != NULL)
continue;
PyObject *name =
PyTuple_GET_ITEM(co->co_varnames, i);
PyObject *def = NULL;
if (kwdefs != NULL)
def = PyDict_GetItem(kwdefs, name);
if (def != NULL) {
Py_INCREF(def);
SETLOCAL(i, def);
continue;
}
PyErr_Format(PyExc_TypeError,
"%.200s() needs "
"keyword only argument %s",
PyString_AsString(co->co_name),
PyString_AsString(name));
goto fail;
}
}
if (argcount < co->co_argcount) {
int m = co->co_argcount - defcount;
for (i = argcount; i < m; i++) {
if (GETLOCAL(i) == NULL) {
PyErr_Format(PyExc_TypeError,
"%.200s() takes %s %d "
"%sargument%s (%d given)",
"%spositional argument%s "
"(%d given)",
PyString_AsString(co->co_name),
((co->co_flags & CO_VARARGS) ||
defcount) ? "at least"
@ -3565,12 +3613,14 @@ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)
PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
PyObject *globals = PyFunction_GET_GLOBALS(func);
PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
PyObject *kwdefs = PyFunction_GET_KW_DEFAULTS(func);
PyObject **d = NULL;
int nd = 0;
PCALL(PCALL_FUNCTION);
PCALL(PCALL_FAST_FUNCTION);
if (argdefs == NULL && co->co_argcount == n && nk==0 &&
if (argdefs == NULL && co->co_argcount == n &&
co->co_kwonlyargcount == 0 && nk==0 &&
co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) {
PyFrameObject *f;
PyObject *retval = NULL;
@ -3608,7 +3658,7 @@ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)
}
return PyEval_EvalCodeEx(co, globals,
(PyObject *)NULL, (*pp_stack)-n, na,
(*pp_stack)-2*nk, nk, d, nd,
(*pp_stack)-2*nk, nk, d, nd, kwdefs,
PyFunction_GET_CLOSURE(func));
}