Commits

Amaury Forgeot d'Arc  committed d640533

Merge from trunk:
svn merge -r77543:78227 ../trunk/ .

  • Participants
  • Parent commits 5f4b137
  • Branches fast-forward

Comments (0)

Files changed (225)

File dotviewer/drawgraph.py

         else:
             for line in lines:
                 raw_line = line.replace('\\l','').replace('\r','') or ' '
-                img = TextSnippet(self, raw_line, (0, 0, 0), bgcolor)
-                w, h = img.get_size()
-                if w>wmax: wmax = w
-                if raw_line.strip():
-                    if line.endswith('\\l'):
-                        def cmd(img=img, y=hmax):
-                            img.draw(xleft, ytop+y)
-                    elif line.endswith('\r'):
-                        def cmd(img=img, y=hmax, w=w):
-                            img.draw(xright-w, ytop+y)
-                    else:
-                        def cmd(img=img, y=hmax, w=w):
-                            img.draw(xcenter-w//2, ytop+y)
+                if '\f' in raw_line:   # grayed out parts of the line
+                    imgs = []
+                    graytext = True
+                    h = 16
+                    w_total = 0
+                    for linepart in raw_line.split('\f'):
+                        graytext = not graytext
+                        if not linepart.strip():
+                            continue
+                        if graytext:
+                            fgcolor = (128, 160, 160)
+                        else:
+                            fgcolor = (0, 0, 0)
+                        img = TextSnippet(self, linepart, fgcolor, bgcolor)
+                        imgs.append((w_total, img))
+                        w, h = img.get_size()
+                        w_total += w
+                    if w_total > wmax: wmax = w_total
+                    def cmd(imgs=imgs, y=hmax):
+                        for x, img in imgs:
+                            img.draw(xleft+x, ytop+y)
                     commands.append(cmd)
+                else:
+                    img = TextSnippet(self, raw_line, (0, 0, 0), bgcolor)
+                    w, h = img.get_size()
+                    if w>wmax: wmax = w
+                    if raw_line.strip():
+                        if line.endswith('\\l'):
+                            def cmd(img=img, y=hmax):
+                                img.draw(xleft, ytop+y)
+                        elif line.endswith('\r'):
+                            def cmd(img=img, y=hmax, w=w):
+                                img.draw(xright-w, ytop+y)
+                        else:
+                            def cmd(img=img, y=hmax, w=w):
+                                img.draw(xcenter-w//2, ytop+y)
+                        commands.append(cmd)
                 hmax += h
                 #hmax += 8
 

File lib-python/conftest.py

     RegrTest('test_coding.py'),
     RegrTest('test_complex_args.py'),
     RegrTest('test_contextlib.py', usemodules="thread"),
-    RegrTest('test_ctypes.py', usemodules="_rawffi"),
+    # we skip test ctypes, since we adapted it massively in order
+    # to test what we want to support. There are real failures,
+    # but it's about missing features that we don't want to support
+    # now
+    RegrTest('test_ctypes.py', usemodules="_rawffi",
+             skip="missing features that we don't want to support now"),
     RegrTest('test_defaultdict.py'),
     RegrTest('test_email_renamed.py'),
     RegrTest('test_exception_variations.py'),

File lib_pypy/_ctypes/structure.py

 def round_up(size, alignment):
     return (size + alignment - 1) & -alignment
 
-def size_alignment_pos(fields):
+def size_alignment_pos(fields, is_union=False):
     import ctypes
     size = 0
     alignment = 1
     for fieldname, ctype in fields:
         fieldsize = ctypes.sizeof(ctype)
         fieldalignment = ctypes.alignment(ctype)
-        size = round_up(size, fieldalignment)
         alignment = max(alignment, fieldalignment)
-        pos.append(size)
-        size += fieldsize
+        if is_union:
+            pos.append(0)
+            size = max(size, fieldsize)
+        else:
+            size = round_up(size, fieldalignment)
+            pos.append(size)
+            size += fieldsize
     size = round_up(size, alignment)
     return size, alignment, pos
 
-def names_and_fields(_fields_, superclass, zero_offset=False, anon=None):
+def names_and_fields(_fields_, superclass, zero_offset=False, anon=None,
+                     is_union=False):
     if isinstance(_fields_, tuple):
         _fields_ = list(_fields_)
     for _, tp in _fields_:
     rawfields = [(name, ctype._ffishape)
                  for name, ctype in all_fields]
     if not zero_offset:
-        _, _, pos = size_alignment_pos(all_fields)
+        _, _, pos = size_alignment_pos(all_fields, is_union)
     else:
         pos = [0] * len(all_fields)
     fields = {}
 
 # ________________________________________________________________
 
-def _set_shape(tp, rawfields):
-    tp._ffistruct = _rawffi.Structure(rawfields)
+def _set_shape(tp, rawfields, is_union=False):
+    tp._ffistruct = _rawffi.Structure(rawfields, is_union)
     tp._ffiargshape = tp._ffishape = (tp._ffistruct, 1)
     tp._fficompositesize = tp._ffistruct.size
 
             raise AttributeError("Structure or union cannot contain itself")
         self._names, rawfields, self._fieldtypes = names_and_fields(
             value, self.__bases__[0], False,
-            self.__dict__.get('_anonymous_', None))
+            self.__dict__.get('_anonymous_', None), self._is_union)
         _CDataMeta.__setattr__(self, '_fields_', value)
-        _set_shape(self, rawfields)
+        _set_shape(self, rawfields, self._is_union)
         return
     _CDataMeta.__setattr__(self, name, value)
 
-class StructureMeta(_CDataMeta):
+class StructOrUnionMeta(_CDataMeta):
+
     def __new__(self, name, cls, typedict):
         res = type.__new__(self, name, cls, typedict)
         if '_fields_' in typedict:
                     raise AttributeError("Anonymous field not found")
             res._names, rawfields, res._fieldtypes = names_and_fields(
                 typedict['_fields_'], cls[0], False,
-                typedict.get('_anonymous_', None))
-            _set_shape(res, rawfields)
+                typedict.get('_anonymous_', None), self._is_union)
+            _set_shape(res, rawfields, self._is_union)
 
         return res
 
         res.__dict__['_index'] = -1
         return res
 
-class Structure(_CData):
-    __metaclass__ = StructureMeta
+class StructOrUnion(_CData):
+    __metaclass__ = StructOrUnionMeta
 
     def __new__(cls, *args, **kwds):
         if not hasattr(cls, '_ffistruct'):
 
     def _get_buffer_value(self):
         return self._buffer.buffer
+
+
+class StructureMeta(StructOrUnionMeta):
+    _is_union = False
+
+class Structure(StructOrUnion):
+    __metaclass__ = StructureMeta

File lib_pypy/_ctypes/union.py

+from _ctypes import structure
 
+class UnionMeta(structure.StructOrUnionMeta):
+    _is_union = True
 
-import _rawffi
-from _ctypes.basics import _CData, _CDataMeta, store_reference, keepalive_key
-from _ctypes.basics import ensure_objects
-from _ctypes.structure import round_up, names_and_fields, struct_getattr,\
-     struct_setattr
-
-
-def _set_shape(tp):
-    size = tp._sizeofinstances()
-    alignment = tp._alignmentofinstances()
-    tp._ffiopaque = _rawffi.Structure((size, alignment)) # opaque
-    tp._ffiargshape = tp._ffishape = (tp._ffiopaque, 1)
-    tp._fficompositesize = tp._ffiopaque.size
-    # we need to create an array of size one for each
-    # of our elements
-    tp._ffiarrays = {}
-    for name, field in tp._fieldtypes.iteritems():
-        tp._ffiarrays[name] = _rawffi.Array(field.ctype._ffishape)
-        
-class UnionMeta(_CDataMeta):
-    def __new__(self, name, cls, typedict):
-        res = type.__new__(self, name, cls, typedict)
-        if '_fields_' in typedict:
-            res._names, rawfields, res._fieldtypes = names_and_fields(
-                typedict['_fields_'], cls[0], True,
-                typedict.get('_anonymous_', None))
-            _set_shape(res)
-
-        def __init__(self): # don't allow arguments by now
-            if not hasattr(self, '_ffiarrays'):
-                raise TypeError("Cannot instantiate union, has no type")
-            # malloc size
-            size = self.__class__._sizeofinstances()
-            self.__dict__['_objects'] = {}
-            self.__dict__['_buffer'] = self._ffiopaque(autofree=True)
-        res.__init__ = __init__
-        return res
-
-    def _sizeofinstances(self):
-        if not hasattr(self, '_size_'):
-            self._size_ = max([field.size for field in
-                               self._fieldtypes.values()] + [0])
-        return self._size_
-
-    def _alignmentofinstances(self):
-        from ctypes import alignment
-        if not hasattr(self, '_alignment_'):
-            self._alignment_ = max([alignment(field.ctype) for field in
-                                    self._fieldtypes.values()] + [1])
-        return self._alignment_
-    
-    __getattr__ = struct_getattr
-
-    def __setattr__(self, name, value):
-        if name == '_fields_':
-            if self.__dict__.get('_fields_', None):
-                raise AttributeError("_fields_ is final")
-            if self in [v for k, v in value]:
-                raise AttributeError("Union cannot contain itself")
-            self._names, rawfields, self._fieldtypes = names_and_fields(
-                value, self.__bases__[0], True,
-                self.__dict__.get('_anonymous_', None))
-            _CDataMeta.__setattr__(self, '_fields_', value)
-            _set_shape(self)
-        _CDataMeta.__setattr__(self, name, value)
-
-    def _CData_output(self, resarray, base=None, index=-1):
-        res = self.__new__(self)
-        ffiopaque = self._ffiopaque.fromaddress(resarray.buffer)
-        res.__dict__['_buffer'] = ffiopaque
-        res.__dict__['_base'] = base
-        res.__dict__['_index'] = index
-        return res
-    
-    def _CData_retval(self, resbuffer):
-        res = self.__new__(self)
-        res.__dict__['_buffer'] = resbuffer
-        res.__dict__['_base'] = None
-        res.__dict__['_index'] = -1
-        return res
-
-
-class Union(_CData):
+class Union(structure.StructOrUnion):
     __metaclass__ = UnionMeta
-
-    def __getattr__(self, name):
-        try:
-            field = self._fieldtypes[name]
-        except KeyError:
-            raise AttributeError(name)
-        fieldtype = field.ctype
-        val = self._ffiarrays[name].fromaddress(self._buffer.buffer, 1)
-        offset = field.num
-        return fieldtype._CData_output(val, self, offset)
-
-    def __setattr__(self, name, value):
-        try:
-            field = self._fieldtypes[name]
-        except KeyError:
-            raise AttributeError(name)
-        fieldtype = field.ctype
-        cobj = fieldtype.from_param(value)
-        if ensure_objects(cobj) is not None:
-            key = keepalive_key(field.num)
-            store_reference(self, key, cobj._objects)
-        arg = cobj._get_buffer_value()
-        if fieldtype._fficompositesize is not None:
-            from ctypes import memmove
-            dest = self._buffer.buffer
-            memmove(dest, arg, fieldtype._fficompositesize)
-        else:
-            buf = self._ffiarrays[name].fromaddress(self._buffer.buffer, 1)
-            buf[0] = arg
-
-    def _get_buffer_value(self):
-        return self._buffer.buffer

File pypy/annotation/builtin.py

 from pypy.annotation.model import SomePtr
 from pypy.rpython.lltypesystem import lltype
 
-def malloc(s_T, s_n=None, s_flavor=None, s_zero=None):
+def malloc(s_T, s_n=None, s_flavor=None, s_zero=None, s_track_allocation=None):
     assert (s_n is None or s_n.knowntype == int
             or issubclass(s_n.knowntype, pypy.rlib.rarithmetic.base_int))
     assert s_T.is_constant()
         r = SomePtr(lltype.typeOf(p))
     else:
         assert s_flavor.is_constant()
+        assert s_track_allocation is None or s_track_allocation.is_constant()
         # not sure how to call malloc() for the example 'p' in the
         # presence of s_extraargs
         r = SomePtr(lltype.Ptr(s_T.const))
     return r
 
-def free(s_p, s_flavor):
+def free(s_p, s_flavor, s_track_allocation=None):
     assert s_flavor.is_constant()
+    assert s_track_allocation is None or s_track_allocation.is_constant()
     # same problem as in malloc(): some flavors are not easy to
     # malloc-by-example
     #T = s_p.ll_ptrtype.TO

File pypy/annotation/model.py

         
 NUMBER = object()
 annotation_to_ll_map = [
+    (SomeSingleFloat(), lltype.SingleFloat),
     (s_None, lltype.Void),   # also matches SomeImpossibleValue()
     (s_Bool, lltype.Bool),
     (SomeInteger(knowntype=r_ulonglong), NUMBER),    
     (SomeFloat(), lltype.Float),
-    (SomeSingleFloat(), lltype.SingleFloat),
     (SomeLongFloat(), lltype.LongFloat),
     (SomeChar(), lltype.Char),
     (SomeUnicodeCodePoint(), lltype.UniChar),

File pypy/annotation/policy.py

-# base annotation policy for overrides and specialization
+# base annotation policy for specialization
 from pypy.annotation.specialize import default_specialize as default
 from pypy.annotation.specialize import specialize_argvalue, specialize_argtype, specialize_arglistitemtype
 from pypy.annotation.specialize import memo
         if directive is None:
             return pol.default_specialize
 
-        # specialize|override:name[(args)]
+        # specialize[(args)]
         directive_parts = directive.split('(', 1)
         if len(directive_parts) == 1:
             [name] = directive_parts
         except AttributeError:
             raise AttributeError("%r specialize tag not defined in annotation"
                                  "policy %s" % (name, pol))
-        if directive.startswith('override:'):
-            # different signature: override__xyz(*args_s)
-            if parms:
-                raise Exception, "override:* specialisations don't support parameters"
-            def specialize_override(funcdesc, args_s):
-                funcdesc.overridden = True
-                return specializer(*args_s)
-            return specialize_override
         else:
             if not parms:
                 return specializer
         from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy
         return LowLevelAnnotatorPolicy.specialize__ll_and_arg(*args)
 
-    def override__ignore(pol, *args):
-        bk = getbookkeeper()
-        return bk.immutablevalue(None)
-
 class StrictAnnotatorPolicy(AnnotatorPolicy):
     allow_someobjects = False

File pypy/annotation/test/test_annrpython.py

         s = a.build_types(f, [list])
         assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError)  # KeyError ignored because l is a list
 
-    def test_overrides(self):
-        excs = []
-        def record_exc(e):
-            """NOT_RPYTHON"""
-            excs.append(sys.exc_info)
-        record_exc._annspecialcase_ = "override:record_exc"
-        def g():
-            pass
-        def f():
-            try:
-                g()
-            except Exception, e:
-                record_exc(e)
-        class MyAnnotatorPolicy(policy.AnnotatorPolicy):
-
-            def override__record_exc(pol, s_e):
-                return a.bookkeeper.immutablevalue(None)
-            
-        a = self.RPythonAnnotator(policy=MyAnnotatorPolicy())
-        s = a.build_types(f, [])
-        assert s.const is None
-
     def test_freeze_protocol(self):
         class Stuff:
             def __init__(self, flag):
         s = a.build_types(f, [])
         assert isinstance(s, annmodel.SomeChar)
 
+    def test_context_manager(self):
+        class C:
+            def __init__(self):
+                pass
+            def __enter__(self):
+                self.x = 1
+            def __exit__(self, *args):
+                self.x = 3
+        def f():
+            c = C()
+            with c:
+                pass
+            return c.x
+
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [])
+        assert isinstance(s, annmodel.SomeInteger)
+        # not a constant: both __enter__ and __exit__ have been annotated
+        assert not s.is_constant()
+
 
 def g(n):
     return [0,1,2,n]

File pypy/annotation/test/test_model.py

     assert isinstance(s_p, SomeOOInstance) and s_p.ootype == C
 
 def test_annotation_to_lltype():
-    from pypy.rlib.rarithmetic import r_uint
+    from pypy.rlib.rarithmetic import r_uint, r_singlefloat
     s_i = SomeInteger()
     s_pos = SomeInteger(nonneg=True)
     s_1 = SomeInteger(nonneg=True); s_1.const = 1
     C = ootype.Instance('C', ROOT, {})
     ref = SomeOOInstance(C)
     assert annotation_to_lltype(ref) == C
+    s_singlefloat = SomeSingleFloat()
+    s_singlefloat.const = r_singlefloat(0.0)
+    assert annotation_to_lltype(s_singlefloat) == lltype.SingleFloat
     
 def test_ll_union():
     PS1 = lltype.Ptr(lltype.GcStruct('s'))

File pypy/config/pypyoption.py

     }
 
 module_import_dependencies = {
-    # no _rawffi if importing pypy.rlib.libffi raises ImportError
+    # no _rawffi if importing pypy.rlib.clibffi raises ImportError
     # or CompilationError
-    "_rawffi"   : ["pypy.rlib.libffi"],
+    "_rawffi"   : ["pypy.rlib.clibffi"],
 
     "zlib"      : ["pypy.rlib.rzlib"],
     "bz2"       : ["pypy.module.bz2.interp_bz2"],
         BoolOption("withstrslice", "use strings optimized for slicing",
                    default=False),
 
+        BoolOption("withstrbuf", "use strings optimized for addition (ver 2)",
+                   default=False),
+
         BoolOption("withprebuiltchar",
                    "use prebuilt single-character string objects",
                    default=False),
         BoolOption("withrope", "use ropes as the string implementation",
                    default=False,
                    requires=[("objspace.std.withstrslice", False),
-                             ("objspace.std.withstrjoin", False)],
+                             ("objspace.std.withstrjoin", False),
+                             ("objspace.std.withstrbuf", False)],
                    suggests=[("objspace.std.withprebuiltchar", True),
                              ("objspace.std.sharesmallstr", True)]),
 
                    default=False,
                    requires=[("objspace.std.withshadowtracking", False)]),
 
+        BoolOption("withmapdict",
+                   "make instances really small but slow without the JIT",
+                   default=False,
+                   requires=[("objspace.std.withshadowtracking", False),
+                             ("objspace.std.withinlineddict", False),
+                             ("objspace.std.withsharingdict", False),
+                             ("objspace.std.getattributeshortcut", True),
+                             ("objspace.std.withtypeversion", True),
+                       ]),
+
         BoolOption("withrangelist",
                    "enable special range list implementation that does not "
                    "actually create the full list until the resulting "
         config.objspace.std.suggest(withprebuiltint=True)
         config.objspace.std.suggest(withrangelist=True)
         config.objspace.std.suggest(withprebuiltchar=True)
-        config.objspace.std.suggest(withinlineddict=True)
+        config.objspace.std.suggest(withmapdict=True)
         config.objspace.std.suggest(withstrslice=True)
         config.objspace.std.suggest(withstrjoin=True)
         # xxx other options? ropes maybe?
     # extra optimizations with the JIT
     if level == 'jit':
         config.objspace.std.suggest(withcelldict=True)
+        #config.objspace.std.suggest(withmapdict=True)
 
 
 def enable_allworkingmodules(config):

File pypy/conftest.py

 from inspect import isclass, getmro
 from pypy.tool.udir import udir
 from pypy.tool.autopath import pypydir
+from pypy.tool import leakfinder
 
 # pytest settings
 pytest_plugins = "resultlog",
 
     def runtest(self):
         try:
-            super(IntTestFunction, self).runtest()
+            leakfinder.start_tracking_allocations()
+            try:
+                super(IntTestFunction, self).runtest()
+            finally:
+                if leakfinder.TRACK_ALLOCATIONS:
+                    leaks = leakfinder.stop_tracking_allocations(False)
+                else:
+                    leaks = None   # stop_tracking_allocations() already called
         except OperationError, e:
             check_keyboard_interrupt(e)
             raise
                 _pygame_imported = True
                 assert option.view, ("should not invoke Pygame "
                                      "if conftest.option.view is False")
+        if leaks:        # check for leaks, but only if the test passed so far
+            raise leakfinder.MallocMismatch(leaks)
 
 class AppTestFunction(PyPyTestFunction):
     def _prunetraceback(self, traceback):

File pypy/doc/config/objspace.std.withmapdict.txt

+Enable the new version of "sharing dictionaries".
+
+See the section in `Standard Interpreter Optimizations`_ for more details.
+
+.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#sharing-dicts

File pypy/doc/config/objspace.std.withstrbuf.txt

+Enable "string buffer" objects.
+
+Similar to "string join" objects, but using a StringBuilder to represent
+a string built by repeated application of ``+=``.

File pypy/doc/config/objspace.usemodules._ffi.txt

+Applevel interface to libffi.  It is more high level than _rawffi, and most importantly it is JIT friendly

File pypy/doc/docindex.txt

 
 PyPy's own tests `summary`_, daily updated, run through BuildBot infrastructure.
 You can also find CPython's compliance tests run with compiled ``pypy-c``
-exeuctables there.
+executables there.
 
 information dating from early 2007: 
 

File pypy/interpreter/baseobjspace.py

     def _call_builtin_destructor(self):
         pass     # method overridden in typedef.py
 
+    # hooks that the mapdict implementations needs:
+    def _get_mapdict_map(self):
+        return None
+    def _set_mapdict_map(self, map):
+        raise NotImplementedError
+    def _mapdict_read_storage(self, index):
+        raise NotImplementedError
+    def _mapdict_write_storage(self, index, value):
+        raise NotImplementedError
+    def _mapdict_storage_length(self):
+        raise NotImplementedError
+    def _set_mapdict_storage_and_map(self, storage, map):
+        raise NotImplementedError
+
 
 class Wrappable(W_Root):
     """A subclass of Wrappable is an internal, interpreter-level class

File pypy/interpreter/pycode.py

 
         self._compute_flatcall()
 
+        if self.space.config.objspace.std.withmapdict:
+            from pypy.objspace.std.mapdict import init_mapdict_cache
+            init_mapdict_cache(self)
+
     def _freeze_(self):
         if (self.magic == cpython_magic and
             '__pypy__' not in sys.builtin_module_names):

File pypy/interpreter/pyopcode.py

             next_instr = block.handle(self, unroller)
             return next_instr
 
+    def call_contextmanager_exit_function(self, w_func, w_typ, w_val, w_tb):
+        return self.space.call_function(w_func, w_typ, w_val, w_tb)
+
     @jit.unroll_safe
     def dispatch_bytecode(self, co_code, next_instr, ec):
         space = self.space
 
     def LOAD_ATTR(self, nameindex, next_instr):
         "obj.attributename"
-        w_attributename = self.getname_w(nameindex)
         w_obj = self.popvalue()
-        w_value = self.space.getattr(w_obj, w_attributename)
+        if (self.space.config.objspace.std.withmapdict
+            and not jit.we_are_jitted()):
+            from pypy.objspace.std.mapdict import LOAD_ATTR_caching
+            w_value = LOAD_ATTR_caching(self.getcode(), w_obj, nameindex)
+        else:
+            w_attributename = self.getname_w(nameindex)
+            w_value = self.space.getattr(w_obj, w_attributename)
         self.pushvalue(w_value)
     LOAD_ATTR._always_inline_ = True
 
         self.pushvalue(w_result)
 
     def WITH_CLEANUP(self, oparg, next_instr):
-        self.dropvalues(2)
-        w_unroller = self.popvalue()
+        # see comment in END_FINALLY for stack state
+        # This opcode changed a lot between CPython versions
+        if (self.pycode.magic >= 0xa0df2ef
+            # Implementation since 2.7a0: 62191 (introduce SETUP_WITH)
+            or self.pycode.magic >= 0xa0df2d1):
+            # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization)
+            self.popvalue()
+            self.popvalue()
+            w_unroller = self.popvalue()
+            w_exitfunc = self.popvalue()
+            self.pushvalue(w_unroller)
+            self.pushvalue(self.space.w_None)
+            self.pushvalue(self.space.w_None)
+        elif self.pycode.magic >= 0xa0df28c:
+            # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode)
+            w_exitfunc = self.popvalue()
+            w_unroller = self.peekvalue(2)
+        else:
+            raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4")
+
         unroller = self.space.interpclass_w(w_unroller)
         w_exit = self.popvalue()
         is_app_exc = (unroller is not None and
                       isinstance(unroller, SApplicationException))
         if is_app_exc:
             operr = unroller.operr
-            w_type = operr.w_type
-            w_value = operr.get_w_value(self.space)
-            w_tb = self.space.wrap(operr.application_traceback)
+            w_traceback = self.space.wrap(operr.application_traceback)
+            w_suppress = self.call_contextmanager_exit_function(
+                w_exitfunc,
+                operr.w_type,
+                operr.get_w_value(self.space),
+                w_traceback)
+            if self.space.is_true(w_suppress):
+                # __exit__() returned True -> Swallow the exception.
+                self.settopvalue(self.space.w_None, 2)
         else:
-            w_type = w_value = w_tb = self.space.w_None
-        w_suppress = self.space.call_function(w_exit, w_type, w_value, w_tb)
-        if is_app_exc and self.space.is_true(w_suppress):
-            self.pushvalue(self.space.w_None)
-            self.pushvalue(self.space.w_None)
-            self.pushvalue(self.space.w_None)
-        else:
-            self.pushvalue(w_unroller)
-            self.pushvalue(w_value)
-            self.pushvalue(w_type)
+            self.call_contextmanager_exit_function(
+                w_exitfunc,
+                self.space.w_None,
+                self.space.w_None,
+                self.space.w_None)
 
     @jit.unroll_safe
     def call_function(self, oparg, w_star=None, w_starstar=None):
             unroller.operr.normalize_exception(frame.space)
         return FinallyBlock.really_handle(self, frame, unroller)
 
-
 block_classes = {'SETUP_LOOP': LoopBlock,
                  'SETUP_EXCEPT': ExceptBlock,
-                 'SETUP_FINALLY': FinallyBlock}
+                 'SETUP_FINALLY': FinallyBlock,
+                 'SETUP_WITH': WithBlock}
 
 ### helpers written at the application-level ###
 # Some of these functions are expected to be generally useful if other

File pypy/interpreter/pyparser/genpytokenize.py

         i += 1
     import StringIO
     print "states = ["
-    for state in dfa.states:
+    for numstate, state in enumerate(dfa.states):
+        print "    #", numstate
         s = StringIO.StringIO()
         i = 0
         for k, v in sorted(state.items()):
                 s.write(', ')
         s.write('},')
         i = 0
-        for line in textwrap.wrap(s.getvalue(), width=35):
+        if len(state) <= 4:
+            text = [s.getvalue()]
+        else:
+            text = textwrap.wrap(s.getvalue(), width=36)
+        for line in text:
             line = line.replace('::', ': ')
             if i == 0:
                 print '    {' + line
             else:
                 print '     ' + line
             i += 1
-        print
     print "    ]"
     print "%s = automata.%s(states, accepts)" % (name, dfa_class)
     print
     endDFAMap = makePyEndDFAMap()
     output("double3DFA", "NonGreedyDFA", endDFAMap['"""'])
     output("single3DFA", "NonGreedyDFA", endDFAMap["'''"])
+    output("singleDFA", "DFA", endDFAMap["'"])
     output("doubleDFA", "DFA", endDFAMap['"'])
-    output("singleDFA", "DFA", endDFAMap["'"])
-    print "endDFAs = {\"'\" : singleDFA,"
-    print "           '\"' : doubleDFA,"
-    print "           'r' : None,"
-    print "           'R' : None,"
-    print "           'u' : None,"
-    print "           'U' : None,"
-    print "           'b' : None,"
-    print "           'B' : None}"
 
 # ______________________________________________________________________
 

File pypy/interpreter/pyparser/pytokenize.py

            True, False, False, False, False, True, False,
            False, False, True]
 states = [
+    # 0
     {'\t': 0, '\n': 13, '\x0c': 0,
      '\r': 14, ' ': 0, '!': 10, '"': 16,
      '#': 18, '%': 12, '&': 12, "'": 15,
      'u': 2, 'v': 1, 'w': 1, 'x': 1,
      'y': 1, 'z': 1, '{': 13, '|': 12,
      '}': 13, '~': 13},
-
+    # 1
     {'0': 1, '1': 1, '2': 1, '3': 1,
      '4': 1, '5': 1, '6': 1, '7': 1,
      '8': 1, '9': 1, 'A': 1, 'B': 1,
      'p': 1, 'q': 1, 'r': 1, 's': 1,
      't': 1, 'u': 1, 'v': 1, 'w': 1,
      'x': 1, 'y': 1, 'z': 1},
-
+    # 2
     {'"': 16, "'": 15, '0': 1, '1': 1,
      '2': 1, '3': 1, '4': 1, '5': 1,
      '6': 1, '7': 1, '8': 1, '9': 1,
      'r': 3, 's': 1, 't': 1, 'u': 1,
      'v': 1, 'w': 1, 'x': 1, 'y': 1,
      'z': 1},
-
+    # 3
     {'"': 16, "'": 15, '0': 1, '1': 1,
      '2': 1, '3': 1, '4': 1, '5': 1,
      '6': 1, '7': 1, '8': 1, '9': 1,
      'r': 1, 's': 1, 't': 1, 'u': 1,
      'v': 1, 'w': 1, 'x': 1, 'y': 1,
      'z': 1},
-
+    # 4
     {'.': 24, '0': 21, '1': 21, '2': 21,
      '3': 21, '4': 21, '5': 21, '6': 21,
      '7': 21, '8': 23, '9': 23, 'B': 22,
      'E': 25, 'J': 13, 'L': 13, 'O': 20,
      'X': 19, 'b': 22, 'e': 25, 'j': 13,
      'l': 13, 'o': 20, 'x': 19},
-
+    # 5
     {'.': 24, '0': 5, '1': 5, '2': 5,
      '3': 5, '4': 5, '5': 5, '6': 5,
      '7': 5, '8': 5, '9': 5, 'E': 25,
      'J': 13, 'L': 13, 'e': 25, 'j': 13,
      'l': 13},
-
+    # 6
     {'0': 26, '1': 26, '2': 26, '3': 26,
      '4': 26, '5': 26, '6': 26, '7': 26,
      '8': 26, '9': 26},
-
+    # 7
     {'*': 12, '=': 13},
-
+    # 8
     {'=': 13, '>': 12},
-
+    # 9
     {'<': 12, '=': 13, '>': 13},
-
+    # 10
     {'=': 13},
-
+    # 11
     {'/': 12, '=': 13},
-
+    # 12
     {'=': 13},
-
+    # 13
     {},
-
+    # 14
     {'\n': 13},
-
-    {automata.DEFAULT: 30, '\n': 27,
-     "'": 28, '\\': 29},
-
-    {automata.DEFAULT: 33, '\n': 27,
-     '"': 31, '\\': 32},
-
+    # 15
+    {automata.DEFAULT: 30, '\n': 27, "'": 28, '\\': 29},
+    # 16
+    {automata.DEFAULT: 33, '\n': 27, '"': 31, '\\': 32},
+    # 17
     {'\n': 13, '\r': 14},
-
-    {automata.DEFAULT: 18, '\n': 27,
-     '\r': 27},
-
+    # 18
+    {automata.DEFAULT: 18, '\n': 27, '\r': 27},
+    # 19
     {'0': 19, '1': 19, '2': 19, '3': 19,
      '4': 19, '5': 19, '6': 19, '7': 19,
      '8': 19, '9': 19, 'A': 19, 'B': 19,
      'C': 19, 'D': 19, 'E': 19, 'F': 19,
      'L': 13, 'a': 19, 'b': 19, 'c': 19,
-     'd': 19, 'e': 19, 'f': 19,
-     'l': 13},
-
+     'd': 19, 'e': 19, 'f': 19, 'l': 13},
+    # 20
     {'0': 20, '1': 20, '2': 20, '3': 20,
      '4': 20, '5': 20, '6': 20, '7': 20,
      'L': 13, 'l': 13},
-
+    # 21
     {'.': 24, '0': 21, '1': 21, '2': 21,
      '3': 21, '4': 21, '5': 21, '6': 21,
      '7': 21, '8': 23, '9': 23, 'E': 25,
      'J': 13, 'L': 13, 'e': 25, 'j': 13,
      'l': 13},
-
-    {'0': 22, '1': 22, 'L': 13,
-     'l': 13},
-
+    # 22
+    {'0': 22, '1': 22, 'L': 13, 'l': 13},
+    # 23
     {'.': 24, '0': 23, '1': 23, '2': 23,
      '3': 23, '4': 23, '5': 23, '6': 23,
      '7': 23, '8': 23, '9': 23, 'E': 25,
      'J': 13, 'e': 25, 'j': 13},
-
+    # 24
     {'0': 24, '1': 24, '2': 24, '3': 24,
      '4': 24, '5': 24, '6': 24, '7': 24,
      '8': 24, '9': 24, 'E': 34, 'J': 13,
      'e': 34, 'j': 13},
-
+    # 25
     {'+': 35, '-': 35, '0': 36, '1': 36,
      '2': 36, '3': 36, '4': 36, '5': 36,
-     '6': 36, '7': 36, '8': 36,
-     '9': 36},
-
+     '6': 36, '7': 36, '8': 36, '9': 36},
+    # 26
     {'0': 26, '1': 26, '2': 26, '3': 26,
      '4': 26, '5': 26, '6': 26, '7': 26,
      '8': 26, '9': 26, 'E': 34, 'J': 13,
      'e': 34, 'j': 13},
-
+    # 27
     {},
-
+    # 28
     {"'": 13},
-
-    {automata.DEFAULT: 37, '\n': 13,
-     '\r': 14},
-
-    {automata.DEFAULT: 30, '\n': 27,
-     "'": 13, '\\': 29},
-
+    # 29
+    {automata.DEFAULT: 37, '\n': 13, '\r': 14},
+    # 30
+    {automata.DEFAULT: 30, '\n': 27, "'": 13, '\\': 29},
+    # 31
     {'"': 13},
-
-    {automata.DEFAULT: 38, '\n': 13,
-     '\r': 14},
-
-    {automata.DEFAULT: 33, '\n': 27,
-     '"': 13, '\\': 32},
-
+    # 32
+    {automata.DEFAULT: 38, '\n': 13, '\r': 14},
+    # 33
+    {automata.DEFAULT: 33, '\n': 27, '"': 13, '\\': 32},
+    # 34
     {'+': 39, '-': 39, '0': 40, '1': 40,
      '2': 40, '3': 40, '4': 40, '5': 40,
-     '6': 40, '7': 40, '8': 40,
-     '9': 40},
-
+     '6': 40, '7': 40, '8': 40, '9': 40},
+    # 35
     {'0': 36, '1': 36, '2': 36, '3': 36,
      '4': 36, '5': 36, '6': 36, '7': 36,
      '8': 36, '9': 36},
-
+    # 36
     {'0': 36, '1': 36, '2': 36, '3': 36,
      '4': 36, '5': 36, '6': 36, '7': 36,
-     '8': 36, '9': 36, 'J': 13,
-     'j': 13},
-
-    {automata.DEFAULT: 37, '\n': 27,
-     "'": 13, '\\': 29},
-
-    {automata.DEFAULT: 38, '\n': 27,
-     '"': 13, '\\': 32},
-
+     '8': 36, '9': 36, 'J': 13, 'j': 13},
+    # 37
+    {automata.DEFAULT: 37, '\n': 27, "'": 13, '\\': 29},
+    # 38
+    {automata.DEFAULT: 38, '\n': 27, '"': 13, '\\': 32},
+    # 39
     {'0': 40, '1': 40, '2': 40, '3': 40,
      '4': 40, '5': 40, '6': 40, '7': 40,
      '8': 40, '9': 40},
-
+    # 40
     {'0': 40, '1': 40, '2': 40, '3': 40,
      '4': 40, '5': 40, '6': 40, '7': 40,
-     '8': 40, '9': 40, 'J': 13,
-     'j': 13},
-
+     '8': 40, '9': 40, 'J': 13, 'j': 13},
     ]
 pseudoDFA = automata.DFA(states, accepts)
 
 accepts = [False, False, False, False, False, True]
 states = [
-    {automata.DEFAULT: 0, '"': 1,
-     '\\': 2},
-
-    {automata.DEFAULT: 4, '"': 3,
-     '\\': 2},
-
+    # 0
+    {automata.DEFAULT: 0, '"': 1, '\\': 2},
+    # 1
+    {automata.DEFAULT: 4, '"': 3, '\\': 2},
+    # 2
     {automata.DEFAULT: 4},
-
-    {automata.DEFAULT: 4, '"': 5,
-     '\\': 2},
-
-    {automata.DEFAULT: 4, '"': 1,
-     '\\': 2},
-
-    {automata.DEFAULT: 4, '"': 5,
-     '\\': 2},
-
+    # 3
+    {automata.DEFAULT: 4, '"': 5, '\\': 2},
+    # 4
+    {automata.DEFAULT: 4, '"': 1, '\\': 2},
+    # 5
+    {automata.DEFAULT: 4, '"': 5, '\\': 2},
     ]
 double3DFA = automata.NonGreedyDFA(states, accepts)
 
 accepts = [False, False, False, False, False, True]
 states = [
-    {automata.DEFAULT: 0, "'": 1,
-     '\\': 2},
-
-    {automata.DEFAULT: 4, "'": 3,
-     '\\': 2},
-
+    # 0
+    {automata.DEFAULT: 0, "'": 1, '\\': 2},
+    # 1
+    {automata.DEFAULT: 4, "'": 3, '\\': 2},
+    # 2
     {automata.DEFAULT: 4},
-
-    {automata.DEFAULT: 4, "'": 5,
-     '\\': 2},
-
-    {automata.DEFAULT: 4, "'": 1,
-     '\\': 2},
-
-    {automata.DEFAULT: 4, "'": 5,
-     '\\': 2},
-
+    # 3
+    {automata.DEFAULT: 4, "'": 5, '\\': 2},
+    # 4
+    {automata.DEFAULT: 4, "'": 1, '\\': 2},
+    # 5
+    {automata.DEFAULT: 4, "'": 5, '\\': 2},
     ]
 single3DFA = automata.NonGreedyDFA(states, accepts)
 
 accepts = [False, True, False, False]
 states = [
-    {automata.DEFAULT: 0, '"': 1,
-     '\\': 2},
+    # 0
+    {automata.DEFAULT: 0, "'": 1, '\\': 2},
+    # 1
+    {},
+    # 2
+    {automata.DEFAULT: 3},
+    # 3
+    {automata.DEFAULT: 3, "'": 1, '\\': 2},
+    ]
+singleDFA = automata.DFA(states, accepts)
 
+accepts = [False, True, False, False]
+states = [
+    # 0
+    {automata.DEFAULT: 0, '"': 1, '\\': 2},
+    # 1
     {},
-
+    # 2
     {automata.DEFAULT: 3},
-
-    {automata.DEFAULT: 3, '"': 1,
-     '\\': 2},
-
+    # 3
+    {automata.DEFAULT: 3, '"': 1, '\\': 2},
     ]
 doubleDFA = automata.DFA(states, accepts)
 
-accepts = [False, True, False, False]
-states = [
-    {automata.DEFAULT: 0, "'": 1,
-     '\\': 2},
-
-    {},
-
-    {automata.DEFAULT: 3},
-
-    {automata.DEFAULT: 3, "'": 1,
-     '\\': 2},
-
-    ]
-singleDFA = automata.DFA(states, accepts)
+#_______________________________________________________________________
+# End of automatically generated DFA's
 
 endDFAs = {"'" : singleDFA,
            '"' : doubleDFA,

File pypy/interpreter/typedef.py

     typedef = cls.typedef
     if wants_dict and typedef.hasdict:
         wants_dict = False
+    if config.objspace.std.withmapdict and not typedef.hasdict:
+        # mapdict only works if the type does not already have a dict
+        if wants_del:
+            parentcls = get_unique_interplevel_subclass(config, cls, True, True,
+                                                        False, True)
+            return _usersubclswithfeature(config, parentcls, "del")
+        return _usersubclswithfeature(config, cls, "user", "dict", "weakref", "slots")
     # Forest of if's - see the comment above.
     if wants_del:
         if wants_dict:
 
     def add(Proto):
         for key, value in Proto.__dict__.items():
-            if not key.startswith('__') or key == '__del__':
+            if (not key.startswith('__') and not key.startswith('_mixin_') 
+                    or key == '__del__'):
+                if hasattr(value, "func_name"):
+                    value = func_with_new_name(value, value.func_name)
                 body[key] = value
 
+    if (config.objspace.std.withmapdict and "dict" in features):
+        from pypy.objspace.std.mapdict import BaseMapdictObject, ObjectMixin
+        add(BaseMapdictObject)
+        add(ObjectMixin)
+        features = ()
+
     if "user" in features:     # generic feature needed by all subcls
+
         class Proto(object):
             user_overridden_class = True
 
             wantdict = False
 
     if wantdict:
+        base_user_setup = supercls.user_setup.im_func
+        if "user_setup" in body:
+            base_user_setup = body["user_setup"]
         class Proto(object):
             def getdict(self):
                 return self.w__dict__
                 self.w__dict__ = check_new_dictionary(space, w_dict)
             
             def user_setup(self, space, w_subtype):
-                self.space = space
-                self.w__class__ = w_subtype
                 self.w__dict__ = space.newdict(
                     instance=True, classofinstance=w_subtype)
-                self.user_setup_slots(w_subtype.nslots)
+                base_user_setup(self, space, w_subtype)
 
             def setclass(self, space, w_subtype):
                 # only used by descr_set___class__

File pypy/jit/backend/llgraph/llimpl.py

                                          BoxInt, BoxPtr, BoxObj, BoxFloat,
                                          REF, INT, FLOAT)
 from pypy.jit.codewriter import heaptracker
-from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr
+from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr, rffi
 from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.module.support import LLSupport, OOSupport
 from pypy.rpython.llinterp import LLException
     loop = _from_opaque(loop)
     loop.operations.append(Operation(opnum))
 
-def compile_add_descr(loop, ofs, type):
+def compile_add_descr(loop, ofs, type, arg_types):
     from pypy.jit.backend.llgraph.runner import Descr
     loop = _from_opaque(loop)
     op = loop.operations[-1]
     assert isinstance(type, str) and len(type) == 1
-    op.descr = Descr(ofs, type)
+    op.descr = Descr(ofs, type, arg_types=arg_types)
 
 def compile_add_loop_token(loop, descr):
     if we_are_translated():
             else:
                 raise TypeError(x)
         try:
-            return _do_call_common(func, args_in_order)
+            return _do_call_common(func, args_in_order, calldescr)
         except LLException, lle:
             _last_exception = lle
             d = {'v': None,
     if isinstance(TYPE, lltype.Ptr):
         if isinstance(x, (int, long, llmemory.AddressAsInt)):
             x = llmemory.cast_int_to_adr(x)
+        if TYPE is rffi.VOIDP:
+            # assume that we want a "C-style" cast, without typechecking the value
+            return rffi.cast(TYPE, x)
         return llmemory.cast_adr_to_ptr(x, TYPE)
     elif TYPE == llmemory.Address:
         if isinstance(x, (int, long, llmemory.AddressAsInt)):
 def do_call_pushfloat(x):
     _call_args_f.append(x)
 
-def _do_call_common(f, args_in_order=None):
+kind2TYPE = {
+    'i': lltype.Signed,
+    'f': lltype.Float,
+    'v': lltype.Void,
+    }
+
+def _do_call_common(f, args_in_order=None, calldescr=None):
     ptr = llmemory.cast_int_to_adr(f).ptr
-    FUNC = lltype.typeOf(ptr).TO
-    ARGS = FUNC.ARGS
+    PTR = lltype.typeOf(ptr)
+    if PTR == rffi.VOIDP:
+        # it's a pointer to a C function, so we don't have a precise
+        # signature: create one from the descr
+        ARGS = map(kind2TYPE.get, calldescr.arg_types)
+        RESULT = kind2TYPE[calldescr.typeinfo]
+        FUNC = lltype.FuncType(ARGS, RESULT)
+        func_to_call = rffi.cast(lltype.Ptr(FUNC), ptr)
+    else:
+        FUNC = PTR.TO
+        ARGS = FUNC.ARGS
+        func_to_call = ptr._obj._callable
     args = cast_call_args(ARGS, _call_args_i, _call_args_r, _call_args_f,
                           args_in_order)
     del _call_args_i[:]
         result = llinterp.eval_graph(ptr._obj.graph, args)
         # ^^^ may raise, in which case we get an LLException
     else:
-        result = ptr._obj._callable(*args)
+        result = func_to_call(*args)
     return result
 
 def do_call_void(f):

File pypy/jit/backend/llgraph/runner.py

             llimpl.compile_add(c, op.getopnum())
             descr = op.getdescr()
             if isinstance(descr, Descr):
-                llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo)
+                llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo, descr.arg_types)
             if isinstance(descr, history.LoopToken) and op.getopnum() != rop.JUMP:
                 llimpl.compile_add_loop_token(c, descr)
             if self.is_oo and isinstance(descr, (OODescr, MethDescr)):
         return self.getdescr(0, token[0], extrainfo=extrainfo,
                              arg_types=''.join(arg_types))
 
+    def calldescrof_dynamic(self, ffi_args, ffi_result, extrainfo=None):
+        from pypy.jit.backend.llsupport.ffisupport import get_ffi_type_kind
+        arg_types = []
+        for arg in ffi_args:
+            kind = get_ffi_type_kind(arg)
+            if kind != history.VOID:
+                arg_types.append(kind)
+        reskind = get_ffi_type_kind(ffi_result)
+        return self.getdescr(0, reskind, extrainfo=extrainfo,
+                             arg_types=''.join(arg_types))
+
+
     def grab_exc_value(self):
         return llimpl.grab_exc_value()
 

File pypy/jit/backend/llsupport/descr.py

 
     _is_pointer_field = False   # unless overridden by GcPtrFieldDescr
     _is_float_field = False     # unless overridden by FloatFieldDescr
+    _is_field_signed = False    # unless overridden by XxxFieldDescr
 
     def is_pointer_field(self):
         return self._is_pointer_field
     def is_float_field(self):
         return self._is_float_field
 
+    def is_field_signed(self):
+        return self._is_field_signed
+
     def repr_of_descr(self):
         return '<%s %s %s>' % (self._clsname, self.name, self.offset)
 
 def getFieldDescrClass(TYPE):
     return getDescrClass(TYPE, BaseFieldDescr, GcPtrFieldDescr,
                          NonGcPtrFieldDescr, 'Field', 'get_field_size',
-                         '_is_float_field')
+                         '_is_float_field', '_is_field_signed')
 
 def get_field_descr(gccache, STRUCT, fieldname):
     cache = gccache._cache_field
 
     _is_array_of_pointers = False      # unless overridden by GcPtrArrayDescr
     _is_array_of_floats   = False      # unless overridden by FloatArrayDescr
+    _is_item_signed       = False      # unless overridden by XxxArrayDescr
 
     def is_array_of_pointers(self):
         return self._is_array_of_pointers
     def is_array_of_floats(self):
         return self._is_array_of_floats
 
+    def is_item_signed(self):
+        return self._is_item_signed
+
     def repr_of_descr(self):
         return '<%s>' % self._clsname
 
 def getArrayDescrClass(ARRAY):
     return getDescrClass(ARRAY.OF, BaseArrayDescr, GcPtrArrayDescr,
                          NonGcPtrArrayDescr, 'Array', 'get_item_size',
-                         '_is_array_of_floats')
+                         '_is_array_of_floats', '_is_item_signed')
 
 def getArrayNoLengthDescrClass(ARRAY):
     return getDescrClass(ARRAY.OF, BaseArrayNoLengthDescr, GcPtrArrayNoLengthDescr,
                          NonGcPtrArrayNoLengthDescr, 'ArrayNoLength', 'get_item_size',
-                         '_is_array_of_floats')
+                         '_is_array_of_floats', '_is_item_signed')
 
 def get_array_descr(gccache, ARRAY):
     cache = gccache._cache_array
     def get_result_size(self, translate_support_code):
         raise NotImplementedError
 
+    def is_result_signed(self):
+        return False    # unless overridden
+
     def create_call_stub(self, rtyper, RESULT):
         def process(c):
             arg = 'args_%s[%d]' % (c, seen[c])
     _return_type = history.INT
     call_stub = staticmethod(lambda func, args_i, args_r, args_f: 0)
 
+    _is_result_signed = False      # can be overridden in XxxCallDescr
+    def is_result_signed(self):
+        return self._is_result_signed
+
+class DynamicIntCallDescr(BaseIntCallDescr):
+    """
+    calldescr that works for every integer type, by explicitly passing it the
+    size of the result. Used only by get_call_descr_dynamic
+    """
+    _clsname = 'DynamicIntCallDescr'
+
+    def __init__(self, arg_classes, result_size, result_sign, extrainfo=None):
+        BaseIntCallDescr.__init__(self, arg_classes, extrainfo)
+        assert isinstance(result_sign, bool)
+        self._result_size = chr(result_size)
+        self._result_sign = result_sign
+
+    def get_result_size(self, translate_support_code):
+        return ord(self._result_size)
+
+    def is_result_signed(self):
+        return self._result_sign
+
+
 class NonGcPtrCallDescr(BaseIntCallDescr):
     _clsname = 'NonGcPtrCallDescr'
     def get_result_size(self, translate_support_code):
         return FloatCallDescr
     return getDescrClass(RESULT, BaseIntCallDescr, GcPtrCallDescr,
                          NonGcPtrCallDescr, 'Call', 'get_result_size',
-                         Ellipsis)  # <= floatattrname should not be used here
+                         Ellipsis,  # <= floatattrname should not be used here
+                         '_is_result_signed')
 
 def get_call_descr(gccache, ARGS, RESULT, extrainfo=None):
     arg_classes = []
 # ____________________________________________________________
 
 def getDescrClass(TYPE, BaseDescr, GcPtrDescr, NonGcPtrDescr,
-                  nameprefix, methodname, floatattrname, _cache={}):
+                  nameprefix, methodname, floatattrname, signedattrname,
+                  _cache={}):
     if isinstance(TYPE, lltype.Ptr):
         if TYPE.TO._gckind == 'gc':
             return GcPtrDescr
         #
         if TYPE is lltype.Float:
             setattr(Descr, floatattrname, True)
+        elif TYPE is not lltype.Bool and rffi.cast(TYPE, -1) == -1:
+            setattr(Descr, signedattrname, True)
         #
         _cache[nameprefix, TYPE] = Descr
         return Descr

File pypy/jit/backend/llsupport/ffisupport.py

+from pypy.rlib.rarithmetic import intmask
+from pypy.jit.metainterp import history
+from pypy.jit.backend.llsupport.descr import DynamicIntCallDescr, NonGcPtrCallDescr,\
+    FloatCallDescr, VoidCallDescr
+
+def get_call_descr_dynamic(ffi_args, ffi_result, extrainfo=None):
+    """Get a call descr: the types of result and args are represented by
+    rlib.libffi.types.*"""
+    try:
+        reskind = get_ffi_type_kind(ffi_result)
+        argkinds = [get_ffi_type_kind(arg) for arg in ffi_args]
+    except KeyError:
+        return None # ??
+    arg_classes = ''.join(argkinds)
+    if reskind == history.INT:
+        size = intmask(ffi_result.c_size)
+        signed = is_ffi_type_signed(ffi_result)
+        return DynamicIntCallDescr(arg_classes, size, signed, extrainfo)
+    elif reskind == history.REF:
+        return  NonGcPtrCallDescr(arg_classes, extrainfo)
+    elif reskind == history.FLOAT:
+        return FloatCallDescr(arg_classes, extrainfo)
+    elif reskind == history.VOID:
+        return VoidCallDescr(arg_classes, extrainfo)
+    assert False
+
+def get_ffi_type_kind(ffi_type):
+    from pypy.rlib.libffi import types
+    kind = types.getkind(ffi_type)
+    if kind == 'i' or kind == 'u':
+        return history.INT
+    elif kind == 'f':
+        return history.FLOAT
+    elif kind == 'v':
+        return history.VOID
+    assert False, "Unsupported kind '%s'" % kind
+
+def is_ffi_type_signed(ffi_type):
+    from pypy.rlib.libffi import types
+    kind = types.getkind(ffi_type)
+    return kind != 'u'

File pypy/jit/backend/llsupport/gc.py

         # used to avoid too many duplications in the GCREF_LISTs.
         self.hashtable = lltype.malloc(self.HASHTABLE,
                                        self.HASHTABLE_SIZE+1,
-                                       flavor='raw')
+                                       flavor='raw', track_allocation=False)
         dummy = lltype.direct_ptradd(lltype.direct_arrayitems(self.hashtable),
                                      self.HASHTABLE_SIZE)
         dummy = llmemory.cast_ptr_to_adr(dummy)
 
     def _enlarge_gcmap(self):
         newlength = 250 + self._gcmap_maxlength * 2
-        newgcmap = lltype.malloc(self.GCMAP_ARRAY, newlength, flavor='raw')
+        newgcmap = lltype.malloc(self.GCMAP_ARRAY, newlength, flavor='raw',
+                                 track_allocation=False)
         oldgcmap = self._gcmap
         for i in range(self._gcmap_curlength):
             newgcmap[i] = oldgcmap[i]
         self._gcmap = newgcmap
         self._gcmap_maxlength = newlength
         if oldgcmap:
-            lltype.free(oldgcmap, flavor='raw')
+            lltype.free(oldgcmap, flavor='raw', track_allocation=False)
 
     def get_basic_shape(self, is_64_bit=False):
         # XXX: Should this code even really know about stack frame layout of
         # them inside bigger arrays) and we never try to share them.
         length = len(shape)
         compressed = lltype.malloc(self.CALLSHAPE_ARRAY, length,
-                                   flavor='raw')
+                                   flavor='raw',
+                                   track_allocation=False)   # memory leak
         for i in range(length):
             compressed[length-1-i] = rffi.cast(rffi.UCHAR, shape[i])
         return llmemory.cast_ptr_to_adr(compressed)

File pypy/jit/backend/llsupport/llmodel.py

 from pypy.jit.backend.llsupport.descr import get_call_descr
 from pypy.jit.backend.llsupport.descr import BaseIntCallDescr, GcPtrCallDescr
 from pypy.jit.backend.llsupport.descr import FloatCallDescr, VoidCallDescr
+from pypy.jit.backend.llsupport.ffisupport import get_call_descr_dynamic
 from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
 
 
         # read back by the machine code reading at the address given by
         # pos_exception() and pos_exc_value().
         _exception_emulator = lltype.malloc(rffi.CArray(lltype.Signed), 2,
-                                            zero=True, flavor='raw')
+                                            zero=True, flavor='raw',
+                                            immortal=True)
         self._exception_emulator = _exception_emulator
 
         def _store_exception(lle):
         assert isinstance(fielddescr, BaseFieldDescr)
         ofs = fielddescr.offset
         size = fielddescr.get_field_size(self.translate_support_code)
-        return ofs, size
+        sign = fielddescr.is_field_signed()
+        return ofs, size, sign
     unpack_fielddescr_size._always_inline_ = True
 
     def arraydescrof(self, A):
         assert isinstance(arraydescr, BaseArrayDescr)
         ofs = arraydescr.get_base_size(self.translate_support_code)
         size = arraydescr.get_item_size(self.translate_support_code)
-        return ofs, size
+        sign = arraydescr.is_item_signed()
+        return ofs, size, sign
     unpack_arraydescr_size._always_inline_ = True
 
     def calldescrof(self, FUNC, ARGS, RESULT, extrainfo=None):
         return get_call_descr(self.gc_ll_descr, ARGS, RESULT, extrainfo)
 
+    def calldescrof_dynamic(self, ffi_args, ffi_result, extrainfo=None):
+        return get_call_descr_dynamic(ffi_args, ffi_result, extrainfo)
+
     def get_overflow_error(self):
         ovf_vtable = self.cast_adr_to_int(self._ovf_error_vtable)
         ovf_inst = lltype.cast_opaque_ptr(llmemory.GCREF,
 
     @specialize.argtype(2)
     def bh_getarrayitem_gc_i(self, arraydescr, gcref, itemindex):
-        ofs, size = self.unpack_arraydescr_size(arraydescr)
+        ofs, size, sign = self.unpack_arraydescr_size(arraydescr)
         # --- start of GC unsafe code (no GC operation!) ---
         items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
-        for TYPE, itemsize in unroll_basic_sizes:
+        for STYPE, UTYPE, itemsize in unroll_basic_sizes:
             if size == itemsize:
-                items = rffi.cast(rffi.CArrayPtr(TYPE), items) 
-                val = items[itemindex]
+                if sign:
+                    items = rffi.cast(rffi.CArrayPtr(STYPE), items)
+                    val = items[itemindex]
+                    val = rffi.cast(lltype.Signed, val)
+                else:
+                    items = rffi.cast(rffi.CArrayPtr(UTYPE), items)
+                    val = items[itemindex]
+                    val = rffi.cast(lltype.Signed, val)
                 # --- end of GC unsafe code ---
-                return rffi.cast(lltype.Signed, val)
+                return val
         else:
             raise NotImplementedError("size = %d" % size)
 
 
     @specialize.argtype(2)
     def bh_setarrayitem_gc_i(self, arraydescr, gcref, itemindex, newvalue):
-        ofs, size = self.unpack_arraydescr_size(arraydescr)
+        ofs, size, sign = self.unpack_arraydescr_size(arraydescr)
         # --- start of GC unsafe code (no GC operation!) ---
         items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
-        for TYPE, itemsize in unroll_basic_sizes:
+        for TYPE, _, itemsize in unroll_basic_sizes:
             if size == itemsize:
                 items = rffi.cast(rffi.CArrayPtr(TYPE), items)
                 items[itemindex] = rffi.cast(TYPE, newvalue)
 
     @specialize.argtype(1)
     def _base_do_getfield_i(self, struct, fielddescr):
-        ofs, size = self.unpack_fielddescr_size(fielddescr)
+        ofs, size, sign = self.unpack_fielddescr_size(fielddescr)
         # --- start of GC unsafe code (no GC operation!) ---
         fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
-        for TYPE, itemsize in unroll_basic_sizes:
+        for STYPE, UTYPE, itemsize in unroll_basic_sizes:
             if size == itemsize:
-                val = rffi.cast(rffi.CArrayPtr(TYPE), fieldptr)[0]
+                # Note that in the common case where size==sizeof(Signed),
+                # both cases of what follows are doing the same thing.
+                # But gcc is clever enough to figure this out :-)
+                if sign:
+                    val = rffi.cast(rffi.CArrayPtr(STYPE), fieldptr)[0]
+                    val = rffi.cast(lltype.Signed, val)
+                else:
+                    val = rffi.cast(rffi.CArrayPtr(UTYPE), fieldptr)[0]
+                    val = rffi.cast(lltype.Signed, val)
                 # --- end of GC unsafe code ---
-                return rffi.cast(lltype.Signed, val)
+                return val
         else:
             raise NotImplementedError("size = %d" % size)
 
 
     @specialize.argtype(1)
     def _base_do_setfield_i(self, struct, fielddescr, newvalue):
-        ofs, size = self.unpack_fielddescr_size(fielddescr)
+        ofs, size, sign = self.unpack_fielddescr_size(fielddescr)
         # --- start of GC unsafe code (no GC operation!) ---
         fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
-        for TYPE, itemsize in unroll_basic_sizes:
+        for TYPE, _, itemsize in unroll_basic_sizes:
             if size == itemsize:
                 fieldptr = rffi.cast(rffi.CArrayPtr(TYPE), fieldptr)
                 fieldptr[0] = rffi.cast(TYPE, newvalue)

File pypy/jit/backend/llsupport/symbolic.py

 SIZEOF_INT   = get_size(rffi.INT, False)
 SIZEOF_FLOAT = get_size(lltype.Float, False)
 
-unroll_basic_sizes = unrolling_iterable([(lltype.Signed, WORD),
-                                         (lltype.Char,   SIZEOF_CHAR),
-                                         (rffi.SHORT,    SIZEOF_SHORT),
-                                         (rffi.INT,      SIZEOF_INT)])
+unroll_basic_sizes = unrolling_iterable([
+    (lltype.Signed,   lltype.Unsigned, WORD),
+    (rffi.SIGNEDCHAR, lltype.Char,     SIZEOF_CHAR),
+    (rffi.SHORT,      rffi.USHORT,     SIZEOF_SHORT),
+    (rffi.INT,        rffi.UINT,       SIZEOF_INT)])
 # does not contain Float ^^^ which must be special-cased

File pypy/jit/backend/llsupport/test/test_descr.py

         assert     descr_f.is_float_field()
 
 
+def test_get_field_descr_sign():
+    for RESTYPE, signed in [(rffi.SIGNEDCHAR, True), (rffi.UCHAR,  False),
+                            (rffi.SHORT,      True), (rffi.USHORT, False),
+                            (rffi.INT,        True), (rffi.UINT,   False),
+                            (rffi.LONG,       True), (rffi.ULONG,  False)]:
+        S = lltype.GcStruct('S', ('x', RESTYPE))