Author: Hakan Ardo <[email protected]>
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):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit