mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	Jiwon Seo's PEP 3102 implementation.
See SF#1549670. The compiler package has not yet been updated.
This commit is contained in:
		
							parent
							
								
									fc2a0a8e3c
								
							
						
					
					
						commit
						4f72a78684
					
				
					 31 changed files with 739 additions and 227 deletions
				
			
		| 
						 | 
				
			
			@ -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 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
 | 
			
		|||
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));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue