Commits

wlav committed be67c06 Merge

merge default into branch

  • Participants
  • Parent commits be8483a, e311e98
  • Branches reflex-support

Comments (0)

Files changed (139)

lib_pypy/_ctypes/basics.py

         'resbuffer' is a _rawffi array of length 1 containing the value,
         and this returns a general Python object that corresponds.
         """
-        res = self.__new__(self)
+        res = object.__new__(self)
+        res.__class__ = self
         res.__dict__['_buffer'] = resbuffer
         res.__dict__['_base'] = base
         res.__dict__['_index'] = index

lib_pypy/_marshal.py

 def _read(self, n):
     pos = self.bufpos
     newpos = pos + n
+    if newpos > len(self.bufstr): raise EOFError
     ret = self.bufstr[pos : newpos]
     self.bufpos = newpos
     return ret

lib_pypy/greenlet.py

         try:
             unbound_method = getattr(_continulet, methodname)
             args = unbound_method(current, *args, to=target)
-        except GreenletExit, e:
-            args = (e,)
         finally:
             _tls.current = current
         #
     _tls.current = greenlet
     try:
         res = greenlet.run(*args)
+    except GreenletExit, e:
+        res = e
     finally:
         _continuation.permute(greenlet, greenlet.parent)
     return (res,)

lib_pypy/pypy_test/test_marshal_extra.py

         f2.close()
     assert obj == case
 
-
+def test_load_truncated_string():
+    s = '(\x02\x00\x00\x00i\x03\x00\x00\x00sB\xf9\x00\x00\nabcd'
+    py.test.raises(EOFError, marshal.loads, s)

pypy/annotation/description.py

                     attrs.update(self.basedesc.all_enforced_attrs)
                 self.all_enforced_attrs = attrs
 
+            if (self.is_builtin_exception_class() and
+                self.all_enforced_attrs is None):
+                from pypy.annotation import classdef
+                if self.pyobj not in classdef.FORCE_ATTRIBUTES_INTO_CLASSES:
+                    self.all_enforced_attrs = []    # no attribute allowed
+
     def add_source_attribute(self, name, value, mixin=False):
         if isinstance(value, types.FunctionType):
             # for debugging

pypy/annotation/test/test_annrpython.py

         assert len(a.translator.graphs) == 3 # fn, __iter__, next
         assert isinstance(s, annmodel.SomeInteger)
 
+    def test_no_attr_on_common_exception_classes(self):
+        for cls in [ValueError, Exception]:
+            def fn():
+                e = cls()
+                e.foo = "bar"
+            a = self.RPythonAnnotator()
+            py.test.raises(Exception, a.build_types, fn, [])
+
 def g(n):
     return [0,1,2,n]
 

pypy/config/pypyoption.py

      "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array",
      "_bisect", "binascii", "_multiprocessing", '_warnings',
      "_collections", "_multibytecodec", "micronumpy", "_ffi",
-     "_continuation"]
+     "_continuation", "_cffi_backend"]
 ))
 
 translation_modules = default_modules.copy()
     "_rawffi": [("objspace.usemodules.struct", True)],
     "cpyext": [("translation.secondaryentrypoints", "cpyext"),
                ("translation.shared", sys.platform == "win32")],
-    "_ffi":    [("translation.jit_ffi", True)],
 }
 
 module_import_dependencies = {

pypy/config/test/test_pypyoption.py

         for path in c.getpaths(include_groups=True):
             fn = prefix + "." + path + ".txt"
             yield fn, check_file_exists, fn
-
-def test__ffi_opt():
-    config = get_pypy_config(translating=True)
-    config.objspace.usemodules._ffi = True
-    assert config.translation.jit_ffi

pypy/config/translationoption.py

     ChoiceOption("jit_profiler", "integrate profiler support into the JIT",
                  ["off", "oprofile"],
                  default="off"),
-    # jit_ffi is automatically turned on by withmod-_ffi (which is enabled by default)
-    BoolOption("jit_ffi", "optimize libffi calls", default=False, cmdline=None),
     BoolOption("check_str_without_nul",
                "Forbid NUL chars in strings in some external function calls",
                default=False, cmdline=None),
     def delslice(self, obj, *args):
         obj.__delslice__(*args)
 
+    def is_w(self, obj1, obj2):
+        return obj1 is obj2
+
 def translation_test_so_skip_if_appdirect():
     if option.runappdirect:
         py.test.skip("translation test, skipped for appdirect")

pypy/doc/config/objspace.usemodules._cffi_backend.txt

+Core of CFFI (http://cffi.readthedocs.org)

pypy/interpreter/baseobjspace.py

         w_meth = self.getattr(w_obj, self.wrap(methname))
         return self.call_function(w_meth, *arg_w)
 
+    def raise_key_error(self, w_key):
+        e = self.call_function(self.w_KeyError, w_key)
+        raise OperationError(self.w_KeyError, e)
+
     def lookup(self, w_obj, name):
         w_type = self.type(w_obj)
         w_mro = self.getattr(w_type, self.wrap("__mro__"))

pypy/interpreter/test/test_function.py

         assert f.func_defaults == None
         assert f.func_dict == {}
         assert type(f.func_globals) == dict
+        assert f.func_globals is f.__globals__
         assert f.func_closure is None
         assert f.func_doc == None
         assert f.func_name == 'f'

pypy/interpreter/typedef.py

         assert __total_ordering__ in (None, 'auto'), "Unknown value for __total_ordering"
         if __total_ordering__ == 'auto':
             self.auto_total_ordering()
-    
+
     def add_entries(self, **rawdict):
         # xxx fix the names of the methods to match what app-level expects
         for key, value in rawdict.items():
 
     def add(Proto):
         for key, value in Proto.__dict__.items():
-            if (not key.startswith('__') and not key.startswith('_mixin_') 
+            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)
         class Proto(object):
             def getdict(self, space):
                 return self.w__dict__
-            
+
             def setdict(self, space, w_dict):
                 self.w__dict__ = check_new_dictionary(space, w_dict)
-            
+
             def user_setup(self, space, w_subtype):
                 self.w__dict__ = space.newdict(
                     instance=True)
             return %(name)s(%(args)s, %(extra)s)
         """
         miniglobals[cls_name] = cls
-    
+
     name = func.__name__
     extra = ', '.join(extraargs)
     from pypy.interpreter import pycode
                 space, '__delattr__',
                 self.reqcls, Arguments(space, [w_obj,
                                                space.wrap(self.name)]))
-    
+
     def descr_get_objclass(space, property):
         return property.objclass_getter(space)
 
             return space.w_None
         else:
             return w_value
-    
+
     return GetSetProperty(fget, cls=cls, doc=doc)
 
 GetSetProperty.typedef = TypeDef(
         self.index = index
         self.name = name
         self.w_cls = w_cls
-    
+
     def typecheck(self, space, w_obj):
         if not space.is_true(space.isinstance(w_obj, self.w_cls)):
             raise operationerrfmt(space.w_TypeError,
                                   self.name,
                                   self.w_cls.name,
                                   space.type(w_obj).getname(space))
-    
+
     def descr_member_get(self, space, w_obj, w_w_cls=None):
         """member.__get__(obj[, type]) -> value
         Read the slot 'member' of the given 'obj'."""
                 raise OperationError(space.w_AttributeError,
                                      space.wrap(self.name)) # XXX better message
             return w_result
-    
+
     def descr_member_set(self, space, w_obj, w_value):
         """member.__set__(obj, value)
         Write into the slot 'member' of the given 'obj'."""
         self.typecheck(space, w_obj)
         w_obj.setslotvalue(self.index, w_value)
-    
+
     def descr_member_del(self, space, w_obj):
         """member.__delete__(obj)
         Delete the value of the slot 'member' from the given 'obj'."""
     func_dict = getset_func_dict,
     func_defaults = getset_func_defaults,
     func_globals = interp_attrproperty_w('w_func_globals', cls=Function),
-    func_closure = GetSetProperty( Function.fget_func_closure ),
+    func_closure = GetSetProperty(Function.fget_func_closure),
     __code__ = getset_func_code,
     __doc__ = getset_func_doc,
     __name__ = getset_func_name,
     __dict__ = getset_func_dict,
     __defaults__ = getset_func_defaults,
+    __globals__ = interp_attrproperty_w('w_func_globals', cls=Function),
     __module__ = getset___module__,
     __weakref__ = make_weakref_descr(Function),
-    )
+)
 Function.typedef.acceptable_as_base_class = False
 
 Method.typedef = TypeDef(

pypy/jit/backend/llgraph/llimpl.py

 from pypy.jit.backend.llgraph import symbolic
 from pypy.jit.codewriter import longlong
 
-from pypy.rlib import libffi, clibffi
 from pypy.rlib.objectmodel import ComputedIntSymbolic, we_are_translated
 from pypy.rlib.rarithmetic import ovfcheck
 from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint
 
 FLOAT_ARRAY_TP = lltype.Ptr(lltype.Array(lltype.Float, hints={"nolength": True}))
 def maybe_uncast(TP, array):
-    if array._TYPE.TO._hints.get("uncast_on_llgraph"):
+    if array._TYPE.TO.OF != lltype.Float:
+        # array._TYPE.TO._hints.get("uncast_on_llgraph"):
         array = rffi.cast(TP, array)
     return array
 
         if arraydescr.typeinfo == REF:
             raise NotImplementedError("getarrayitem_raw -> gcref")
         elif arraydescr.typeinfo == INT:
-            return do_getarrayitem_raw_int(array, index)
+            return do_getarrayitem_raw_int(array, index, arraydescr.ofs)
         elif arraydescr.typeinfo == FLOAT:
             return do_getarrayitem_raw_float(array, index)
         else:
     op_getfield_gc_pure = op_getfield_gc
 
     def op_getfield_raw(self, fielddescr, struct):
-        if fielddescr.arg_types == 'dynamic': # abuse of .arg_types
-            return do_getfield_raw_dynamic(struct, fielddescr)
-        elif fielddescr.typeinfo == REF:
+        if fielddescr.typeinfo == REF:
             return do_getfield_raw_ptr(struct, fielddescr.ofs)
         elif fielddescr.typeinfo == INT:
             return do_getfield_raw_int(struct, fielddescr.ofs)
 
     op_getfield_raw_pure = op_getfield_raw
 
+    def op_raw_store(self, arraydescr, addr, offset, value):
+        if arraydescr.typeinfo == REF:
+            raise AssertionError("cannot store GC pointer in raw storage")
+        elif arraydescr.typeinfo == INT:
+            do_raw_store_int(addr, offset, arraydescr.ofs, value)
+        elif arraydescr.typeinfo == FLOAT:
+            do_raw_store_float(addr, offset, value)
+        else:
+            raise NotImplementedError
+
+    def op_raw_load(self, arraydescr, addr, offset):
+        if arraydescr.typeinfo == REF: 
+            raise AssertionError("cannot store GC pointer in raw storage")
+        elif arraydescr.typeinfo == INT:
+            return do_raw_load_int(addr, offset, arraydescr.ofs)
+        elif arraydescr.typeinfo == FLOAT:
+            return do_raw_load_float(addr, offset)
+        else:
+            raise NotImplementedError
+
     def op_new(self, size):
         return do_new(size.ofs)
 
         if arraydescr.typeinfo == REF:
             raise NotImplementedError("setarrayitem_raw <- gcref")
         elif arraydescr.typeinfo == INT:
-            do_setarrayitem_raw_int(array, index, newvalue)
+            do_setarrayitem_raw_int(array, index, newvalue, arraydescr.ofs)
         elif arraydescr.typeinfo == FLOAT:
             do_setarrayitem_raw_float(array, index, newvalue)
         else:
             raise NotImplementedError
 
     def op_setfield_raw(self, fielddescr, struct, newvalue):
-        if fielddescr.arg_types == 'dynamic': # abuse of .arg_types
-            do_setfield_raw_dynamic(struct, fielddescr, newvalue)
-        elif fielddescr.typeinfo == REF:
+        if fielddescr.typeinfo == REF:
             do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue)
         elif fielddescr.typeinfo == INT:
             do_setfield_raw_int(struct, fielddescr.ofs, newvalue)
     array = array._obj.container
     return cast_to_int(array.getitem(index))
 
-def do_getarrayitem_raw_int(array, index):
-    array = array.adr.ptr._obj
-    return cast_to_int(array.getitem(index))
+def do_getarrayitem_raw_int(array, index, itemsize):
+    array = array.adr.ptr
+    ITEMTYPE = lltype.typeOf(array).TO.OF
+    TYPE = symbolic.Size2Type[itemsize]
+    if TYPE.OF != ITEMTYPE:
+        array = rffi.cast(lltype.Ptr(TYPE), array)
+    return cast_to_int(array._obj.getitem(index))
 
 def do_getarrayitem_gc_float(array, index):
     array = array._obj.container
     struct = array._obj.container.getitem(index)
     return cast_to_ptr(_getinteriorfield_gc(struct, fieldnum))
 
-def _getinteriorfield_raw(ffitype, array, index, width, ofs):
-    addr = rffi.cast(rffi.VOIDP, array)
-    return libffi.array_getitem(ffitype, width, addr, index, ofs)
-
-def do_getinteriorfield_raw_int(array, index, width, ofs):
-    res = _getinteriorfield_raw(libffi.types.slong, array, index, width, ofs)
-    return res
-
-def do_getinteriorfield_raw_float(array, index, width, ofs):
-    res = _getinteriorfield_raw(libffi.types.double, array, index, width, ofs)
-    return res
-
 def _getfield_raw(struct, fieldnum):
     STRUCT, fieldname = symbolic.TokenToField[fieldnum]
     ptr = cast_from_int(lltype.Ptr(STRUCT), struct)
 def do_getfield_raw_ptr(struct, fieldnum):
     return cast_to_ptr(_getfield_raw(struct, fieldnum))
 
-def do_getfield_raw_dynamic(struct, fielddescr):
-    from pypy.rlib import libffi
-    addr = cast_from_int(rffi.VOIDP, struct)
-    ofs = fielddescr.ofs
-    if fielddescr.is_pointer_field():
-        assert False, 'fixme'
-    elif fielddescr.is_float_field():
-        assert False, 'fixme'
-    else:
-        return libffi._struct_getfield(lltype.Signed, addr, ofs)
+def do_raw_load_int(struct, offset, descrofs):
+    TYPE = symbolic.Size2Type[descrofs]
+    ll_p = rffi.cast(rffi.CCHARP, struct)
+    ll_p = rffi.cast(lltype.Ptr(TYPE), rffi.ptradd(ll_p, offset))
+    value = ll_p[0]
+    return rffi.cast(lltype.Signed, value)
+
+def do_raw_load_float(struct, offset):
+    ll_p = rffi.cast(rffi.CCHARP, struct)
+    ll_p = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE),
+                     rffi.ptradd(ll_p, offset))
+    value = ll_p[0]
+    return value
+
+def do_raw_store_int(struct, offset, descrofs, value):
+    TYPE = symbolic.Size2Type[descrofs]
+    ll_p = rffi.cast(rffi.CCHARP, struct)
+    ll_p = rffi.cast(lltype.Ptr(TYPE), rffi.ptradd(ll_p, offset))
+    ll_p[0] = rffi.cast(TYPE.OF, value)
+
+def do_raw_store_float(struct, offset, value):
+    ll_p = rffi.cast(rffi.CCHARP, struct)
+    ll_p = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE),
+                     rffi.ptradd(ll_p, offset))
+    ll_p[0] = value
 
 def do_new(size):
     TYPE = symbolic.Size2Type[size]
     newvalue = cast_from_int(ITEMTYPE, newvalue)
     array.setitem(index, newvalue)
 
-def do_setarrayitem_raw_int(array, index, newvalue):
+def do_setarrayitem_raw_int(array, index, newvalue, itemsize):
     array = array.adr.ptr
     ITEMTYPE = lltype.typeOf(array).TO.OF
-    newvalue = cast_from_int(ITEMTYPE, newvalue)
+    TYPE = symbolic.Size2Type[itemsize]
+    if TYPE.OF != ITEMTYPE:
+        array = rffi.cast(lltype.Ptr(TYPE), array)
+    newvalue = cast_from_int(TYPE.OF, newvalue)
     array._obj.setitem(index, newvalue)
 
 def do_setarrayitem_gc_float(array, index, newvalue):
 do_setinteriorfield_gc_float = new_setinteriorfield_gc(cast_from_floatstorage)
 do_setinteriorfield_gc_ptr = new_setinteriorfield_gc(cast_from_ptr)
 
-def new_setinteriorfield_raw(cast_func, ffitype):
-    def do_setinteriorfield_raw(array, index, newvalue, width, ofs):
-        addr = rffi.cast(rffi.VOIDP, array)
-        for TYPE, ffitype2 in clibffi.ffitype_map:
-            if ffitype2 is ffitype:
-                newvalue = cast_func(TYPE, newvalue)
-                break
-        return libffi.array_setitem(ffitype, width, addr, index, ofs, newvalue)
-    return do_setinteriorfield_raw
-do_setinteriorfield_raw_int = new_setinteriorfield_raw(cast_from_int, libffi.types.slong)
-do_setinteriorfield_raw_float = new_setinteriorfield_raw(cast_from_floatstorage, libffi.types.double)
-
 def do_setfield_raw_int(struct, fieldnum, newvalue):
     STRUCT, fieldname = symbolic.TokenToField[fieldnum]
     ptr = cast_from_int(lltype.Ptr(STRUCT), struct)
     newvalue = cast_from_ptr(FIELDTYPE, newvalue)
     setattr(ptr, fieldname, newvalue)
 
-def do_setfield_raw_dynamic(struct, fielddescr, newvalue):
-    from pypy.rlib import libffi
-    addr = cast_from_int(rffi.VOIDP, struct)
-    ofs = fielddescr.ofs
-    if fielddescr.is_pointer_field():
-        assert False, 'fixme'
-    elif fielddescr.is_float_field():
-        assert False, 'fixme'
-    else:
-        libffi._struct_setfield(lltype.Signed, addr, ofs, newvalue)
-
 def do_newstr(length):
     x = rstr.mallocstr(length)
     return cast_to_ptr(x)
 setannotation(do_getinteriorfield_gc_int, annmodel.SomeInteger())
 setannotation(do_getinteriorfield_gc_ptr, annmodel.SomePtr(llmemory.GCREF))
 setannotation(do_getinteriorfield_gc_float, s_FloatStorage)
+setannotation(do_raw_load_int, annmodel.SomeInteger())
 setannotation(do_new, annmodel.SomePtr(llmemory.GCREF))
 setannotation(do_new_array, annmodel.SomePtr(llmemory.GCREF))
 setannotation(do_setarrayitem_gc_int, annmodel.s_None)
 setannotation(do_setinteriorfield_gc_int, annmodel.s_None)
 setannotation(do_setinteriorfield_gc_ptr, annmodel.s_None)
 setannotation(do_setinteriorfield_gc_float, annmodel.s_None)
+setannotation(do_raw_store_int, annmodel.s_None)
 setannotation(do_newstr, annmodel.SomePtr(llmemory.GCREF))
 setannotation(do_strsetitem, annmodel.s_None)
 setannotation(do_newunicode, annmodel.SomePtr(llmemory.GCREF))

pypy/jit/backend/llgraph/runner.py

         token = history.getkind(getattr(S, fieldname))
         return self.getdescr(ofs, token[0], name=fieldname)
 
-    def fielddescrof_dynamic(self, offset, fieldsize, is_pointer, is_float, is_signed):
-        if is_pointer:
-            typeinfo = REF
-        elif is_float:
-            typeinfo = FLOAT
-        else:
-            typeinfo = INT
-        # we abuse the arg_types field to distinguish dynamic and static descrs
-        return self.getdescr(offset, typeinfo, arg_types='dynamic', name='<dynamic field>')
-
     def interiorfielddescrof(self, A, fieldname):
         S = A.OF
         width = symbolic.get_size(A)
         token = history.getkind(getattr(S, fieldname))
         return self.getdescr(ofs, token[0], name=fieldname, width=width)
 
-    def interiorfielddescrof_dynamic(self, offset, width, fieldsize,
-        is_pointer, is_float, is_signed):
-
-        if is_pointer:
-            typeinfo = REF
-        elif is_float:
-            typeinfo = FLOAT
-        else:
-            typeinfo = INT
-        # we abuse the arg_types field to distinguish dynamic and static descrs
-        return Descr(offset, typeinfo, arg_types='dynamic', name='<dynamic interior field>', width=width)
-
     def calldescrof(self, FUNC, ARGS, RESULT, extrainfo):
         arg_types = []
         for ARG in ARGS:
         return self.getdescr(0, token[0], extrainfo=extrainfo,
                              arg_types=''.join(arg_types))
 
-    def calldescrof_dynamic(self, ffi_args, ffi_result, extrainfo, ffi_flags):
+    def calldescrof_dynamic(self, cif_description, extrainfo):
         from pypy.jit.backend.llsupport.ffisupport import get_ffi_type_kind
         from pypy.jit.backend.llsupport.ffisupport import UnsupportedKind
         arg_types = []
         try:
-            for arg in ffi_args:
+            for arg in cif_description.atypes:
                 kind = get_ffi_type_kind(self, arg)
                 if kind != history.VOID:
                     arg_types.append(kind)
-            reskind = get_ffi_type_kind(self, ffi_result)
+            reskind = get_ffi_type_kind(self, cif_description.rtype)
         except UnsupportedKind:
             return None
         return self.getdescr(0, reskind, extrainfo=extrainfo,
                              arg_types=''.join(arg_types),
-                             ffi_flags=ffi_flags)
+                             ffi_flags=cif_description.abi)
 
+    def _calldescr_dynamic_for_tests(self, atypes, rtype,
+                                     abiname='FFI_DEFAULT_ABI'):
+        from pypy.jit.backend.llsupport import ffisupport
+        return ffisupport.calldescr_dynamic_for_tests(self, atypes, rtype,
+                                                      abiname)
 
     def grab_exc_value(self):
         return llimpl.grab_exc_value()
         return llimpl.do_getarrayitem_gc_int(array, index)
     def bh_getarrayitem_raw_i(self, arraydescr, array, index):
         assert isinstance(arraydescr, Descr)
-        return llimpl.do_getarrayitem_raw_int(array, index)
+        return llimpl.do_getarrayitem_raw_int(array, index, arraydescr.ofs)
     def bh_getarrayitem_gc_r(self, arraydescr, array, index):
         assert isinstance(arraydescr, Descr)
         return llimpl.do_getarrayitem_gc_ptr(array, index)
         return llimpl.do_setinteriorfield_gc_float(array, index, descr.ofs,
                                                    value)
 
+    def bh_raw_store_i(self, struct, offset, descr, newvalue):
+        assert isinstance(descr, Descr)
+        return llimpl.do_raw_store_int(struct, offset, descr.ofs, newvalue)
+    def bh_raw_store_f(self, struct, offset, descr, newvalue):
+        assert isinstance(descr, Descr)
+        return llimpl.do_raw_store_float(struct, offset, newvalue)
+    def bh_raw_load_i(self, struct, offset, descr):
+        assert isinstance(descr, Descr)
+        return llimpl.do_raw_load_int(struct, offset, descr.ofs)
+    def bh_raw_load_f(self, struct, offset, descr):
+        assert isinstance(descr, Descr)
+        return llimpl.do_raw_load_float(struct, offset)
+
     def bh_new(self, sizedescr):
         assert isinstance(sizedescr, Descr)
         return llimpl.do_new(sizedescr.ofs)
 
     def bh_setarrayitem_raw_i(self, arraydescr, array, index, newvalue):
         assert isinstance(arraydescr, Descr)
-        llimpl.do_setarrayitem_raw_int(array, index, newvalue)
+        llimpl.do_setarrayitem_raw_int(array, index, newvalue, arraydescr.ofs)
 
     def bh_setarrayitem_gc_r(self, arraydescr, array, index, newvalue):
         assert isinstance(arraydescr, Descr)

pypy/jit/backend/llgraph/symbolic.py

-import ctypes
 from pypy.rpython.lltypesystem import lltype, rffi, rclass
 
 
-Size2Type = [None]
+Size2Type = [None] * 100
 Type2Size = {}
 
 def get_size(TYPE):
         Type2Size[TYPE] = size
         return size
 
-TokenToField = [None]
+TokenToField = [None] * 100
 FieldToToken = {}
 
 def get_field_token(STRUCT, fieldname):
         FieldToToken[STRUCT, fieldname] = token
         return token
 get_field_token(rclass.OBJECT, 'typeptr')     # force the index 1 for this
-
-def get_array_token(T):
-    # T can be an array or a var-sized structure
-    if isinstance(T, lltype.Struct):
-        assert T._arrayfld is not None, "%r is not variable-sized" % (T,)
-        cstruct = ll2ctypes.get_ctypes_type(T)
-        cfield = getattr(cstruct, T._arrayfld)
-        before_array_part = cfield.offset
-        T = getattr(T, T._arrayfld)
-    else:
-        before_array_part = 0
-    carray = ll2ctypes.get_ctypes_type(T)
-    assert carray.length.size == 4
-    ofs_length = before_array_part + carray.length.offset
-    basesize = before_array_part + carray.items.offset
-    carrayitem = ll2ctypes.get_ctypes_type(T.OF)
-    itemsize = ctypes.sizeof(carrayitem)
-    return basesize, itemsize, ofs_length

pypy/jit/backend/llsupport/descr.py

         cache[(ARRAY, name)] = descr
         return descr
 
-def compute_flag(is_pointer, is_float, is_signed):
-    if is_pointer:
-        assert not is_float
-        return FLAG_POINTER
-    elif is_float:
-        return FLAG_FLOAT
-    elif is_signed:
-        return FLAG_SIGNED
-    else:
-        return FLAG_UNSIGNED
-
-def get_dynamic_field_descr(offset, fieldsize, is_pointer, is_float, is_signed):
-    flag = compute_flag(is_pointer, is_float, is_signed)
-    return FieldDescr('dynamic', offset, fieldsize, flag)
-
-def get_dynamic_interiorfield_descr(gc_ll_descr, offset, width, fieldsize,
-                                    is_pointer, is_float, is_signed):
-    arraydescr = ArrayDescr(0, width, None, FLAG_STRUCT)
-    flag = compute_flag(is_pointer, is_float, is_signed)
-    fielddescr = FieldDescr('dynamic', offset, fieldsize, flag)
-    return InteriorFieldDescr(arraydescr, fielddescr)
-
-
 # ____________________________________________________________
 # CallDescrs
 

pypy/jit/backend/llsupport/ffisupport.py

 from pypy.rlib.rarithmetic import intmask
-from pypy.jit.metainterp import history
-from pypy.rpython.lltypesystem import rffi
+from pypy.rlib.objectmodel import specialize
+from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.jit.backend.llsupport.descr import CallDescr
 
 class UnsupportedKind(Exception):
     pass
 
-def get_call_descr_dynamic(cpu, ffi_args, ffi_result, extrainfo, ffi_flags):
-    """Get a call descr: the types of result and args are represented by
-    rlib.libffi.types.*"""
+def get_call_descr_dynamic(cpu, cif_description, extrainfo):
+    """Get a call descr from the given CIF_DESCRIPTION"""
+    ffi_result = cif_description.rtype
     try:
         reskind = get_ffi_type_kind(cpu, ffi_result)
-        argkinds = [get_ffi_type_kind(cpu, arg) for arg in ffi_args]
+        argkinds = [get_ffi_type_kind(cpu, cif_description.atypes[i])
+                    for i in range(cif_description.nargs)]
     except UnsupportedKind:
         return None
-    if reskind == history.VOID:
+    if reskind == 'v':
         result_size = 0
     else:
         result_size = intmask(ffi_result.c_size)
     argkinds = ''.join(argkinds)
     return CallDescr(argkinds, reskind, is_ffi_type_signed(ffi_result),
-                     result_size, extrainfo, ffi_flags=ffi_flags)
+                     result_size, extrainfo, ffi_flags=cif_description.abi)
 
 def get_ffi_type_kind(cpu, ffi_type):
-    from pypy.rlib.libffi import types
+    from pypy.rlib.jit_libffi import types
+    kind = types.getkind(ffi_type)
+    if ((not cpu.supports_floats and kind == 'f') or
+        (not cpu.supports_longlong and kind == 'L') or
+        (not cpu.supports_singlefloats and kind == 'S') or
+        kind == '*' or kind == '?'):
+        raise UnsupportedKind("Unsupported kind '%s'" % kind)
+    if kind == 'u':
+        kind = 'i'
+    return kind
+
+def is_ffi_type_signed(ffi_type):
+    from pypy.rlib.jit_libffi import types
+    kind = types.getkind(ffi_type)
+    return kind != 'u'
+
+@specialize.memo()
+def _get_ffi2descr_dict(cpu):
+    d = {('v', 0): ('v', None)}
+    if cpu.supports_floats:
+        d[('f', 0)] = ('f', cpu.arraydescrof(rffi.CArray(lltype.Float)))
+    if cpu.supports_singlefloats:
+        d[('S', 0)] = ('i', cpu.arraydescrof(rffi.CArray(lltype.SingleFloat)))
+    for SIGNED_TYPE in [rffi.SIGNEDCHAR,
+                        rffi.SHORT,
+                        rffi.INT,
+                        rffi.LONG,
+                        rffi.LONGLONG]:
+        key = ('i', rffi.sizeof(SIGNED_TYPE))
+        kind = 'i'
+        if key[1] > rffi.sizeof(lltype.Signed):
+            if not cpu.supports_longlong:
+                continue
+            key = ('L', 0)
+            kind = 'f'
+        d[key] = (kind, cpu.arraydescrof(rffi.CArray(SIGNED_TYPE)))
+    for UNSIGNED_TYPE in [rffi.UCHAR,
+                          rffi.USHORT,
+                          rffi.UINT,
+                          rffi.ULONG,
+                          rffi.ULONGLONG]:
+        key = ('u', rffi.sizeof(UNSIGNED_TYPE))
+        if key[1] > rffi.sizeof(lltype.Signed):
+            continue
+        d[key] = ('i', cpu.arraydescrof(rffi.CArray(UNSIGNED_TYPE)))
+    return d
+
+def get_arg_descr(cpu, ffi_type):
+    from pypy.rlib.jit_libffi import types
     kind = types.getkind(ffi_type)
     if kind == 'i' or kind == 'u':
-        return history.INT
-    elif cpu.supports_floats and kind == 'f':
-        return history.FLOAT
-    elif kind == 'v':
-        return history.VOID
-    elif cpu.supports_longlong and (kind == 'I' or kind == 'U'):     # longlong
-        return 'L'
-    elif cpu.supports_singlefloats and kind == 's':    # singlefloat
-        return 'S'
-    raise UnsupportedKind("Unsupported kind '%s'" % kind)
+        size = rffi.getintfield(ffi_type, 'c_size')
+    else:
+        size = 0
+    return _get_ffi2descr_dict(cpu)[kind, size]
 
-def is_ffi_type_signed(ffi_type):
-    from pypy.rlib.libffi import types
-    kind = types.getkind(ffi_type)
-    return kind != 'u'
+def calldescr_dynamic_for_tests(cpu, atypes, rtype, abiname='FFI_DEFAULT_ABI'):
+    from pypy.rlib import clibffi
+    from pypy.rlib.jit_libffi import CIF_DESCRIPTION, FFI_TYPE_PP
+    from pypy.jit.codewriter.effectinfo import EffectInfo
+    #
+    p = lltype.malloc(CIF_DESCRIPTION, len(atypes),
+                      flavor='raw', immortal=True)
+    p.abi = getattr(clibffi, abiname)
+    p.nargs = len(atypes)
+    p.rtype = rtype
+    p.atypes = lltype.malloc(FFI_TYPE_PP.TO, len(atypes),
+                             flavor='raw', immortal=True)
+    for i in range(len(atypes)):
+        p.atypes[i] = atypes[i]
+    return cpu.calldescrof_dynamic(p, EffectInfo.MOST_GENERAL)

pypy/jit/backend/llsupport/llmodel.py

 from pypy.jit.backend.llsupport.symbolic import WORD, unroll_basic_sizes
 from pypy.jit.backend.llsupport.descr import (
     get_size_descr, get_field_descr, get_array_descr,
-    get_call_descr, get_interiorfield_descr, get_dynamic_interiorfield_descr,
-    FieldDescr, ArrayDescr, CallDescr, InteriorFieldDescr, get_dynamic_field_descr)
+    get_call_descr, get_interiorfield_descr,
+    FieldDescr, ArrayDescr, CallDescr, InteriorFieldDescr)
 from pypy.jit.backend.llsupport.asmmemmgr import AsmMemoryManager
 
 
     def fielddescrof(self, STRUCT, fieldname):
         return get_field_descr(self.gc_ll_descr, STRUCT, fieldname)
 
-    def fielddescrof_dynamic(self, offset, fieldsize, is_pointer, is_float, is_signed):
-        return get_dynamic_field_descr(offset, fieldsize, is_pointer, is_float, is_signed)
-
     def unpack_fielddescr(self, fielddescr):
         assert isinstance(fielddescr, FieldDescr)
         return fielddescr.offset
     def interiorfielddescrof(self, A, fieldname):
         return get_interiorfield_descr(self.gc_ll_descr, A, fieldname)
 
-    def interiorfielddescrof_dynamic(self, offset, width, fieldsize,
-                                     is_pointer, is_float, is_signed):
-        return get_dynamic_interiorfield_descr(self.gc_ll_descr,
-                                               offset, width, fieldsize,
-                                               is_pointer, is_float, is_signed)
-
     def unpack_arraydescr(self, arraydescr):
         assert isinstance(arraydescr, ArrayDescr)
         return arraydescr.basesize
     def calldescrof(self, FUNC, ARGS, RESULT, extrainfo):
         return get_call_descr(self.gc_ll_descr, ARGS, RESULT, extrainfo)
 
-    def calldescrof_dynamic(self, ffi_args, ffi_result, extrainfo, ffi_flags):
+    def calldescrof_dynamic(self, cif_description, extrainfo):
         from pypy.jit.backend.llsupport import ffisupport
-        return ffisupport.get_call_descr_dynamic(self, ffi_args, ffi_result,
-                                                 extrainfo, ffi_flags)
+        return ffisupport.get_call_descr_dynamic(self, cif_description,
+                                                 extrainfo)
+
+    def _calldescr_dynamic_for_tests(self, atypes, rtype,
+                                     abiname='FFI_DEFAULT_ABI'):
+        from pypy.jit.backend.llsupport import ffisupport
+        return ffisupport.calldescr_dynamic_for_tests(self, atypes, rtype,
+                                                      abiname)
 
     def get_overflow_error(self):
         ovf_vtable = self.cast_adr_to_int(self._ovf_error_vtable)
     bh_setfield_raw_r = _base_do_setfield_r
     bh_setfield_raw_f = _base_do_setfield_f
 
+    def bh_raw_store_i(self, addr, offset, descr, newvalue):
+        ofs, size, sign = self.unpack_arraydescr_size(descr)
+        items = addr + offset
+        for TYPE, _, itemsize in unroll_basic_sizes:
+            if size == itemsize:
+                items = rffi.cast(rffi.CArrayPtr(TYPE), items)
+                items[0] = rffi.cast(TYPE, newvalue)
+                break
+
+    def bh_raw_store_f(self, addr, offset, descr, newvalue):
+        items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), addr + offset)
+        items[0] = newvalue
+
+    def bh_raw_load_i(self, addr, offset, descr):
+        ofs, size, sign = self.unpack_arraydescr_size(descr)
+        items = addr + offset
+        for TYPE, _, itemsize in unroll_basic_sizes:
+            if size == itemsize:
+                items = rffi.cast(rffi.CArrayPtr(TYPE), items)
+                return rffi.cast(lltype.Signed, items[0])
+        assert False # unreachable code
+
+    def bh_raw_load_f(self, addr, offset, descr):
+        items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), addr + offset)
+        return items[0]
+
     def bh_new(self, sizedescr):
         return self.gc_ll_descr.gc_malloc(sizedescr)
 

pypy/jit/backend/llsupport/test/test_ffisupport.py

-from pypy.rlib.libffi import types
+from pypy.rlib.jit_libffi import types, CIF_DESCRIPTION, FFI_TYPE_PP
+from pypy.rlib.clibffi import FFI_DEFAULT_ABI
+from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.jit.codewriter.longlong import is_64_bit
 from pypy.jit.backend.llsupport.descr import *
 from pypy.jit.backend.llsupport.ffisupport import *
         self.supports_floats = supports_floats
         self.supports_longlong = supports_longlong
         self.supports_singlefloats = supports_singlefloats
-
+    def calldescrof_dynamic(self, cif_descr, effectinfo):
+        return get_call_descr_dynamic(self, cif_descr, effectinfo)
 
 def test_call_descr_dynamic():
     args = [types.sint, types.pointer]
-    descr = get_call_descr_dynamic(FakeCPU(), args, types.sint, None,
-                                   ffi_flags=42)
+    descr = calldescr_dynamic_for_tests(FakeCPU(), args, types.sint)
     assert isinstance(descr, CallDescr)
     assert descr.result_type == 'i'
     assert descr.result_flag == FLAG_SIGNED
     assert descr.arg_classes == 'ii'
-    assert descr.get_ffi_flags() == 42
+    assert descr.get_ffi_flags() == FFI_DEFAULT_ABI
 
     args = [types.sint, types.double, types.pointer]
-    descr = get_call_descr_dynamic(FakeCPU(), args, types.void, None, 42)
+    descr = calldescr_dynamic_for_tests(FakeCPU(), args, types.void)
     assert descr is None    # missing floats
-    descr = get_call_descr_dynamic(FakeCPU(supports_floats=True),
-                                   args, types.void, None, ffi_flags=43)
+    descr = calldescr_dynamic_for_tests(FakeCPU(supports_floats=True),
+                                        args, types.void)
     assert descr.result_type == 'v'
     assert descr.result_flag == FLAG_VOID
     assert descr.arg_classes == 'ifi'
-    assert descr.get_ffi_flags() == 43
+    assert descr.get_ffi_flags() == FFI_DEFAULT_ABI
 
-    descr = get_call_descr_dynamic(FakeCPU(), [], types.sint8, None, 42)
+    descr = calldescr_dynamic_for_tests(FakeCPU(), [], types.sint8)
     assert descr.get_result_size() == 1
     assert descr.result_flag == FLAG_SIGNED
     assert descr.is_result_signed() == True
 
-    descr = get_call_descr_dynamic(FakeCPU(), [], types.uint8, None, 42)
+    descr = calldescr_dynamic_for_tests(FakeCPU(), [], types.uint8)
     assert isinstance(descr, CallDescr)
     assert descr.get_result_size() == 1
     assert descr.result_flag == FLAG_UNSIGNED
     assert descr.is_result_signed() == False
 
     if not is_64_bit or is_emulated_long:
-        descr = get_call_descr_dynamic(FakeCPU(), [], types.slonglong,
-                                       None, 42)
+        descr = calldescr_dynamic_for_tests(FakeCPU(), [], types.slonglong)
         assert descr is None   # missing longlongs
-        descr = get_call_descr_dynamic(FakeCPU(supports_longlong=True),
-                                       [], types.slonglong, None, ffi_flags=43)
+        descr = calldescr_dynamic_for_tests(FakeCPU(supports_longlong=True),
+                                            [], types.slonglong)
         assert isinstance(descr, CallDescr)
         assert descr.result_flag == FLAG_FLOAT
         assert descr.result_type == 'L'
-        assert descr.get_ffi_flags() == 43
+        assert descr.get_ffi_flags() == FFI_DEFAULT_ABI
     else:
         assert types.slonglong is types.slong
 
-    descr = get_call_descr_dynamic(FakeCPU(), [], types.float, None, 42)
+    descr = calldescr_dynamic_for_tests(FakeCPU(), [], types.float)
     assert descr is None   # missing singlefloats
-    descr = get_call_descr_dynamic(FakeCPU(supports_singlefloats=True),
-                                   [], types.float, None, ffi_flags=44)
+    descr = calldescr_dynamic_for_tests(FakeCPU(supports_singlefloats=True),
+                                        [], types.float)
     assert descr.result_flag == FLAG_UNSIGNED
     assert descr.result_type == 'S'
-    assert descr.get_ffi_flags() == 44
+    assert descr.get_ffi_flags() == FFI_DEFAULT_ABI

pypy/jit/backend/model.py

     def interiorfielddescrof(self, A, fieldname):
         raise NotImplementedError
 
-    def interiorfielddescrof_dynamic(self, offset, width, fieldsize, is_pointer,
-        is_float, is_signed):
-        raise NotImplementedError
-
     def arraydescrof(self, A):
         raise NotImplementedError
 

pypy/jit/backend/test/calling_convention_test.py

         return ConstInt(heaptracker.adr2int(addr))
 
     def test_call_aligned_with_spilled_values(self):
-        from pypy.rlib.libffi import types
         cpu = self.cpu
         if not cpu.supports_floats:
             py.test.skip('requires floats')
             assert abs(x - expected_result) < 0.0001
 
     def test_call_aligned_with_imm_values(self):
-        from pypy.rlib.libffi import types
         cpu = self.cpu
         if not cpu.supports_floats:
             py.test.skip('requires floats')
             assert abs(res.getfloat() - result) < 0.0001
 
     def test_call_aligned_with_args_on_the_stack(self):
-        from pypy.rlib.libffi import types
         cpu = self.cpu
         if not cpu.supports_floats:
             py.test.skip('requires floats')
             assert abs(res.getfloat() - result) < 0.0001
 
     def test_call_alignment_call_assembler(self):
-        from pypy.rlib.libffi import types
         cpu = self.cpu
         if not cpu.supports_floats:
             py.test.skip('requires floats')
             py.test.skip('requires floats and singlefloats')
 
         import random
-        from pypy.rlib.libffi import types
         from pypy.rlib.rarithmetic import r_singlefloat
 
         def func(*args):

pypy/jit/backend/test/runner_test.py

             assert longlong.getrealfloat(x) == 3.5 - 42
 
     def test_call(self):
-        from pypy.rlib.libffi import types, FUNCFLAG_CDECL
+        from pypy.rlib.jit_libffi import types
 
         def func_int(a, b):
             return a + b
                                          'int', descr=calldescr)
             assert res.value == 2 * num
             # then, try it with the dynamic calldescr
-            dyn_calldescr = cpu.calldescrof_dynamic([ffi_type, ffi_type], ffi_type,
-                                                    EffectInfo.MOST_GENERAL,
-                                                    ffi_flags=FUNCFLAG_CDECL)
+            dyn_calldescr = cpu._calldescr_dynamic_for_tests(
+                [ffi_type, ffi_type], ffi_type)
             res = self.execute_operation(rop.CALL,
                                          [funcbox, BoxInt(num), BoxInt(num)],
                                          'int', descr=dyn_calldescr)
         assert s.x == chr(190)
         assert s.y == chr(150)
 
-    def test_fielddescrof_dynamic(self):
-        S = lltype.Struct('S',
-                          ('x', lltype.Signed),
-                          ('y', lltype.Signed),
-                          )
-        longsize = rffi.sizeof(lltype.Signed)
-        y_ofs = longsize
-        s = lltype.malloc(S, flavor='raw')
-        sa = llmemory.cast_ptr_to_adr(s)
-        s_box = BoxInt(heaptracker.adr2int(sa))
-        #
-        field = self.cpu.fielddescrof(S, 'y')
-        field_dyn = self.cpu.fielddescrof_dynamic(offset=y_ofs,
-                                                  fieldsize=longsize,
-                                                  is_pointer=False,
-                                                  is_float=False,
-                                                  is_signed=True)
-        assert field.is_pointer_field() == field_dyn.is_pointer_field()
-        assert field.is_float_field()   == field_dyn.is_float_field()
-        if 'llgraph' not in str(self.cpu):
-            assert field.is_field_signed()  == field_dyn.is_field_signed()
-
-        #
-        for get_op, set_op in ((rop.GETFIELD_RAW, rop.SETFIELD_RAW),
-                               (rop.GETFIELD_RAW_PURE, rop.SETFIELD_RAW)):
-            for descr in (field, field_dyn):
-                self.execute_operation(set_op, [s_box, BoxInt(32)], 'void',
-                                       descr=descr)
-                res = self.execute_operation(get_op, [s_box], 'int', descr=descr)
-                assert res.getint()  == 32
-
-        lltype.free(s, flavor='raw')
-
     def test_new_with_vtable(self):
         cpu = self.cpu
         t_box, T_box = self.alloc_instance(self.T)
         cpu = self.cpu
         func_adr = llmemory.cast_ptr_to_adr(c_tolower.funcsym)
         funcbox = ConstInt(heaptracker.adr2int(func_adr))
-        calldescr = cpu.calldescrof_dynamic([types.uchar], types.sint,
-                                            EffectInfo.MOST_GENERAL,
-                                            ffi_flags=FUNCFLAG_CDECL)
+        calldescr = cpu._calldescr_dynamic_for_tests([types.uchar], types.sint)
         i1 = BoxInt()
         i2 = BoxInt()
         tok = BoxInt()
         cpu = self.cpu
         func_adr = llmemory.cast_ptr_to_adr(c_qsort.funcsym)
         funcbox = ConstInt(heaptracker.adr2int(func_adr))
-        calldescr = cpu.calldescrof_dynamic([types.pointer, types_size_t,
-                                             types_size_t, types.pointer],
-                                            types.void,
-                                            EffectInfo.MOST_GENERAL,
-                                            ffi_flags=clibffi.FUNCFLAG_CDECL)
+        calldescr = cpu._calldescr_dynamic_for_tests(
+            [types.pointer, types_size_t, types_size_t, types.pointer],
+            types.void)
         i0 = BoxInt()
         i1 = BoxInt()
         i2 = BoxInt()
         cpu = self.cpu
         func_adr = llmemory.cast_ptr_to_adr(c_GetCurrentDir.funcsym)
         funcbox = ConstInt(heaptracker.adr2int(func_adr))
-        calldescr = cpu.calldescrof_dynamic([types.ulong, types.pointer],
-                                            types.ulong,
-                                            EffectInfo.MOST_GENERAL,
-                                            ffi_flags=FUNCFLAG_STDCALL)
+        calldescr = cpu._calldescr_dynamic_for_tests(
+            [types.ulong, types.pointer],
+            types.ulong,
+            abiname='FFI_STDCALL')
         i1 = BoxInt()
         i2 = BoxInt()
         faildescr = BasicFailDescr(1)
         assert str.chars[4] == '/'
 
     def test_sorting_of_fields(self):
-        S = self.S
+        S = lltype.GcStruct('S', ('parent', rclass.OBJECT),
+                                  ('value', lltype.Signed),
+                                  ('chr1', lltype.Char),
+                                  ('chr2', lltype.Char))
+        chr1 = self.cpu.fielddescrof(S, 'chr1').sort_key()
         value = self.cpu.fielddescrof(S, 'value').sort_key()
-        chr1 = self.cpu.fielddescrof(S, 'chr1').sort_key()
         chr2 = self.cpu.fielddescrof(S, 'chr2').sort_key()
-        assert (sorted([chr2, chr1, value]) ==
-                [value, chr1, chr2])
-        assert len(dict.fromkeys([value, chr1, chr2]).keys()) == 3
+        assert len(set([value, chr1, chr2])) == 3
 
     def test_guards_nongc(self):
         x = lltype.malloc(lltype.Struct('x'), flavor='raw')
         res = self.cpu.get_latest_value_int(0)
         assert res == -10
 
+    def test_int_force_ge_zero(self):
+        ops = """
+        [i0]
+        i1 = int_force_ge_zero(i0)    # but forced to be in a register
+        finish(i1, descr=1)
+        """
+        loop = parse(ops, self.cpu, namespace=locals())
+        descr = loop.operations[-1].getdescr()
+        looptoken = JitCellToken()
+        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        for inp, outp in [(2,2), (-3, 0)]:
+            self.cpu.execute_token(looptoken, inp)
+            assert outp == self.cpu.get_latest_value_int(0)
+
     def test_compile_asmlen(self):
         from pypy.jit.backend.llsupport.llmodel import AbstractLLCPU
         if not isinstance(self.cpu, AbstractLLCPU):
         fail = self.cpu.execute_token(looptoken2, -9)
         assert fail.identifier == 42
 
+    def test_raw_load_int(self):
+        from pypy.rlib import rawstorage
+        for T in [rffi.UCHAR, rffi.SIGNEDCHAR,
+                  rffi.USHORT, rffi.SHORT,
+                  rffi.UINT, rffi.INT,
+                  rffi.ULONG, rffi.LONG]:
+            ops = """
+            [i0, i1]
+            i2 = raw_load(i0, i1, descr=arraydescr)
+            finish(i2)
+            """
+            arraydescr = self.cpu.arraydescrof(rffi.CArray(T))
+            p = rawstorage.alloc_raw_storage(31)
+            for i in range(31):
+                p[i] = '\xDD'
+            value = rffi.cast(T, 0x4243444546474849)
+            rawstorage.raw_storage_setitem(p, 16, value)
+            loop = parse(ops, self.cpu, namespace=locals())
+            looptoken = JitCellToken()
+            self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+            self.cpu.execute_token(looptoken,
+                                   rffi.cast(lltype.Signed, p), 16)
+            result = self.cpu.get_latest_value_int(0)
+            assert result == rffi.cast(lltype.Signed, value)
+            rawstorage.free_raw_storage(p)
+
+    def test_raw_load_float(self):
+        if not self.cpu.supports_floats:
+            py.test.skip("requires floats")
+        from pypy.rlib import rawstorage
+        for T in [rffi.DOUBLE]:
+            ops = """
+            [i0, i1]
+            f2 = raw_load(i0, i1, descr=arraydescr)
+            finish(f2)
+            """
+            arraydescr = self.cpu.arraydescrof(rffi.CArray(T))
+            p = rawstorage.alloc_raw_storage(31)
+            for i in range(31):
+                p[i] = '\xDD'
+            value = rffi.cast(T, 1.12e20)
+            rawstorage.raw_storage_setitem(p, 16, value)
+            loop = parse(ops, self.cpu, namespace=locals())
+            looptoken = JitCellToken()
+            self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+            self.cpu.execute_token(looptoken,
+                                   rffi.cast(lltype.Signed, p), 16)
+            result = self.cpu.get_latest_value_float(0)
+            result = longlong.getrealfloat(result)
+            assert result == rffi.cast(lltype.Float, value)
+            rawstorage.free_raw_storage(p)
+
+    def test_raw_store_int(self):
+        from pypy.rlib import rawstorage
+        for T in [rffi.UCHAR, rffi.SIGNEDCHAR,
+                  rffi.USHORT, rffi.SHORT,
+                  rffi.UINT, rffi.INT,
+                  rffi.ULONG, rffi.LONG]:
+            ops = """
+            [i0, i1, i2]
+            raw_store(i0, i1, i2, descr=arraydescr)
+            finish()
+            """
+            arraydescr = self.cpu.arraydescrof(rffi.CArray(T))
+            p = rawstorage.alloc_raw_storage(31)
+            for i in range(31):
+                p[i] = '\xDD'
+            value = 0x4243444546474849 & sys.maxint
+            loop = parse(ops, self.cpu, namespace=locals())
+            looptoken = JitCellToken()
+            self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+            self.cpu.execute_token(looptoken,
+                                   rffi.cast(lltype.Signed, p), 16, value)
+            result = rawstorage.raw_storage_getitem(T, p, 16)
+            assert result == rffi.cast(T, value)
+            rawstorage.free_raw_storage(p)
+
+    def test_raw_store_float(self):
+        if not self.cpu.supports_floats:
+            py.test.skip("requires floats")
+        from pypy.rlib import rawstorage
+        for T in [rffi.DOUBLE]:
+            ops = """
+            [i0, i1, f2]
+            raw_store(i0, i1, f2, descr=arraydescr)
+            finish()
+            """
+            arraydescr = self.cpu.arraydescrof(rffi.CArray(T))
+            p = rawstorage.alloc_raw_storage(31)
+            for i in range(31):
+                p[i] = '\xDD'
+            value = 1.23e20
+            loop = parse(ops, self.cpu, namespace=locals())
+            looptoken = JitCellToken()
+            self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+            self.cpu.execute_token(looptoken,
+                                   rffi.cast(lltype.Signed, p), 16,
+                                   longlong.getfloatstorage(value))
+            result = rawstorage.raw_storage_getitem(T, p, 16)
+            assert result == rffi.cast(T, value)
+            rawstorage.free_raw_storage(p)
 
 class OOtypeBackendTest(BaseBackendTest):
 

pypy/jit/backend/x86/assembler.py

         self._build_stack_check_slowpath()
         if gc_ll_descr.gcrootmap:
             self._build_release_gil(gc_ll_descr.gcrootmap)
-        debug_start('jit-backend-counts')
-        self.set_debug(have_debug_prints())
-        debug_stop('jit-backend-counts')
+        if not self._debug:
+            # if self._debug is already set it means that someone called
+            # set_debug by hand before initializing the assembler. Leave it
+            # as it is
+            debug_start('jit-backend-counts')
+            self.set_debug(have_debug_prints())
+            debug_stop('jit-backend-counts')
 
     def setup(self, looptoken):
         assert self.memcpy_addr != 0, "setup_once() not called?"
             getattr(self.mc, asmop)(arglocs[0], arglocs[1])
         return genop_binary
 
+    def _binaryop_or_lea(asmop, is_add):
+        def genop_binary_or_lea(self, op, arglocs, result_loc):
+            # use a regular ADD or SUB if result_loc is arglocs[0],
+            # and a LEA only if different.
+            if result_loc is arglocs[0]:
+                getattr(self.mc, asmop)(arglocs[0], arglocs[1])
+            else:
+                loc = arglocs[0]
+                argloc = arglocs[1]
+                assert isinstance(loc, RegLoc)
+                assert isinstance(argloc, ImmedLoc)
+                assert isinstance(result_loc, RegLoc)
+                delta = argloc.value
+                if not is_add:    # subtraction
+                    delta = -delta
+                self.mc.LEA_rm(result_loc.value, (loc.value, delta))
+        return genop_binary_or_lea
+
     def _cmpop(cond, rev_cond):
         def genop_cmp(self, op, arglocs, result_loc):
             rl = result_loc.lowest8bits()
 
     genop_int_neg = _unaryop("NEG")
     genop_int_invert = _unaryop("NOT")
-    genop_int_add = _binaryop("ADD", True)
-    genop_int_sub = _binaryop("SUB")
+    genop_int_add = _binaryop_or_lea("ADD", True)
+    genop_int_sub = _binaryop_or_lea("SUB", False)
     genop_int_mul = _binaryop("IMUL", True)
     genop_int_and = _binaryop("AND", True)
     genop_int_or  = _binaryop("OR", True)
     def genop_int_force_ge_zero(self, op, arglocs, resloc):
         self.mc.TEST(arglocs[0], arglocs[0])
         self.mov(imm0, resloc)
-        self.mc.CMOVNS(arglocs[0], resloc)
+        self.mc.CMOVNS(resloc, arglocs[0])
 
     def genop_int_mod(self, op, arglocs, resloc):
         if IS_X86_32:
 
     genop_getarrayitem_gc_pure = genop_getarrayitem_gc
     genop_getarrayitem_raw = genop_getarrayitem_gc
+    genop_getarrayitem_raw_pure = genop_getarrayitem_gc
+
+    def genop_raw_load(self, op, arglocs, resloc):
+        base_loc, ofs_loc, size_loc, ofs, sign_loc = arglocs
+        assert isinstance(ofs, ImmedLoc)
+        src_addr = addr_add(base_loc, ofs_loc, ofs.value, 0)
+        self.load_from_mem(resloc, src_addr, size_loc, sign_loc)
 
     def _get_interiorfield_addr(self, temp_loc, index_loc, itemsize_loc,
                                 base_loc, ofs_loc):
                                                 ofs_loc)
         self.load_from_mem(resloc, src_addr, fieldsize_loc, sign_loc)
 
-    genop_getinteriorfield_raw = genop_getinteriorfield_gc
-
-
     def genop_discard_setfield_gc(self, op, arglocs):
         base_loc, ofs_loc, size_loc, value_loc = arglocs
         assert isinstance(size_loc, ImmedLoc)
         dest_addr = AddressLoc(base_loc, ofs_loc, scale, baseofs.value)
         self.save_into_mem(dest_addr, value_loc, size_loc)
 
+    def genop_discard_raw_store(self, op, arglocs):
+        base_loc, ofs_loc, value_loc, size_loc, baseofs = arglocs
+        assert isinstance(baseofs, ImmedLoc)
+        dest_addr = AddressLoc(base_loc, ofs_loc, 0, baseofs.value)
+        self.save_into_mem(dest_addr, value_loc, size_loc)
+
     def genop_discard_strsetitem(self, op, arglocs):
         base_loc, ofs_loc, val_loc = arglocs
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
                             guard_op.getopname())
 
     def genop_guard_int_add_ovf(self, op, guard_op, guard_token, arglocs, result_loc):
-        self.genop_int_add(op, arglocs, result_loc)
+        self.mc.ADD(arglocs[0], arglocs[1])
         return self._gen_guard_overflow(guard_op, guard_token)
 
     def genop_guard_int_sub_ovf(self, op, guard_op, guard_token, arglocs, result_loc):
-        self.genop_int_sub(op, arglocs, result_loc)
+        self.mc.SUB(arglocs[0], arglocs[1])
         return self._gen_guard_overflow(guard_op, guard_token)
 
     def genop_guard_int_mul_ovf(self, op, guard_op, guard_token, arglocs, result_loc):
-        self.genop_int_mul(op, arglocs, result_loc)
+        self.mc.IMUL(arglocs[0], arglocs[1])
         return self._gen_guard_overflow(guard_op, guard_token)
 
     def genop_guard_guard_false(self, ign_1, guard_op, guard_token, locs, ign_2):
     return AddressLoc(reg_or_imm1, reg_or_imm2, scale, offset)
 
 def addr_add_const(reg_or_imm1, offset):
-    return AddressLoc(reg_or_imm1, ImmedLoc(0), 0, offset)
+    return AddressLoc(reg_or_imm1, imm0, 0, offset)
 
 def mem(loc, offset):
-    return AddressLoc(loc, ImmedLoc(0), 0, offset)
+    return AddressLoc(loc, imm0, 0, offset)
 
 def heap(addr):
-    return AddressLoc(ImmedLoc(addr), ImmedLoc(0), 0, 0)
+    return AddressLoc(ImmedLoc(addr), imm0, 0, 0)
 
 def not_implemented(msg):
     os.write(2, '[x86/asm] %s\n' % msg)

pypy/jit/backend/x86/regalloc.py

      TempBox
 from pypy.jit.backend.x86.arch import WORD, FRAME_FIXED_SIZE
 from pypy.jit.backend.x86.arch import IS_X86_32, IS_X86_64, MY_COPY_OF_REGS
+from pypy.jit.backend.x86 import rx86
 from pypy.rlib.rarithmetic import r_longlong
 
 class X86RegisterManager(RegisterManager):
         loc, argloc = self._consider_binop_part(op)
         self.Perform(op, [loc, argloc], loc)
 
-    consider_int_add = _consider_binop
+    def _consider_lea(self, op, loc):
+        argloc = self.loc(op.getarg(1))
+        self.rm.possibly_free_var(op.getarg(0))
+        resloc = self.force_allocate_reg(op.result)
+        self.Perform(op, [loc, argloc], resloc)
+
+    def consider_int_add(self, op):
+        loc = self.loc(op.getarg(0))
+        y = op.getarg(1)
+        if (isinstance(loc, RegLoc) and
+            isinstance(y, ConstInt) and rx86.fits_in_32bits(y.value)):
+            self._consider_lea(op, loc)
+        else:
+            self._consider_binop(op)
+
+    def consider_int_sub(self, op):
+        loc = self.loc(op.getarg(0))
+        y = op.getarg(1)
+        if (isinstance(loc, RegLoc) and
+            isinstance(y, ConstInt) and rx86.fits_in_32bits(-y.value)):
+            self._consider_lea(op, loc)
+        else:
+            self._consider_binop(op)
+
     consider_int_mul = _consider_binop
-    consider_int_sub = _consider_binop
     consider_int_and = _consider_binop
     consider_int_or  = _consider_binop
     consider_int_xor = _consider_binop
                                  imm(itemsize), imm(ofs)])
 
     consider_setarrayitem_raw = consider_setarrayitem_gc
+    consider_raw_store = consider_setarrayitem_gc
 
     def consider_getfield_gc(self, op):
         ofs_loc, size_loc, sign = self._unpack_fielddescr(op.getdescr())
 
     consider_getarrayitem_raw = consider_getarrayitem_gc
     consider_getarrayitem_gc_pure = consider_getarrayitem_gc
+    consider_getarrayitem_raw_pure = consider_getarrayitem_gc
+    consider_raw_load = consider_getarrayitem_gc
 
     def consider_getinteriorfield_gc(self, op):
         t = self._unpack_interiorfielddescr(op.getdescr())
         self.Perform(op, [base_loc, ofs, itemsize, fieldsize,
                           index_loc, temp_loc, sign_loc], result_loc)
 
-    consider_getinteriorfield_raw = consider_getinteriorfield_gc
-
     def consider_int_is_true(self, op, guard_op):
         # doesn't need arg to be in a register
         argloc = self.loc(op.getarg(0))

pypy/jit/backend/x86/rx86.py

     NOT_r = insn(rex_w, '\xF7', register(1), '\xD0')
     NOT_b = insn(rex_w, '\xF7', orbyte(2<<3), stack_bp(1))
 
-    CMOVNS_rr = insn(rex_w, '\x0F\x49', register(2, 8), register(1), '\xC0')
+    CMOVNS_rr = insn(rex_w, '\x0F\x49', register(1, 8), register(2), '\xC0')
 
     # ------------------------------ Misc stuff ------------------------------
 

pypy/jit/backend/x86/test/test_fficall.py

 from pypy.jit.metainterp.test import test_fficall
 from pypy.jit.backend.x86.test.test_basic import Jit386Mixin
 
-class TestFfiLookups(Jit386Mixin, test_fficall.FfiLookupTests):
+class TestFfiCall(Jit386Mixin, test_fficall.FfiCallTests):
     # for the individual tests see
     # ====> ../../../metainterp/test/test_fficall.py
-    supports_all = True
+    pass

pypy/jit/backend/x86/test/test_rawmem.py

+
+from pypy.jit.backend.x86.test.test_basic import Jit386Mixin
+from pypy.jit.metainterp.test.test_rawmem import RawMemTests
+
+
+class TestRawMem(Jit386Mixin, RawMemTests):
+    # for the individual tests see
+    # ====> ../../../metainterp/test/test_rawmem.py
+    pass

pypy/jit/backend/x86/test/test_runner.py

                 mc.RET16_i(40)
             rawstart = mc.materialize(cpu.asmmemmgr, [])
             #
-            calldescr = cpu.calldescrof_dynamic([types.slong] * 10,
-                                                types.slong,
-                                                EffectInfo.MOST_GENERAL,
-                                                ffi_flags=-1)
+            calldescr = cpu._calldescr_dynamic_for_tests([types.slong] * 10,
+                                                         types.slong)
             calldescr.get_call_conv = lambda: ffi      # <==== hack
             # ^^^ we patch get_call_conv() so that the test also makes sense
             #     on Linux, because clibffi.get_call_conv() would always

pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py

                 # CALL_j is actually relative, so tricky to test
                 (instrname == 'CALL' and argmodes == 'j') or
                 # SET_ir must be tested manually
-                (instrname == 'SET' and argmodes == 'ir') or
-                # asm gets CMOVNS args the wrong way
-                (instrname.startswith('CMOV'))
+                (instrname == 'SET' and argmodes == 'ir')
         )
 
 

pypy/jit/backend/x86/test/test_ztranslation.py

             return len(ll_times)
 
         res = self.meta_interp(main, [])
-        assert res == 1
+        assert res == 3
+        # one for loop, one for entry point and one for the prologue
 
 class TestTranslationRemoveTypePtrX86(CCompiledMixin):
     CPUClass = getcpuclass()

pypy/jit/backend/x86/tool/test/test_viewcode.py

 from cStringIO import StringIO
 from pypy.jit.backend.x86.tool.viewcode import format_code_dump_with_labels
+from pypy.jit.backend.x86.tool.viewcode import find_objdump
+import os
+import py
+import tempfile
+from pypy.tool.udir import udir
 
 def test_format_code_dump_with_labels():
     lines = StringIO("""
     lines = format_code_dump_with_labels(0xAA00, lines, label_list=None)
     out = ''.join(lines)
     assert out.strip() == input
+
+def test_find_objdump():
+    old = os.environ['PATH']
+    os.environ['PATH'] = ''
+    py.test.raises(find_objdump)
+
+    #
+    path = udir.join('objdump')
+    print >>path, 'hello world'
+    os.environ['PATH'] = path.dirname
+    assert find_objdump() == 'objdump'
+    #
+    os.environ['PATH'] = old

pypy/jit/backend/x86/tool/viewcode.py

     ./viewcode.py log               # also includes a pygame viewer
 """
 
-import autopath
 import new
 import operator
+import os
 import py
 import re
 import sys
 if sys.platform == "win32":
     pass   # lots more in Psyco
 
+def find_objdump():
+    exe = ('objdump', 'gobjdump')
+    path = os.environ['PATH'].split(os.pathsep)
+    for e in exe:
+        for p in path:
+            path_to = os.path.join(p, e)
+            if not os.path.exists(path_to):
+                continue
+            return e
+    raise AssertionError('(g)objdump was not found in PATH')
+
 def machine_code_dump(data, originaddr, backend_name, label_list=None):
     objdump_backend_option = {
         'x86': 'i386',
         'x86_64': 'x86-64',
         'i386': 'i386',
     }
-    objdump = ('objdump -M %(backend)s -b binary -m i386 '
+    cmd = find_objdump()
+    objdump = ('%(command)s -M %(backend)s -b binary -m i386 '
                '--disassembler-options=intel-mnemonics '
                '--adjust-vma=%(origin)d -D %(file)s')
     #
     f.write(data)
     f.close()
     p = subprocess.Popen(objdump % {
+        'command': cmd,
         'file': tmpfile,
         'origin': originaddr,
         'backend': objdump_backend_option[backend_name],

pypy/jit/codewriter/call.py

 
 class CallControl(object):
     virtualref_info = None     # optionally set from outside
+    has_libffi_call = False    # default value
 
     def __init__(self, cpu=None, jitdrivers_sd=[]):
         assert isinstance(jitdrivers_sd, list)   # debugging

pypy/jit/codewriter/effectinfo.py

     OS_UNIEQ_LENGTHOK           = 51   #
     _OS_offset_uni              = OS_UNI_CONCAT - OS_STR_CONCAT
     #
-    OS_LIBFFI_PREPARE           = 60
-    OS_LIBFFI_PUSH_ARG          = 61
     OS_LIBFFI_CALL              = 62
-    OS_LIBFFI_STRUCT_GETFIELD   = 63
-    OS_LIBFFI_STRUCT_SETFIELD   = 64
-    OS_LIBFFI_GETARRAYITEM      = 65
-    OS_LIBFFI_SETARRAYITEM      = 66
     #
     OS_LLONG_INVERT             = 69
     OS_LLONG_ADD                = 70
     OS_LLONG_U_TO_FLOAT         = 94
     #
     OS_MATH_SQRT                = 100
+    #
+    OS_RAW_MALLOC_VARSIZE       = 110
+    OS_RAW_FREE                 = 111
 
     # for debugging:
-    _OS_CANRAISE = set([OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL])
+    _OS_CANRAISE = set([OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL,
+                        OS_RAW_MALLOC_VARSIZE])
 
     def __new__(cls, readonly_descrs_fields, readonly_descrs_arrays,
                 write_descrs_fields, write_descrs_arrays,

pypy/jit/codewriter/jtransform.py

 from pypy.objspace.flow.model import SpaceOperation, Variable, Constant, c_last_exception
 from pypy.rlib import objectmodel
 from pypy.rlib.jit import _we_are_jitted
+from pypy.rlib.rgc import lltype_is_gc
 from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rclass, rffi
 from pypy.rpython.rclass import IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY
 from pypy.translator.simplify import get_funcobj
         if op.args[0] in self.vable_array_vars:
             self.vable_array_vars[op.result]= self.vable_array_vars[op.args[0]]
 
+    def rewrite_op_cast_ptr_to_adr(self, op):
+        if lltype_is_gc(op.args[0].concretetype):
+            raise Exception("cast_ptr_to_adr for GC types unsupported")
+
     def rewrite_op_cast_pointer(self, op):
         newop = self.rewrite_op_same_as(op)
         assert newop is None
                 return [None, # hack, do the right renaming from op.args[0] to op.result
                         SpaceOperation("record_known_class", [op.args[0], const_vtable], None)]
 
+    def rewrite_op_raw_malloc_usage(self, op):
+        pass
+
     def rewrite_op_jit_record_known_class(self, op):
         return SpaceOperation("record_known_class", [op.args[0], op.args[1]], None)
 
             name += '_add_memory_pressure'
         if not track_allocation:
             name += '_no_track_allocation'
-        return self._do_builtin_call(op, name, args,
-                                     extra = (TYPE,),
-                                     extrakey = TYPE)
+        op1 = self.prepare_builtin_call(op, name, args, (TYPE,), TYPE)
+        if name == 'raw_malloc_varsize':
+            return self._handle_oopspec_call(op1, args,
+                                             EffectInfo.OS_RAW_MALLOC_VARSIZE,
+                                             EffectInfo.EF_CAN_RAISE)
+        return self.rewrite_op_direct_call(op1)
 
     def rewrite_op_malloc_varsize(self, op):
         if op.args[1].value['flavor'] == 'raw':
         name = 'raw_free'
         if not track_allocation:
             name += '_no_track_allocation'
-        return self._do_builtin_call(op, name, [op.args[0]],
-                                     extra = (STRUCT,), extrakey = STRUCT)
+        op1 = self.prepare_builtin_call(op, name, [op.args[0]], (STRUCT,),
+                                        STRUCT)
+        if name == 'raw_free':
+            return self._handle_oopspec_call(op1, [op.args[0]],
+                                             EffectInfo.OS_RAW_FREE,
+                                             EffectInfo.EF_CANNOT_RAISE)
+        return self.rewrite_op_direct_call(op1)
 
     def rewrite_op_getarrayitem(self, op):
         ARRAY = op.args[0].concretetype.TO
                                    [v_base, arrayfielddescr, arraydescr,