[pypy-svn] r14307 - in pypy/branch/dist-2.4.1/pypy: annotation interpreter interpreter/pyparser module/recparser objspace/std objspace/std/test rpython rpython/test translator/c translator/c/test translator/llvm2 translator/llvm2/test

arigo at codespeak.net arigo at codespeak.net
Tue Jul 5 20:13:27 CEST 2005


Author: arigo
Date: Tue Jul  5 20:13:26 2005
New Revision: 14307

Added:
   pypy/branch/dist-2.4.1/pypy/rpython/extfunctable.py
      - copied unchanged from r14306, pypy/dist/pypy/rpython/extfunctable.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/varsize.py
      - copied unchanged from r14306, pypy/dist/pypy/translator/llvm2/varsize.py
Modified:
   pypy/branch/dist-2.4.1/pypy/annotation/bookkeeper.py
   pypy/branch/dist-2.4.1/pypy/annotation/builtin.py
   pypy/branch/dist-2.4.1/pypy/interpreter/pyopcode.py
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonutil.py
   pypy/branch/dist-2.4.1/pypy/module/recparser/pyparser.py
   pypy/branch/dist-2.4.1/pypy/objspace/std/intobject.py
   pypy/branch/dist-2.4.1/pypy/objspace/std/longobject.py
   pypy/branch/dist-2.4.1/pypy/objspace/std/test/test_longobject.py
   pypy/branch/dist-2.4.1/pypy/rpython/llinterp.py
   pypy/branch/dist-2.4.1/pypy/rpython/rbuiltin.py
   pypy/branch/dist-2.4.1/pypy/rpython/rmodel.py
   pypy/branch/dist-2.4.1/pypy/rpython/rstr.py
   pypy/branch/dist-2.4.1/pypy/rpython/rtyper.py
   pypy/branch/dist-2.4.1/pypy/rpython/test/test_rbuiltin.py
   pypy/branch/dist-2.4.1/pypy/rpython/test/test_rstr.py
   pypy/branch/dist-2.4.1/pypy/translator/c/database.py
   pypy/branch/dist-2.4.1/pypy/translator/c/node.py
   pypy/branch/dist-2.4.1/pypy/translator/c/test/test_database.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/arraynode.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/atomic.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/codewriter.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/database.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/funcnode.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/node.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/structnode.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/test/test_genllvm.py
Log:
svn merge -r14266:14306 http://codespeak.net/svn/pypy/dist


Modified: pypy/branch/dist-2.4.1/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/annotation/bookkeeper.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/annotation/bookkeeper.py	Tue Jul  5 20:13:26 2005
@@ -627,7 +627,7 @@
                     raise Exception, "no __init__ found in %r" % (cls,)
             return s_instance
 
-        assert isinstance(func, FunctionType), "[%s] expected function, got %r" % (self.whereami(), func)
+        assert isinstance(func, FunctionType), "[%s] expected user-defined function, got %r" % (self.whereami(), func)
 
         inputcells = self.get_inputcells(func, args)
 

Modified: pypy/branch/dist-2.4.1/pypy/annotation/builtin.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/annotation/builtin.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/annotation/builtin.py	Tue Jul  5 20:13:26 2005
@@ -67,9 +67,8 @@
     return constpropagate(bool, [s_obj], SomeBool())
 
 def builtin_int(s_obj, s_base=None):
-    assert (s_base is None or s_base.is_constant() 
-            and s_base.const == 16
-            and s_obj.knowntype == str), "only int(v|string) or int(string,16) expected"
+    assert (s_base is None or isinstance(s_base, SomeInteger)
+            and s_obj.knowntype == str), "only int(v|string) or int(string,int) expected"
     if s_base is not None:
         args_s = [s_obj, s_base]
     else:
@@ -336,3 +335,9 @@
 BUILTIN_ANALYZERS[lltype.getRuntimeTypeInfo] = getRuntimeTypeInfo
 BUILTIN_ANALYZERS[lltype.runtime_type_info] = runtime_type_info
 
+from pypy.rpython import extfunctable
+
+# import annotation information for external functions 
+# from the extfunctable.table  into our own annotation specific table 
+for func, extfuncinfo in extfunctable.table.iteritems():
+    BUILTIN_ANALYZERS[func] = extfuncinfo.annotation 

Modified: pypy/branch/dist-2.4.1/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/pyopcode.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/pyopcode.py	Tue Jul  5 20:13:26 2005
@@ -171,6 +171,7 @@
     BINARY_TRUE_DIVIDE  = binaryoperation("truediv")
     BINARY_FLOOR_DIVIDE = binaryoperation("floordiv")
     BINARY_DIVIDE       = binaryoperation("div")
+    # XXX BINARY_DIVIDE must fall back to BINARY_TRUE_DIVIDE with -Qnew
     BINARY_MODULO       = binaryoperation("mod")
     BINARY_ADD      = binaryoperation("add")
     BINARY_SUBTRACT = binaryoperation("sub")
@@ -191,6 +192,7 @@
     INPLACE_TRUE_DIVIDE  = binaryoperation("inplace_truediv")
     INPLACE_FLOOR_DIVIDE = binaryoperation("inplace_floordiv")
     INPLACE_DIVIDE       = binaryoperation("inplace_div")
+    # XXX INPLACE_DIVIDE must fall back to INPLACE_TRUE_DIVIDE with -Qnew
     INPLACE_MODULO       = binaryoperation("inplace_mod")
     INPLACE_ADD      = binaryoperation("inplace_add")
     INPLACE_SUBTRACT = binaryoperation("inplace_sub")

Modified: pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonutil.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonutil.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonutil.py	Tue Jul  5 20:13:26 2005
@@ -1,5 +1,4 @@
-__all__ = ["python_parse", "pypy_parse", "ast_single_input", "ast_file_input",
-           "ast_eval_input"]
+__all__ = ["python_parse", "pypy_parse"]
 
 import parser
 import symbol

Modified: pypy/branch/dist-2.4.1/pypy/module/recparser/pyparser.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/module/recparser/pyparser.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/module/recparser/pyparser.py	Tue Jul  5 20:13:26 2005
@@ -8,7 +8,6 @@
 from pypy.interpreter.typedef import interp_attrproperty, GetSetProperty
 from pypy.interpreter.pycode import PyCode 
 from pypy.interpreter.pyparser.syntaxtree import SyntaxNode
-from pypy.interpreter.pyparser.pythonparse import parse_python_source
 from pypy.interpreter.pyparser.pythonutil import PYTHON_PARSER
 
 __all__ = [ "ASTType", "STType", "suite", "expr" ]
@@ -101,16 +100,14 @@
 
 def suite( space, source ):
     # make the annotator life easier (don't use str.splitlines())
-    strings = [line + '\n' for line in source.split('\n')]
-    builder = parse_python_source( strings, PYTHON_PARSER, "file_input" )
+    builder = PYTHON_PARSER.parse_source( source, "file_input" )
     return space.wrap( STType(space, builder.stack[-1]) )    
 
 suite.unwrap_spec = [ObjSpace, str]
 
 def expr( space, source ):
     # make the annotator life easier (don't use str.splitlines())
-    strings = [line + '\n' for line in source.split('\n')]
-    builder = parse_python_source( strings, PYTHON_PARSER, "eval_input" )
+    builder = PYTHON_PARSER.parse_source( source, "eval_input" )
     return space.wrap( STType(space, builder.stack[-1]) )    
 
 expr.unwrap_spec = [ObjSpace, str]

Modified: pypy/branch/dist-2.4.1/pypy/objspace/std/intobject.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/objspace/std/intobject.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/objspace/std/intobject.py	Tue Jul  5 20:13:26 2005
@@ -209,13 +209,8 @@
     m = x % y
     return space.wrap((z,m))
 
-old_style_div = 1 / 2 == 1 // 2
 def div__Int_Int(space, w_int1, w_int2):
-    # Select the proper div
-    if old_style_div:
-        return _floordiv(space, w_int1, w_int2)
-    else:
-        return _truediv(space, w_int1, w_int2)
+    return _floordiv(space, w_int1, w_int2)
 
 floordiv__Int_Int = _floordiv
 truediv__Int_Int = _truediv

Modified: pypy/branch/dist-2.4.1/pypy/objspace/std/longobject.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/objspace/std/longobject.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/objspace/std/longobject.py	Tue Jul  5 20:13:26 2005
@@ -9,7 +9,7 @@
 import math
 
 SHORT_BIT = int(LONG_BIT // 2)
-SHORT_MASK = int(LONG_MASK >> SHORT_BIT)
+SHORT_MASK = int((1 << SHORT_BIT) - 1)
 
 SIGN_BIT = LONG_BIT-1
 SIGN_MASK = r_uint(1) << SIGN_BIT
@@ -63,7 +63,8 @@
 
     def _setshort(self, index, short):
         a = self.digits[index // 2]
-        assert isinstance(short, r_uint)
+        ##!!assert isinstance(short, r_uint)
+        assert short & SHORT_MASK == short
         if index % 2 == 0:
             self.digits[index // 2] = ((a >> SHORT_BIT) << SHORT_BIT) + short
         else:
@@ -258,25 +259,19 @@
     return space.newfloat(div)
 
 def floordiv__Long_Long(space, w_long1, w_long2):
-    div, rem = _divrem(space, w_long1, w_long2)
+    div, mod = _l_divmod(space, w_long1, w_long2)
     return div
 
-old_style_div = 1 / 2 == 1 // 2
 def div__Long_Long(space, w_long1, w_long2):
-    # Select the proper div
-    if old_style_div:
-        return floordiv__Long_Long(space, w_long1, w_long2)
-    else:
-        return truediv__Long_Long(space, w_long1, w_long2)
-
+    return floordiv__Long_Long(space, w_long1, w_long2)
 
 def mod__Long_Long(space, w_long1, w_long2):
-    div, rem = _divrem(space, w_long1, w_long2)
-    return rem
+    div, mod = _l_divmod(space, w_long1, w_long2)
+    return mod
 
 def divmod__Long_Long(space, w_long1, w_long2):
-    div, rem = _divrem(space, w_long1, w_long2)
-    return space.newtuple([div, rem])
+    div, mod = _l_divmod(space, w_long1, w_long2)
+    return space.newtuple([div, mod])
 
 # helper for pow()  #YYYYYY: still needs longval if second argument is negative
 def _impl_long_long_pow(space, lv, lw, lz=None):
@@ -733,6 +728,15 @@
         res >>= n
         return res
 
+    def __ilshift__(self, n):
+        self.value <<= n
+        return self
+
+    def __lshift__(self, n):
+        res = r_suint(self)
+        res <<= n
+        return res
+
     def __and__(self, mask):
         # only used to get bits from the value
         return self.value & mask
@@ -742,7 +746,7 @@
             other = r_suint(other)
         return self.sign == other.sign and self.value == other.value
 
-def _x_divrem(space, v1, w1): # return as tuple, PyLongObject **prem)
+def _x_divrem(space, v1, w1):
     size_w = len(w1.digits) * 2
     # hack for the moment:
     # find where w1 is really nonzero
@@ -762,8 +766,10 @@
     size_a = size_v - size_w + 1
     digitpairs = (size_a + 1) // 2
     a = W_LongObject(space, [r_uint(0)] * digitpairs, 1)
+
     j = size_v
-    for k in range(size_a-1, -1, -1):
+    k = size_a - 1
+    while k >= 0:
         if j >= size_v:
             vj = r_uint(0)
         else:
@@ -775,18 +781,20 @@
         else:
             q = ((vj << SHORT_BIT) + v._getshort(j-1)) // w._getshort(size_w-1)
 
+        # notabene!
+        # this check needs a signed two digits result
+        # or we get an overflow.
         while (w._getshort(size_w-2) * q >
                 ((
-                    (vj << SHORT_BIT)
+                    r_suint(vj << SHORT_BIT) # this one dominates
                     + v._getshort(j-1)
                     - q * w._getshort(size_w-1)
                                 ) << SHORT_BIT)
                 + v._getshort(j-2)):
             q -= 1
 
-        for i in range(size_w):
-            if i+k >= size_v:
-                break
+        i = 0
+        while i < size_w and i+k < size_v:
             z = w._getshort(i) * q
             zz = z >> SHORT_BIT
             carry += v._getshort(i+k) + (zz << SHORT_BIT)
@@ -794,8 +802,8 @@
             v._setshort(i+k, r_uint(carry.value & SHORT_MASK))
             carry >>= SHORT_BIT
             carry -= zz
+            i += 1
 
-        i += 1 # compare C code which re-uses i of loop
         if i+k < size_v:
             carry += v._getshort(i+k)
             v._setshort(i+k, r_uint(0))
@@ -803,18 +811,18 @@
         if carry == 0:
             a._setshort(k, q)
         else:
-            #assert carry == -1
-            # the above would hold if we didn't minimize size_w
+            assert carry == -1
             a._setshort(k, q-1)
-            carry = r_suint(0)
 
-            for i in range(size_w):
-                if i+k >= size_v:
-                    break
+            carry = r_suint(0)
+            i = 0
+            while i < size_w and i+k < size_v:
                 carry += v._getshort(i+k) + w._getshort(i)
-                v._setshort(i+k, r_uint(carry) & SHORT_MASK)
+                v._setshort(i+k, r_uint(carry.value) & SHORT_MASK)
                 carry >>= SHORT_BIT
+                i += 1
         j -= 1
+        k -= 1
 
     a._normalize()
     rem, _ = _divrem1(space, v, d)
@@ -830,9 +838,9 @@
     if b._getshort(size_b-1) == 0:
         size_b -= 1
 
-    if size_b == 0:
-        raise OperationError(w_longobj.space.w_ZeroDivisionError,
-                             w_longobj.space.wrap("long division or modulo by zero"))
+    if b.sign == 0:
+        raise OperationError(space.w_ZeroDivisionError,
+                             space.wrap("long division or modulo by zero"))
 
     if (size_a < size_b or
         (size_a == size_b and
@@ -852,7 +860,7 @@
     # so a = b*z + r.
     if a.sign != b.sign:
         z.sign = - z.sign
-    if z.sign < 0 and rem.sign != 0:
+    if a.sign < 0 and rem.sign != 0:
         rem.sign = - rem.sign
     return z, rem
 
@@ -891,29 +899,31 @@
     assert x > 0.0
     return x * sign, exponent
 
-# XXX make ldexp and isinf a builtin float support function
-
 def isinf(x):
-    return x*2 == x
+    return x != 0.0 and x / 2 == x
+
+##def ldexp(x, exp):
+##    assert type(x) is float
+##    lb1 = LONG_BIT - 1
+##    multiplier = float(r_uint(1) << lb1)
+##    while exp >= lb1:
+##        x *= multiplier
+##        exp -= lb1
+##    if exp:
+##        x *= float(r_uint(1) << exp)
+##    return x
 
-def ldexp(x, exp):
-    assert type(x) is float
-    lb1 = LONG_BIT - 1
-    multiplier = float(r_uint(1) << lb1)
-    while exp >= lb1:
-        x *= multiplier
-        exp -= lb1
-    if exp:
-        x *= float(r_uint(1) << exp)
-    return x
+# note that math.ldexp checks for overflows,
+# while the C ldexp is not guaranteed to.
 
 def _AsDouble(v):
     """ Get a C double from a long int object. """
     x, e = _AsScaledDouble(v)
     if e <= sys.maxint / SHORT_BIT:
-        x = ldexp(x, e * SHORT_BIT)
-        if not isinf(x):
-            return x
+        x = math.ldexp(x, e * SHORT_BIT)
+        #if not isinf(x):
+        # this is checked by math.ldexp
+        return x
     raise OverflowError# sorry, "long int too large to convert to float"
 
 def _long_true_divide(space, a, b):
@@ -931,10 +941,61 @@
             raise OverflowError
         elif aexp < -(sys.maxint / SHORT_BIT):
             return 0.0 # underflow to 0
-        ad = ldexp(ad, aexp * SHORT_BIT)
-        if isinf(ad):   # ignore underflow to 0.0
-            raise OverflowError
+        ad = math.ldexp(ad, aexp * SHORT_BIT)
+        #if isinf(ad):   # ignore underflow to 0.0
+        #    raise OverflowError
+        # math.ldexp checks and raises
         return ad
     except OverflowError:
         raise OperationError(space.w_OverflowError,
                              space.wrap("long/long too large for a float"))
+
+
+def _FromDouble(space, dval):
+    """ Create a new long int object from a C double """
+    neg = 0
+    if isinf(dval):
+        raise OperationError(space.w_OverflowError,
+                             space.wrap("cannot convert float infinity to long"))
+    if dval < 0.0:
+        neg = 1
+        dval = -dval
+    frac, expo = math.frexp(dval) # dval = frac*2**expo; 0.0 <= frac < 1.0
+    if expo <= 0:
+        return W_LongObject(space, [r_uint(0)], 0)
+    ndig = (expo-1) // SHORT_BIT + 1 # Number of 'digits' in result
+    digitpairs = (ndig + 1) // 2
+    v = W_LongObject(space, [r_uint(0)] * digitpairs, 1)
+    frac = math.ldexp(frac, (expo-1) % SHORT_BIT + 1)
+    for i in range(ndig-1, -1, -1):
+        bits = int(frac)
+        v._setshort(i, r_uint(bits))
+        frac -= float(bits)
+        frac = math.ldexp(frac, SHORT_BIT)
+    if neg:
+        v.sign = -1
+    return v
+
+def _l_divmod(space, v, w):
+    """
+    The / and % operators are now defined in terms of divmod().
+    The expression a mod b has the value a - b*floor(a/b).
+    The _divrem function gives the remainder after division of
+    |a| by |b|, with the sign of a.  This is also expressed
+    as a - b*trunc(a/b), if trunc truncates towards zero.
+    Some examples:
+      a   b   a rem b     a mod b
+      13  10   3           3
+     -13  10  -3           7
+      13 -10   3          -7
+     -13 -10  -3          -3
+    So, to get from rem to mod, we have to add b if a and b
+    have different signs.  We then subtract one from the 'div'
+    part of the outcome to keep the invariant intact.
+    """
+    div, mod = _divrem(space, v, w)
+    if mod.sign * w.sign == -1:
+        mod = add__Long_Long(space, mod, w)
+        one = W_LongObject(space, [r_uint(1)], 1)
+        div = sub__Long_Long(space, div, one)
+    return div, mod

Modified: pypy/branch/dist-2.4.1/pypy/objspace/std/test/test_longobject.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/objspace/std/test/test_longobject.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/objspace/std/test/test_longobject.py	Tue Jul  5 20:13:26 2005
@@ -4,6 +4,7 @@
 from pypy.objspace.std import longobject as lobj
 from pypy.objspace.std.objspace import FailedToImplement
 from pypy.rpython.rarithmetic import r_uint
+from pypy.interpreter.error import OperationError
 
 objspacename = 'std'
 
@@ -112,6 +113,18 @@
         f1 = lobj.W_LongObject(self.space, *lobj.args_from_long(x))
         assert raises(OverflowError, lobj._AsDouble, f1)
 
+    def test__FromDouble(self):
+        x = 1234567890.1234567890
+        f1 = lobj._FromDouble(self.space, x)
+        y = lobj._AsDouble(f1)
+        assert f1.longval() == long(x)
+        # check overflow
+        x = 12345.6789e10000000000000000000000000000
+        try:
+            lobj._FromDouble(self.space, x)
+        except OperationError, e:
+            assert e.w_type is self.space.w_OverflowError
+
     def test_eq(self):
         x = 5858393919192332223L
         y = 585839391919233111223311112332L
@@ -289,3 +302,21 @@
     def test_getnewargs(self):
         assert  0L .__getnewargs__() == (0L,)
         assert  (-1L) .__getnewargs__() == (-1L,)
+
+    def test_divmod(self):
+        def check_division(x, y):
+            q, r = divmod(x, y)
+            pab, pba = x*y, y*x
+            assert pab == pba
+            assert q == x//y
+            assert r == x%y
+            assert x == q*y + r
+            if y > 0:
+                assert 0 <= r < y
+            else:
+                assert y < r <= 0
+        for x in [-1L, 0L, 1L, 2L ** 100 - 1, -2L ** 100 - 1]:
+            for y in [-105566530L, -1L, 1L, 1034522340L]:
+                print "checking division for %s, %s" % (x, y)
+                check_division(x, y)
+            raises(ZeroDivisionError, "x // 0L")

Modified: pypy/branch/dist-2.4.1/pypy/rpython/llinterp.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/rpython/llinterp.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/rpython/llinterp.py	Tue Jul  5 20:13:26 2005
@@ -169,7 +169,11 @@
         if hasattr(f._obj, 'graph'):
             graph = f._obj.graph
         else:
-            graph = self.llinterpreter.getgraph(f._obj._callable)
+            try:
+                graph = self.llinterpreter.getgraph(f._obj._callable)
+            except KeyError:
+                assert hasattr(f._obj, '_callable'), "don't know how to execute %r" % f
+                return f._obj._callable(*args)
         frame = self.__class__(graph, args, self.llinterpreter)
         return frame.eval()
 

Modified: pypy/branch/dist-2.4.1/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/rpython/rbuiltin.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/rpython/rbuiltin.py	Tue Jul  5 20:13:26 2005
@@ -9,7 +9,7 @@
 from pypy.rpython.robject import pyobj_repr
 from pypy.rpython.rfloat import float_repr, FloatRepr
 from pypy.rpython import rclass
-
+from pypy.tool import sourcetools
 
 class __extend__(annmodel.SomeBuiltin):
     def rtyper_makerepr(self, rtyper):
@@ -87,7 +87,8 @@
 
 def rtype_builtin_int(hop):
     if isinstance(hop.args_s[0], annmodel.SomeString):
-        raise TyperError('int("string") not supported')
+	assert 1 <= hop.nb_args <= 2
+	return hop.args_r[0].rtype_int(hop)
     assert hop.nb_args == 1
     return hop.args_r[0].rtype_int(hop)
 
@@ -240,3 +241,27 @@
                                  includes=("math.h",))   # XXX clean up needed
 
 BUILTIN_TYPER[math.exp] = rtype_math_exp
+
+from pypy.rpython import extfunctable
+
+def make_rtype_extfunc(extfuncinfo):
+    ll_function = extfuncinfo.ll_function
+    if extfuncinfo.ll_annotable:
+        def rtype_extfunc(hop):
+            vars = hop.inputargs(*hop.args_r)
+            return hop.gendirectcall(ll_function, *vars)
+    else:
+        def rtype_extfunc(hop):
+            resulttype = hop.r_result
+            vars = hop.inputargs(*hop.args_r)
+            return hop.llops.genexternalcall(ll_function.__name__, vars, resulttype=resulttype,
+                                             _callable = ll_function)
+            
+    return sourcetools.func_with_new_name(rtype_extfunc,
+                                          "rtype_extfunc_%s" % extfuncinfo.func.__name__)
+
+# import rtyping information for external functions 
+# from the extfunctable.table  into our own specific table 
+for func, extfuncinfo in extfunctable.table.iteritems():
+    BUILTIN_TYPER[func] = make_rtype_extfunc(extfuncinfo)
+

Modified: pypy/branch/dist-2.4.1/pypy/rpython/rmodel.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/rpython/rmodel.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/rpython/rmodel.py	Tue Jul  5 20:13:26 2005
@@ -226,11 +226,13 @@
 def getconcretetype(v):
     return getattr(v, 'concretetype', PyObjPtr)
 
-def getfunctionptr(translator, func, getconcretetype=getconcretetype):
+def getfunctionptr(translator, graphfunc, getconcretetype=getconcretetype, _callable=None):
     """Make a functionptr from the given Python function."""
-    graph = translator.getflowgraph(func)
+    graph = translator.getflowgraph(graphfunc)
     llinputs = [getconcretetype(v) for v in graph.getargs()]
     lloutput = getconcretetype(graph.getreturnvar())
     FT = FuncType(llinputs, lloutput)
-    return functionptr(FT, func.func_name, graph = graph, _callable = func)
+    if _callable is None:
+        _callable = graphfunc
+    return functionptr(FT, graphfunc.func_name, graph = graph, _callable = _callable)
 

Modified: pypy/branch/dist-2.4.1/pypy/rpython/rstr.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/rpython/rstr.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/rpython/rstr.py	Tue Jul  5 20:13:26 2005
@@ -23,8 +23,8 @@
 #        chars: array of Char
 #    }
 
-STR = GcStruct('str', ('hash',  Signed),
-                      ('chars', Array(Char)))
+STR = GcStruct('rpy_string', ('hash',  Signed),
+                             ('chars', Array(Char)))
 
 SIGNED_ARRAY = GcArray(Signed)
 
@@ -142,6 +142,16 @@
         v_str, v_c1, v_c2 = hop.inputargs(string_repr, char_repr, char_repr)
         return hop.gendirectcall(ll_replace_chr_chr, v_str, v_c1, v_c2)
 
+    def rtype_int(_, hop):
+	if hop.nb_args == 1:
+	    v_str, = hop.inputargs(string_repr)
+	    c_base = inputconst(Signed, 10)
+	    return hop.gendirectcall(ll_int, v_str, c_base)
+        if not hop.args_r[1] == rint.signed_repr:
+            raise TyperError, 'base needs to be an int'
+	v_str, v_base= hop.inputargs(string_repr, rint.signed_repr)
+	return hop.gendirectcall(ll_int, v_str, v_base)
+
     def ll_str(s, r):
         if typeOf(s) == Char:
             return ll_chr2str(s)
@@ -768,6 +778,47 @@
         i += 1
     return False
 
+def ll_int(s, base):
+    if not 2 <= base <= 36:
+	raise ValueError
+    chars = s.chars
+    strlen = len(chars)
+    i = 0
+    #XXX: only space is allowed as white space for now
+    while i < strlen and chars[i] == ' ':
+	i += 1
+    if not i < strlen:
+	raise ValueError
+    #check sign
+    sign = 1
+    if chars[i] == '-':
+	sign = -1
+	i += 1
+    elif chars[i] == '+':
+	i += 1;
+    #now get digits
+    val = 0
+    while i < strlen:
+	c = ord(chars[i])
+	if ord('a') <= c <= ord('z'):
+	    digit = c - ord('a') + 10
+	elif ord('A') <= c <= ord('Z'):
+	    digit = c - ord('A') + 10
+	elif ord('0') <= c <= ord('9'):
+	    digit = c - ord('0')
+	else:
+	    break
+	if digit >= base:
+	    break
+	val = val * base + digit
+	i += 1
+    #skip trailing whitespace
+    while i < strlen and chars[i] == ' ':
+	i += 1
+    if not i == strlen:
+	raise ValueError
+    return sign * val
+
 # ____________________________________________________________
 #
 #  Iteration.

Modified: pypy/branch/dist-2.4.1/pypy/rpython/rtyper.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/rpython/rtyper.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/rpython/rtyper.py	Tue Jul  5 20:13:26 2005
@@ -50,6 +50,7 @@
             r = self.getrepr(s_primitive)
             self.primitive_to_repr[r.lowleveltype] = r
         self.exceptiondata = ExceptionData(self)
+        self.fixednames = self.fixednames.copy()
 
     def getexceptiondata(self):
         return self.exceptiondata    # built at the end of specialize()
@@ -355,10 +356,10 @@
 
     # __________ utilities __________
 
-    def getfunctionptr(self, func):
+    def getfunctionptr(self, graphfunc, _callable=None):
         def getconcretetype(v):
             return self.bindingrepr(v).lowleveltype
-        return getfunctionptr(self.annotator.translator, func, getconcretetype)
+        return getfunctionptr(self.annotator.translator, graphfunc, getconcretetype, _callable=_callable)
 
     def attachRuntimeTypeInfoFunc(self, GCSTRUCT, func, ARG_GCSTRUCT=None):
         self.call_all_setups()  # compute ForwardReferences now
@@ -516,20 +517,22 @@
         dontcare, spec_function = annotate_lowlevel_helper(rtyper.annotator, ll_function, args_s)
 
         # build the 'direct_call' operation
-        f = self.rtyper.getfunctionptr(spec_function)
+        f = self.rtyper.getfunctionptr(spec_function, _callable=ll_function)
         c = inputconst(typeOf(f), f)
         return self.genop('direct_call', [c]+list(args_v),
                           resulttype = typeOf(f).TO.RESULT)
 
-    def gencapicall(self, cfnname, args_v, resulttype=None, **flags):
+    def genexternalcall(self, fnname, 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", **flags)
+        f = functionptr(FUNCTYPE, fnname, **flags)
         cf = inputconst(typeOf(f), f)
         return self.genop('direct_call', [cf]+list(args_v), resulttype)
 
+    def gencapicall(self, cfnname, args_v, resulttype=None, **flags):
+        return self.genexternalcall(cfnname, args_v, resulttype=resulttype, external="C")
 
 # _______________________________________________________________________
 # this has the side-effect of registering the unary and binary operations
@@ -540,3 +543,6 @@
 from pypy.rpython import rlist, rstr, rtuple, rdict 
 from pypy.rpython import rclass, rbuiltin, rpbc
 from pypy.rpython import rptr
+
+RPythonTyper.fixednames = {}
+RPythonTyper.fixednames[rstr.STR] = True

Modified: pypy/branch/dist-2.4.1/pypy/rpython/test/test_rbuiltin.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/rpython/test/test_rbuiltin.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/rpython/test/test_rbuiltin.py	Tue Jul  5 20:13:26 2005
@@ -1,4 +1,7 @@
 from pypy.rpython.test.test_llinterp import interpret
+from pypy.rpython.test import test_llinterp
+from pypy.objspace.flow import model as flowmodel
+from pypy.tool import udir
 
 from pypy.annotation.builtin import *
 import py
@@ -61,6 +64,59 @@
             ry = 100 * float(i-10) +0.1
             assert fn(rv,ry) == interpret(fn, (rv, ry))
 
+def enum_direct_calls(translator, func):
+    blocks = []
+    graph = translator.getflowgraph(func)
+    def visit(block):
+        if isinstance(block, flowmodel.Block):
+            blocks.append(block)
+    flowmodel.traverse(visit, graph)
+    for block in blocks:
+        for op in block.operations:
+            if op.opname == 'direct_call':
+                yield op
+
+def test_os_getcwd():
+    import os
+    def fn():
+        return os.getcwd()
+    res = interpret(fn, []) 
+    assert ''.join(res.chars) == fn()
+        
+def test_os_dup():
+    import os
+    def fn(fd):
+        return os.dup(fd)
+    res = interpret(fn, [0])
+    #try:
+    #    os.close(res)
+    #except OSError:
+    #    pass
+    count = 0
+    from pypy.rpython import extfunctable
+    for dir_call in enum_direct_calls(test_llinterp.typer.annotator.translator, fn):
+        cfptr = dir_call.args[0]
+        assert cfptr.value._obj._callable == extfunctable.ll_os_dup
+        count += 1
+    assert count == 1
+
+def test_os_open():
+    tmpdir = str(udir.udir.join("os_open_test"))
+    import os
+    def wr_open(fname):
+        return os.open(fname, os.O_WRONLY|os.O_CREAT)
+    def f():
+        return wr_open(tmpdir)
+    res = interpret(f, [])
+    os.close(res)
+    count = 0
+    from pypy.rpython import extfunctable
+    for dir_call in enum_direct_calls(test_llinterp.typer.annotator.translator, wr_open):
+        cfptr = dir_call.args[0]
+        assert cfptr.value._obj._callable == extfunctable.ll_os_open
+        count += 1
+    assert count == 1
+        
 def test_pbc_isTrue():
     class C:
         def f(self):

Modified: pypy/branch/dist-2.4.1/pypy/rpython/test/test_rstr.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/rpython/test/test_rstr.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/rpython/test/test_rstr.py	Tue Jul  5 20:13:26 2005
@@ -2,8 +2,8 @@
 from pypy.rpython.lltype import *
 from pypy.rpython.rstr import parse_fmt_string
 from pypy.rpython.rtyper import RPythonTyper, TyperError
-from pypy.rpython.test.test_llinterp import interpret
-
+from pypy.rpython.test.test_llinterp import interpret,find_exception
+from pypy.rpython.llinterp import LLException
 
 def test_simple():
     def fn(i):
@@ -356,3 +356,20 @@
         s = 'abbccc'
         s = s.replace('abb', 'c')
     raises (TyperError, interpret, fn, ())
+
+def test_int():
+    s1 = [ '42', '01001', 'abc', 'ABC', '4aBc', ' 12ef ', '+42', 'foo', '42foo', '42.1', '']
+    def fn(i, base):
+        s = s1[i]
+        res = int(s, base)
+        return res
+    for j in (10, 16, 2, 1, 36, 42, -3):
+	for i in range(len(s1)):
+	    try:
+		expected = fn(i, j)
+	    except ValueError:
+		info = raises(LLException, interpret, fn, [i, j])
+		assert find_exception(info.value) is ValueError
+	    else:
+		res = interpret(fn, [i, j])
+		assert res == expected

Modified: pypy/branch/dist-2.4.1/pypy/translator/c/database.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/c/database.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/c/database.py	Tue Jul  5 20:13:26 2005
@@ -21,6 +21,16 @@
         self.containernodes = {}
         self.containerlist = []
         self.namespace = CNameManager()
+        if translator is not None and translator.rtyper is not None:
+            rtyper = translator.rtyper
+            for lltype, nameorflag in rtyper.fixednames.iteritems():
+                if nameorflag is True:
+                    self.namespace.make_reserved_names(lltype._name)
+                #else:
+                #    self.namespace.make_reserved_names(nameorflag)
+            self.fixednames = rtyper.fixednames
+        else:
+            self.fixednames = {}
         self.pyobjmaker = PyObjMaker(self.namespace, self.get, translator)
 
     def gettypedefnode(self, T, varlength=1):

Modified: pypy/branch/dist-2.4.1/pypy/translator/c/node.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/c/node.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/c/node.py	Tue Jul  5 20:13:26 2005
@@ -38,7 +38,10 @@
         else:
             basename = db.gettypedefnode(STRUCT).name
             basename = '%s_len%d' % (basename, varlength)
-        self.name = db.namespace.uniquename(basename)
+        if STRUCT in db.fixednames:
+            self.name = basename
+        else:
+            self.name = db.namespace.uniquename(basename)
         self.dependencies = {}
         self.fields = []
         self.prefix = somelettersfrom(STRUCT._name) + '_'

Modified: pypy/branch/dist-2.4.1/pypy/translator/c/test/test_database.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/c/test/test_database.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/c/test/test_database.py	Tue Jul  5 20:13:26 2005
@@ -196,6 +196,23 @@
     db.complete()
     dump_on_stdout(db)
 
+def test_fixedname():
+    def f():
+        return "foo"
+    t = Translator(f)
+    t.annotate([])
+    t.specialize()
+
+    db = LowLevelDatabase(t)
+    S = GcStruct('rpy_string', ('x', Signed))
+    s = malloc(S)
+    s.x = 42
+    db.get(s)    
+    Sname = db.gettype(S)
+    db.get(pyobjectptr(f))
+    from pypy.rpython import rstr
+    assert db.gettype(rstr.STR) == "struct rpy_string @"
+    assert Sname != "struct rpy_string @"
 
 def test_malloc():
     S = GcStruct('testing', ('x', Signed), ('y', Signed))

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/arraynode.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/arraynode.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/arraynode.py	Tue Jul  5 20:13:26 2005
@@ -3,65 +3,34 @@
 from pypy.translator.llvm2.log import log
 from pypy.translator.llvm2.node import LLVMNode
 from pypy.objspace.flow.model import Constant
+from pypy.translator.llvm2 import varsize 
 import itertools  
 log = log.structnode
 
-count = itertools.count().next 
-
-def wrapstr(s):
-    return '"%s"' % s
+nextnum = itertools.count().next 
 
 class ArrayTypeNode(LLVMNode):
     _issetup = False
     def __init__(self, db, array):
-        self.db = db
         assert isinstance(array, lltype.Array)
+
+        self.db = db
         self.array = array
-        c = count()
-        ref_template = wrapstr("%%array.%s." + str(c))
 
-        self.ref = ref_template % array.OF
-        self.constructor_ref = wrapstr("%%new.array.%s" % c)
+        # ref is used to reference the arraytype in llvm source 
+        # constructor_ref is used to reference the constructor 
+        # for the array type in llvm source code 
+        # constructor_decl is used to declare the constructor
+        # for the array type (see writeimpl)
+        c = nextnum()
+        self.ref = "%%array.%s.%s" % (c, array.OF)
+        self.constructor_ref = "%%new.array.%s" % c 
         self.constructor_decl = "%s * %s(int %%len)" % \
                                 (self.ref, self.constructor_ref)
 
     def __str__(self):
         return "<ArrayTypeNode %r>" % self.ref
         
-    def writedecl(self, codewriter): 
-        # declaration for constructor
-        codewriter.declare(self.constructor_decl)
-
-    def writeimpl(self, codewriter):
-        """ this function generates a LLVM function like the following:
-        %array = type { int, [0 x double] }
-        %array *%NewArray(int %len) {
-           ;; Get the offset of the 'len' element of the array from the null
-           ;; pointer.
-           %size = getelementptr %array* null, int 0, uint 1, %int %len
-           %usize = cast double* %size to uint
-           %ptr = malloc sbyte, uint %usize
-           %result = cast sbyte* %ptr to %array*
-           %arraylength = getelementptr %array* %result, int 0, uint 0
-           store int %len, int* %arraylength 
-           ret %array* %result
-        }"""
-        from pypy.translator.llvm2.atomic import is_atomic
-
-        log.writeimpl(self.ref)
-        codewriter.openfunc(self.constructor_decl)
-        indices = [("uint", 1), ("int", "%len")]
-        codewriter.getelementptr("%size", self.ref + "*",
-                                 "null", *indices)
-        fromtype = self.db.repr_arg_type(self.array.OF) 
-        codewriter.cast("%usize", fromtype + "*", "%size", "uint")
-        codewriter.malloc("%ptr", "sbyte", "%usize", atomic=is_atomic(self))
-        codewriter.cast("%result", "sbyte*", "%ptr", self.ref+"*")
-        codewriter.getelementptr("%arraylength", self.ref+"*", "%result", ("uint", 0))
-        codewriter.store("int", "%len", "%arraylength")
-        codewriter.ret(self.ref+"*", "%result")
-        codewriter.closefunc()
-
     def setup(self):
         self.db.prepare_repr_arg_type(self.array.OF)
         self._issetup = True
@@ -72,60 +41,65 @@
     def writedatatypedecl(self, codewriter):
         codewriter.arraydef(self.ref, self.db.repr_arg_type(self.array.OF))
 
-# Each ArrayNode is a global constant.  This needs to have a specific type of
-# a certain type.
+    def writedecl(self, codewriter): 
+        # declaration for constructor
+        codewriter.declare(self.constructor_decl)
+
+    def writeimpl(self, codewriter):
+        log.writeimpl(self.ref)
+        fromtype = self.db.repr_arg_type(self.array.OF) 
+        varsize.write_constructor(codewriter, self.ref, 
+                                  self.constructor_decl,
+                                  fromtype)
 
 class ArrayNode(LLVMNode):
-
     _issetup = False 
-    array_counter = 0
-
     def __init__(self, db, value):
         self.db = db
-        name = '"%%arrayinstance.%s.%s"' % (value._TYPE.OF, ArrayNode.array_counter)
-        self.ref = name
         self.value = value
-        ArrayNode.array_counter += 1
+        self.arraytype = value._TYPE.OF
+        self.ref = "%%arrayinstance.%s.%s" % (value._TYPE.OF, nextnum())
 
     def __str__(self):
         return "<ArrayNode %r>" %(self.ref,)
 
     def setup(self):
-        T = self.value._TYPE.OF
         for item in self.value.items:
-            if not isinstance(T, lltype.Primitive):
+            if not isinstance(self.arraytype, lltype.Primitive):
                 # Create a dummy constant hack XXX
-                c = Constant(item, T)
-                self.db.prepare_arg(c)
-
+                self.db.prepare_arg(Constant(item, self.arraytype))
         self._issetup = True
 
+    def value_helper(self, value):        
+        """ This should really be pushed back to the database??? XXX """
+        if not isinstance(self.arraytype, lltype.Primitive):
+            # Create a dummy constant hack XXX
+            value = self.db.repr_arg(Constant(value, self.arraytype))
+        else:
+            if isinstance(value, str) and len(value) == 1:
+                value = ord(value)                    
+            value = str(value)
+        return value
+    
     def getall(self):
-        arraylen = len(self.value.items)
+        """ Returns the type and value for this node. """
+        items = self.value.items
+        typeval = self.db.repr_arg_type(self.arraytype)
+        arraylen = len(items)
+
+        type_ = "{ int, [%s x %s] }" % (arraylen, typeval)        
+        arrayvalues = ["%s %s" % (typeval,
+                                  self.value_helper(v)) for v in items]
 
-        res = []
-
-        T = self.value._TYPE.OF
-        typval = self.db.repr_arg_type(self.value._TYPE.OF)
-        for value in self.value.items:
-            if not isinstance(T, lltype.Primitive):
-                # Create a dummy constant hack XXX
-                value = self.db.repr_arg(Constant(value, T))
-            else:
-                value = repr(value)
-            res.append((typval, value))
-
-        arrayvalues = ", ".join(["%s %s" % (t, v) for t, v in res])
-
-        type_ = "{ int, [%s x %s] }" % (len(self.value.items),
-                                        self.db.repr_arg_type(self.value._TYPE.OF))
-        
         value = "int %s, [%s x %s] [ %s ]" % (arraylen,
                                               arraylen,
-                                              typval,
-                                              arrayvalues)
+                                              typeval,
+                                              ", ".join(arrayvalues))
         return type_, value
     
+    # ______________________________________________________________________
+    # entry points from genllvm
+
     def writeglobalconstants(self, codewriter):
         type_, values = self.getall()
         codewriter.globalinstance(self.ref, type_, values)

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/atomic.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/atomic.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/atomic.py	Tue Jul  5 20:13:26 2005
@@ -1,16 +1,20 @@
 from pypy.translator.llvm2.log import log
 from pypy.translator.llvm2.structnode import StructTypeNode
 from pypy.translator.llvm2.arraynode import ArrayTypeNode
+from pypy.rpython import lltype
 
 log = log.atomic
 
 def is_atomic(node):
+    # XXX is the below really right? 
     if isinstance(node, StructTypeNode):
-        fields = str([getattr(node.struct, name) for name in node.struct._names_without_voids()])
-        if '*' not in fields:
+        fields = [getattr(node.struct, name) 
+                    for name in node.struct._names_without_voids()]
+        fields = [x for x in fields if isinstance(x, lltype.Ptr)]
+        if not fields: 
             return True #non-pointers only
         return False    #contains pointer(s)
     elif isinstance(node, ArrayTypeNode):
-        return False    #because they actually are arrays of pointers
+        return not isinstance(node.array.OF, lltype.Ptr)
     log("unknown type %s, assuming non-atomic" % str(type(node)))
     return False    

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/codewriter.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/codewriter.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/codewriter.py	Tue Jul  5 20:13:26 2005
@@ -4,7 +4,7 @@
 from pypy.translator.llvm2.genllvm import use_boehm_gc
 
 log = log.codewriter 
-show_line_numbers = True
+show_line_numbers = False # True
 count = count().next
 
 class CodeWriter(object): 

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/database.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/database.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/database.py	Tue Jul  5 20:13:26 2005
@@ -84,7 +84,6 @@
 
                 if isinstance(ct, lltype.Struct):
                     if ct._arrayfld:
-                        assert False, "HERE"
                         self.addpending(const_or_var, StructVarsizeNode(self, value))
                     else:
                         self.addpending(const_or_var, StructNode(self, value))
@@ -153,6 +152,10 @@
     def repr_arg(self, arg):
         if (isinstance(arg, Constant) and 
             isinstance(arg.concretetype, lltype.Primitive)):
+           
+            # XXX generalize and test this 
+            if isinstance(arg.value, str) and len(arg.value) == 1: 
+                return str(ord(arg.value))
             return str(arg.value).lower() #False --> false
         elif isinstance(arg, Variable):
             return "%" + str(arg)

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/funcnode.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/funcnode.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/funcnode.py	Tue Jul  5 20:13:26 2005
@@ -7,19 +7,16 @@
 from pypy.translator.llvm2.node import LLVMNode
 from pypy.translator.llvm2.atomic import is_atomic
 from pypy.translator.llvm2.log import log 
+nextnum = py.std.itertools.count().next
 log = log.funcnode
 
 
 class FuncTypeNode(LLVMNode):
-    func_type_node_counter = 0
-
     def __init__(self, db, type_):
         self.db = db
         assert isinstance(type_, lltype.FuncType)
         self.type_ = type_
-        ref = '"ft.%s.%s"' % (type_, FuncTypeNode.func_type_node_counter)
-        self.ref = ref.replace(" ", "")
-        FuncTypeNode.func_type_node_counter += 1
+        self.ref = 'ft.%s.%s' % (type_, nextnum())
         
     def __str__(self):
         return "<FuncTypeNode %r>" % self.ref
@@ -132,6 +129,7 @@
     def write_block_operations(self, codewriter, block):
         opwriter = OpWriter(self.db, codewriter)
         for op in block.operations:
+            codewriter.comment(str(op))
             opwriter.write_operation(op)
     def write_startblock(self, codewriter, block):
         self.write_block_operations(codewriter, block)
@@ -197,6 +195,15 @@
             assert meth is not None, "operation %r not found" %(op.opname,)
             meth(op)    
 
+    def int_neg(self, op): 
+        self.codewriter.binaryop("sub", 
+                                 self.db.repr_arg(op.result),
+                                 self.db.repr_arg_type(op.args[0]),
+                                 "0", 
+                                 self.db.repr_arg(op.args[0]),
+                                 )
+                    
+
     def binaryop(self, op):
         name = self.binary_operations[op.opname]
         assert len(op.args) == 2
@@ -216,6 +223,7 @@
 
     cast_bool_to_int = cast_primitive
     cast_bool_to_uint = uint_is_true = cast_primitive
+    cast_int_to_char = cast_char_to_int = cast_primitive
 
     def int_is_true(self, op):
         self.codewriter.binaryop("setne",
@@ -260,7 +268,7 @@
         targetvar = self.db.repr_arg(op.result)
         arg_type = op.args[0]
         assert (isinstance(arg_type, Constant) and 
-                isinstance(arg_type.value, lltype.Array))
+                isinstance(arg_type.value, (lltype.Array, lltype.Struct)))
         #XXX unclean
         struct_type = self.db.obj2node[arg_type.value].ref
         struct_cons = self.db.obj2node[arg_type.value].constructor_ref
@@ -279,14 +287,19 @@
         targetvar = self.db.repr_arg(op.result)
         targettype = self.db.repr_arg_type(op.result)
         assert targettype != "void"
-        if isinstance(op.result.concretetype, lltype.ContainerType):
-            # noop
-            self.codewriter.cast(targetvar, targettype, tmpvar, targettype)
-        else:
-            self.codewriter.load(targetvar, targettype, tmpvar)
-
-    getsubstruct = getfield
+        self.codewriter.load(targetvar, targettype, tmpvar)
 
+    def getsubstruct(self, op): 
+        typ = self.db.repr_arg_type(op.args[0]) 
+        typevar = self.db.repr_arg(op.args[0])
+        fieldnames = list(op.args[0].concretetype.TO._names)
+        index = fieldnames.index(op.args[1].value)
+        targetvar = self.db.repr_arg(op.result)
+        self.codewriter.getelementptr(targetvar, typ, 
+                                      typevar, ("uint", index))        
+        targettype = self.db.repr_arg_type(op.result)
+        assert targettype != "void"
+         
     def setfield(self, op): 
         tmpvar = self.db.repr_tmpvar()
         type = self.db.repr_arg_type(op.args[0]) 
@@ -309,11 +322,7 @@
                                       ("uint", 1), (indextype, index))
         targetvar = self.db.repr_arg(op.result)
         targettype = self.db.repr_arg_type(op.result)
-        if isinstance(op.result.concretetype, lltype.ContainerType):
-            # noop
-            self.codewriter.cast(targetvar, targettype, tmpvar, targettype)
-        else:
-            self.codewriter.load(targetvar, targettype, tmpvar)
+        self.codewriter.load(targetvar, targettype, tmpvar)
 
     def setarrayitem(self, op):
         array = self.db.repr_arg(op.args[0])
@@ -327,6 +336,7 @@
 
         valuevar = self.db.repr_arg(op.args[2]) 
         valuetype = self.db.repr_arg_type(op.args[2])
+        assert valuevar.strip() != '-'
         self.codewriter.store(valuetype, valuevar, tmpvar) 
 
     def getarraysize(self, op):

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/node.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/node.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/node.py	Tue Jul  5 20:13:26 2005
@@ -1,12 +1,30 @@
 class LLVMNode(object):
-    def _get_ref(self):
-        return self._ref
-    def _set_ref(self, ref):
-        if hasattr(self, "_ref"):
-            raise TypeError, ("can only set ref once! currently: %s" %
-                               (self._ref,))
-        self._ref = ref
-    ref = property(_get_ref, _set_ref)
+
+    def ref(): 
+        def _get_ref(self):
+            return self._ref 
+        def _set_ref(self, ref):
+            if hasattr(self, "_ref"):
+                raise TypeError, ("can only set ref once! currently: %s" %
+                                   (self._ref,))
+            if " " in ref: 
+                ref = '"%s"' % (ref,)
+            self._ref = ref
+        return property(_get_ref, _set_ref)
+    ref = ref()
+
+    def constructor_ref(): 
+        def _get_ref(self):
+            return self._constructor_ref 
+        def _set_ref(self, ref):
+            if hasattr(self, "_constructor_ref"):
+                raise TypeError, ("can only set constructor_ref once!"
+                                  " currently: %s" % (self._constructor_ref,))
+            if " " in ref: 
+                ref = '"%s"' % (ref,)
+            self._constructor_ref = ref
+        return property(_get_ref, _set_ref)
+    constructor_ref = constructor_ref()
 
     # __________________ before "implementation" ____________________
     def writedatatypedecl(self, codewriter):

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/structnode.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/structnode.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/structnode.py	Tue Jul  5 20:13:26 2005
@@ -2,21 +2,23 @@
 from pypy.objspace.flow.model import Block, Constant, Variable, Link
 from pypy.translator.llvm2.log import log
 from pypy.translator.llvm2.node import LLVMNode
+from pypy.translator.llvm2 import varsize
 from pypy.rpython import lltype
 
+import itertools  
+nextnum = itertools.count().next 
+
 log = log.structnode 
 
 class StructTypeNode(LLVMNode):
     _issetup = False 
-    struct_counter = 0
 
     def __init__(self, db, struct): 
         assert isinstance(struct, lltype.Struct)
         self.db = db
         self.struct = struct
-        self.name = "%s.%s" % (self.struct._name, StructTypeNode.struct_counter)
+        self.name = "%s.%s" % (self.struct._name, nextnum())
         self.ref = "%%st.%s" % self.name
-        StructTypeNode.struct_counter += 1
         
     def __str__(self):
         return "<StructTypeNode %r>" %(self.ref,)
@@ -40,50 +42,37 @@
 
     def __init__(self, db, struct): 
         super(StructVarsizeTypeNode, self).__init__(db, struct)
-        new_var_name = "%%new.st.var.%s" % self.name
-        self.constructor_name = "%s * %s(int %%len)" % (self.ref, new_var_name)
+        self.constructor_ref = "%%new.st.var.%s" % (self.name)
+        self.constructor_decl = "%s * %s(int %%len)" % \
+                                (self.ref, self.constructor_ref)
 
     def __str__(self):
         return "<StructVarsizeTypeNode %r>" %(self.ref,)
         
     def writedecl(self, codewriter): 
         # declaration for constructor
-        codewriter.declare(self.constructor_name)
+        codewriter.declare(self.constructor_decl)
 
     def writeimpl(self, codewriter):
         from pypy.translator.llvm2.atomic import is_atomic
 
         log.writeimpl(self.ref)
-        codewriter.openfunc(self.constructor_name)
-        codewriter.label("block0")
-        indices_to_array = [("int", 0)]
-        s = self.struct
-        while isinstance(s, lltype.Struct):
-            last_pos = len(self.struct._names_without_voids()) - 1
-            indices_to_array.append(("uint", last_pos))
-            s = s._flds.values()[-1]
-
-        # Into array and length            
-        indices = indices_to_array + [("uint", 1), ("int", "%len")]
-        codewriter.getelementptr("%size", self.ref + "*",
-                                 "null", *indices)
-
-        #XXX is this ok for 64bit?
-        codewriter.cast("%sizeu", arraytype + "*", "%size", "uint")
-        codewriter.malloc("%resulttmp", "sbyte", "%sizeu", atomic=is_atomic(self))
-        codewriter.cast("%result", "sbyte*", "%resulttmp", self.ref + "*")
-
-        # remember the allocated length for later use.
-        indices = indices_to_array + [("uint", 0)]
-        codewriter.getelementptr("%size_ptr", self.ref + "*",
-                                 "%result", *indices)
-
-        codewriter.cast("%signedsize", "uint", "%sizeu", "int")
-        codewriter.store("int", "%signedsize", "%size_ptr")
-
-        codewriter.ret(self.ref + "*", "%result")
-        codewriter.closefunc()
 
+        # build up a list of indices to get to the last 
+        # var-sized struct (or rather the according array) 
+        indices_to_array = [] 
+        current = self.struct
+        while isinstance(current, lltype.Struct):
+            last_pos = len(current._names_without_voids()) - 1
+            indices_to_array.append(("uint", last_pos))
+            name = current._names_without_voids()[-1]
+            current = current._flds[name]
+        assert isinstance(current, lltype.Array)
+        arraytype = self.db.repr_arg_type(current.OF)
+        # XXX write type info as a comment 
+        varsize.write_constructor(codewriter, 
+            self.ref, self.constructor_decl, arraytype, 
+            indices_to_array)
 
 def cast_global(toptr, from_, name):
     s = "cast(%s* getelementptr (%s* %s, int 0) to %s)" % (from_,
@@ -94,14 +83,11 @@
 
 class StructNode(LLVMNode):
     _issetup = False 
-    struct_counter = 0
 
     def __init__(self, db, value):
         self.db = db
-        name = "%s.%s" % (value._TYPE._name, StructNode.struct_counter)
-        self.ref = "%%stinstance.%s" % name
         self.value = value
-        StructNode.struct_counter += 1
+        self.ref = "%%stinstance.%s.%s" % (value._TYPE._name, nextnum())
 
     def __str__(self):
         return "<StructNode %r>" %(self.ref,)
@@ -127,6 +113,8 @@
             if not isinstance(T, lltype.Primitive):
                 # Create a dummy constant hack XXX
                 c = Constant(value, T)
+
+                # Needs some sanitisation
                 x = self.db.obj2node[c]
                 value = self.db.repr_arg(c)
                 t, v = x.getall()
@@ -149,10 +137,10 @@
         return "<StructVarsizeNode %r>" %(self.ref,)
 
     def getall(self):
-
         res = []
-        for name in self.value._TYPE._names_without_voids()[:-1]:
-            T = self.value._TYPE._flds[name]
+        type_ = self.value._TYPE
+        for name in type_._names_without_voids()[:-1]:
+            T = type_._flds[name]
             value = getattr(self.value, name)
             if not isinstance(T, lltype.Primitive):
                 # Create a dummy constant hack XXX
@@ -162,16 +150,19 @@
             res.append((self.db.repr_arg_type(T), value))
 
         # Special case for varsized arrays
-        self.value._TYPE._names_without_voids()[-1]
-        x = self.db.obj2node[Constant(value, T)]
-        t, v = x.get_values() 
-        res.append((t, "{%s}" % v))
+        name = type_._names_without_voids()[-1]
+        T = type_._flds[name]
+        assert not isinstance(T, lltype.Primitive)
+        value = getattr(self.value, name)
+        c = Constant(value, T)
+        x = self.db.obj2node[c]
+        t, v = x.getall()
+
+        #value = self.db.repr_arg(c)
+        value = cast_global(self.db.repr_arg_type(T), t, "{%s}" % v)
+        res.append((self.db.repr_arg_type(T), value))
 
-        s = self.value._TYPE
-        fields = [getattr(s, name) for name in s._names_without_voids()[-1]] 
-        l = [self.db.repr_arg_type(field) for field in fields]
-        l += t
-        typestr = "{ %s }" % ", ".join(l)
+        typestr = self.db.repr_arg_type(type_)
         values = ", ".join(["%s %s" % (t, v) for t, v in res])
         return typestr, values
     

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/test/test_genllvm.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/test/test_genllvm.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/test/test_genllvm.py	Tue Jul  5 20:13:26 2005
@@ -12,7 +12,7 @@
 from pypy.rpython.rtyper import RPythonTyper
 from pypy.rpython.rarithmetic import r_uint
 
-py.log.setconsumer("genllvm", py.log.STDOUT)
+#py.log.setconsumer("genllvm", py.log.STDOUT)
 py.log.setconsumer("genllvm database prepare", None)
 
 
@@ -288,7 +288,7 @@
     f = compile_function(list_getitem_pbc, [int])
     assert f(0) == 1
     assert f(1) == 2
-
+    
 def test_list_list_getitem_pbc(): 
     l = [[0, 1], [0, 1]]
     def list_list_getitem_pbc(i): 
@@ -314,11 +314,17 @@
         for j in range(6): 
             assert f(i,j) == list_basic_ops(i,j)
 
+def test_string_simple(): 
+    def string_simple(i): 
+        return ord(str(i))
+    f = compile_function(string_simple, [int], view=False)
+    assert f(0) 
+
 def Xtest_string_getitem1():
     l = "Hello, World"
-    def string_test(i): 
+    def string_getitem1(i): 
         return l[i]
-    f = compile_function(string_test, [int], view=True)
+    f = compile_function(string_getitem1, [int], view=True)
     assert f(0) == ord("H")
 
 def DONOT_test_string_getitem2():



More information about the Pypy-commit mailing list