Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r46952:ececb40f961c Date: 2011-08-31 18:49 +0200 http://bitbucket.org/pypy/pypy/changeset/ececb40f961c/
Log: merge heads 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,9 @@ def get_extra_info(self): return self.extrainfo + def get_ffi_flags(self): + return self.ffi_flags + def get_arg_types(self): return self.arg_classes @@ -391,8 +396,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 @@ -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=0) res = self.execute_operation(rop.CALL, [funcbox, BoxInt(num), BoxInt(num)], 'int', descr=dyn_calldescr) @@ -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=0) 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=0) i0 = BoxInt() i1 = BoxInt() i2 = BoxInt() 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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit