Author: Alex Gaynor <alex.gay...@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: _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit