Author: Wim Lavrijsen <wlavrij...@lbl.gov> Branch: cppyy-packaging Changeset: r94775:f6f3039d686c Date: 2018-06-20 22:04 -0700 http://bitbucket.org/pypy/pypy/changeset/f6f3039d686c/
Log: more simplification of function calls diff --git a/pypy/module/_cppyy/converter.py b/pypy/module/_cppyy/converter.py --- a/pypy/module/_cppyy/converter.py +++ b/pypy/module/_cppyy/converter.py @@ -82,10 +82,9 @@ class TypeConverter(object): - _immutable_fields_ = ['cffi_name', 'uses_local', 'name'] + _immutable_fields_ = ['cffi_name', 'name'] cffi_name = None - uses_local = False name = "" def __init__(self, space, extra): @@ -111,7 +110,7 @@ def convert_argument(self, space, w_obj, address): self._is_abstract(space) - def convert_argument_libffi(self, space, w_obj, address, call_local): + def convert_argument_libffi(self, space, w_obj, address, scratch): from pypy.module._cppyy.interp_cppyy import FastCallNotPossible raise FastCallNotPossible @@ -208,7 +207,7 @@ class NumericTypeConverterMixin(object): _mixin_ = True - def convert_argument_libffi(self, space, w_obj, address, call_local): + def convert_argument_libffi(self, space, w_obj, address, scratch): x = rffi.cast(self.c_ptrtype, address) x[0] = self._unwrap_object(space, w_obj) @@ -228,21 +227,18 @@ class ConstRefNumericTypeConverterMixin(NumericTypeConverterMixin): _mixin_ = True - _immutable_fields_ = ['uses_local'] - - uses_local = True def cffi_type(self, space): state = space.fromcache(ffitypes.State) return state.c_voidp - def convert_argument_libffi(self, space, w_obj, address, call_local): - assert rffi.sizeof(self.c_type) <= 2*rffi.sizeof(rffi.VOIDP) # see interp_cppyy.py + def convert_argument_libffi(self, space, w_obj, address, scratch): obj = self._unwrap_object(space, w_obj) - typed_buf = rffi.cast(self.c_ptrtype, call_local) + typed_buf = rffi.cast(self.c_ptrtype, scratch) typed_buf[0] = obj x = rffi.cast(rffi.VOIDPP, address) - x[0] = call_local + x[0] = scratch + class IntTypeConverterMixin(NumericTypeConverterMixin): _mixin_ = True @@ -284,7 +280,7 @@ ba = rffi.cast(rffi.CCHARP, address) ba[capi.c_function_arg_typeoffset(space)] = 'b' - def convert_argument_libffi(self, space, w_obj, address, call_local): + def convert_argument_libffi(self, space, w_obj, address, scratch): x = rffi.cast(rffi.LONGP, address) x[0] = self._unwrap_object(space, w_obj) @@ -309,7 +305,7 @@ ba = rffi.cast(rffi.CCHARP, address) ba[capi.c_function_arg_typeoffset(space)] = 'b' - def convert_argument_libffi(self, space, w_obj, address, call_local): + def convert_argument_libffi(self, space, w_obj, address, scratch): x = rffi.cast(self.c_ptrtype, address) x[0] = self._unwrap_object(space, w_obj) @@ -348,7 +344,7 @@ state = space.fromcache(ffitypes.State) return state.c_voidp - def convert_argument_libffi(self, space, w_obj, address, call_local): + def convert_argument_libffi(self, space, w_obj, address, scratch): from pypy.module._cppyy.interp_cppyy import FastCallNotPossible raise FastCallNotPossible @@ -429,7 +425,7 @@ ba = rffi.cast(rffi.CCHARP, address) ba[capi.c_function_arg_typeoffset(space)] = 'o' - def convert_argument_libffi(self, space, w_obj, address, call_local): + def convert_argument_libffi(self, space, w_obj, address, scratch): x = rffi.cast(rffi.VOIDPP, address) x[0] = self._unwrap_object(space, w_obj) @@ -517,7 +513,7 @@ ba = rffi.cast(rffi.CCHARP, address) ba[capi.c_function_arg_typeoffset(space)] = self.typecode - def convert_argument_libffi(self, space, w_obj, address, call_local): + def convert_argument_libffi(self, space, w_obj, address, scratch): x = rffi.cast(rffi.VOIDPP, address) x[0] = rffi.cast(rffi.VOIDP, self._unwrap_object(space, w_obj)) @@ -541,7 +537,7 @@ class InstanceConverter(InstanceRefConverter): - def convert_argument_libffi(self, space, w_obj, address, call_local): + def convert_argument_libffi(self, space, w_obj, address, scratch): from pypy.module._cppyy.interp_cppyy import FastCallNotPossible raise FastCallNotPossible # TODO: by-value is a jit_libffi special case @@ -590,7 +586,7 @@ ba = rffi.cast(rffi.CCHARP, address) ba[capi.c_function_arg_typeoffset(space)] = self.typecode - def convert_argument_libffi(self, space, w_obj, address, call_local): + def convert_argument_libffi(self, space, w_obj, address, scratch): # TODO: finalize_call not yet called for fast call (see interp_cppyy.py) from pypy.module._cppyy.interp_cppyy import FastCallNotPossible raise FastCallNotPossible @@ -663,7 +659,7 @@ ba = rffi.cast(rffi.CCHARP, address) ba[capi.c_function_arg_typeoffset(space)] = 'a' - def convert_argument_libffi(self, space, w_obj, address, call_local): + def convert_argument_libffi(self, space, w_obj, address, scratch): # TODO: free_argument not yet called for fast call (see interp_cppyy.py) from pypy.module._cppyy.interp_cppyy import FastCallNotPossible raise FastCallNotPossible diff --git a/pypy/module/_cppyy/interp_cppyy.py b/pypy/module/_cppyy/interp_cppyy.py --- a/pypy/module/_cppyy/interp_cppyy.py +++ b/pypy/module/_cppyy/interp_cppyy.py @@ -183,9 +183,9 @@ the memory_regulator.""" _attrs_ = ['space', 'scope', 'cppmethod', 'arg_defs', 'args_required', - 'converters', 'executor', '_funcaddr', 'cif_descr', 'uses_local'] + 'converters', 'executor', '_funcaddr', 'cif_descr'] _immutable_fields_ = ['scope', 'cppmethod', 'arg_defs', 'args_required', - 'converters', 'executor', '_funcaddr', 'cif_descr', 'uses_local'] + 'converters', 'executor', '_funcaddr', 'cif_descr'] def __init__(self, space, declaring_scope, cppmethod, arg_defs, args_required): self.space = space @@ -200,14 +200,6 @@ self.executor = None self.cif_descr = lltype.nullptr(jit_libffi.CIF_DESCRIPTION) self._funcaddr = lltype.nullptr(capi.C_FUNC_PTR.TO) - self.uses_local = False - - def _address_from_local_buffer(self, call_local, idx): - if not call_local: - return call_local - stride = 2*rffi.sizeof(rffi.VOIDP) - loc_idx = lltype.direct_ptradd(rffi.cast(rffi.CCHARP, call_local), idx*stride) - return rffi.cast(rffi.VOIDP, loc_idx) @jit.unroll_safe def call(self, cppthis, args_w, useffi): @@ -233,45 +225,35 @@ except Exception: pass - # some calls, e.g. for ptr-ptr or reference need a local array to store data for - # the duration of the call - if self.uses_local: - call_local = lltype.malloc(rffi.VOIDP.TO, 2*len(args_w), flavor='raw') - else: - call_local = lltype.nullptr(rffi.VOIDP.TO) + # attempt to call directly through ffi chain + if useffi and self._funcaddr: + try: + return self.do_fast_call(cppthis, args_w) + except FastCallNotPossible: + pass # can happen if converters or executor does not implement ffi + # ffi chain must have failed; using stub functions instead + args, stat = self.prepare_arguments(args_w) try: - # attempt to call directly through ffi chain - if useffi and self._funcaddr: - try: - return self.do_fast_call(cppthis, args_w, call_local) - except FastCallNotPossible: - pass # can happen if converters or executor does not implement ffi - - # ffi chain must have failed; using stub functions instead - args, stat = self.prepare_arguments(args_w) - try: - result = self.executor.execute( - self.space, self.cppmethod, cppthis, len(args_w), args) - if stat[0] != rffi.cast(rffi.ULONG, 0): - what = rffi.cast(rffi.CCHARP, stat[1]) - pywhat = rffi.charp2str(what) - capi.c_free(self.space, rffi.cast(rffi.VOIDP, what)) - raise OperationError(self.space.w_Exception, self.space.newtext(pywhat)) - return result - finally: - self.finalize_call(args, args_w) + result = self.executor.execute( + self.space, self.cppmethod, cppthis, len(args_w), args) + if stat[0] != rffi.cast(rffi.ULONG, 0): + what = rffi.cast(rffi.CCHARP, stat[1]) + pywhat = rffi.charp2str(what) + capi.c_free(self.space, rffi.cast(rffi.VOIDP, what)) + raise OperationError(self.space.w_Exception, self.space.newtext(pywhat)) + return result finally: - if call_local: - lltype.free(call_local, flavor='raw') + self.finalize_call(args, args_w) @jit.unroll_safe - def do_fast_call(self, cppthis, args_w, call_local): + def do_fast_call(self, cppthis, args_w): if self.cif_descr == lltype.nullptr(jit_libffi.CIF_DESCRIPTION): raise FastCallNotPossible jit.promote(self) cif_descr = self.cif_descr - buffer = lltype.malloc(rffi.CCHARP.TO, cif_descr.exchange_size, flavor='raw') + # add extra space for const-ref support (see converter.py) + buffer = lltype.malloc(rffi.CCHARP.TO, cif_descr.exchange_size+len(args_w)*rffi.sizeof(rffi.DOUBLE), flavor='raw') try: # this pointer data = rffi.ptradd(buffer, cif_descr.exchange_args[0]) @@ -284,7 +266,8 @@ conv = self.converters[i] w_arg = args_w[i] data = rffi.ptradd(buffer, cif_descr.exchange_args[i+1]) - conv.convert_argument_libffi(self.space, w_arg, data, call_local) + scratch = rffi.ptradd(buffer, cif_descr.exchange_size+i*rffi.sizeof(rffi.DOUBLE)) + conv.convert_argument_libffi(self.space, w_arg, data, scratch) for j in range(i+1, len(self.arg_defs)): conv = self.converters[j] data = rffi.ptradd(buffer, cif_descr.exchange_args[j+1]) @@ -346,11 +329,6 @@ self.executor = executor.get_executor( self.space, capi.c_method_result_type(self.space, self.cppmethod)) - for conv in self.converters: - if conv.uses_local: - self.uses_local = True - break - # Each CPPMethod corresponds one-to-one to a C++ equivalent and cppthis # has been offset to the matching class. Hence, the libffi pointer is # uniquely defined and needs to be setup only once. _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit