[pypy-svn] r13655 - in pypy/dist/pypy: rpython translator/c translator/c/test

arigo at codespeak.net arigo at codespeak.net
Tue Jun 21 16:10:31 CEST 2005


Author: arigo
Date: Tue Jun 21 16:10:27 2005
New Revision: 13655

Modified:
   pypy/dist/pypy/rpython/rbuiltin.py
   pypy/dist/pypy/rpython/rstr.py
   pypy/dist/pypy/rpython/rtyper.py
   pypy/dist/pypy/translator/c/g_support.h
   pypy/dist/pypy/translator/c/genc.py
   pypy/dist/pypy/translator/c/node.py
   pypy/dist/pypy/translator/c/test/test_genc.py
Log:
Hacked support for math.exp().  We will soon need a cleaner approach for this.

Conversion from PyObject* to rstring, needed by the 'str' operation when
applied to PyObjRepr.


Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/rbuiltin.py	Tue Jun 21 16:10:27 2005
@@ -2,7 +2,7 @@
 from pypy.annotation import model as annmodel
 from pypy.rpython import lltype
 from pypy.rpython import rarithmetic
-from pypy.rpython.lltype import Void, Signed, Ptr, RuntimeTypeInfo
+from pypy.rpython.lltype import Void, Signed, Float, Ptr, RuntimeTypeInfo
 from pypy.rpython.rtyper import TyperError
 from pypy.rpython.rrange import rtype_builtin_range
 from pypy.rpython.rmodel import Repr, TyperError
@@ -161,5 +161,12 @@
 
 BUILTIN_TYPER[time.clock] = rtype_time_clock
     
+import math
 
+def rtype_math_exp(hop):
+    vlist = hop.inputargs(Float)
+    # XXX need PyFPE_START_PROTECT/PyFPE_END_PROTECT/Py_SET_ERRNO_ON_MATH_ERROR
+    return hop.llops.gencapicall('exp', vlist, resulttype=Float,
+                                 includes=["math.h"])   # XXX clean up needed
 
+BUILTIN_TYPER[math.exp] = rtype_math_exp

Modified: pypy/dist/pypy/rpython/rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/rstr.py	(original)
+++ pypy/dist/pypy/rpython/rstr.py	Tue Jun 21 16:10:27 2005
@@ -146,9 +146,17 @@
             return llops.gendirectcall(ll_stritem_nonneg, v, c_zero)
         return NotImplemented
 
-##class __extend__(pairtype(PyObjRepr, StringRepr)):
-##    def convert_from_to((r_from, r_to), v, llops):
-##        XXX
+class __extend__(pairtype(PyObjRepr, StringRepr)):
+    def convert_from_to((r_from, r_to), v, llops):
+        v_len = llops.gencapicall('PyString_Size', [v], resulttype=Signed)
+        cstr = inputconst(Void, STR)
+        v_result = llops.genop('malloc_varsize', [cstr, v_len],
+                               resulttype=Ptr(STR))
+        cchars = inputconst(Void, "chars")
+        v_chars = llops.genop('getsubstruct', [v_result, cchars],
+                              resulttype=Ptr(STR.chars))
+        llops.gencapicall('PyString_ToLLCharArray', [v, v_chars])
+        return v_result
 
 class __extend__(pairtype(StringRepr, PyObjRepr)):
     def convert_from_to((r_from, r_to), v, llops):
@@ -158,7 +166,7 @@
                               resulttype=Ptr(STR.chars))
         v_size = llops.genop('getarraysize', [v_chars],
                              resulttype=Signed)
-        return llops.gencapicall('PyString_FromRPythonCharArrayAndSize',
+        return llops.gencapicall('PyString_FromLLCharArrayAndSize',
                                  [v_chars, v_size],
                                  resulttype=pyobj_repr)
 

Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py	(original)
+++ pypy/dist/pypy/rpython/rtyper.py	Tue Jun 21 16:10:27 2005
@@ -508,12 +508,12 @@
         return self.genop('direct_call', [c]+list(args_v),
                           resulttype = typeOf(f).TO.RESULT)
 
-    def gencapicall(self, cfnname, args_v, resulttype=None):
+    def gencapicall(self, cfnname, args_v, resulttype=None, **flags):
         if isinstance(resulttype, Repr):
             resulttype = resulttype.lowleveltype
         argtypes = [v.concretetype for v in args_v]
         FUNCTYPE = FuncType(argtypes, resulttype or Void)
-        f = functionptr(FUNCTYPE, cfnname, external="C")
+        f = functionptr(FUNCTYPE, cfnname, external="C", **flags)
         cf = inputconst(typeOf(f), f)
         return self.genop('direct_call', [cf]+list(args_v), resulttype)
 

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 21 16:10:27 2005
@@ -369,5 +369,9 @@
 	return PyTuple_SetItem(tuple, index, o);
 }
 
-#define PyString_FromRPythonCharArrayAndSize(itemsarray, size) \
+#define PyString_FromLLCharArrayAndSize(itemsarray, size) \
 		PyString_FromStringAndSize(itemsarray->items, size)
+
+#define PyString_ToLLCharArray(s, itemsarray)                           \
+		memcpy(itemsarray->items, PyString_AS_STRING(s),        \
+                       itemsarray->length)

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 21 16:10:27 2005
@@ -108,6 +108,14 @@
     for key, value in defines.items():
         print >> f, '#define %s %s' % (key, value)
     print >> f, '#include "Python.h"'
+    includes = {}
+    for node in database.globalcontainers():
+        for include in node.includes:
+            includes[include] = True
+    includes = includes.keys()
+    includes.sort()
+    for include in includes:
+        print >> f, '#include <%s>' % (include,)
 
     #
     # 1) All declarations

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 21 16:10:27 2005
@@ -263,6 +263,7 @@
 
 
 class ContainerNode:
+    includes = ()
 
     def __init__(self, db, T, obj):
         self.db = db
@@ -396,10 +397,13 @@
         self.obj = obj
         #self.dependencies = {}
         self.typename = db.gettype(T)  #, who_asks=self)
-        argnames = self.funcgen.argnames()
-        self.implementationtypename = db.gettype(T, argnames=argnames)
+        if self.funcgen:
+            argnames = self.funcgen.argnames()
+            self.implementationtypename = db.gettype(T, argnames=argnames)
         self.name = db.namespace.uniquename('g_' + self.basename())
         self.ptrname = self.name
+        if hasattr(obj, 'includes'):
+            self.includes = obj.includes
 
     def basename(self):
         return self.obj._name
@@ -407,8 +411,16 @@
     def enum_dependencies(self):
         return self.funcgen.allconstantvalues()
 
+    def forward_declaration(self):
+        if self.funcgen:
+            return ContainerNode.forward_declaration(self)
+        else:
+            return []
+
     def implementation(self):
         funcgen = self.funcgen
+        if funcgen is None:
+            return
         yield '%s {' % cdecl(self.implementationtypename, self.name)
         #
         # declare the local variables
@@ -456,7 +468,10 @@
         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)
+        if getattr(fnptr, 'includes', None):
+            return None   # assume no wrapper needed
+        else:
+            return CExternalFunctionCodeGenerator(fnptr, db)
     else:
         raise ValueError, "don't know how to generate code for %r" % (fnptr,)
 

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 21 16:10:27 2005
@@ -206,3 +206,24 @@
     assert t0 <= t1 <= t2
     mallocs, frees = module.malloc_counters()
     assert mallocs == frees
+
+def test_str():
+    def call_str(o):
+        return str(o)
+    t = Translator(call_str)
+    t.annotate([object])
+    t.specialize()
+    #t.view()
+
+    db = LowLevelDatabase(t)
+    entrypoint = db.get(pyobjectptr(call_str))
+    db.complete()
+
+    module = compile_db(db)
+
+    f1 = getattr(module, entrypoint)
+    lst = (1, [5], "'hello'", lambda x: x+1)
+    res = f1(lst)
+    assert res == str(lst)
+    mallocs, frees = module.malloc_counters()
+    assert mallocs == frees



More information about the Pypy-commit mailing list