[pypy-svn] r13380 - in pypy/dist/pypy/translator/c: . test

arigo at codespeak.net arigo at codespeak.net
Tue Jun 14 15:03:35 CEST 2005


Author: arigo
Date: Tue Jun 14 15:03:28 2005
New Revision: 13380

Added:
   pypy/dist/pypy/translator/c/external.py   (contents, props changed)
   pypy/dist/pypy/translator/c/g_exception.h   (contents, props changed)
   pypy/dist/pypy/translator/c/test/test_exception.py   (contents, props changed)
Modified:
   pypy/dist/pypy/translator/c/database.py
   pypy/dist/pypy/translator/c/funcgen.py
   pypy/dist/pypy/translator/c/g_include.h
   pypy/dist/pypy/translator/c/g_module.h
   pypy/dist/pypy/translator/c/g_support.h
   pypy/dist/pypy/translator/c/genc.py
   pypy/dist/pypy/translator/c/int_include.h
   pypy/dist/pypy/translator/c/ll_include.h
   pypy/dist/pypy/translator/c/node.py
   pypy/dist/pypy/translator/c/pyobj_include.h
   pypy/dist/pypy/translator/c/test/test_genc.py
   pypy/dist/pypy/translator/c/wrapper.py
Log:
Support for real RPython exceptions in genc.  Exceptions are regular RPython
instances, set in a pair of global variables (for now), rpython_exc_type and
rpython_exc_value.

Standard exceptions (ValueError, OverflowError, etc.) have no 'args' field;
the message is ignored right now.  Moreover, the part about exchanging these
exceptions with CPython exceptions at the correct point is quite messy, and
looses almost all information.  So if any rpython exception is raised by the
code and not caught, the module throws you a completely useless
"RPythonError".  Needs to be improved...



Modified: pypy/dist/pypy/translator/c/database.py
==============================================================================
--- pypy/dist/pypy/translator/c/database.py	(original)
+++ pypy/dist/pypy/translator/c/database.py	Tue Jun 14 15:03:28 2005
@@ -1,6 +1,7 @@
 from pypy.rpython.lltype import Primitive, Ptr, typeOf
 from pypy.rpython.lltype import Struct, Array, FuncType, PyObject, Void
-from pypy.rpython.lltype import ContainerType
+from pypy.rpython.lltype import ContainerType, pyobjectptr
+from pypy.rpython.rmodel import getfunctionptr
 from pypy.objspace.flow.model import Constant
 from pypy.translator.c.primitive import PrimitiveName, PrimitiveType
 from pypy.translator.c.primitive import PrimitiveErrorValue
@@ -14,6 +15,7 @@
 class LowLevelDatabase:
 
     def __init__(self, translator=None):
+        self.translator = translator
         self.structdefnodes = {}
         self.structdeflist = []
         self.containernodes = {}
@@ -144,3 +146,45 @@
         for node in self.containerlist:
             if node.globalcontainer:
                 yield node
+
+    def pre_include_code_lines(self):
+        # generate some #defines that go before the #include to control
+        # what g_exception.h does
+        if self.translator is not None and self.translator.rtyper is not None:
+            exceptiondata = self.translator.rtyper.getexceptiondata()
+
+            TYPE = exceptiondata.lltype_of_exception_type
+            assert isinstance(TYPE, Ptr)
+            typename = self.gettype(TYPE)
+            yield '#define RPYTHON_EXCEPTION_VTABLE %s' % cdecl(typename, '')
+
+            TYPE = exceptiondata.lltype_of_exception_value
+            assert isinstance(TYPE, Ptr)
+            typename = self.gettype(TYPE)
+            yield '#define RPYTHON_EXCEPTION        %s' % cdecl(typename, '')
+
+            fnptr = getfunctionptr(self.translator,
+                                   exceptiondata.ll_exception_match)
+            fnname = self.get(fnptr)
+            yield '#define RPYTHON_EXCEPTION_MATCH  %s' % (fnname,)
+
+            fnptr = getfunctionptr(self.translator,
+                                   exceptiondata.ll_type_of_exc_inst)
+            fnname = self.get(fnptr)
+            yield '#define RPYTHON_TYPE_OF_EXC_INST %s' % (fnname,)
+
+            fnptr = getfunctionptr(self.translator,
+                                   exceptiondata.ll_pyexcclass2exc)
+            fnname = self.get(fnptr)
+            yield '#define RPYTHON_PYEXCCLASS2EXC   %s' % (fnname,)
+
+            for pyexccls in [TypeError, OverflowError, ValueError,
+                             ZeroDivisionError, MemoryError]:
+                exc_llvalue = exceptiondata.ll_pyexcclass2exc(
+                    pyobjectptr(pyexccls))
+                # strange naming here because the macro name must be
+                # a substring of PyExc_%s
+                yield '#define Exc_%s\t%s' % (
+                    pyexccls.__name__, self.get(exc_llvalue))
+
+            self.complete()   # because of the get() and gettype() above

Added: pypy/dist/pypy/translator/c/external.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/c/external.py	Tue Jun 14 15:03:28 2005
@@ -0,0 +1,35 @@
+from __future__ import generators
+from pypy.rpython.lltype import typeOf, Void
+from pypy.translator.c.support import cdecl, ErrorValue, somelettersfrom
+
+
+class CExternalFunctionCodeGenerator:
+
+    def __init__(self, fnptr, db):
+        self.fnptr = fnptr
+        self.db = db
+        self.FUNCTYPE = typeOf(fnptr)
+        assert Void not in self.FUNCTYPE.ARGS
+        self.argtypenames = [db.gettype(T) for T in self.FUNCTYPE.ARGS]
+        self.resulttypename = db.gettype(self.FUNCTYPE.RESULT)
+
+    def argnames(self):
+        return ['%s%d' % (somelettersfrom(self.argtypenames[i]), i)
+                for i in range(len(self.argtypenames))]
+
+    def allconstantvalues(self):
+        return []
+
+    def cfunction_declarations(self):
+        if self.FUNCTYPE.RESULT != Void:
+            yield '%s;' % cdecl(self.resulttypename, 'result')
+
+    def cfunction_body(self):
+        call = '%s(%s)' % (self.fnptr._name, ', '.join(self.argnames()))
+        if self.FUNCTYPE.RESULT != Void:
+            yield 'result = %s;' % call
+            yield 'if (PyErr_Occurred()) ConvertExceptionFromCPython();'
+            yield 'return result;'
+        else:
+            yield '%s;' % call
+            yield 'if (PyErr_Occurred()) ConvertExceptionFromCPython();'

Modified: pypy/dist/pypy/translator/c/funcgen.py
==============================================================================
--- pypy/dist/pypy/translator/c/funcgen.py	(original)
+++ pypy/dist/pypy/translator/c/funcgen.py	Tue Jun 14 15:03:28 2005
@@ -2,7 +2,7 @@
 from pypy.translator.c.support import cdecl, ErrorValue
 from pypy.translator.c.support import llvalue_from_constant
 from pypy.objspace.flow.model import Variable, Constant, Block
-from pypy.objspace.flow.model import traverse, uniqueitems, last_exception
+from pypy.objspace.flow.model import traverse, last_exception
 from pypy.rpython.lltype import Ptr, PyObject, Void, Bool
 from pypy.rpython.lltype import pyobjectptr, Struct, Array
 from pypy.translator.unsimplify import remove_direct_loops
@@ -16,55 +16,72 @@
     from a flow graph.
     """
 
-    def __init__(self, graph, db):
+    def __init__(self, graph, db, cpython_exc=False):
         self.graph = graph
         remove_direct_loops(None, graph)
         self.db = db
-        self.lltypemap = self.collecttypes()
-        self.typemap = {}
-        for v, T in self.lltypemap.items():
-            self.typemap[v] = db.gettype(T)
-
-    def collecttypes(self):
+        self.cpython_exc = cpython_exc
+        #
         # collect all variables and constants used in the body,
         # and get their types now
-        result = []
+        #
+        # NOTE: cannot use dictionaries with Constants has keys, because
+        #       Constants may hash and compare equal but have different lltypes
+        mix = []
+        self.more_ll_values = {}
         def visit(block):
             if isinstance(block, Block):
-                result.extend(block.inputargs)
+                mix.extend(block.inputargs)
                 for op in block.operations:
-                    result.extend(op.args)
-                    result.append(op.result)
+                    mix.extend(op.args)
+                    mix.append(op.result)
                 for link in block.exits:
-                    result.extend(link.getextravars())
-                    result.extend(link.args)
-                    result.append(Constant(link.exitcase))
-        traverse(visit, self.graph)
-        resultvar = self.graph.getreturnvar()
-        lltypemap = {resultvar: Void}   # default value, normally overridden
-        for v in uniqueitems(result):
-            # xxx what kind of pointer for constants?
-            T = getattr(v, 'concretetype', PyObjPtr)           
-            lltypemap[v] = T
-        return lltypemap
+                    mix.extend(link.getextravars())
+                    mix.extend(link.args)
+                    mix.append(Constant(link.exitcase))
+                    if hasattr(link, 'llexitcase'):
+                        self.more_ll_values[link.llexitcase] = True
+        traverse(visit, graph)
+        resultvar = graph.getreturnvar()
+
+        self.lltypes = {
+            # default, normally overridden:
+            id(resultvar): (resultvar, Void, db.gettype(Void)),
+            }
+        for v in mix:
+            T = getattr(v, 'concretetype', PyObjPtr)
+            typename = db.gettype(T)
+            self.lltypes[id(v)] = v, T, typename
 
     def argnames(self):
         return [v.name for v in self.graph.getargs()]
 
     def allvariables(self):
-        return [v for v in self.typemap if isinstance(v, Variable)]
+        return [v for v, T, typename in self.lltypes.values()
+                  if isinstance(v, Variable)]
 
     def allconstants(self):
-        return [v for v in self.typemap if isinstance(v, Constant)]
+        return [c for c, T, typename in self.lltypes.values()
+                  if isinstance(c, Constant)]
 
     def allconstantvalues(self):
-        for v in self.typemap:
-            if isinstance(v, Constant):
-                yield llvalue_from_constant(v)
+        for c, T, typename in self.lltypes.values():
+            if isinstance(c, Constant):
+                yield llvalue_from_constant(c)
+        for llvalue in self.more_ll_values:
+            yield llvalue
+
+    def lltypemap(self, v):
+        v, T, typename = self.lltypes[id(v)]
+        return T
+
+    def lltypename(self, v):
+        v, T, typename = self.lltypes[id(v)]
+        return typename
 
     def expr(self, v):
         if isinstance(v, Variable):
-            if self.lltypemap[v] == Void:
+            if self.lltypemap(v) == Void:
                 return '/* nothing */'
             else:
                 return v.name
@@ -74,8 +91,12 @@
             raise TypeError, "expr(%r)" % (v,)
 
     def error_return_value(self):
-        returnlltype = self.lltypemap[self.graph.getreturnvar()]
-        return self.db.get(ErrorValue(returnlltype))
+        if self.cpython_exc:
+            assert self.lltypemap(self.graph.getreturnvar()) == PyObjPtr
+            return 'ConvertExceptionToCPython()'
+        else:
+            returnlltype = self.lltypemap(self.graph.getreturnvar())
+            return self.db.get(ErrorValue(returnlltype))
 
     # ____________________________________________________________
 
@@ -88,8 +109,8 @@
         result_by_name = []
         for v in self.allvariables():
             if v not in inputargset:
-                result = cdecl(self.typemap[v], v.name) + ';'
-                if self.lltypemap[v] == Void:
+                result = cdecl(self.lltypename(v), v.name) + ';'
+                if self.lltypemap(v) == Void:
                     result = '/*%s*/' % result
                 result_by_name.append((v._name, result))
         result_by_name.sort()
@@ -117,7 +138,7 @@
                 linklocalvars[v] = self.expr(v)
             has_ref = linklocalvars.copy()
             for a1, a2 in zip(link.args, link.target.inputargs):
-                if self.lltypemap[a2] == Void:
+                if self.lltypemap(a2) == Void:
                     continue
                 if a1 in linklocalvars:
                     src = linklocalvars[a1]
@@ -127,7 +148,7 @@
                 if a1 in has_ref:
                     del has_ref[a1]
                 else:
-                    assert self.lltypemap[a1] == self.lltypemap[a2]
+                    assert self.lltypemap(a1) == self.lltypemap(a2)
                     line += '\t' + self.cincref(a2)
                 yield line
             for v in has_ref:
@@ -169,7 +190,7 @@
                     # exceptional return block
                     exc_cls   = self.expr(block.inputargs[0])
                     exc_value = self.expr(block.inputargs[1])
-                    yield 'PyErr_Restore(%s, %s, NULL);' % (exc_cls, exc_value)
+                    yield 'RaiseException(%s, %s);' % (exc_cls, exc_value)
                     yield 'return %s;' % self.error_return_value()
                 else:
                     # regular return block
@@ -197,31 +218,40 @@
                 yield ''
                 for link in block.exits[1:]:
                     assert issubclass(link.exitcase, Exception)
-                    yield 'if (PyErr_ExceptionMatches(%s)) {' % (
-                        self.db.get(pyobjectptr(link.exitcase)),)
-                    yield '\tPyObject *exc_cls, *exc_value, *exc_tb;'
-                    yield '\tPyErr_Fetch(&exc_cls, &exc_value, &exc_tb);'
-                    yield '\tif (exc_value == NULL) {'
-                    yield '\t\texc_value = Py_None;'
-                    yield '\t\tPy_INCREF(Py_None);'
-                    yield '\t}'
-                    yield '\tPy_XDECREF(exc_tb);'
+                    try:
+                        etype = link.llexitcase
+                    except AttributeError:
+                        etype = pyobjectptr(link.exitcase)
+                        T1 = PyObjPtr
+                        T2 = PyObjPtr
+                    else:
+                        assert hasattr(link.last_exception, 'concretetype')
+                        assert hasattr(link.last_exc_value, 'concretetype')
+                        T1 = link.last_exception.concretetype
+                        T2 = link.last_exc_value.concretetype
+                    typ1 = self.db.gettype(T1)
+                    typ2 = self.db.gettype(T2)
+                    yield 'if (MatchException(%s)) {' % (self.db.get(etype),)
+                    yield '\t%s;' % cdecl(typ1, 'exc_cls')
+                    yield '\t%s;' % cdecl(typ2, 'exc_value')
+                    yield '\tFetchException(exc_cls, exc_value, %s);' % (
+                        cdecl(typ2, ''))
                     d = {}
                     if isinstance(link.last_exception, Variable):
                         d[link.last_exception] = 'exc_cls'
                     else:
-                        yield '\tPy_XDECREF(exc_cls);'
+                        yield '\t' + self.db.cdecrefstmt('exc_cls', T1)
                     if isinstance(link.last_exc_value, Variable):
                         d[link.last_exc_value] = 'exc_value'
                     else:
-                        yield '\tPy_XDECREF(exc_value);'
+                        yield '\t' + self.db.cdecrefstmt('exc_value', T2)
                     for op in gen_link(link, d):
                         yield '\t' + op
                     yield '}'
                 err_reachable = True
             else:
                 # block ending in a switch on a value
-                TYPE = self.lltypemap[block.exitswitch]
+                TYPE = self.lltypemap(block.exitswitch)
                 for link in block.exits[:-1]:
                     assert link.exitcase in (False, True)
                     expr = self.expr(block.exitswitch)
@@ -302,14 +332,14 @@
 
     def OP_DIRECT_CALL(self, op, err):
         # skip 'void' arguments
-        args = [self.expr(v) for v in op.args if self.lltypemap[v] != Void]
-        if self.lltypemap[op.result] == Void:
+        args = [self.expr(v) for v in op.args if self.lltypemap(v) != Void]
+        if self.lltypemap(op.result) == Void:
             # skip assignment of 'void' return value
-            return '%s(%s); if (PyErr_Occurred()) FAIL(%s)' % (
+            return '%s(%s); if (ExceptionOccurred()) FAIL(%s)' % (
                 args[0], ', '.join(args[1:]), err)
         else:
             r = self.expr(op.result)
-            return '%s = %s(%s); if (PyErr_Occurred()) FAIL(%s)' % (
+            return '%s = %s(%s); if (ExceptionOccurred()) FAIL(%s)' % (
                 r, args[0], ', '.join(args[1:]), err)
 
     # low-level operations
@@ -317,7 +347,7 @@
         newvalue = self.expr(op.result)
         result = ['%s = %s;' % (newvalue, sourceexpr)]
         # need to adjust the refcount of the result
-        T = self.lltypemap[op.result]
+        T = self.lltypemap(op.result)
         increfstmt = self.db.cincrefstmt(newvalue, T)
         if increfstmt:
             result.append(increfstmt)
@@ -330,14 +360,14 @@
         newvalue = self.expr(op.args[2])
         result = ['%s = %s;' % (targetexpr, newvalue)]
         # need to adjust some refcounts
-        T = self.lltypemap[op.args[2]]
+        T = self.lltypemap(op.args[2])
         decrefstmt = self.db.cdecrefstmt('prev', T)
         increfstmt = self.db.cincrefstmt(newvalue, T)
         if increfstmt:
             result.append(increfstmt)
         if decrefstmt:
             result.insert(0, '{ %s = %s;' % (
-                cdecl(self.typemap[op.args[2]], 'prev'),
+                cdecl(self.lltypename(op.args[2]), 'prev'),
                 targetexpr))
             result.append(decrefstmt)
             result.append('}')
@@ -348,7 +378,7 @@
 
     def OP_GETFIELD(self, op, err, ampersand=''):
         assert isinstance(op.args[1], Constant)
-        STRUCT = self.lltypemap[op.args[0]].TO
+        STRUCT = self.lltypemap(op.args[0]).TO
         structdef = self.db.gettypedefnode(STRUCT)
         fieldname = structdef.c_struct_field_name(op.args[1].value)
         return self.generic_get(op, '%s%s->%s' % (ampersand,
@@ -357,7 +387,7 @@
 
     def OP_SETFIELD(self, op, err):
         assert isinstance(op.args[1], Constant)
-        STRUCT = self.lltypemap[op.args[0]].TO
+        STRUCT = self.lltypemap(op.args[0]).TO
         structdef = self.db.gettypedefnode(STRUCT)
         fieldname = structdef.c_struct_field_name(op.args[1].value)
         return self.generic_set(op, '%s->%s' % (self.expr(op.args[0]),
@@ -398,7 +428,7 @@
                                      self.expr(op.args[1]))
 
     def OP_MALLOC(self, op, err):
-        TYPE = self.lltypemap[op.result].TO
+        TYPE = self.lltypemap(op.result).TO
         typename = self.db.gettype(TYPE)
         eresult = self.expr(op.result)
         result = ['OP_ZERO_MALLOC(sizeof(%s), %s, %s)' % (cdecl(typename, ''),
@@ -410,7 +440,7 @@
         return '\t'.join(result)
 
     def OP_MALLOC_VARSIZE(self, op, err):
-        TYPE = self.lltypemap[op.result].TO
+        TYPE = self.lltypemap(op.result).TO
         typename = self.db.gettype(TYPE)
         lenfld = 'length'
         nodedef = self.db.gettypedefnode(TYPE)
@@ -439,7 +469,7 @@
         return '\t'.join(result)
 
     def OP_CAST_POINTER(self, op, err):
-        TYPE = self.lltypemap[op.result]
+        TYPE = self.lltypemap(op.result)
         typename = self.db.gettype(TYPE)
         result = []
         result.append('%s = (%s)%s;' % (self.expr(op.result),
@@ -452,8 +482,8 @@
 
     def OP_SAME_AS(self, op, err):
         result = []
-        assert self.lltypemap[op.args[0]] == self.lltypemap[op.result]
-        if self.lltypemap[op.result] != Void:
+        assert self.lltypemap(op.args[0]) == self.lltypemap(op.result)
+        if self.lltypemap(op.result) != Void:
             result.append('%s = %s;' % (self.expr(op.result),
                                         self.expr(op.args[0])))
             line = self.cincref(op.result)
@@ -462,9 +492,9 @@
         return '\t'.join(result)
 
     def cincref(self, v):
-        T = self.lltypemap[v]
+        T = self.lltypemap(v)
         return self.db.cincrefstmt(v.name, T)
 
     def cdecref(self, v, expr=None):
-        T = self.lltypemap[v]
+        T = self.lltypemap(v)
         return self.db.cdecrefstmt(expr or v.name, T)

Added: pypy/dist/pypy/translator/c/g_exception.h
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/c/g_exception.h	Tue Jun 14 15:03:28 2005
@@ -0,0 +1,84 @@
+
+/************************************************************/
+ /***  C header subsection: exceptions                     ***/
+
+static PyObject *RPythonError;
+
+
+/******************************************************************/
+#ifdef RPYTHON_EXCEPTION_VTABLE  /* RPython version of exceptions */
+/******************************************************************/
+
+static RPYTHON_EXCEPTION_VTABLE	rpython_exc_type = NULL;
+static RPYTHON_EXCEPTION	rpython_exc_value = NULL;
+
+#define ExceptionOccurred()	(rpython_exc_type != NULL)
+
+#define RaiseException(etype, evalue)					\
+		assert(!ExceptionOccurred());				\
+		rpython_exc_type = (RPYTHON_EXCEPTION_VTABLE)(etype);	\
+		rpython_exc_value = (RPYTHON_EXCEPTION)(evalue)
+
+#define FetchException(etypevar, evaluevar, type_of_evaluevar)		\
+		etypevar = rpython_exc_type;				\
+		evaluevar = (type_of_evaluevar) rpython_exc_value;	\
+		rpython_exc_type = NULL;				\
+		rpython_exc_value = NULL
+
+#define MatchException(etype)	RPYTHON_EXCEPTION_MATCH(rpython_exc_type,  \
+					(RPYTHON_EXCEPTION_VTABLE) etype)
+
+static void ConvertExceptionFromCPython(void)
+{
+	/* convert the CPython exception to an RPython one */
+	PyObject *exc_type, *exc_value, *exc_tb;
+	assert(PyErr_Occurred());
+	assert(!ExceptionOccurred());
+	PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
+	/* XXX loosing the error message here */
+	rpython_exc_value = RPYTHON_PYEXCCLASS2EXC(exc_type);
+	rpython_exc_type = RPYTHON_TYPE_OF_EXC_INST(rpython_exc_value);
+}
+
+static PyObject *ConvertExceptionToCPython(void)
+{
+	assert(ExceptionOccurred());
+	assert(!PyErr_Occurred());
+	rpython_exc_type = NULL;    /* XXX leaks! */
+	rpython_exc_value = NULL;
+	PyErr_SetNone(RPythonError);
+	return NULL;
+}
+
+#define RaiseSimpleException(exc, msg)				\
+		/* XXX 1. uses officially bad fishing */	\
+		/* XXX 2. msg is ignored */			\
+		rpython_exc_type = (exc)->o_typeptr;		\
+		rpython_exc_value = (exc);			\
+		rpython_exc_value->refcount++
+
+/******************************************************************/
+#else    /* non-RPython version of exceptions, using CPython only */
+/******************************************************************/
+
+#define ExceptionOccurred()           PyErr_Occurred()
+#define RaiseException(etype, evalue) PyErr_Restore(etype, evalue, NULL)
+#define FetchException(etypevar, evaluevar, ignored)   {	\
+		PyObject *__tb;					\
+		PyErr_Fetch(&etypevar, &evaluevar, &__tb);	\
+		if (evaluevar == NULL) {			\
+			evaluevar = Py_None;			\
+			Py_INCREF(Py_None);			\
+		}						\
+		Py_XDECREF(__tb);				\
+	}
+#define MatchException(etype)         PyErr_ExceptionMatches(etype)
+#define ConvertExceptionFromCPython() /* nothing */
+#define ConvertExceptionToCPython()   NULL
+
+#define RaiseSimpleException(exc, msg) \
+		PyErr_SetString(Py##exc, msg)    /* pun */
+
+/******************************************************************/
+#endif                                /* RPYTHON_EXCEPTION_VTABLE */
+/******************************************************************/

Modified: pypy/dist/pypy/translator/c/g_include.h
==============================================================================
--- pypy/dist/pypy/translator/c/g_include.h	(original)
+++ pypy/dist/pypy/translator/c/g_include.h	Tue Jun 14 15:03:28 2005
@@ -10,6 +10,7 @@
 #include "marshal.h"
 #include "eval.h"
 
+#include "g_exception.h"
 #include "g_trace.h"
 #include "g_support.h"
 #include "g_module.h"

Modified: pypy/dist/pypy/translator/c/g_module.h
==============================================================================
--- pypy/dist/pypy/translator/c/g_module.h	(original)
+++ pypy/dist/pypy/translator/c/g_module.h	Tue Jun 14 15:03:28 2005
@@ -15,12 +15,17 @@
 	PyMODINIT_FUNC init##modname(void)
 #endif
 
-#define SETUP_MODULE(modname)					\
+#define SETUP_MODULE(modname)	\
 	PyObject *m = Py_InitModule(#modname, my_methods); \
 	PyModule_AddStringConstant(m, "__sourcefile__", __FILE__); \
 	this_module_globals = PyModule_GetDict(m); \
 	PyGenCFunction_Type.tp_base = &PyCFunction_Type;	\
 	PyType_Ready(&PyGenCFunction_Type);	\
+	RPythonError = PyErr_NewException(#modname ".RPythonError", \
+					  NULL, NULL); \
+	if (RPythonError == NULL) \
+		return; \
+	PyModule_AddObject(m, "RPythonError", RPythonError); \
 	if (setup_globalfunctions(globalfunctiondefs) < 0) \
 		return;	\
 	if (setup_initcode(frozen_initcode, FROZEN_INITCODE_SIZE) < 0) \

Modified: pypy/dist/pypy/translator/c/g_support.h
==============================================================================
--- pypy/dist/pypy/translator/c/g_support.h	(original)
+++ pypy/dist/pypy/translator/c/g_support.h	Tue Jun 14 15:03:28 2005
@@ -11,12 +11,13 @@
 
 #define FAIL_EXCEPTION(err, exc, msg) \
 	{ \
-		PyErr_SetString(exc, msg); \
+		RaiseSimpleException(exc, msg); \
 		FAIL(err) \
 	}
-#define FAIL_OVF(err, msg) FAIL_EXCEPTION(err, PyExc_OverflowError, msg)
-#define FAIL_VAL(err, msg) FAIL_EXCEPTION(err, PyExc_ValueError, msg)
-#define FAIL_ZER(err, msg) FAIL_EXCEPTION(err, PyExc_ZeroDivisionError, msg)
+#define FAIL_OVF(err, msg) FAIL_EXCEPTION(err, Exc_OverflowError, msg)
+#define FAIL_VAL(err, msg) FAIL_EXCEPTION(err, Exc_ValueError, msg)
+#define FAIL_ZER(err, msg) FAIL_EXCEPTION(err, Exc_ZeroDivisionError, msg)
+#define CFAIL(err)         { ConvertExceptionFromCPython(); FAIL(err) }
 
 /* we need a subclass of 'builtin_function_or_method' which can be used
    as methods: builtin function objects that can be bound on instances */

Modified: pypy/dist/pypy/translator/c/genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/genc.py	(original)
+++ pypy/dist/pypy/translator/c/genc.py	Tue Jun 14 15:03:28 2005
@@ -43,6 +43,7 @@
 # ____________________________________________________________
 
 def gen_readable_parts_of_main_c_file(f, database):
+    lines = list(database.pre_include_code_lines())
     #
     # All declarations
     #
@@ -53,9 +54,6 @@
     for node in database.structdeflist:
         for line in node.definition(phase=1):
             print >> f, line
-    for node in database.structdeflist:
-        for line in node.definition(phase=2):
-            print >> f, line
     print >> f
     print >> f, '/***********************************************************/'
     print >> f, '/***  Forward declarations                               ***/'
@@ -63,13 +61,23 @@
     for node in database.globalcontainers():
         for line in node.forward_declaration():
             print >> f, line
+
     #
     # Implementation of functions and global structures and arrays
     #
     print >> f
     print >> f, '/***********************************************************/'
     print >> f, '/***  Implementations                                    ***/'
-    blank = True
+    print >> f
+    for line in lines:
+        print >> f, line
+    print >> f, '#include "g_include.h"'
+    print >> f
+    blank = False
+    for node in database.structdeflist:
+        for line in node.definition(phase=2):
+            print >> f, line
+        blank = True
     for node in database.globalcontainers():
         if blank:
             print >> f
@@ -90,7 +98,7 @@
     #
     for key, value in defines.items():
         print >> f, '#define %s %s' % (key, value)
-    print >> f, '#include "g_include.h"'
+    print >> f, '#include "Python.h"'
 
     #
     # 1) All declarations

Modified: pypy/dist/pypy/translator/c/int_include.h
==============================================================================
--- pypy/dist/pypy/translator/c/int_include.h	(original)
+++ pypy/dist/pypy/translator/c/int_include.h	Tue Jun 14 15:03:28 2005
@@ -4,11 +4,6 @@
 
 /*** unary operations ***/
 
-#define OP_INCREF_int(x)          /* nothing */
-#define OP_DECREF_int(x)          /* nothing */
-#define CONV_TO_OBJ_int           PyInt_FromLong
-#define CONV_FROM_OBJ_int         PyInt_AS_LONG
-
 #define OP_INT_IS_TRUE(x,r,err)   OP_INT_NE(x,0,r,err)
 
 #define OP_INT_INVERT(x,r,err)    r = ~((long)(x));
@@ -197,4 +192,4 @@
 	if (p_rem)
 		*p_rem = xmody;
 	return xdivy;
-}
\ No newline at end of file
+}

Modified: pypy/dist/pypy/translator/c/ll_include.h
==============================================================================
--- pypy/dist/pypy/translator/c/ll_include.h	(original)
+++ pypy/dist/pypy/translator/c/ll_include.h	Tue Jun 14 15:03:28 2005
@@ -3,11 +3,11 @@
  /***  C header subsection: operations on LowLevelTypes    ***/
 
 
-#define OP_ZERO_MALLOC(size, r, err)  {                 \
-    r = (void*) PyObject_Malloc(size);                  \
-    if (r == NULL) { PyErr_NoMemory(); FAIL(err) }      \
-    memset((void*) r, 0, size);                         \
-    COUNT_MALLOC                                        \
+#define OP_ZERO_MALLOC(size, r, err)  {                                 \
+    r = (void*) PyObject_Malloc(size);                                  \
+    if (r == NULL) FAIL_EXCEPTION(err, Exc_MemoryError, "out of memory")\
+    memset((void*) r, 0, size);                                         \
+    COUNT_MALLOC                                                        \
   }
 
 #define OP_FREE(p)	{ PyObject_Free(p); COUNT_FREE }

Modified: pypy/dist/pypy/translator/c/node.py
==============================================================================
--- pypy/dist/pypy/translator/c/node.py	(original)
+++ pypy/dist/pypy/translator/c/node.py	Tue Jun 14 15:03:28 2005
@@ -3,6 +3,7 @@
 from pypy.rpython.lltype import GcStruct, GcArray, GC_CONTAINER, ContainerType
 from pypy.rpython.lltype import parentlink, Ptr, PyObject, Void
 from pypy.translator.c.funcgen import FunctionCodeGenerator
+from pypy.translator.c.external import CExternalFunctionCodeGenerator
 from pypy.translator.c.support import cdecl, somelettersfrom
 from pypy.translator.c.primitive import PrimitiveType
 
@@ -318,8 +319,7 @@
     globalcontainer = True
 
     def __init__(self, db, T, obj):
-        graph = obj.graph # only user-defined functions with graphs for now
-        self.funcgen = FunctionCodeGenerator(graph, db)
+        self.funcgen = select_function_code_generator(obj, db)
         self.db = db
         self.T = T
         self.obj = obj
@@ -380,39 +380,14 @@
         yield '}'
 
 
-class CExternalFuncNode(ContainerNode):
-    globalcontainer = True
-
-    def __init__(self, db, T, obj):
-        self.db = db
-        self.T = T
-        self.obj = obj
-        #self.dependencies = {}
-        self.typename = db.gettype(T)  #, who_asks=self)
-        self.name = obj._name
-        self.ptrname = self.name
-
-    def enum_dependencies(self):
-        return []
-
-    def implementation(self):
-        return []
-
-    def forward_declaration(self):
-        return []
-
-    def implementation(self):
-        return []
-
-
-def funcnodemaker(db, T, obj):
-    if hasattr(obj, 'graph'):
-        cls = FuncNode
-    elif getattr(obj, 'external', None) == 'C':
-        cls = CExternalFuncNode
+def select_function_code_generator(fnptr, db):
+    if hasattr(fnptr, 'graph'):
+        cpython_exc = getattr(fnptr, 'exception_policy', None) == "CPython"
+        return FunctionCodeGenerator(fnptr.graph, db, cpython_exc)
+    elif getattr(fnptr, 'external', None) == 'C':
+        return CExternalFunctionCodeGenerator(fnptr, db)
     else:
-        raise ValueError, "don't know about %r" % (obj,)
-    return cls(db, T, obj)
+        raise ValueError, "don't know how to generate code for %r" % (fnptr,)
 
 
 class PyObjectNode(ContainerNode):
@@ -446,6 +421,6 @@
     GcStruct:     StructNode,
     Array:        ArrayNode,
     GcArray:      ArrayNode,
-    FuncType:     funcnodemaker,
+    FuncType:     FuncNode,
     PyObjectType: PyObjectNode,
     }

Modified: pypy/dist/pypy/translator/c/pyobj_include.h
==============================================================================
--- pypy/dist/pypy/translator/c/pyobj_include.h	(original)
+++ pypy/dist/pypy/translator/c/pyobj_include.h	Tue Jun 14 15:03:28 2005
@@ -7,13 +7,13 @@
 #define op_bool(r,err,what) { \
 		int _retval = what; \
 		if (_retval < 0) { \
-			FAIL(err) \
+			CFAIL(err) \
 		} \
 		r = PyBool_FromLong(_retval); \
 	}
 
 #define op_richcmp(x,y,r,err,dir) \
-					if (!(r=PyObject_RichCompare(x,y,dir))) FAIL(err)
+					if (!(r=PyObject_RichCompare(x,y,dir))) CFAIL(err)
 #define OP_LT(x,y,r,err)  op_richcmp(x,y,r,err, Py_LT)
 #define OP_LE(x,y,r,err)  op_richcmp(x,y,r,err, Py_LE)
 #define OP_EQ(x,y,r,err)  op_richcmp(x,y,r,err, Py_EQ)
@@ -29,71 +29,71 @@
 #define OP_LEN(x,r,err) { \
 		int _retval = PyObject_Size(x); \
 		if (_retval < 0) { \
-			FAIL(err) \
+			CFAIL(err) \
 		} \
 		r = PyInt_FromLong(_retval); \
 	}
-#define OP_NEG(x,r,err)           if (!(r=PyNumber_Negative(x)))     FAIL(err)
-#define OP_POS(x,r,err)           if (!(r=PyNumber_Positive(x)))     FAIL(err)
-#define OP_INVERT(x,r,err)        if (!(r=PyNumber_Invert(x)))       FAIL(err)
-#define OP_ABS(x,r,err)           if (!(r=PyNumber_Absolute(x)))     FAIL(err)
-
-#define OP_ADD(x,y,r,err)         if (!(r=PyNumber_Add(x,y)))        FAIL(err)
-#define OP_SUB(x,y,r,err)         if (!(r=PyNumber_Subtract(x,y)))   FAIL(err)
-#define OP_MUL(x,y,r,err)         if (!(r=PyNumber_Multiply(x,y)))   FAIL(err)
-#define OP_TRUEDIV(x,y,r,err)     if (!(r=PyNumber_TrueDivide(x,y))) FAIL(err)
-#define OP_FLOORDIV(x,y,r,err)    if (!(r=PyNumber_FloorDivide(x,y)))FAIL(err)
-#define OP_DIV(x,y,r,err)         if (!(r=PyNumber_Divide(x,y)))     FAIL(err)
-#define OP_MOD(x,y,r,err)         if (!(r=PyNumber_Remainder(x,y)))  FAIL(err)
-#define OP_DIVMOD(x,y,r,err)      if (!(r=PyNumber_Divmod(x,y)))     FAIL(err)
-#define OP_POW(x,y,z,r,err)       if (!(r=PyNumber_Power(x,y,z)))    FAIL(err)
-#define OP_LSHIFT(x,y,r,err)      if (!(r=PyNumber_Lshift(x,y)))     FAIL(err)
-#define OP_RSHIFT(x,y,r,err)      if (!(r=PyNumber_Rshift(x,y)))     FAIL(err)
-#define OP_AND_(x,y,r,err)        if (!(r=PyNumber_And(x,y)))        FAIL(err)
-#define OP_OR_(x,y,r,err)         if (!(r=PyNumber_Or(x,y)))         FAIL(err)
-#define OP_XOR(x,y,r,err)         if (!(r=PyNumber_Xor(x,y)))        FAIL(err)
+#define OP_NEG(x,r,err)           if (!(r=PyNumber_Negative(x)))     CFAIL(err)
+#define OP_POS(x,r,err)           if (!(r=PyNumber_Positive(x)))     CFAIL(err)
+#define OP_INVERT(x,r,err)        if (!(r=PyNumber_Invert(x)))       CFAIL(err)
+#define OP_ABS(x,r,err)           if (!(r=PyNumber_Absolute(x)))     CFAIL(err)
+
+#define OP_ADD(x,y,r,err)         if (!(r=PyNumber_Add(x,y)))        CFAIL(err)
+#define OP_SUB(x,y,r,err)         if (!(r=PyNumber_Subtract(x,y)))   CFAIL(err)
+#define OP_MUL(x,y,r,err)         if (!(r=PyNumber_Multiply(x,y)))   CFAIL(err)
+#define OP_TRUEDIV(x,y,r,err)     if (!(r=PyNumber_TrueDivide(x,y))) CFAIL(err)
+#define OP_FLOORDIV(x,y,r,err)    if (!(r=PyNumber_FloorDivide(x,y)))CFAIL(err)
+#define OP_DIV(x,y,r,err)         if (!(r=PyNumber_Divide(x,y)))     CFAIL(err)
+#define OP_MOD(x,y,r,err)         if (!(r=PyNumber_Remainder(x,y)))  CFAIL(err)
+#define OP_DIVMOD(x,y,r,err)      if (!(r=PyNumber_Divmod(x,y)))     CFAIL(err)
+#define OP_POW(x,y,z,r,err)       if (!(r=PyNumber_Power(x,y,z)))    CFAIL(err)
+#define OP_LSHIFT(x,y,r,err)      if (!(r=PyNumber_Lshift(x,y)))     CFAIL(err)
+#define OP_RSHIFT(x,y,r,err)      if (!(r=PyNumber_Rshift(x,y)))     CFAIL(err)
+#define OP_AND_(x,y,r,err)        if (!(r=PyNumber_And(x,y)))        CFAIL(err)
+#define OP_OR_(x,y,r,err)         if (!(r=PyNumber_Or(x,y)))         CFAIL(err)
+#define OP_XOR(x,y,r,err)         if (!(r=PyNumber_Xor(x,y)))        CFAIL(err)
 
 #define OP_INPLACE_ADD(x,y,r,err) if (!(r=PyNumber_InPlaceAdd(x,y)))           \
-								     FAIL(err)
+								     CFAIL(err)
 #define OP_INPLACE_SUB(x,y,r,err) if (!(r=PyNumber_InPlaceSubtract(x,y)))      \
-								     FAIL(err)
+								     CFAIL(err)
 #define OP_INPLACE_MUL(x,y,r,err) if (!(r=PyNumber_InPlaceMultiply(x,y)))      \
-								     FAIL(err)
+								     CFAIL(err)
 #define OP_INPLACE_TRUEDIV(x,y,r,err) if (!(r=PyNumber_InPlaceTrueDivide(x,y)))\
-								     FAIL(err)
+								     CFAIL(err)
 #define OP_INPLACE_FLOORDIV(x,y,r,err)if(!(r=PyNumber_InPlaceFloorDivide(x,y)))\
-								     FAIL(err)
+								     CFAIL(err)
 #define OP_INPLACE_DIV(x,y,r,err) if (!(r=PyNumber_InPlaceDivide(x,y)))        \
-								     FAIL(err)
+								     CFAIL(err)
 #define OP_INPLACE_MOD(x,y,r,err) if (!(r=PyNumber_InPlaceRemainder(x,y)))     \
-								     FAIL(err)
+								     CFAIL(err)
 #define OP_INPLACE_POW(x,y,r,err) if (!(r=PyNumber_InPlacePower(x,y,Py_None))) \
-								     FAIL(err)
+								     CFAIL(err)
 #define OP_INPLACE_LSHIFT(x,y,r,err) if (!(r=PyNumber_InPlaceLshift(x,y)))     \
-								     FAIL(err)
+								     CFAIL(err)
 #define OP_INPLACE_RSHIFT(x,y,r,err) if (!(r=PyNumber_InPlaceRshift(x,y)))     \
-								     FAIL(err)
+								     CFAIL(err)
 #define OP_INPLACE_AND(x,y,r,err)    if (!(r=PyNumber_InPlaceAnd(x,y)))        \
-								     FAIL(err)
+								     CFAIL(err)
 #define OP_INPLACE_OR(x,y,r,err)     if (!(r=PyNumber_InPlaceOr(x,y)))         \
-								     FAIL(err)
+								     CFAIL(err)
 #define OP_INPLACE_XOR(x,y,r,err)    if (!(r=PyNumber_InPlaceXor(x,y)))        \
-								     FAIL(err)
+								     CFAIL(err)
 
-#define OP_GETITEM(x,y,r,err)     if (!(r=PyObject_GetItem1(x,y)))   FAIL(err)
-#define OP_SETITEM(x,y,z,r,err)   if ((PyObject_SetItem1(x,y,z))<0)  FAIL(err) \
+#define OP_GETITEM(x,y,r,err)     if (!(r=PyObject_GetItem1(x,y)))   CFAIL(err)
+#define OP_SETITEM(x,y,z,r,err)   if ((PyObject_SetItem1(x,y,z))<0)  CFAIL(err) \
 				  r=Py_None; Py_INCREF(r);
-#define OP_DELITEM(x,y,r,err)     if ((PyObject_DelItem(x,y))<0)     FAIL(err) \
+#define OP_DELITEM(x,y,r,err)     if ((PyObject_DelItem(x,y))<0)     CFAIL(err) \
 				  r=Py_None; Py_INCREF(r);
 #define OP_CONTAINS(x,y,r,err)    op_bool(r,err,(PySequence_Contains(x,y)))
 
-#define OP_GETATTR(x,y,r,err)     if (!(r=PyObject_GetAttr(x,y)))    FAIL(err)
-#define OP_SETATTR(x,y,z,r,err)   if ((PyObject_SetAttr(x,y,z))<0)   FAIL(err) \
+#define OP_GETATTR(x,y,r,err)     if (!(r=PyObject_GetAttr(x,y)))    CFAIL(err)
+#define OP_SETATTR(x,y,z,r,err)   if ((PyObject_SetAttr(x,y,z))<0)   CFAIL(err) \
 				  r=Py_None; Py_INCREF(r);
-#define OP_DELATTR(x,y,r,err)     if ((PyObject_SetAttr(x,y,NULL))<0)FAIL(err) \
+#define OP_DELATTR(x,y,r,err)     if ((PyObject_SetAttr(x,y,NULL))<0)CFAIL(err) \
 				  r=Py_None; Py_INCREF(r);
 
-#define OP_NEWSLICE(x,y,z,r,err)  if (!(r=PySlice_New(x,y,z)))       FAIL(err)
+#define OP_NEWSLICE(x,y,z,r,err)  if (!(r=PySlice_New(x,y,z)))       CFAIL(err)
 
 #define OP_GETSLICE(x,y,z,r,err)  {					\
 		PyObject *__yo = y, *__zo = z;				\
@@ -102,46 +102,46 @@
 		if (__zo == Py_None) __zo = NULL;			\
 		if (!_PyEval_SliceIndex(__yo, &__y) ||			\
 		    !_PyEval_SliceIndex(__zo, &__z) ||			\
-		    !(r=PySequence_GetSlice(x, __y, __z))) FAIL(err)	\
+		    !(r=PySequence_GetSlice(x, __y, __z))) CFAIL(err)	\
 	}
 
 #define OP_ALLOC_AND_SET(x,y,r,err) { \
 		/* XXX check for long/int overflow */ \
 		int __i, __x = PyInt_AsLong(x); \
-		if (PyErr_Occurred()) FAIL(err) \
-		if (!(r = PyList_New(__x))) FAIL(err) \
+		if (PyErr_Occurred()) CFAIL(err) \
+		if (!(r = PyList_New(__x))) CFAIL(err) \
 		for (__i=0; __i<__x; __i++) { \
 			Py_INCREF(y); \
 			PyList_SET_ITEM(r, __i, y); \
 		} \
 	}
 
-#define OP_ITER(x,r,err)          if (!(r=PyObject_GetIter(x)))      FAIL(err)
+#define OP_ITER(x,r,err)          if (!(r=PyObject_GetIter(x)))      CFAIL(err)
 #define OP_NEXT(x,r,err)          if (!(r=PyIter_Next(x))) {                   \
 		if (!PyErr_Occurred()) PyErr_SetNone(PyExc_StopIteration);     \
-		FAIL(err)                                                      \
+		CFAIL(err)                                                      \
 	}
 
-#define OP_STR(x,r,err)           if (!(r=PyObject_Str(x)))          FAIL(err)
-#define OP_REPR(x,r,err)          if (!(r=PyObject_Repr(x)))         FAIL(err)
+#define OP_STR(x,r,err)           if (!(r=PyObject_Str(x)))          CFAIL(err)
+#define OP_REPR(x,r,err)          if (!(r=PyObject_Repr(x)))         CFAIL(err)
 #define OP_ORD(s,r,err) { \
 	char *__c = PyString_AsString(s); \
 	int __len; \
-	if ( !__c) FAIL(err) \
+	if ( !__c) CFAIL(err) \
 	if ((__len = PyString_GET_SIZE(s)) != 1) { \
 	    PyErr_Format(PyExc_TypeError, \
 		  "ord() expected a character, but string of length %d found", \
 		  __len); \
-	    FAIL(err) \
+	    CFAIL(err) \
 	} \
 	if (!(r = PyInt_FromLong((unsigned char)(__c[0])))) \
-	    FAIL(err) \
+	    CFAIL(err) \
     }
-#define OP_ID(x,r,err)    if (!(r=PyLong_FromVoidPtr(x))) FAIL(err)
+#define OP_ID(x,r,err)    if (!(r=PyLong_FromVoidPtr(x))) CFAIL(err)
 #define OP_HASH(x,r,err)  { \
 	long __hash = PyObject_Hash(x); \
-	if (__hash == -1 && PyErr_Occurred()) FAIL(err) \
-	if (!(r = PyInt_FromLong(__hash))) FAIL(err) \
+	if (__hash == -1 && PyErr_Occurred()) CFAIL(err) \
+	if (!(r = PyInt_FromLong(__hash))) CFAIL(err) \
     }
 
 #define OP_HEX(x,r,err)   { \
@@ -150,9 +150,9 @@
 	    __nb->nb_hex == NULL) { \
 		PyErr_SetString(PyExc_TypeError, \
 			   "hex() argument can't be converted to hex"); \
-		FAIL(err) \
+		CFAIL(err) \
 	} \
-	if (!(r = (*__nb->nb_hex)(x))) FAIL(err) \
+	if (!(r = (*__nb->nb_hex)(x))) CFAIL(err) \
     }
 #define OP_OCT(x,r,err)   { \
 	PyNumberMethods *__nb; \
@@ -160,32 +160,32 @@
 	    __nb->nb_oct == NULL) { \
 		PyErr_SetString(PyExc_TypeError, \
 			   "oct() argument can't be converted to oct"); \
-		FAIL(err) \
+		CFAIL(err) \
 	} \
-	if (!(r = (*__nb->nb_oct)(x))) FAIL(err) \
+	if (!(r = (*__nb->nb_oct)(x))) CFAIL(err) \
     }
 
 #define OP_INT(x,r,err)   { \
 	long __val = PyInt_AsLong(x); \
-	if (__val == -1 && PyErr_Occurred()) FAIL(err) \
-	if (!(r = PyInt_FromLong(__val))) FAIL (err) \
+	if (__val == -1 && PyErr_Occurred()) CFAIL(err) \
+	if (!(r = PyInt_FromLong(__val))) CFAIL (err) \
     }
 #define OP_FLOAT(x,r,err)   { \
 	double __val = PyFloat_AsDouble(x); \
-	if (PyErr_Occurred()) FAIL(err) \
-	if (!(r = PyFloat_FromDouble(__val))) FAIL (err) \
+	if (PyErr_Occurred()) CFAIL(err) \
+	if (!(r = PyFloat_FromDouble(__val))) CFAIL (err) \
     }
 
 #define OP_CMP(x,y,r,err)   { \
 	int __val = PyObject_Compare(x, y); \
-	if (PyErr_Occurred()) FAIL(err) \
-	if (!(r = PyInt_FromLong(__val))) FAIL (err) \
+	if (PyErr_Occurred()) CFAIL(err) \
+	if (!(r = PyInt_FromLong(__val))) CFAIL (err) \
     }
 
 
 #define OP_SIMPLE_CALL(args,r,err) if (!(r=PyObject_CallFunctionObjArgs args)) \
-					FAIL(err)
-#define OP_CALL_ARGS(args,r,err)   if (!(r=CallWithShape args))    FAIL(err)
+					CFAIL(err)
+#define OP_CALL_ARGS(args,r,err)   if (!(r=CallWithShape args))    CFAIL(err)
 
 /* Needs to act like getattr(x, '__class__', type(x)) */
 #define OP_TYPE(x,r,err) { \
@@ -205,27 +205,17 @@
 
 /*** operations with a variable number of arguments ***/
 
-#define OP_NEWLIST0(r,err)         if (!(r=PyList_New(0))) FAIL(err)
-#define OP_NEWLIST(args,r,err)     if (!(r=PyList_Pack args)) FAIL(err)
-#define OP_NEWDICT0(r,err)         if (!(r=PyDict_New())) FAIL(err)
-#define OP_NEWDICT(args,r,err)     if (!(r=PyDict_Pack args)) FAIL(err)
-#define OP_NEWTUPLE(args,r,err)    if (!(r=PyTuple_Pack args)) FAIL(err)
+#define OP_NEWLIST0(r,err)         if (!(r=PyList_New(0))) CFAIL(err)
+#define OP_NEWLIST(args,r,err)     if (!(r=PyList_Pack args)) CFAIL(err)
+#define OP_NEWDICT0(r,err)         if (!(r=PyDict_New())) CFAIL(err)
+#define OP_NEWDICT(args,r,err)     if (!(r=PyDict_Pack args)) CFAIL(err)
+#define OP_NEWTUPLE(args,r,err)    if (!(r=PyTuple_Pack args)) CFAIL(err)
 
 /*** argument parsing ***/
 
 #define OP_DECODE_ARG(fname, pos, name, vargs, vkwds, r, err)	\
-	if (!(r=decode_arg(fname, pos, name, vargs, vkwds, NULL))) FAIL(err)
+	if (!(r=decode_arg(fname, pos, name, vargs, vkwds, NULL))) CFAIL(err)
 #define OP_DECODE_ARG_DEF(fname, pos, name, vargs, vkwds, def, r, err)	\
-	if (!(r=decode_arg(fname, pos, name, vargs, vkwds, def))) FAIL(err)
+	if (!(r=decode_arg(fname, pos, name, vargs, vkwds, def))) CFAIL(err)
 #define OP_CHECK_NO_MORE_ARG(fname, n, vargs, r, err)	\
-	if (check_no_more_arg(fname, n, vargs) < 0) FAIL(err)
-
-/*** conversions, reference counting ***/
-
-#define OP_INCREF_pyobj(o)          Py_INCREF(o);
-#define OP_DECREF_pyobj(o)          Py_DECREF(o);
-#define CONV_TO_OBJ_pyobj(o)        ((void)Py_INCREF(o), o)
-#define CONV_FROM_OBJ_pyobj(o)      ((void)Py_INCREF(o), o)
-
-#define OP_INCREF_borrowedpyobj(o)  /* nothing */
-#define OP_DECREF_borrowedpyobj(o)  /* nothing */
+	if (check_no_more_arg(fname, n, vargs) < 0) CFAIL(err)

Added: pypy/dist/pypy/translator/c/test/test_exception.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/c/test/test_exception.py	Tue Jun 14 15:03:28 2005
@@ -0,0 +1,23 @@
+from pypy.translator.translator import Translator
+
+
+class MyException(Exception):
+    pass
+
+def test_myexception():
+    def g():
+        raise MyException
+    def f():
+        try:
+            g()
+        except MyException:
+            return 5
+        else:
+            return 2
+
+    t = Translator(f)
+    t.annotate([]).simplify()
+    t.specialize()
+    #t.view()
+    f1 = t.ccompile()
+    assert f1() == 5

Modified: pypy/dist/pypy/translator/c/test/test_genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_genc.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_genc.py	Tue Jun 14 15:03:28 2005
@@ -58,12 +58,12 @@
     assert f1(5) == 10
     assert f1(x=5) == 10
     assert f1(-123) == -246
-    py.test.raises(TypeError, f1, "world")  # check that it's really typed
-    py.test.raises(TypeError, f1)
-    py.test.raises(TypeError, f1, 2, 3)
-    py.test.raises(TypeError, f1, 2, x=2)
-    #py.test.raises(TypeError, f1, 2, y=2)   XXX missing a check at the moment
     assert module.malloc_counters() == (0, 0)
+    py.test.raises(Exception, f1, "world")  # check that it's really typed
+    py.test.raises(Exception, f1)
+    py.test.raises(Exception, f1, 2, 3)
+    py.test.raises(Exception, f1, 2, x=2)
+    #py.test.raises(Exception, f1, 2, y=2)   XXX missing a check at the moment
 
 
 def test_rlist():

Modified: pypy/dist/pypy/translator/c/wrapper.py
==============================================================================
--- pypy/dist/pypy/translator/c/wrapper.py	(original)
+++ pypy/dist/pypy/translator/c/wrapper.py	Tue Jun 14 15:03:28 2005
@@ -118,4 +118,5 @@
                                  PyObjPtr],
                                 PyObjPtr),
                        wgraph.name,
-                       graph = wgraph)
+                       graph = wgraph,
+                       exception_policy = "CPython")



More information about the Pypy-commit mailing list