[pypy-commit] pypy unroll-if-alt: merged default.
alex_gaynor
noreply at buildbot.pypy.org
Thu Sep 1 05:25:39 CEST 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: unroll-if-alt
Changeset: r46967:e13ef7acdedb
Date: 2011-08-31 15:08 -0400
http://bitbucket.org/pypy/pypy/changeset/e13ef7acdedb/
Log: merged default.
diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -25,13 +25,14 @@
class Descr(history.AbstractDescr):
def __init__(self, ofs, typeinfo, extrainfo=None, name=None,
- arg_types=None, count_fields_if_immut=-1):
+ arg_types=None, count_fields_if_immut=-1, ffi_flags=0):
self.ofs = ofs
self.typeinfo = typeinfo
self.extrainfo = extrainfo
self.name = name
self.arg_types = arg_types
self.count_fields_if_immut = count_fields_if_immut
+ self.ffi_flags = ffi_flags
def get_arg_types(self):
return self.arg_types
@@ -67,6 +68,9 @@
def count_fields_if_immutable(self):
return self.count_fields_if_immut
+ def get_ffi_flags(self):
+ return self.ffi_flags
+
def __lt__(self, other):
raise TypeError("cannot use comparison on Descrs")
def __le__(self, other):
@@ -114,14 +118,14 @@
return False
def getdescr(self, ofs, typeinfo='?', extrainfo=None, name=None,
- arg_types=None, count_fields_if_immut=-1):
+ arg_types=None, count_fields_if_immut=-1, ffi_flags=0):
key = (ofs, typeinfo, extrainfo, name, arg_types,
- count_fields_if_immut)
+ count_fields_if_immut, ffi_flags)
try:
return self._descrs[key]
except KeyError:
descr = Descr(ofs, typeinfo, extrainfo, name, arg_types,
- count_fields_if_immut)
+ count_fields_if_immut, ffi_flags)
self._descrs[key] = descr
return descr
@@ -326,7 +330,7 @@
return self.getdescr(0, token[0], extrainfo=extrainfo,
arg_types=''.join(arg_types))
- def calldescrof_dynamic(self, ffi_args, ffi_result, extrainfo):
+ def calldescrof_dynamic(self, ffi_args, ffi_result, extrainfo, ffi_flags):
from pypy.jit.backend.llsupport.ffisupport import get_ffi_type_kind
from pypy.jit.backend.llsupport.ffisupport import UnsupportedKind
arg_types = []
@@ -339,7 +343,8 @@
except UnsupportedKind:
return None
return self.getdescr(0, reskind, extrainfo=extrainfo,
- arg_types=''.join(arg_types))
+ arg_types=''.join(arg_types),
+ ffi_flags=ffi_flags)
def grab_exc_value(self):
diff --git a/pypy/jit/backend/llsupport/descr.py b/pypy/jit/backend/llsupport/descr.py
--- a/pypy/jit/backend/llsupport/descr.py
+++ b/pypy/jit/backend/llsupport/descr.py
@@ -260,10 +260,12 @@
_clsname = ''
loop_token = None
arg_classes = '' # <-- annotation hack
+ ffi_flags = 0
- def __init__(self, arg_classes, extrainfo=None):
+ def __init__(self, arg_classes, extrainfo=None, ffi_flags=0):
self.arg_classes = arg_classes # string of "r" and "i" (ref/int)
self.extrainfo = extrainfo
+ self.ffi_flags = ffi_flags
def __repr__(self):
res = '%s(%s)' % (self.__class__.__name__, self.arg_classes)
@@ -284,6 +286,13 @@
def get_extra_info(self):
return self.extrainfo
+ def get_ffi_flags(self):
+ return self.ffi_flags
+
+ def get_call_conv(self):
+ from pypy.rlib.clibffi import get_call_conv
+ return get_call_conv(self.ffi_flags)
+
def get_arg_types(self):
return self.arg_classes
@@ -391,8 +400,8 @@
"""
_clsname = 'DynamicIntCallDescr'
- def __init__(self, arg_classes, result_size, result_sign, extrainfo=None):
- BaseIntCallDescr.__init__(self, arg_classes, extrainfo)
+ def __init__(self, arg_classes, result_size, result_sign, extrainfo=None, ffi_flags=0):
+ BaseIntCallDescr.__init__(self, arg_classes, extrainfo, ffi_flags)
assert isinstance(result_sign, bool)
self._result_size = chr(result_size)
self._result_sign = result_sign
diff --git a/pypy/jit/backend/llsupport/ffisupport.py b/pypy/jit/backend/llsupport/ffisupport.py
--- a/pypy/jit/backend/llsupport/ffisupport.py
+++ b/pypy/jit/backend/llsupport/ffisupport.py
@@ -8,7 +8,7 @@
class UnsupportedKind(Exception):
pass
-def get_call_descr_dynamic(cpu, ffi_args, ffi_result, extrainfo=None):
+def get_call_descr_dynamic(cpu, ffi_args, ffi_result, extrainfo=None, ffi_flags=0):
"""Get a call descr: the types of result and args are represented by
rlib.libffi.types.*"""
try:
@@ -20,18 +20,24 @@
if reskind == history.INT:
size = intmask(ffi_result.c_size)
signed = is_ffi_type_signed(ffi_result)
- return DynamicIntCallDescr(arg_classes, size, signed, extrainfo)
+ return DynamicIntCallDescr(arg_classes, size, signed, extrainfo,
+ ffi_flags=ffi_flags)
elif reskind == history.REF:
- return NonGcPtrCallDescr(arg_classes, extrainfo)
+ return NonGcPtrCallDescr(arg_classes, extrainfo,
+ ffi_flags=ffi_flags)
elif reskind == history.FLOAT:
- return FloatCallDescr(arg_classes, extrainfo)
+ return FloatCallDescr(arg_classes, extrainfo,
+ ffi_flags=ffi_flags)
elif reskind == history.VOID:
- return VoidCallDescr(arg_classes, extrainfo)
+ return VoidCallDescr(arg_classes, extrainfo,
+ ffi_flags=ffi_flags)
elif reskind == 'L':
- return LongLongCallDescr(arg_classes, extrainfo)
+ return LongLongCallDescr(arg_classes, extrainfo,
+ ffi_flags=ffi_flags)
elif reskind == 'S':
SingleFloatCallDescr = getCallDescrClass(rffi.FLOAT)
- return SingleFloatCallDescr(arg_classes, extrainfo)
+ return SingleFloatCallDescr(arg_classes, extrainfo,
+ ffi_flags=ffi_flags)
assert False
def get_ffi_type_kind(cpu, ffi_type):
diff --git a/pypy/jit/backend/llsupport/llmodel.py b/pypy/jit/backend/llsupport/llmodel.py
--- a/pypy/jit/backend/llsupport/llmodel.py
+++ b/pypy/jit/backend/llsupport/llmodel.py
@@ -257,10 +257,10 @@
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):
+ def calldescrof_dynamic(self, ffi_args, ffi_result, extrainfo, ffi_flags):
from pypy.jit.backend.llsupport import ffisupport
return ffisupport.get_call_descr_dynamic(self, ffi_args, ffi_result,
- extrainfo)
+ extrainfo, ffi_flags)
def get_overflow_error(self):
ovf_vtable = self.cast_adr_to_int(self._ovf_error_vtable)
diff --git a/pypy/jit/backend/llsupport/test/test_ffisupport.py b/pypy/jit/backend/llsupport/test/test_ffisupport.py
--- a/pypy/jit/backend/llsupport/test/test_ffisupport.py
+++ b/pypy/jit/backend/llsupport/test/test_ffisupport.py
@@ -13,17 +13,19 @@
def test_call_descr_dynamic():
args = [types.sint, types.pointer]
- descr = get_call_descr_dynamic(FakeCPU(), args, types.sint)
+ descr = get_call_descr_dynamic(FakeCPU(), args, types.sint, ffi_flags=42)
assert isinstance(descr, DynamicIntCallDescr)
assert descr.arg_classes == 'ii'
+ assert descr.get_ffi_flags() == 42
args = [types.sint, types.double, types.pointer]
descr = get_call_descr_dynamic(FakeCPU(), args, types.void)
assert descr is None # missing floats
descr = get_call_descr_dynamic(FakeCPU(supports_floats=True),
- args, types.void)
+ args, types.void, ffi_flags=43)
assert isinstance(descr, VoidCallDescr)
assert descr.arg_classes == 'ifi'
+ assert descr.get_ffi_flags() == 43
descr = get_call_descr_dynamic(FakeCPU(), [], types.sint8)
assert isinstance(descr, DynamicIntCallDescr)
@@ -39,14 +41,16 @@
descr = get_call_descr_dynamic(FakeCPU(), [], types.slonglong)
assert descr is None # missing longlongs
descr = get_call_descr_dynamic(FakeCPU(supports_longlong=True),
- [], types.slonglong)
+ [], types.slonglong, ffi_flags=43)
assert isinstance(descr, LongLongCallDescr)
+ assert descr.get_ffi_flags() == 43
else:
assert types.slonglong is types.slong
descr = get_call_descr_dynamic(FakeCPU(), [], types.float)
assert descr is None # missing singlefloats
descr = get_call_descr_dynamic(FakeCPU(supports_singlefloats=True),
- [], types.float)
+ [], types.float, ffi_flags=44)
SingleFloatCallDescr = getCallDescrClass(rffi.FLOAT)
assert isinstance(descr, SingleFloatCallDescr)
+ assert descr.get_ffi_flags() == 44
diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -468,7 +468,7 @@
assert longlong.getrealfloat(x) == 3.5 - 42
def test_call(self):
- from pypy.rlib.libffi import types
+ from pypy.rlib.libffi import types, FUNCFLAG_CDECL
def func_int(a, b):
return a + b
@@ -497,7 +497,8 @@
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)
+ EffectInfo.MOST_GENERAL,
+ ffi_flags=FUNCFLAG_CDECL)
res = self.execute_operation(rop.CALL,
[funcbox, BoxInt(num), BoxInt(num)],
'int', descr=dyn_calldescr)
@@ -1944,7 +1945,7 @@
assert values == [1, 10]
def test_call_to_c_function(self):
- from pypy.rlib.libffi import CDLL, types, ArgChain
+ from pypy.rlib.libffi import CDLL, types, ArgChain, FUNCFLAG_CDECL
from pypy.rpython.lltypesystem.ll2ctypes import libc_name
libc = CDLL(libc_name)
c_tolower = libc.getpointer('tolower', [types.uchar], types.sint)
@@ -1955,7 +1956,8 @@
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)
+ EffectInfo.MOST_GENERAL,
+ ffi_flags=FUNCFLAG_CDECL)
i1 = BoxInt()
i2 = BoxInt()
tok = BoxInt()
@@ -2012,7 +2014,8 @@
calldescr = cpu.calldescrof_dynamic([types.pointer, types_size_t,
types_size_t, types.pointer],
types.void,
- EffectInfo.MOST_GENERAL)
+ EffectInfo.MOST_GENERAL,
+ ffi_flags=clibffi.FUNCFLAG_CDECL)
i0 = BoxInt()
i1 = BoxInt()
i2 = BoxInt()
@@ -2038,6 +2041,57 @@
assert len(glob.lst) > 0
lltype.free(raw, flavor='raw')
+ def test_call_to_winapi_function(self):
+ from pypy.rlib.clibffi import _WIN32, FUNCFLAG_STDCALL
+ if not _WIN32:
+ py.test.skip("Windows test only")
+ from pypy.rlib.libffi import CDLL, types, ArgChain
+ from pypy.rlib.rwin32 import DWORD
+ libc = CDLL('KERNEL32')
+ c_GetCurrentDir = libc.getpointer('GetCurrentDirectoryA',
+ [types.ulong, types.pointer],
+ types.ulong)
+
+ cwd = os.getcwd()
+ buflen = len(cwd) + 10
+ buffer = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw')
+ argchain = ArgChain().arg(rffi.cast(DWORD, buflen)).arg(buffer)
+ res = c_GetCurrentDir.call(argchain, DWORD)
+ assert rffi.cast(lltype.Signed, res) == len(cwd)
+ assert rffi.charp2strn(buffer, buflen) == cwd
+ lltype.free(buffer, flavor='raw')
+
+ 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)
+ i1 = BoxInt()
+ i2 = BoxInt()
+ i3 = BoxInt()
+ tok = BoxInt()
+ faildescr = BasicFailDescr(1)
+ ops = [
+ ResOperation(rop.CALL_RELEASE_GIL, [funcbox, i1, i2], i3,
+ descr=calldescr),
+ ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr),
+ ResOperation(rop.FINISH, [i3], None, descr=BasicFailDescr(0))
+ ]
+ ops[1].setfailargs([])
+ looptoken = LoopToken()
+ self.cpu.compile_loop([i1, i2], ops, looptoken)
+
+ buffer = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw')
+ self.cpu.set_future_value_int(0, buflen)
+ self.cpu.set_future_value_int(1, rffi.cast(lltype.Signed, buffer))
+ fail = self.cpu.execute_token(looptoken)
+ assert fail.identifier == 0
+ assert self.cpu.get_latest_value_int(0) == len(cwd)
+ assert rffi.charp2strn(buffer, buflen) == cwd
+ lltype.free(buffer, flavor='raw')
+
def test_guard_not_invalidated(self):
cpu = self.cpu
i0 = BoxInt()
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -91,9 +91,12 @@
reds_v = op.args[2+numgreens:]
assert len(reds_v) == numreds
#
- def _sort(args_v):
+ def _sort(args_v, is_green):
from pypy.jit.metainterp.history import getkind
lst = [v for v in args_v if v.concretetype is not lltype.Void]
+ if is_green:
+ assert len(lst) == len(args_v), (
+ "not supported so far: 'greens' variables contain Void")
_kind2count = {'int': 1, 'ref': 2, 'float': 3}
lst2 = sorted(lst, key=lambda v: _kind2count[getkind(v.concretetype)])
# a crash here means that you have to reorder the variable named in
@@ -102,7 +105,7 @@
assert lst == lst2
return lst
#
- return (_sort(greens_v), _sort(reds_v))
+ return (_sort(greens_v, True), _sort(reds_v, False))
def maybe_on_top_of_llinterp(rtyper, fnptr):
# Run a generated graph on top of the llinterp for testing.
diff --git a/pypy/jit/metainterp/optimizeopt/fficall.py b/pypy/jit/metainterp/optimizeopt/fficall.py
--- a/pypy/jit/metainterp/optimizeopt/fficall.py
+++ b/pypy/jit/metainterp/optimizeopt/fficall.py
@@ -18,26 +18,27 @@
def __init__(self, funcval, cpu, prepare_op):
self.funcval = funcval
self.opargs = []
- argtypes, restype = self._get_signature(funcval)
+ argtypes, restype, flags = self._get_signature(funcval)
self.descr = cpu.calldescrof_dynamic(argtypes, restype,
- EffectInfo.MOST_GENERAL)
+ EffectInfo.MOST_GENERAL,
+ ffi_flags=flags)
# ^^^ may be None if unsupported
self.prepare_op = prepare_op
self.delayed_ops = []
def _get_signature(self, funcval):
"""
- given the funcval, return a tuple (argtypes, restype), where the
- actuall types are libffi.types.*
+ given the funcval, return a tuple (argtypes, restype, flags), where
+ the actuall types are libffi.types.*
The implementation is tricky because we have three possible cases:
- translated: the easiest case, we can just cast back the pointer to
- the original Func instance and read .argtypes and .restype
+ the original Func instance and read .argtypes, .restype and .flags
- completely untranslated: this is what we get from test_optimizeopt
tests. funcval contains a FakeLLObject whose _fake_class is Func,
- and we can just get .argtypes and .restype
+ and we can just get .argtypes, .restype and .flags
- partially translated: this happens when running metainterp tests:
funcval contains the low-level equivalent of a Func, and thus we
@@ -49,10 +50,10 @@
llfunc = funcval.box.getref_base()
if we_are_translated():
func = cast_base_ptr_to_instance(Func, llfunc)
- return func.argtypes, func.restype
+ return func.argtypes, func.restype, func.flags
elif getattr(llfunc, '_fake_class', None) is Func:
# untranslated
- return llfunc.argtypes, llfunc.restype
+ return llfunc.argtypes, llfunc.restype, llfunc.flags
else:
# partially translated
# llfunc contains an opaque pointer to something like the following:
@@ -63,7 +64,7 @@
# because we don't have the exact TYPE to cast to. Instead, we
# just fish it manually :-(
f = llfunc._obj.container
- return f.inst_argtypes, f.inst_restype
+ return f.inst_argtypes, f.inst_restype, f.inst_flags
class OptFfiCall(Optimization):
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizefficall.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizefficall.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizefficall.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizefficall.py
@@ -14,12 +14,15 @@
can check that the signature of a call is really what you want.
"""
- def __init__(self, arg_types, typeinfo):
+ def __init__(self, arg_types, typeinfo, flags):
self.arg_types = arg_types
self.typeinfo = typeinfo # return type
+ self.flags = flags
def __eq__(self, other):
- return self.arg_types == other.arg_types and self.typeinfo == other.typeinfo
+ return (self.arg_types == other.arg_types and
+ self.typeinfo == other.typeinfo and
+ self.flags == other.get_ffi_flags())
class FakeLLObject(object):
@@ -41,14 +44,17 @@
vable_token_descr = LLtypeMixin.valuedescr
valuedescr = LLtypeMixin.valuedescr
- int_float__int = MyCallDescr('if', 'i')
+ int_float__int_42 = MyCallDescr('if', 'i', 42)
+ int_float__int_43 = MyCallDescr('if', 'i', 43)
funcptr = FakeLLObject()
func = FakeLLObject(_fake_class=Func,
argtypes=[types.sint, types.double],
- restype=types.sint)
+ restype=types.sint,
+ flags=42)
func2 = FakeLLObject(_fake_class=Func,
argtypes=[types.sint, types.double],
- restype=types.sint)
+ restype=types.sint,
+ flags=43)
#
def calldescr(cpu, FUNC, oopspecindex, extraeffect=None):
if extraeffect == EffectInfo.EF_RANDOM_EFFECTS:
@@ -83,7 +89,7 @@
"""
expected = """
[i0, f1]
- i3 = call_release_gil(12345, i0, f1, descr=int_float__int)
+ i3 = call_release_gil(12345, i0, f1, descr=int_float__int_42)
guard_not_forced() []
guard_no_exception() []
jump(i3, f1)
@@ -123,7 +129,7 @@
[i0, f1, p2]
i4 = force_token()
setfield_gc(p2, i4, descr=vable_token_descr)
- i3 = call_release_gil(12345, i0, f1, descr=int_float__int)
+ i3 = call_release_gil(12345, i0, f1, descr=int_float__int_42)
guard_not_forced() [p2]
guard_no_exception() [p2]
jump(i3, f1, p2)
@@ -220,7 +226,7 @@
call(0, ConstPtr(func), descr=libffi_prepare)
#
# this "nested" call is nicely optimized
- i4 = call_release_gil(67890, i0, f1, descr=int_float__int)
+ i4 = call_release_gil(67890, i0, f1, descr=int_float__int_43)
guard_not_forced() []
guard_no_exception() []
#
@@ -265,7 +271,7 @@
expected = """
[i0, f1, p2]
setfield_gc(p2, i0, descr=valuedescr)
- i3 = call_release_gil(12345, i0, f1, descr=int_float__int)
+ i3 = call_release_gil(12345, i0, f1, descr=int_float__int_42)
guard_not_forced() []
guard_no_exception() []
jump(i3, f1, p2)
diff --git a/pypy/jit/metainterp/test/test_warmspot.py b/pypy/jit/metainterp/test/test_warmspot.py
--- a/pypy/jit/metainterp/test/test_warmspot.py
+++ b/pypy/jit/metainterp/test/test_warmspot.py
@@ -252,6 +252,41 @@
self.check_loops({'int_sub': 1, 'int_gt': 1, 'guard_true': 1,
'jump': 1})
+ def test_void_red_variable(self):
+ mydriver = JitDriver(greens=[], reds=['a', 'm'])
+ def f1(m):
+ a = None
+ while m > 0:
+ mydriver.jit_merge_point(a=a, m=m)
+ m = m - 1
+ if m == 10:
+ pass # other case
+ self.meta_interp(f1, [18])
+
+ def test_bug_constant_rawptrs(self):
+ py.test.skip("crashes because a is a constant")
+ from pypy.rpython.lltypesystem import lltype, rffi
+ mydriver = JitDriver(greens=['a'], reds=['m'])
+ def f1(m):
+ a = lltype.nullptr(rffi.VOIDP.TO)
+ while m > 0:
+ mydriver.jit_merge_point(a=a, m=m)
+ m = m - 1
+ self.meta_interp(f1, [18])
+
+ def test_bug_rawptrs(self):
+ from pypy.rpython.lltypesystem import lltype, rffi
+ mydriver = JitDriver(greens=['a'], reds=['m'])
+ def f1(m):
+ a = lltype.malloc(rffi.VOIDP.TO, 5, flavor='raw')
+ while m > 0:
+ mydriver.jit_merge_point(a=a, m=m)
+ m = m - 1
+ if m == 10:
+ pass
+ lltype.free(a, flavor='raw')
+ self.meta_interp(f1, [18])
+
class TestLLWarmspot(WarmspotTests, LLJitMixin):
CPUClass = runner.LLtypeCPU
diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -245,7 +245,8 @@
graph.startblock = support.split_before_jit_merge_point(*jmpp)
graph.startblock.isstartblock = True
# a crash in the following checkgraph() means that you forgot
- # to list some variable in greens=[] or reds=[] in JitDriver.
+ # to list some variable in greens=[] or reds=[] in JitDriver,
+ # or that a jit_merge_point() takes a constant as an argument.
checkgraph(graph)
for v in graph.getargs():
assert isinstance(v, Variable)
@@ -655,11 +656,13 @@
portalfunc_ARGS = []
nums = {}
for i, ARG in enumerate(PORTALFUNC.ARGS):
+ kind = history.getkind(ARG)
+ assert kind != 'void'
if i < len(jd.jitdriver.greens):
color = 'green'
else:
color = 'red'
- attrname = '%s_%s' % (color, history.getkind(ARG))
+ attrname = '%s_%s' % (color, kind)
count = nums.get(attrname, 0)
nums[attrname] = count + 1
portalfunc_ARGS.append((ARG, attrname, count))
diff --git a/pypy/jit/metainterp/warmstate.py b/pypy/jit/metainterp/warmstate.py
--- a/pypy/jit/metainterp/warmstate.py
+++ b/pypy/jit/metainterp/warmstate.py
@@ -124,7 +124,7 @@
# Hash of lltype or ootype object.
# Only supports strings, unicodes and regular instances,
# as well as primitives that can meaningfully be cast to Signed.
- if isinstance(TYPE, lltype.Ptr):
+ if isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc':
if TYPE.TO is rstr.STR or TYPE.TO is rstr.UNICODE:
return rstr.LLHelpers.ll_strhash(x) # assumed not null
else:
@@ -140,7 +140,7 @@
else:
return 0
else:
- return lltype.cast_primitive(lltype.Signed, x)
+ return rffi.cast(lltype.Signed, x)
@specialize.ll_and_arg(3)
def set_future_value(cpu, j, value, typecode):
diff --git a/pypy/module/bz2/interp_bz2.py b/pypy/module/bz2/interp_bz2.py
--- a/pypy/module/bz2/interp_bz2.py
+++ b/pypy/module/bz2/interp_bz2.py
@@ -446,7 +446,9 @@
result = self.buffer[pos:pos + n]
self.pos += n
else:
- result = self.buffer
+ pos = self.pos
+ assert pos >= 0
+ result = self.buffer[pos:]
self.pos = 0
self.buffer = ""
self.readlength += len(result)
diff --git a/pypy/objspace/std/test/test_rangeobject.py b/pypy/objspace/std/test/test_rangeobject.py
--- a/pypy/objspace/std/test/test_rangeobject.py
+++ b/pypy/objspace/std/test/test_rangeobject.py
@@ -89,6 +89,9 @@
assert not self.not_forced(r)
r.sort()
assert r == range(1, 100) + [999]
+ r = range(10)
+ r.sort(key=lambda x: -x)
+ assert r == range(9, -1, -1)
def test_pop(self):
r = range(10)
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -402,12 +402,19 @@
closureHeap = ClosureHeap()
-FUNCFLAG_STDCALL = 0
-FUNCFLAG_CDECL = 1 # for WINAPI calls
+FUNCFLAG_STDCALL = 0 # on Windows: for WINAPI calls
+FUNCFLAG_CDECL = 1 # on Windows: for __cdecl calls
FUNCFLAG_PYTHONAPI = 4
FUNCFLAG_USE_ERRNO = 8
FUNCFLAG_USE_LASTERROR = 16
+def get_call_conv(flags):
+ if _WIN32 and (flags & FUNCFLAG_CDECL == 0):
+ return FFI_STDCALL
+ else:
+ return FFI_DEFAULT_ABI
+
+
class AbstractFuncPtr(object):
ll_cif = lltype.nullptr(FFI_CIFP.TO)
ll_argtypes = lltype.nullptr(FFI_TYPE_PP.TO)
@@ -427,11 +434,6 @@
self.ll_cif = lltype.malloc(FFI_CIFP.TO, flavor='raw',
track_allocation=False) # freed by the __del__
- if _WIN32 and (flags & FUNCFLAG_CDECL == 0):
- cc = FFI_STDCALL
- else:
- cc = FFI_DEFAULT_ABI
-
if _MSVC:
# This little trick works correctly with MSVC.
# It returns small structures in registers
@@ -441,7 +443,7 @@
elif restype.c_size <= 8:
restype = ffi_type_sint64
- res = c_ffi_prep_cif(self.ll_cif, cc,
+ res = c_ffi_prep_cif(self.ll_cif, get_call_conv(flags),
rffi.cast(rffi.UINT, argnum), restype,
self.ll_argtypes)
if not res == FFI_OK:
diff --git a/pypy/rpython/lltypesystem/ll2ctypes.py b/pypy/rpython/lltypesystem/ll2ctypes.py
--- a/pypy/rpython/lltypesystem/ll2ctypes.py
+++ b/pypy/rpython/lltypesystem/ll2ctypes.py
@@ -113,7 +113,7 @@
rffi.LONGLONG: ctypes.c_longlong,
rffi.ULONGLONG: ctypes.c_ulonglong,
rffi.SIZE_T: ctypes.c_size_t,
- lltype.Bool: ctypes.c_bool,
+ lltype.Bool: getattr(ctypes, "c_bool", ctypes.c_long),
llmemory.Address: ctypes.c_void_p,
llmemory.GCREF: ctypes.c_void_p,
llmemory.WeakRef: ctypes.c_void_p, # XXX
@@ -1153,7 +1153,11 @@
# an OverflowError on the following line.
cvalue = ctypes.cast(ctypes.c_void_p(cvalue), cresulttype)
else:
- cvalue = cresulttype(cvalue).value # mask high bits off if needed
+ try:
+ cvalue = cresulttype(cvalue).value # mask high bits off if needed
+ except TypeError:
+ cvalue = int(cvalue) # float -> int
+ cvalue = cresulttype(cvalue).value # try again
return ctypes2lltype(RESTYPE, cvalue)
class ForceCastEntry(ExtRegistryEntry):
diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py
--- a/pypy/rpython/lltypesystem/lltype.py
+++ b/pypy/rpython/lltypesystem/lltype.py
@@ -1283,6 +1283,8 @@
try:
return p._obj._hash_cache_
except AttributeError:
+ assert self._T._gckind == 'gc'
+ assert self # not for NULL
result = hash(p._obj)
if cache:
try:
diff --git a/pypy/rpython/lltypesystem/test/test_rffi.py b/pypy/rpython/lltypesystem/test/test_rffi.py
--- a/pypy/rpython/lltypesystem/test/test_rffi.py
+++ b/pypy/rpython/lltypesystem/test/test_rffi.py
@@ -699,7 +699,10 @@
def test_cast(self):
res = cast(SIZE_T, -1)
assert type(res) is r_size_t
- assert res == r_size_t(-1)
+ assert res == r_size_t(-1)
+ #
+ res = cast(lltype.Signed, 42.5)
+ assert res == 42
def test_rffi_sizeof(self):
try:
More information about the pypy-commit
mailing list