[pypy-commit] pypy jit-short_from_state: hg merge default

hakanardo noreply at buildbot.pypy.org
Wed Aug 10 16:29:03 CEST 2011


Author: Hakan Ardo <hakan at debian.org>
Branch: jit-short_from_state
Changeset: r46419:70f7459e294a
Date: 2011-08-10 15:48 +0200
http://bitbucket.org/pypy/pypy/changeset/70f7459e294a/

Log:	hg merge default

diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -14,6 +14,15 @@
             raise TypeError("Expected CData subclass, got %s" % (tp,))
         if isinstance(tp, StructOrUnionMeta):
             tp._make_final()
+        if len(f) == 3:
+            if (not hasattr(tp, '_type_')
+                or not isinstance(tp._type_, str)
+                or tp._type_ not in "iIhHbBlL"):
+                #XXX: are those all types?
+                #     we just dont get the type name
+                #     in the interp levle thrown TypeError
+                #     from rawffi if there are more
+                raise TypeError('bit fields not allowed for type ' + tp.__name__)
 
     all_fields = []
     for cls in reversed(inspect.getmro(superclass)):
@@ -91,7 +100,7 @@
     if name == '_fields_':
         if self.__dict__.get('_fields_', None) is not None:
             raise AttributeError("_fields_ is final")
-        if self in [v for k, v in value]:
+        if self in [f[1] for f in value]:
             raise AttributeError("Structure or union cannot contain itself")
         names_and_fields(
             self,
diff --git a/pypy/jit/metainterp/test/test_loop.py b/pypy/jit/metainterp/test/test_loop.py
--- a/pypy/jit/metainterp/test/test_loop.py
+++ b/pypy/jit/metainterp/test/test_loop.py
@@ -800,6 +800,38 @@
 
         res = self.meta_interp(f, [200])        
 
+    def test_regular_pointers_in_short_preamble(self):
+        # XXX do we really care about this case?  If not, we should
+        # at least detect it and complain during codewriter/jtransform
+        from pypy.rpython.lltypesystem import lltype
+        BASE = lltype.GcStruct('BASE')
+        A = lltype.GcStruct('A', ('parent', BASE), ('val', lltype.Signed))
+        B = lltype.GcStruct('B', ('parent', BASE), ('charval', lltype.Char))
+        myjitdriver = JitDriver(greens = [], reds = ['n', 'm', 'i', 'j', 'sa', 'p'])
+        def f(n, m, j):
+            i = sa = 0
+            pa = lltype.malloc(A)
+            pa.val = 7
+            p = pa.parent
+            while i < n:
+                myjitdriver.jit_merge_point(n=n, m=m, i=i, j=j, sa=sa, p=p)
+                if i < m:
+                    pa = lltype.cast_pointer(lltype.Ptr(A), p)
+                    sa += pa.val
+                elif i == m:
+                    pb = lltype.malloc(B)
+                    pb.charval = 'y'
+                    p = pb.parent
+                else:
+                    pb = lltype.cast_pointer(lltype.Ptr(B), p)
+                    sa += ord(pb.charval)
+                sa += 100
+                assert n>0 and m>0
+                i += j
+            return sa
+        expected = f(20, 10, 1)
+        res = self.meta_interp(f, [20, 10, 1])
+        assert res == expected
 
     def test_unerased_pointers_in_short_preamble(self):
         from pypy.rlib.rerased import new_erasing_pair
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_bitfields.py b/pypy/module/test_lib_pypy/ctypes_tests/test_bitfields.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_bitfields.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_bitfields.py
@@ -5,8 +5,6 @@
 
 import ctypes
 
-py.test.skip("bitfields not supported")
-
 def setup_module(mod):
     import conftest
     _ctypes_test = str(conftest.sofile)
@@ -14,7 +12,7 @@
     func.argtypes = POINTER(BITS), c_char
     mod.func = func
 
-class BITS(BaseCTypesTestChecker):
+class BITS(Structure):
     _fields_ = [("A", c_int, 1),
                 ("B", c_int, 2),
                 ("C", c_int, 3),
@@ -197,6 +195,8 @@
         try:
             func(*args, **kw)
         except Exception, detail:
+            import traceback
+            traceback.print_exc()
             return detail.__class__, str(detail)
 
     def test_mixed_1(self):
@@ -228,3 +228,24 @@
         class Y(Structure):
             _anonymous_ = ["_"]
             _fields_ = [("_", X)]
+
+    def test_set_fields_attr(self):
+        class A(Structure):
+            pass
+        A._fields_ = [("a", c_byte),
+                      ("b", c_ubyte)]
+
+    def test_set_fields_attr_bitfields(self):
+        class A(Structure):
+            pass
+        A._fields_ = [("a", POINTER(A)),
+                      ("b", c_ubyte, 4)]
+
+
+    def test_set_fields_cycle_fails(self):
+        class A(Structure):
+            pass
+        import pytest
+        pytest.raises(AttributeError, """
+            A._fields_ = [("a", A)]
+                      """)
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -117,7 +117,7 @@
         s_x = annmodel.not_const(s_x)
         access_directly = 's_access_directly' in kwds_s
         fresh_virtualizable = 's_fresh_virtualizable' in kwds_s
-        if  access_directly or fresh_virtualizable:
+        if access_directly or fresh_virtualizable:
             assert access_directly, "lone fresh_virtualizable hint"
             if isinstance(s_x, annmodel.SomeInstance):
                 from pypy.objspace.flow.model import Constant
@@ -282,7 +282,7 @@
 
     def specialize_call(self, hop):
         pass
-    
+
 vref_None = non_virtual_ref(None)
 
 # ____________________________________________________________
@@ -292,7 +292,7 @@
     """Inconsistency in the JIT hints."""
 
 PARAMETERS = {'threshold': 1032, # just above 1024
-              'function_threshold': 1617, # slightly more than one above 
+              'function_threshold': 1617, # slightly more than one above
               'trace_eagerness': 200,
               'trace_limit': 12000,
               'inlining': 1,
@@ -402,7 +402,7 @@
                             raise
     set_user_param._annspecialcase_ = 'specialize:arg(0)'
 
-    
+
     def on_compile(self, logger, looptoken, operations, type, *greenargs):
         """ A hook called when loop is compiled. Overwrite
         for your own jitdriver if you want to do something special, like
@@ -573,7 +573,7 @@
                 c_llname = hop.inputconst(lltype.Void, mangled_name)
                 getfield_op = self.get_getfield_op(hop.rtyper)
                 v_green = hop.genop(getfield_op, [v_red, c_llname],
-                                    resulttype = r_field)
+                                    resulttype=r_field)
                 s_green = s_red.classdef.about_attribute(fieldname)
                 assert s_green is not None
                 hop.rtyper.annotator.setbinding(v_green, s_green)
diff --git a/pypy/tool/gdb_pypy.py b/pypy/tool/gdb_pypy.py
--- a/pypy/tool/gdb_pypy.py
+++ b/pypy/tool/gdb_pypy.py
@@ -10,6 +10,7 @@
 
 from __future__ import with_statement
 
+import re
 import sys
 import os.path
 
@@ -64,7 +65,7 @@
     """
 
     prog2typeids = {}
- 
+
     def __init__(self, gdb=None):
         # dependency injection, for tests
         if gdb is None:
@@ -108,6 +109,9 @@
         exename = progspace.filename
         root = os.path.dirname(exename)
         typeids_txt = os.path.join(root, 'typeids.txt')
+        if not os.path.exists(typeids_txt):
+            newroot = os.path.dirname(root)
+            typeids_txt = os.path.join(newroot, 'typeids.txt')
         print 'loading', typeids_txt
         typeids = {}
         with open(typeids_txt) as f:
@@ -118,8 +122,80 @@
                 typeids[offset] = descr
         return typeids
 
+
+def is_ptr(type, gdb):
+    if gdb is None:
+        import gdb # so we can pass a fake one from the tests
+    return type.code == gdb.TYPE_CODE_PTR
+
+
+class RPyStringPrinter(object):
+    """
+    Pretty printer for rpython strings.
+
+    Note that this pretty prints *pointers* to strings: this way you can do "p
+    val" and see the nice string, and "p *val" to see the underyling struct
+    fields
+    """
+
+    def __init__(self, val):
+        self.val = val
+
+    @classmethod
+    def lookup(cls, val, gdb=None):
+        t = val.type
+        if is_ptr(t, gdb) and t.target().tag == 'pypy_rpy_string0':
+            return cls(val)
+        return None
+
+    def to_string(self):
+        chars = self.val['rs_chars']
+        length = int(chars['length'])
+        items = chars['items']
+        res = [chr(items[i]) for i in range(length)]
+        string = ''.join(res)
+        return 'r' + repr(string)
+
+
+class RPyListPrinter(object):
+    """
+    Pretty printer for rpython lists
+
+    Note that this pretty prints *pointers* to lists: this way you can do "p
+    val" and see the nice repr, and "p *val" to see the underyling struct
+    fields
+    """
+
+    def __init__(self, val):
+        self.val = val
+
+    @classmethod
+    def lookup(cls, val, gdb=None):
+        t = val.type
+        if (is_ptr(t, gdb) and t.target().tag is not None and
+            re.match(r'pypy_list\d*', t.target().tag)):
+            return cls(val)
+        return None
+
+    def to_string(self):
+        length = int(self.val['l_length'])
+        array = self.val['l_items']
+        allocated = int(array['length'])
+        items = array['items']
+        itemlist = []
+        for i in range(length):
+            item = items[i]
+            itemlist.append(str(item))
+        str_items = ', '.join(itemlist)
+        return 'r[%s] (len=%d, alloc=%d)' % (str_items, length, allocated)
+
+
 try:
     import gdb
     RPyType() # side effects
+    gdb.pretty_printers += [
+        RPyStringPrinter.lookup,
+        RPyListPrinter.lookup
+        ]
 except ImportError:
     pass
diff --git a/pypy/tool/test/test_gdb_pypy.py b/pypy/tool/test/test_gdb_pypy.py
--- a/pypy/tool/test/test_gdb_pypy.py
+++ b/pypy/tool/test/test_gdb_pypy.py
@@ -4,6 +4,10 @@
 class FakeGdb(object):
 
     COMMAND_NONE = -1
+    #
+    TYPE_CODE_PTR = 1
+    TYPE_CODE_ARRAY = 2
+    TYPE_CODE_STRUCT = 3
 
     def __init__(self, exprs, progspace=None):
         self.exprs = exprs
@@ -24,20 +28,40 @@
     pass
 
 class Struct(object):
-    def __init__(self, fieldnames):
+    code = FakeGdb.TYPE_CODE_STRUCT
+
+    def __init__(self, fieldnames, tag):
         self._fields = [Field(name=name) for name in fieldnames]
+        self.tag = tag
 
     def fields(self):
         return self._fields[:]
 
+class Pointer(object):
+    code = FakeGdb.TYPE_CODE_PTR
+
+    def __init__(self, target):
+        self._target = target
+
+    def target(self):
+        return self._target
+
 class Value(dict):
     def __init__(self, *args, **kwds):
+        type_tag = kwds.pop('type_tag', None)
         dict.__init__(self, *args, **kwds)
-        self.type = Struct(self.keys())
+        self.type = Struct(self.keys(), type_tag)
         for key, val in self.iteritems():
             if isinstance(val, dict):
                 self[key] = Value(val)
 
+class PtrValue(Value):
+    def __init__(self, *args, **kwds):
+        # in python gdb, we can use [] to access fields either if we have an
+        # actual struct or a pointer to it, so we just reuse Value here
+        Value.__init__(self, *args, **kwds)
+        self.type = Pointer(self.type)
+
 def test_mock_objects():
     d = {'a': 1,
          'b': 2,
@@ -76,6 +100,21 @@
     hdr = gdb_pypy.lookup(obj, 'gcheader')
     assert hdr['h_tid'] == 123
 
+def test_load_typeids(tmpdir):
+    exe = tmpdir.join('testing_1').join('pypy-c')
+    typeids = tmpdir.join('typeids.txt')
+    typeids.write("""
+member0    GcStruct xxx {}
+""".strip())
+    progspace = Mock(filename=str(exe))
+    exprs = {
+        '((char*)(&pypy_g_typeinfo.member0)) - (char*)&pypy_g_typeinfo': 0,
+        }
+    gdb = FakeGdb(exprs, progspace)
+    cmd = gdb_pypy.RPyType(gdb)
+    typeids = cmd.load_typeids(progspace)
+    assert typeids[0] == 'GcStruct xxx {}'
+
 def test_RPyType(tmpdir):
     exe = tmpdir.join('pypy-c')
     typeids = tmpdir.join('typeids.txt')
@@ -103,3 +142,42 @@
     gdb = FakeGdb(exprs, progspace)
     cmd = gdb_pypy.RPyType(gdb)
     assert cmd.do_invoke('*myvar', True) == 'GcStruct yyy {}'
+
+def test_pprint_string():
+    d = {'_gcheader': {
+            'h_tid': 123
+            },
+         'rs_hash': 456,
+         'rs_chars': {
+            'length': 6,
+            'items': map(ord, 'foobar'),
+            }
+         }
+    p_string = PtrValue(d, type_tag='pypy_rpy_string0')
+    printer = gdb_pypy.RPyStringPrinter.lookup(p_string, FakeGdb)
+    assert printer.to_string() == "r'foobar'"
+
+def test_pprint_list():
+    d = {'_gcheader': {
+            'h_tid': 123
+            },
+         'l_length': 3, # the lenght of the rpython list
+         'l_items':
+             # this is the array which contains the items
+             {'_gcheader': {
+                'h_tid': 456
+                },
+              'length': 5, # the lenght of the underlying array
+              'items': [40, 41, 42, -1, -2],
+              }
+         }
+    mylist = PtrValue(d, type_tag='pypy_list0')
+    printer = gdb_pypy.RPyListPrinter.lookup(mylist, FakeGdb)
+    assert printer.to_string() == 'r[40, 41, 42] (len=3, alloc=5)'
+    #
+    mylist.type.target().tag = 'pypy_list1234'
+    printer = gdb_pypy.RPyListPrinter.lookup(mylist, FakeGdb)
+    assert printer.to_string() == 'r[40, 41, 42] (len=3, alloc=5)'
+
+    mylist.type.target().tag = None
+    assert gdb_pypy.RPyListPrinter.lookup(mylist, FakeGdb) is None
\ No newline at end of file
diff --git a/pypy/translator/goal/app_main.py b/pypy/translator/goal/app_main.py
--- a/pypy/translator/goal/app_main.py
+++ b/pypy/translator/goal/app_main.py
@@ -33,11 +33,9 @@
         except:
             # not an integer: print it to stderr
             try:
-                stderr = sys.stderr
-            except AttributeError:
+                print >> sys.stderr, exitcode
+            except:
                 pass   # too bad
-            else:
-                stderr.write(exitcode)
             exitcode = 1
     raise SystemExit(exitcode)
 
diff --git a/pypy/translator/translator.py b/pypy/translator/translator.py
--- a/pypy/translator/translator.py
+++ b/pypy/translator/translator.py
@@ -16,7 +16,7 @@
 import py
 log = py.log.Producer("flowgraph")
 py.log.setconsumer("flowgraph", ansi_log)
- 
+
 class TranslationContext(object):
     FLOWING_FLAGS = {
         'verbose': False,
@@ -105,7 +105,7 @@
             raise ValueError("we already have an rtyper")
         from pypy.rpython.rtyper import RPythonTyper
         self.rtyper = RPythonTyper(self.annotator,
-                                   type_system = type_system)
+                                   type_system=type_system)
         return self.rtyper
 
     def getexceptiontransformer(self):


More information about the pypy-commit mailing list