[pypy-svn] r7884 - in pypy/trunk/src/pypy/translator: . test
arigo at codespeak.net
arigo at codespeak.net
Thu Dec 16 15:20:45 CET 2004
Author: arigo
Date: Thu Dec 16 15:20:45 2004
New Revision: 7884
Modified:
pypy/trunk/src/pypy/translator/genc.h
pypy/trunk/src/pypy/translator/genc.py
pypy/trunk/src/pypy/translator/test/test_ctrans.py
Log:
- supports keyword arguments in the functions created by genc.py.
- some clean-up of a workaround for a C preprocessor limitation.
Modified: pypy/trunk/src/pypy/translator/genc.h
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.h (original)
+++ pypy/trunk/src/pypy/translator/genc.h Thu Dec 16 15:20:45 2004
@@ -199,6 +199,11 @@
#if defined(USE_CALL_TRACE)
+#define TRACE_CALL __f, __tstate,
+#define TRACE_ARGS PyFrameObject *__f, PyThreadState *__tstate,
+#define TRACE_CALL_VOID __f, __tstate
+#define TRACE_ARGS_VOID PyFrameObject *__f, PyThreadState *__tstate
+
#define FAIL(err) { __f->f_lineno = __f->f_code->co_firstlineno = __LINE__; goto err; }
#define FUNCTION_HEAD(signature, self, args, names, file, line) \
@@ -215,6 +220,11 @@
#else /* !defined(USE_CALL_TRACE) */
+#define TRACE_CALL /* nothing */
+#define TRACE_ARGS /* nothing */
+#define TRACE_CALL_VOID /* nothing */
+#define TRACE_ARGS_VOID void
+
#define FAIL(err) { goto err; }
#define FUNCTION_HEAD(signature, self, args, names, file, line)
Modified: pypy/trunk/src/pypy/translator/genc.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.py (original)
+++ pypy/trunk/src/pypy/translator/genc.py Thu Dec 16 15:20:45 2004
@@ -38,8 +38,6 @@
class GenC:
MODNAMES = {}
- # XXX - I don't know how to make a macro do this.. so..
- USE_CALL_TRACE = True
def __init__(self, f, translator, modname=None, f2=None, f2name=None):
self.f = f
@@ -454,8 +452,6 @@
'entrypoint': self.nameof(self.translator.functions[0]),
}
# header
- if self.USE_CALL_TRACE:
- print >> f, '#define USE_CALL_TRACE'
print >> f, self.C_HEADER
# function implementations
@@ -510,9 +506,9 @@
self.gen_global_declarations()
# print header
- name = self.nameof(func)
- assert name.startswith('gfunc_')
- f_name = 'f_' + name[6:]
+ cname = self.nameof(func)
+ assert cname.startswith('gfunc_')
+ f_name = 'f_' + cname[6:]
# collect all the local variables
graph = self.translator.getflowgraph(func)
@@ -540,22 +536,31 @@
fast_set = dict(zip(fast_args, fast_args))
declare_fast_args = [('PyObject *' + a) for a in fast_args]
- if self.USE_CALL_TRACE:
- declare_fast_args[:0] = ['PyFrameObject *__f', 'PyThreadState *__tstate']
+ if declare_fast_args:
+ declare_fast_args = 'TRACE_ARGS ' + ', '.join(declare_fast_args)
+ else:
+ declare_fast_args = 'TRACE_ARGS_VOID'
+ fast_function_header = ('static PyObject *\n'
+ '%s(%s)' % (fast_name, declare_fast_args))
- print >> f, 'static PyObject *'
- print >> f, '%s(%s);' % (fast_name, ', '.join(declare_fast_args))
+ print >> f, fast_function_header + ';' # forward
print >> f
print >> f, 'static PyObject *'
- print >> f, '%s(PyObject* self, PyObject* args)' % (f_name,)
+ print >> f, '%s(PyObject* self, PyObject* args, PyObject* kwds)' % (
+ f_name,)
print >> f, '{'
print >> f, '\tFUNCTION_HEAD(%s, %s, args, %s, __FILE__, __LINE__ - 2)' % (
- c_string('%s(%s)' % (name, ', '.join(name_of_defaults))),
- name,
+ c_string('%s(%s)' % (cname, ', '.join(name_of_defaults))),
+ cname,
'(%s)' % (', '.join(map(c_string, name_of_defaults) + ['NULL']),),
)
+ kwlist = ['"%s"' % name for name in
+ func.func_code.co_varnames[:func.func_code.co_argcount]]
+ kwlist.append('0')
+ print >> f, '\tstatic char* kwlist[] = {%s};' % (', '.join(kwlist),)
+
if fast_args:
print >> f, '\tPyObject *%s;' % (', *'.join(fast_args))
print >> f
@@ -586,24 +591,27 @@
print >> f, '\t%s = %s;' % (
positional_args[min_number_of_args+i],
name_of_defaults[i])
- lst = ['args',
- '"%s"' % func.__name__,
- '%d' % min_number_of_args,
- '%d' % len(positional_args),
+ fmt = 'O'*min_number_of_args
+ if min_number_of_args < len(positional_args):
+ fmt += '|' + 'O'*(len(positional_args)-min_number_of_args)
+ lst = ['args', 'kwds',
+ '"%s:%s"' % (fmt, func.__name__),
+ 'kwlist',
]
lst += ['&' + a.name for a in positional_args]
- print >> f, '\tif (!PyArg_UnpackTuple(%s))' % ', '.join(lst),
+ print >> f, '\tif (!PyArg_ParseTupleAndKeywords(%s))' % ', '.join(lst),
print >> f, tail
call_fast_args = list(fast_args)
- if self.USE_CALL_TRACE:
- call_fast_args[:0] = ['__f', '__tstate']
- print >> f, '\treturn %s(%s);' % (fast_name, ', '.join(call_fast_args))
+ if call_fast_args:
+ call_fast_args = 'TRACE_CALL ' + ', '.join(call_fast_args)
+ else:
+ call_fast_args = 'TRACE_CALL_VOID'
+ print >> f, '\treturn %s(%s);' % (fast_name, call_fast_args)
print >> f, '}'
print >> f
- print >> f, 'static PyObject *'
- print >> f, '%s(%s)' % (fast_name, ', '.join(declare_fast_args))
+ print >> f, fast_function_header
print >> f, '{'
fast_locals = [arg for arg in localnames if arg not in fast_set]
@@ -630,8 +638,9 @@
print >> f, '}'
# print the PyMethodDef
- print >> f, 'static PyMethodDef ml_%s = { "%s", %s, METH_VARARGS };' % (
- name, func.__name__, f_name)
+ print >> f, ('static PyMethodDef ml_%s = {\n'
+ ' "%s", (PyCFunction)%s, METH_VARARGS|METH_KEYWORDS };' % (
+ cname, func.__name__, f_name))
print >> f
if not self.translator.frozen:
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 Thu Dec 16 15:20:45 2004
@@ -152,7 +152,7 @@
self.assertRaises(TypeError, call_with_star, [4,7,12,63])
self.assertRaises(TypeError, call_with_star, 521)
- def XXX_test_call_with_keyword(self):
+ def test_call_with_keyword(self):
call_with_keyword = self.build_cfunc(snippet.call_with_keyword)
self.assertEquals(call_with_keyword(100), 82)
More information about the Pypy-commit
mailing list