[pypy-svn] r7804 - in pypy/trunk/src/pypy: interpreter translator translator/test

arigo at codespeak.net arigo at codespeak.net
Fri Dec 10 12:27:47 CET 2004


Author: arigo
Date: Fri Dec 10 12:27:46 2004
New Revision: 7804

Modified:
   pypy/trunk/src/pypy/interpreter/argument.py
   pypy/trunk/src/pypy/translator/genc.h
   pypy/trunk/src/pypy/translator/genc.py
   pypy/trunk/src/pypy/translator/test/snippet.py
   pypy/trunk/src/pypy/translator/test/test_ctrans.py
Log:
Implemented call_args() in genc.h.

Note that genc.py generates functions that never accept any keyword parameter,
even though call_args() can now send keyword parameters.



Modified: pypy/trunk/src/pypy/interpreter/argument.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/argument.py	(original)
+++ pypy/trunk/src/pypy/interpreter/argument.py	Fri Dec 10 12:27:46 2004
@@ -213,6 +213,8 @@
             w_star = None
         return Arguments(space, args_w, kwds_w, w_star)
     fromshape = staticmethod(fromshape)
+    # XXX the "shape" tuple should be considered as a black box from
+    #     other code, but translator/genc.h examines it.
 
 
 #

Modified: pypy/trunk/src/pypy/translator/genc.h
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.h	(original)
+++ pypy/trunk/src/pypy/translator/genc.h	Fri Dec 10 12:27:46 2004
@@ -144,7 +144,7 @@
 
 #define OP_SIMPLE_CALL(args,r,err) if (!(r=PyObject_CallFunctionObjArgs args)) \
 					FAIL(err)
-#define OP_CALL(x,y,z,r,err)      if (!(r=PyObject_Call(x,y,z)))     FAIL(err)
+#define OP_CALL_ARGS(args,r,err)   if (!(r=CallWithShape args))    FAIL(err)
 
 /* Needs to act like getattr(x, '__class__', type(x)) */
 #define OP_TYPE(x,r,err) { \
@@ -453,6 +453,73 @@
 	return NULL;
 }
 
+static PyObject* CallWithShape(PyObject* callable, PyObject* shape, ...)
+{
+	/* XXX the 'shape' argument is a tuple as specified by
+	   XXX pypy.interpreter.argument.fromshape().  This code should
+	   XXX we made independent on the format of the 'shape' later... */
+	PyObject* result = NULL;
+	PyObject* t = NULL;
+	PyObject* d = NULL;
+	PyObject* o;
+	PyObject* key;
+	PyObject* t2;
+	int i, nargs, nkwds, nvarargs, starflag;
+	va_list vargs;
+
+	if (!PyTuple_Check(shape) ||
+	    PyTuple_GET_SIZE(shape) != 3 ||
+	    !PyInt_Check(PyTuple_GET_ITEM(shape, 0)) ||
+	    !PyTuple_Check(PyTuple_GET_ITEM(shape, 1)) ||
+	    !PyInt_Check(PyTuple_GET_ITEM(shape, 2))) {
+		Py_FatalError("in genc.h: invalid 'shape' argument");
+	}
+	nargs = PyInt_AS_LONG(PyTuple_GET_ITEM(shape, 0));
+	nkwds = PyTuple_GET_SIZE(PyTuple_GET_ITEM(shape, 1));
+	starflag = PyInt_AS_LONG(PyTuple_GET_ITEM(shape, 2));
+
+	va_start(vargs, shape);
+	t = PyTuple_New(nargs);
+	if (t == NULL)
+		goto finally;
+	for (i = 0; i < nargs; i++) {
+		o = va_arg(vargs, PyObject *);
+		Py_INCREF(o);
+		PyTuple_SET_ITEM(t, i, o);
+	}
+	if (nkwds) {
+		d = PyDict_New();
+		if (d == NULL)
+			goto finally;
+		for (i = 0; i < nkwds; i++) {
+			o = va_arg(vargs, PyObject *);
+			key = PyTuple_GET_ITEM(PyTuple_GET_ITEM(shape, 1), i);
+			if (PyDict_SetItem(d, key, o) < 0)
+				goto finally;
+		}
+	}
+	if (starflag) {
+		o = va_arg(vargs, PyObject *);
+		o = PySequence_Tuple(o);
+		if (o == NULL)
+			goto finally;
+		t2 = PySequence_Concat(t, o);
+		Py_DECREF(o);
+		Py_DECREF(t);
+		t = t2;
+		if (t == NULL)
+			goto finally;
+	}
+	va_end(vargs);
+
+	result = PyObject_Call(callable, t, d);
+
+ finally:
+	Py_XDECREF(d);
+	Py_XDECREF(t);
+	return result;
+}
+
 
 #if defined(USE_CALL_TRACE)
 

Modified: pypy/trunk/src/pypy/translator/genc.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.py	(original)
+++ pypy/trunk/src/pypy/translator/genc.py	Fri Dec 10 12:27:46 2004
@@ -11,7 +11,7 @@
 from pypy.translator.simplify import remove_direct_loops
 from pypy.interpreter.pycode import CO_VARARGS
 from pypy.annotation import model as annmodel
-from types import FunctionType
+from types import FunctionType, CodeType
 
 from pypy.objspace.std.restricted_int import r_int, r_uint
 
@@ -354,6 +354,7 @@
         unicode:'&PyUnicode_Type',
         file:   '&PyFile_Type',
         type(None): 'Py_None->ob_type',
+        CodeType: '&PyCode_Type',
 
         r_int:  '&PyInt_Type',
         r_uint: '&PyInt_Type',
@@ -817,6 +818,9 @@
         args.append('NULL')
         return 'OP_SIMPLE_CALL((%s), %s, %s)' % (', '.join(args), r, err)
 
+    def OP_CALL_ARGS(self, args, r, err):
+        return 'OP_CALL_ARGS((%s), %s, %s)' % (', '.join(args), r, err)
+
 # ____________________________________________________________
 
 def cdecl(type, name):

Modified: pypy/trunk/src/pypy/translator/test/snippet.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/snippet.py	(original)
+++ pypy/trunk/src/pypy/translator/test/snippet.py	Fri Dec 10 12:27:46 2004
@@ -534,6 +534,12 @@
     return (default_and_star_args(111, u),
             default_and_star_args(-1000, -2000, -3000, -4000, -5000))
 
+def call_with_star(z):
+    return default_args(-20, *z)
+
+def call_with_keyword(z):
+    return default_args(-20, z=z)
+
 def powerset(setsize=int):
     """Powerset
 

Modified: pypy/trunk/src/pypy/translator/test/test_ctrans.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/test_ctrans.py	(original)
+++ pypy/trunk/src/pypy/translator/test/test_ctrans.py	Fri Dec 10 12:27:46 2004
@@ -140,6 +140,22 @@
         self.assertEquals(call_default_and_star_args(42),
                           (111+42+3+0, -1000-2000-3000+2))
 
+    def test_call_with_star(self):
+        call_with_star = self.build_cfunc(snippet.call_with_star)
+        self.assertEquals(call_with_star(()), -15L)
+        self.assertEquals(call_with_star((4,)), -13L)
+        self.assertEquals(call_with_star((4,7)), -9L)
+        self.assertEquals(call_with_star([]), -15L)
+        self.assertEquals(call_with_star([4]), -13L)
+        self.assertEquals(call_with_star([4,7]), -9L)
+        self.assertRaises(TypeError, call_with_star, (4,7,12))
+        self.assertRaises(TypeError, call_with_star, [4,7,12,63])
+        self.assertRaises(TypeError, call_with_star, 521)
+
+    def XXX_test_call_with_keyword(self):
+        call_with_keyword = self.build_cfunc(snippet.call_with_keyword)
+        self.assertEquals(call_with_keyword(100), 82)
+
     def test_finallys(self):
         finallys = self.build_cfunc(snippet.finallys)
         self.assertEquals(finallys(['hello']), 8)



More information about the Pypy-commit mailing list