[pypy-commit] pypy cppyy-packaging: more simplification of function calls
wlav
pypy.commits at gmail.com
Thu Jun 21 01:24:08 EDT 2018
Author: Wim Lavrijsen <WLavrijsen at 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.
More information about the pypy-commit
mailing list