Author: Wim Lavrijsen <wlavrij...@lbl.gov> Branch: reflex-support Changeset: r52954:e7c4a93f01f3 Date: 2012-02-27 17:34 -0800 http://bitbucket.org/pypy/pypy/changeset/e7c4a93f01f3/
Log: refactoring and cleanup (Reflex backend): the idea is to speed up the slow path by handing out the stub functions rather than method indices; it should also help with stability in the case of additional methods to a namespace (since the stubs don't move, whereas the indices could change) diff --git a/pypy/module/cppyy/capi/__init__.py b/pypy/module/cppyy/capi/__init__.py --- a/pypy/module/cppyy/capi/__init__.py +++ b/pypy/module/cppyy/capi/__init__.py @@ -9,11 +9,17 @@ _C_OPAQUE_PTR = rffi.LONG _C_OPAQUE_NULL = lltype.nullptr(rffi.LONGP.TO)# ALT: _C_OPAQUE_PTR.TO -C_TYPEHANDLE = _C_OPAQUE_PTR -C_NULL_TYPEHANDLE = rffi.cast(C_TYPEHANDLE, _C_OPAQUE_NULL) +C_SCOPE = _C_OPAQUE_PTR +C_NULL_SCOPE = rffi.cast(C_SCOPE, _C_OPAQUE_NULL) + +C_TYPE = C_SCOPE +C_NULL_TYPE = C_NULL_SCOPE + C_OBJECT = _C_OPAQUE_PTR C_NULL_OBJECT = rffi.cast(C_OBJECT, _C_OPAQUE_NULL) +C_METHOD = _C_OPAQUE_PTR + C_METHPTRGETTER = lltype.FuncType([C_OBJECT], rffi.VOIDP) C_METHPTRGETTER_PTR = lltype.Ptr(C_METHPTRGETTER) @@ -26,128 +32,85 @@ c_load_dictionary = backend.c_load_dictionary -c_get_typehandle = rffi.llexternal( - "cppyy_get_typehandle", - [rffi.CCHARP], C_OBJECT, +# name to opaque C++ scope representation ------------------------------------ +c_get_scope = rffi.llexternal( + "cppyy_get_scope", + [rffi.CCHARP], C_SCOPE, compilation_info=backend.eci) -c_get_templatehandle = rffi.llexternal( - "cppyy_get_templatehandle", - [rffi.CCHARP], C_TYPEHANDLE, +c_get_template = rffi.llexternal( + "cppyy_get_template", + [rffi.CCHARP], C_TYPE, compilation_info=backend.eci) +# memory management ---------------------------------------------------------- c_allocate = rffi.llexternal( "cppyy_allocate", - [C_TYPEHANDLE], C_OBJECT, + [C_TYPE], C_OBJECT, compilation_info=backend.eci) c_deallocate = rffi.llexternal( "cppyy_deallocate", - [C_TYPEHANDLE, C_OBJECT], lltype.Void, + [C_TYPE, C_OBJECT], lltype.Void, compilation_info=backend.eci) c_destruct = rffi.llexternal( "cppyy_destruct", - [C_TYPEHANDLE, C_OBJECT], lltype.Void, + [C_TYPE, C_OBJECT], lltype.Void, compilation_info=backend.eci) -c_is_namespace = rffi.llexternal( - "cppyy_is_namespace", - [C_TYPEHANDLE], rffi.INT, - compilation_info=backend.eci) -c_final_name = rffi.llexternal( - "cppyy_final_name", - [C_TYPEHANDLE], rffi.CCHARP, - compilation_info=backend.eci) - -c_has_complex_hierarchy = rffi.llexternal( - "cppyy_has_complex_hierarchy", - [C_TYPEHANDLE], rffi.INT, - compilation_info=backend.eci) -c_num_bases = rffi.llexternal( - "cppyy_num_bases", - [C_TYPEHANDLE], rffi.INT, - compilation_info=backend.eci) -c_base_name = rffi.llexternal( - "cppyy_base_name", - [C_TYPEHANDLE, rffi.INT], rffi.CCHARP, - compilation_info=backend.eci) - -_c_is_subtype = rffi.llexternal( - "cppyy_is_subtype", - [C_TYPEHANDLE, C_TYPEHANDLE], rffi.INT, - compilation_info=backend.eci, - elidable_function=True) - -@jit.elidable_promote() -def c_is_subtype(td, tb): - if td == tb: - return 1 - return _c_is_subtype(td, tb) - -_c_base_offset = rffi.llexternal( - "cppyy_base_offset", - [C_TYPEHANDLE, C_TYPEHANDLE, C_OBJECT], rffi.SIZE_T, - compilation_info=backend.eci, - elidable_function=True) - -@jit.elidable_promote() -def c_base_offset(td, tb, address): - if td == tb: - return 0 - return _c_base_offset(td, tb, address) - +# method/function dispatching ------------------------------------------------ c_call_v = rffi.llexternal( "cppyy_call_v", - [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], lltype.Void, - compilation_info=backend.eci) -c_call_o = rffi.llexternal( - "cppyy_call_o", - [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP, C_TYPEHANDLE], rffi.LONG, + [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], lltype.Void, compilation_info=backend.eci) c_call_b = rffi.llexternal( "cppyy_call_b", - [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.INT, + [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.INT, compilation_info=backend.eci) c_call_c = rffi.llexternal( "cppyy_call_c", - [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CHAR, + [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CHAR, compilation_info=backend.eci) c_call_h = rffi.llexternal( "cppyy_call_h", - [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.SHORT, + [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.SHORT, compilation_info=backend.eci) c_call_i = rffi.llexternal( "cppyy_call_i", - [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.INT, + [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.INT, compilation_info=backend.eci) - c_call_l = rffi.llexternal( "cppyy_call_l", - [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONG, + [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONG, compilation_info=backend.eci) c_call_f = rffi.llexternal( "cppyy_call_f", - [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.DOUBLE, + [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.DOUBLE, compilation_info=backend.eci) c_call_d = rffi.llexternal( "cppyy_call_d", - [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.DOUBLE, + [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.DOUBLE, compilation_info=backend.eci) c_call_r = rffi.llexternal( "cppyy_call_r", - [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.VOIDP, + [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.VOIDP, + compilation_info=backend.eci) +c_call_s = rffi.llexternal( + "cppyy_call_s", + [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CCHARP, compilation_info=backend.eci) -c_call_s = rffi.llexternal( - "cppyy_call_s", - [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CCHARP, +c_call_o = rffi.llexternal( + "cppyy_call_o", + [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP, C_TYPE], rffi.LONG, compilation_info=backend.eci) c_get_methptr_getter = rffi.llexternal( "cppyy_get_methptr_getter", - [C_TYPEHANDLE, rffi.INT], C_METHPTRGETTER_PTR, + [C_SCOPE, rffi.INT], C_METHPTRGETTER_PTR, compilation_info=backend.eci, elidable_function=True) +# handling of function argument buffer --------------------------------------- c_allocate_function_args = rffi.llexternal( "cppyy_allocate_function_args", [rffi.SIZE_T], rffi.VOIDP, @@ -167,80 +130,136 @@ compilation_info=backend.eci, elidable_function=True) +# scope reflection information ----------------------------------------------- +c_is_namespace = rffi.llexternal( + "cppyy_is_namespace", + [C_SCOPE], rffi.INT, + compilation_info=backend.eci) + +# type/class reflection information ------------------------------------------ +c_final_name = rffi.llexternal( + "cppyy_final_name", + [C_TYPE], rffi.CCHARP, + compilation_info=backend.eci) +c_has_complex_hierarchy = rffi.llexternal( + "cppyy_has_complex_hierarchy", + [C_TYPE], rffi.INT, + compilation_info=backend.eci) +c_num_bases = rffi.llexternal( + "cppyy_num_bases", + [C_TYPE], rffi.INT, + compilation_info=backend.eci) +c_base_name = rffi.llexternal( + "cppyy_base_name", + [C_TYPE, rffi.INT], rffi.CCHARP, + compilation_info=backend.eci) + +_c_is_subtype = rffi.llexternal( + "cppyy_is_subtype", + [C_TYPE, C_TYPE], rffi.INT, + compilation_info=backend.eci, + elidable_function=True) + +@jit.elidable_promote() +def c_is_subtype(derived, base): + if derived == base: + return 1 + return _c_is_subtype(derived, base) + +_c_base_offset = rffi.llexternal( + "cppyy_base_offset", + [C_TYPE, C_TYPE, C_OBJECT], rffi.SIZE_T, + compilation_info=backend.eci, + elidable_function=True) + +@jit.elidable_promote() +def c_base_offset(derived, base, address): + if derived == base: + return 0 + return _c_base_offset(derived, base, address) + +# method/function reflection information ------------------------------------- c_num_methods = rffi.llexternal( "cppyy_num_methods", - [C_TYPEHANDLE], rffi.INT, + [C_SCOPE], rffi.INT, compilation_info=backend.eci) c_method_name = rffi.llexternal( "cppyy_method_name", - [C_TYPEHANDLE, rffi.INT], rffi.CCHARP, + [C_SCOPE, rffi.INT], rffi.CCHARP, compilation_info=backend.eci) c_method_result_type = rffi.llexternal( "cppyy_method_result_type", - [C_TYPEHANDLE, rffi.INT], rffi.CCHARP, + [C_SCOPE, rffi.INT], rffi.CCHARP, compilation_info=backend.eci) c_method_num_args = rffi.llexternal( "cppyy_method_num_args", - [C_TYPEHANDLE, rffi.INT], rffi.INT, + [C_SCOPE, rffi.INT], rffi.INT, compilation_info=backend.eci) c_method_req_args = rffi.llexternal( "cppyy_method_req_args", - [C_TYPEHANDLE, rffi.INT], rffi.INT, + [C_SCOPE, rffi.INT], rffi.INT, compilation_info=backend.eci) c_method_arg_type = rffi.llexternal( "cppyy_method_arg_type", - [C_TYPEHANDLE, rffi.INT, rffi.INT], rffi.CCHARP, + [C_SCOPE, rffi.INT, rffi.INT], rffi.CCHARP, compilation_info=backend.eci) c_method_arg_default = rffi.llexternal( "cppyy_method_arg_default", - [C_TYPEHANDLE, rffi.INT, rffi.INT], rffi.CCHARP, + [C_SCOPE, rffi.INT, rffi.INT], rffi.CCHARP, compilation_info=backend.eci) +c_get_method = rffi.llexternal( + "cppyy_get_method", + [C_SCOPE, rffi.INT], C_METHOD, + compilation_info=backend.eci) + +# method properties ---------------------------------------------------------- c_is_constructor = rffi.llexternal( "cppyy_is_constructor", - [C_TYPEHANDLE, rffi.INT], rffi.INT, + [C_TYPE, rffi.INT], rffi.INT, compilation_info=backend.eci) c_is_staticmethod = rffi.llexternal( "cppyy_is_staticmethod", - [C_TYPEHANDLE, rffi.INT], rffi.INT, + [C_TYPE, rffi.INT], rffi.INT, compilation_info=backend.eci) +# data member reflection information ----------------------------------------- c_num_data_members = rffi.llexternal( "cppyy_num_data_members", - [C_TYPEHANDLE], rffi.INT, + [C_SCOPE], rffi.INT, compilation_info=backend.eci) c_data_member_name = rffi.llexternal( "cppyy_data_member_name", - [C_TYPEHANDLE, rffi.INT], rffi.CCHARP, + [C_SCOPE, rffi.INT], rffi.CCHARP, compilation_info=backend.eci) c_data_member_type = rffi.llexternal( "cppyy_data_member_type", - [C_TYPEHANDLE, rffi.INT], rffi.CCHARP, + [C_SCOPE, rffi.INT], rffi.CCHARP, compilation_info=backend.eci) c_data_member_offset = rffi.llexternal( "cppyy_data_member_offset", - [C_TYPEHANDLE, rffi.INT], rffi.SIZE_T, + [C_SCOPE, rffi.INT], rffi.SIZE_T, compilation_info=backend.eci) +# data member properties ----------------------------------------------------- c_is_publicdata = rffi.llexternal( "cppyy_is_publicdata", - [C_TYPEHANDLE, rffi.INT], rffi.INT, + [C_SCOPE, rffi.INT], rffi.INT, compilation_info=backend.eci) c_is_staticdata = rffi.llexternal( "cppyy_is_staticdata", - [C_TYPEHANDLE, rffi.INT], rffi.INT, + [C_SCOPE, rffi.INT], rffi.INT, compilation_info=backend.eci) +# misc helpers --------------------------------------------------------------- c_strtoll = rffi.llexternal( "cppyy_strtoll", [rffi.CCHARP], rffi.LONGLONG, compilation_info=backend.eci) - c_strtoull = rffi.llexternal( "cppyy_strtoull", [rffi.CCHARP], rffi.ULONGLONG, compilation_info=backend.eci) - c_free = rffi.llexternal( "cppyy_free", [rffi.VOIDP], lltype.Void, @@ -256,12 +275,10 @@ "cppyy_charp2stdstring", [rffi.CCHARP], C_OBJECT, compilation_info=backend.eci) - c_stdstring2stdstring = rffi.llexternal( "cppyy_stdstring2stdstring", [C_OBJECT], C_OBJECT, compilation_info=backend.eci) - c_free_stdstring = rffi.llexternal( "cppyy_free_stdstring", [C_OBJECT], lltype.Void, diff --git a/pypy/module/cppyy/executor.py b/pypy/module/cppyy/executor.py --- a/pypy/module/cppyy/executor.py +++ b/pypy/module/cppyy/executor.py @@ -18,9 +18,8 @@ def __init__(self, space, name, cpptype): self.name = name - def execute(self, space, w_returntype, func, cppthis, num_args, args): - rtype = capi.charp2str_free(capi.c_method_result_type(func.cpptype.handle, func.method_index)) - raise TypeError('return type not available or supported ("%s")' % rtype) + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): + raise TypeError('return type not available or supported ("%s")' % self.name) def execute_libffi(self, space, w_returntype, libffifunc, argchain): from pypy.module.cppyy.interp_cppyy import FastCallNotPossible @@ -31,10 +30,10 @@ _immutable_ = True typecode = 'P' - def execute(self, space, w_returntype, func, cppthis, num_args, args): + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): if hasattr(space, "fake"): raise NotImplementedError - lresult = capi.c_call_l(func.cpptype.handle, func.method_index, cppthis, num_args, args) + lresult = capi.c_call_l(cppmethod, cppthis, num_args, args) address = rffi.cast(rffi.ULONG, lresult) arr = space.interp_w(W_Array, unpack_simple_shape(space, space.wrap(self.typecode))) return arr.fromaddress(space, address, sys.maxint) @@ -44,8 +43,8 @@ _immutable_ = True libffitype = libffi.types.void - def execute(self, space, w_returntype, func, cppthis, num_args, args): - capi.c_call_v(func.cpptype.handle, func.method_index, cppthis, num_args, args) + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): + capi.c_call_v(cppmethod, cppthis, num_args, args) return space.w_None def execute_libffi(self, space, w_returntype, libffifunc, argchain): @@ -57,8 +56,8 @@ _immutable_ = True libffitype = libffi.types.schar - def execute(self, space, w_returntype, func, cppthis, num_args, args): - result = capi.c_call_b(func.cpptype.handle, func.method_index, cppthis, num_args, args) + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): + result = capi.c_call_b(cppmethod, cppthis, num_args, args) return space.wrap(result) def execute_libffi(self, space, w_returntype, libffifunc, argchain): @@ -69,8 +68,8 @@ _immutable_ = True libffitype = libffi.types.schar - def execute(self, space, w_returntype, func, cppthis, num_args, args): - result = capi.c_call_c(func.cpptype.handle, func.method_index, cppthis, num_args, args) + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): + result = capi.c_call_c(cppmethod, cppthis, num_args, args) return space.wrap(result) def execute_libffi(self, space, w_returntype, libffifunc, argchain): @@ -81,8 +80,8 @@ _immutable_ = True libffitype = libffi.types.sshort - def execute(self, space, w_returntype, func, cppthis, num_args, args): - result = capi.c_call_h(func.cpptype.handle, func.method_index, cppthis, num_args, args) + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): + result = capi.c_call_h(cppmethod, cppthis, num_args, args) return space.wrap(result) def execute_libffi(self, space, w_returntype, libffifunc, argchain): @@ -96,8 +95,8 @@ def _wrap_result(self, space, result): return space.wrap(result) - def execute(self, space, w_returntype, func, cppthis, num_args, args): - result = capi.c_call_i(func.cpptype.handle, func.method_index, cppthis, num_args, args) + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): + result = capi.c_call_i(cppmethod, cppthis, num_args, args) return self._wrap_result(space, result) def execute_libffi(self, space, w_returntype, libffifunc, argchain): @@ -111,8 +110,8 @@ def _wrap_result(self, space, result): return space.wrap(rffi.cast(rffi.UINT, result)) - def execute(self, space, w_returntype, func, cppthis, num_args, args): - result = capi.c_call_l(func.cpptype.handle, func.method_index, cppthis, num_args, args) + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): + result = capi.c_call_l(cppmethod, cppthis, num_args, args) return self._wrap_result(space, result) def execute_libffi(self, space, w_returntype, libffifunc, argchain): @@ -126,8 +125,8 @@ def _wrap_result(self, space, result): return space.wrap(result) - def execute(self, space, w_returntype, func, cppthis, num_args, args): - result = capi.c_call_l(func.cpptype.handle, func.method_index, cppthis, num_args, args) + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): + result = capi.c_call_l(cppmethod, cppthis, num_args, args) return self._wrap_result(space, result) def execute_libffi(self, space, w_returntype, libffifunc, argchain): @@ -153,8 +152,8 @@ intptr = rffi.cast(rffi.INTP, result) return space.wrap(intptr[0]) - def execute(self, space, w_returntype, func, cppthis, num_args, args): - result = capi.c_call_r(func.cpptype.handle, func.method_index, cppthis, num_args, args) + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): + result = capi.c_call_r(cppmethod, cppthis, num_args, args) return self._wrap_result(space, result) def execute_libffi(self, space, w_returntype, libffifunc, argchain): @@ -177,8 +176,8 @@ _immutable_ = True libffitype = libffi.types.float - def execute(self, space, w_returntype, func, cppthis, num_args, args): - result = capi.c_call_f(func.cpptype.handle, func.method_index, cppthis, num_args, args) + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): + result = capi.c_call_f(cppmethod, cppthis, num_args, args) return space.wrap(float(result)) def execute_libffi(self, space, w_returntype, libffifunc, argchain): @@ -189,8 +188,8 @@ _immutable_ = True libffitype = libffi.types.double - def execute(self, space, w_returntype, func, cppthis, num_args, args): - result = capi.c_call_d(func.cpptype.handle, func.method_index, cppthis, num_args, args) + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): + result = capi.c_call_d(cppmethod, cppthis, num_args, args) return space.wrap(result) def execute_libffi(self, space, w_returntype, libffifunc, argchain): @@ -201,8 +200,8 @@ class CStringExecutor(FunctionExecutor): _immutable_ = True - def execute(self, space, w_returntype, func, cppthis, num_args, args): - lresult = capi.c_call_l(func.cpptype.handle, func.method_index, cppthis, num_args, args) + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): + lresult = capi.c_call_l(cppmethod, cppthis, num_args, args) ccpresult = rffi.cast(rffi.CCHARP, lresult) result = rffi.charp2str(ccpresult) # TODO: make it a choice to free return space.wrap(result) @@ -245,10 +244,9 @@ FunctionExecutor.__init__(self, space, name, cpptype) self.cpptype = cpptype - def execute(self, space, w_returntype, func, cppthis, num_args, args): + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): from pypy.module.cppyy import interp_cppyy - long_result = capi.c_call_l( - func.cpptype.handle, func.method_index, cppthis, num_args, args) + long_result = capi.c_call_l(cppmethod, cppthis, num_args, args) ptr_result = rffi.cast(capi.C_OBJECT, long_result) return interp_cppyy.new_instance(space, w_returntype, self.cpptype, ptr_result, False) @@ -261,10 +259,9 @@ class InstanceExecutor(InstancePtrExecutor): _immutable_ = True - def execute(self, space, w_returntype, func, cppthis, num_args, args): + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): from pypy.module.cppyy import interp_cppyy - long_result = capi.c_call_o( - func.cpptype.handle, func.method_index, cppthis, num_args, args, self.cpptype.handle) + long_result = capi.c_call_o(cppmethod, cppthis, num_args, args, self.cpptype.handle) ptr_result = rffi.cast(capi.C_OBJECT, long_result) return interp_cppyy.new_instance(space, w_returntype, self.cpptype, ptr_result, True) @@ -276,8 +273,8 @@ class StdStringExecutor(InstancePtrExecutor): _immutable_ = True - def execute(self, space, w_returntype, func, cppthis, num_args, args): - charp_result = capi.c_call_s(func.cpptype.handle, func.method_index, cppthis, num_args, args) + def execute(self, space, w_returntype, cppmethod, cppthis, num_args, args): + charp_result = capi.c_call_s(cppmethod, cppthis, num_args, args) return space.wrap(capi.charp2str_free(charp_result)) def execute_libffi(self, space, w_returntype, libffifunc, argchain): diff --git a/pypy/module/cppyy/helper.py b/pypy/module/cppyy/helper.py --- a/pypy/module/cppyy/helper.py +++ b/pypy/module/cppyy/helper.py @@ -99,7 +99,7 @@ # is put at the end only as it is unlikely and may trigger unwanted # errors in class loaders in the backend, because a typical operator # name is illegal as a class name) - handle = capi.c_get_typehandle(op) + handle = capi.c_get_scope(op) if handle: op = capi.charp2str_free(capi.c_final_name(handle)) diff --git a/pypy/module/cppyy/include/capi.h b/pypy/module/cppyy/include/capi.h --- a/pypy/module/cppyy/include/capi.h +++ b/pypy/module/cppyy/include/capi.h @@ -7,76 +7,81 @@ extern "C" { #endif // ifdef __cplusplus - typedef void* cppyy_typehandle_t; - typedef void* cppyy_object_t; + typedef long cppyy_scope_t; + typedef cppyy_scope_t cppyy_type_t; + typedef long cppyy_object_t; + typedef long cppyy_method_t; typedef void* (*cppyy_methptrgetter_t)(cppyy_object_t); - /* name to handle */ - cppyy_typehandle_t cppyy_get_typehandle(const char* class_name); - cppyy_typehandle_t cppyy_get_templatehandle(const char* template_name); + /* name to opaque C++ scope representation -------------------------------- */ + cppyy_scope_t cppyy_get_scope(const char* scope_name); + cppyy_type_t cppyy_get_template(const char* template_name); - /* memory management */ - void* cppyy_allocate(cppyy_typehandle_t handle); - void cppyy_deallocate(cppyy_typehandle_t handle, cppyy_object_t instance); - void cppyy_destruct(cppyy_typehandle_t handle, cppyy_object_t self); + /* memory management ------------------------------------------------------ */ + cppyy_object_t cppyy_allocate(cppyy_type_t type); + void cppyy_deallocate(cppyy_type_t type, cppyy_object_t self); + void cppyy_destruct(cppyy_type_t type, cppyy_object_t self); - /* method/function dispatching */ - void cppyy_call_v(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args); - long cppyy_call_o(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args, cppyy_typehandle_t rettype); - int cppyy_call_b(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args); - char cppyy_call_c(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args); - short cppyy_call_h(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args); - int cppyy_call_i(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args); - long cppyy_call_l(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args); - double cppyy_call_f(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args); - double cppyy_call_d(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args); + /* method/function dispatching -------------------------------------------- */ + void cppyy_call_v(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + int cppyy_call_b(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + char cppyy_call_c(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + short cppyy_call_h(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + int cppyy_call_i(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + long cppyy_call_l(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + double cppyy_call_f(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + double cppyy_call_d(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); - void* cppyy_call_r(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args); - char* cppyy_call_s(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args); + void* cppyy_call_r(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + char* cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); - cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_typehandle_t handle, int method_index); + cppyy_object_t cppyy_call_o(cppyy_method_t method, cppyy_object_t self, int nargs, void* args, cppyy_type_t result_type); - /* handling of function argument buffer */ + cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_scope_t scope, int method_index); + + /* handling of function argument buffer ----------------------------------- */ void* cppyy_allocate_function_args(size_t nargs); void cppyy_deallocate_function_args(void* args); size_t cppyy_function_arg_sizeof(); size_t cppyy_function_arg_typeoffset(); /* scope reflection information ------------------------------------------- */ - int cppyy_is_namespace(cppyy_typehandle_t handle); + int cppyy_is_namespace(cppyy_scope_t scope); - /* type/class reflection information -------------------------------------- */ - char* cppyy_final_name(cppyy_typehandle_t handle); - int cppyy_has_complex_hierarchy(cppyy_typehandle_t handle); - int cppyy_num_bases(cppyy_typehandle_t handle); - char* cppyy_base_name(cppyy_typehandle_t handle, int base_index); - int cppyy_is_subtype(cppyy_typehandle_t dh, cppyy_typehandle_t bh); - size_t cppyy_base_offset(cppyy_typehandle_t dh, cppyy_typehandle_t bh, cppyy_object_t address); + /* class reflection information ------------------------------------------- */ + char* cppyy_final_name(cppyy_type_t type); + int cppyy_has_complex_hierarchy(cppyy_type_t type); + int cppyy_num_bases(cppyy_type_t type); + char* cppyy_base_name(cppyy_type_t type, int base_index); + int cppyy_is_subtype(cppyy_type_t derived, cppyy_type_t base); + size_t cppyy_base_offset(cppyy_type_t derived, cppyy_type_t base, cppyy_object_t address); - /* method/function reflection information */ - int cppyy_num_methods(cppyy_typehandle_t handle); - char* cppyy_method_name(cppyy_typehandle_t handle, int method_index); - char* cppyy_method_result_type(cppyy_typehandle_t handle, int method_index); - int cppyy_method_num_args(cppyy_typehandle_t handle, int method_index); - int cppyy_method_req_args(cppyy_typehandle_t handle, int method_index); - char* cppyy_method_arg_type(cppyy_typehandle_t handle, int method_index, int index); - char* cppyy_method_arg_default(cppyy_typehandle_t handle, int method_index, int index); + /* method/function reflection information --------------------------------- */ + int cppyy_num_methods(cppyy_scope_t scope); + char* cppyy_method_name(cppyy_scope_t scope, int method_index); + char* cppyy_method_result_type(cppyy_scope_t scope, int method_index); + int cppyy_method_num_args(cppyy_scope_t scope, int method_index); + int cppyy_method_req_args(cppyy_scope_t scope, int method_index); + char* cppyy_method_arg_type(cppyy_scope_t scope, int method_index, int index); + char* cppyy_method_arg_default(cppyy_scope_t scope, int method_index, int index); - /* method properties */ - int cppyy_is_constructor(cppyy_typehandle_t handle, int method_index); - int cppyy_is_staticmethod(cppyy_typehandle_t handle, int method_index); + cppyy_method_t cppyy_get_method(cppyy_scope_t scope, int method_index); - /* data member reflection information */ - int cppyy_num_data_members(cppyy_typehandle_t handle); - char* cppyy_data_member_name(cppyy_typehandle_t handle, int data_member_index); - char* cppyy_data_member_type(cppyy_typehandle_t handle, int data_member_index); - size_t cppyy_data_member_offset(cppyy_typehandle_t handle, int data_member_index); + /* method properties ----------------------------------------------------- */ + int cppyy_is_constructor(cppyy_type_t type, int method_index); + int cppyy_is_staticmethod(cppyy_type_t type, int method_index); - /* data member properties */ - int cppyy_is_publicdata(cppyy_typehandle_t handle, int data_member_index); - int cppyy_is_staticdata(cppyy_typehandle_t handle, int data_member_index); + /* data member reflection information ------------------------------------ */ + int cppyy_num_data_members(cppyy_scope_t scope); + char* cppyy_data_member_name(cppyy_scope_t scope, int data_member_index); + char* cppyy_data_member_type(cppyy_scope_t scope, int data_member_index); + size_t cppyy_data_member_offset(cppyy_scope_t scope, int data_member_index); - /* misc helpers */ + /* data member properties ------------------------------------------------ */ + int cppyy_is_publicdata(cppyy_type_t type, int data_member_index); + int cppyy_is_staticdata(cppyy_type_t type, int data_member_index); + + /* misc helpers ----------------------------------------------------------- */ void cppyy_free(void* ptr); long long cppyy_strtoll(const char* str); unsigned long long cppyy_strtuoll(const char* str); 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 @@ -27,36 +27,39 @@ class State(object): def __init__(self, space): - self.cpptype_cache = { - "void" : W_CPPType(space, "void", capi.C_NULL_TYPEHANDLE) } - self.cpptemplatetype_cache = {} + self.r_cppscope_cache = { + "void" : W_CPPType(space, "void", capi.C_NULL_TYPE) } + self.r_cpptemplate_cache = {} @unwrap_spec(name=str) def type_byname(space, name): state = space.fromcache(State) try: - return state.cpptype_cache[name] + return state.r_cppscope_cache[name] except KeyError: pass - handle = capi.c_get_typehandle(name) - assert lltype.typeOf(handle) == capi.C_TYPEHANDLE - if handle: - final_name = capi.charp2str_free(capi.c_final_name(handle)) - if capi.c_is_namespace(handle): - cpptype = W_CPPNamespace(space, final_name, handle) - elif capi.c_has_complex_hierarchy(handle): - cpptype = W_ComplexCPPType(space, final_name, handle) + cppscope = capi.c_get_scope(name) + assert lltype.typeOf(cppscope) == capi.C_SCOPE + if cppscope: + final_name = capi.charp2str_free(capi.c_final_name(cppscope)) + if capi.c_is_namespace(cppscope): + r_cppscope = W_CPPNamespace(space, final_name, cppscope) + elif capi.c_has_complex_hierarchy(cppscope): + r_cppscope = W_ComplexCPPType(space, final_name, cppscope) else: - cpptype = W_CPPType(space, final_name, handle) - state.cpptype_cache[name] = cpptype + r_cppscope = W_CPPType(space, final_name, cppscope) + state.r_cppscope_cache[name] = r_cppscope + # prevent getting reflection info that may be linked in through the + # back-end libs or that may be available through an auto-loader, during + # translation time (else it will get translated, too) if space.config.translating and not objectmodel.we_are_translated(): - return cpptype + return r_cppscope - cpptype._find_methods() - cpptype._find_data_members() - return cpptype + r_cppscope._find_methods() + r_cppscope._find_data_members() + return r_cppscope return None @@ -64,16 +67,16 @@ def template_byname(space, name): state = space.fromcache(State) try: - return state.cpptemplatetype_cache[name] + return state.r_cpptemplate_cache[name] except KeyError: pass - handle = capi.c_get_templatehandle(name) - assert lltype.typeOf(handle) == capi.C_TYPEHANDLE - if handle: - template = W_CPPTemplateType(space, name, handle) - state.cpptype_cache[name] = template - return template + cpptemplate = capi.c_get_template(name) + assert lltype.typeOf(cpptemplate) == capi.C_TYPE + if cpptemplate: + r_cpptemplate = W_CPPTemplateType(space, name, cpptemplate) + state.r_cpptemplate_cache[name] = r_cpptemplate + return r_cpptemplate return None @@ -96,9 +99,10 @@ _immutable_ = True def __init__(self, cpptype, method_index, result_type, arg_defs, args_required): + self.space = cpptype.space self.cpptype = cpptype - self.space = cpptype.space self.method_index = method_index + self.cppmethod = capi.c_get_method(self.cpptype.handle, method_index) self.arg_defs = arg_defs self.args_required = args_required self.executor = executor.get_executor(self.space, result_type) @@ -129,7 +133,7 @@ args = self.prepare_arguments(args_w) try: - return self.executor.execute(self.space, w_type, self, cppthis, len(args_w), args) + return self.executor.execute(self.space, w_type, self.cppmethod, cppthis, len(args_w), args) finally: self.free_arguments(args, len(args_w)) @@ -229,7 +233,7 @@ def __init__(self, space, scope_handle, func_name, functions): self.space = space - assert lltype.typeOf(scope_handle) == capi.C_TYPEHANDLE + assert lltype.typeOf(scope_handle) == capi.C_SCOPE self.scope_handle = scope_handle self.func_name = func_name self.functions = debug.make_sure_not_resized(functions) @@ -279,7 +283,7 @@ def __init__(self, space, scope_handle, type_name, offset, is_static): self.space = space - assert lltype.typeOf(scope_handle) == capi.C_TYPEHANDLE + assert lltype.typeOf(scope_handle) == capi.C_SCOPE self.scope_handle = scope_handle self.converter = converter.get_converter(self.space, type_name, '') self.offset = offset @@ -341,7 +345,7 @@ def __init__(self, space, name, handle): self.space = space self.name = name - assert lltype.typeOf(handle) == capi.C_TYPEHANDLE + assert lltype.typeOf(handle) == capi.C_SCOPE self.handle = handle self.methods = {} # Do not call "self._find_methods()" here, so that a distinction can @@ -539,7 +543,7 @@ def __init__(self, space, name, handle): self.space = space self.name = name - assert lltype.typeOf(handle) == capi.C_TYPEHANDLE + assert lltype.typeOf(handle) == capi.C_TYPE self.handle = handle def __call__(self, args_w): diff --git a/pypy/module/cppyy/src/reflexcwrapper.cxx b/pypy/module/cppyy/src/reflexcwrapper.cxx --- a/pypy/module/cppyy/src/reflexcwrapper.cxx +++ b/pypy/module/cppyy/src/reflexcwrapper.cxx @@ -1,6 +1,7 @@ #include "cppyy.h" #include "reflexcwrapper.h" +#include "Reflex/Kernel.h" #include "Reflex/Type.h" #include "Reflex/Base.h" #include "Reflex/Member.h" @@ -13,6 +14,7 @@ #include <utility> #include <vector> +#include <assert.h> #include <stdlib.h> @@ -23,18 +25,18 @@ return name_char; } -static inline Reflex::Scope scope_from_handle(cppyy_typehandle_t handle) { +static inline Reflex::Scope scope_from_handle(cppyy_type_t handle) { return Reflex::Scope((Reflex::ScopeName*)handle); } -static inline Reflex::Type type_from_handle(cppyy_typehandle_t handle) { +static inline Reflex::Type type_from_handle(cppyy_type_t handle) { return Reflex::Scope((Reflex::ScopeName*)handle); } -static inline std::vector<void*> build_args(int numargs, void* args) { +static inline std::vector<void*> build_args(int nargs, void* args) { std::vector<void*> arguments; - arguments.reserve(numargs); - for (int i=0; i < numargs; ++i) { + arguments.reserve(nargs); + for (int i=0; i < nargs; ++i) { char tc = ((CPPYY_G__value*)args)[i].type; if (tc != 'a' && tc != 'o') arguments.push_back(&((CPPYY_G__value*)args)[i]); @@ -45,136 +47,100 @@ } -/* name to handle --------------------------------------------------------- */ -cppyy_typehandle_t cppyy_get_typehandle(const char* class_name) { - Reflex::Scope s = Reflex::Scope::ByName(class_name); - return (cppyy_typehandle_t)s.Id(); +/* name to opaque C++ scope representation -------------------------------- */ +cppyy_scope_t cppyy_get_scope(const char* scope_name) { + Reflex::Scope s = Reflex::Scope::ByName(scope_name); + return (cppyy_type_t)s.Id(); } -cppyy_typehandle_t cppyy_get_templatehandle(const char* template_name) { +cppyy_type_t cppyy_get_template(const char* template_name) { Reflex::TypeTemplate tt = Reflex::TypeTemplate::ByName(template_name); - return (cppyy_typehandle_t)tt.Id(); + return (cppyy_type_t)tt.Id(); } /* memory management ------------------------------------------------------ */ -void* cppyy_allocate(cppyy_typehandle_t handle) { +cppyy_object_t cppyy_allocate(cppyy_type_t handle) { Reflex::Type t = type_from_handle(handle); - return t.Allocate(); + return (cppyy_object_t)t.Allocate(); } -void cppyy_deallocate(cppyy_typehandle_t handle, cppyy_object_t instance) { +void cppyy_deallocate(cppyy_type_t handle, cppyy_object_t instance) { Reflex::Type t = type_from_handle(handle); t.Deallocate((void*)instance); } -void cppyy_destruct(cppyy_typehandle_t handle, cppyy_object_t self) { +void cppyy_destruct(cppyy_type_t handle, cppyy_object_t self) { Reflex::Type t = type_from_handle(handle); t.Destruct((void*)self, true); } /* method/function dispatching -------------------------------------------- */ -void cppyy_call_v(cppyy_typehandle_t handle, int method_index, - cppyy_object_t self, int numargs, void* args) { - std::vector<void*> arguments = build_args(numargs, args); - Reflex::Scope s = scope_from_handle(handle); - Reflex::Member m = s.FunctionMemberAt(method_index); - if (self) { - Reflex::Object o((Reflex::Type)s, (void*)self); - m.Invoke(o, 0, arguments); - } else { - m.Invoke(0, arguments); - } -} - -long cppyy_call_o(cppyy_typehandle_t handle, int method_index, - cppyy_object_t self, int numargs, void* args, - cppyy_typehandle_t rettype) { - void* result = cppyy_allocate(rettype); - std::vector<void*> arguments = build_args(numargs, args); - Reflex::Scope s = scope_from_handle(handle); - Reflex::Member m = s.FunctionMemberAt(method_index); - if (self) { - Reflex::Object o((Reflex::Type)s, (void*)self); - m.Invoke(o, *((long*)result), arguments); - } else { - m.Invoke(*((long*)result), arguments); - } - return (long)result; +void cppyy_call_v(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { + std::vector<void*> arguments = build_args(nargs, args); + Reflex::StubFunction stub = (Reflex::StubFunction)method; + stub(NULL /* return address */, (void*)self, arguments, NULL /* stub context */); } template<typename T> -static inline T cppyy_call_T(cppyy_typehandle_t handle, int method_index, - cppyy_object_t self, int numargs, void* args) { +static inline T cppyy_call_T(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { T result; - std::vector<void*> arguments = build_args(numargs, args); - Reflex::Scope s = scope_from_handle(handle); - Reflex::Member m = s.FunctionMemberAt(method_index); - if (self) { - Reflex::Object o((Reflex::Type)s, (void*)self); - m.Invoke(o, result, arguments); - } else { - m.Invoke(result, arguments); - } + std::vector<void*> arguments = build_args(nargs, args); + Reflex::StubFunction stub = (Reflex::StubFunction)method; + stub(&result, (void*)self, arguments, NULL /* stub context */); return result; } -int cppyy_call_b(cppyy_typehandle_t handle, int method_index, - cppyy_object_t self, int numargs, void* args) { - return (int)cppyy_call_T<bool>(handle, method_index, self, numargs, args); +int cppyy_call_b(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { + return (int)cppyy_call_T<bool>(method, self, nargs, args); } -char cppyy_call_c(cppyy_typehandle_t handle, int method_index, - cppyy_object_t self, int numargs, void* args) { - return cppyy_call_T<char>(handle, method_index, self, numargs, args); +char cppyy_call_c(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { + return cppyy_call_T<char>(method, self, nargs, args); } -short cppyy_call_h(cppyy_typehandle_t handle, int method_index, - cppyy_object_t self, int numargs, void* args) { - return cppyy_call_T<short>(handle, method_index, self, numargs, args); +short cppyy_call_h(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { + return cppyy_call_T<short>(method, self, nargs, args); } -int cppyy_call_i(cppyy_typehandle_t handle, int method_index, - cppyy_object_t self, int numargs, void* args) { - return cppyy_call_T<int>(handle, method_index, self, numargs, args); +int cppyy_call_i(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { + return cppyy_call_T<int>(method, self, nargs, args); } -long cppyy_call_l(cppyy_typehandle_t handle, int method_index, - cppyy_object_t self, int numargs, void* args) { - return cppyy_call_T<long>(handle, method_index, self, numargs, args); +long cppyy_call_l(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { + return cppyy_call_T<long>(method, self, nargs, args); } -double cppyy_call_f(cppyy_typehandle_t handle, int method_index, - cppyy_object_t self, int numargs, void* args) { - return cppyy_call_T<float>(handle, method_index, self, numargs, args); +double cppyy_call_f(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { + return cppyy_call_T<float>(method, self, nargs, args); } -double cppyy_call_d(cppyy_typehandle_t handle, int method_index, - cppyy_object_t self, int numargs, void* args) { - return cppyy_call_T<double>(handle, method_index, self, numargs, args); +double cppyy_call_d(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { + return cppyy_call_T<double>(method, self, nargs, args); } -void* cppyy_call_r(cppyy_typehandle_t handle, int method_index, - cppyy_object_t self, int numargs, void* args) { - return (void*)cppyy_call_T<long>(handle, method_index, self, numargs, args); +void* cppyy_call_r(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { + return (void*)cppyy_call_T<long>(method, self, nargs, args); } -char* cppyy_call_s(cppyy_typehandle_t handle, int method_index, - cppyy_object_t self, int numargs, void* args) { +char* cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { std::string result(""); - std::vector<void*> arguments = build_args(numargs, args); - Reflex::Scope s = scope_from_handle(handle); - Reflex::Member m = s.FunctionMemberAt(method_index); - if (self) { - Reflex::Object o((Reflex::Type)s, (void*)self); - m.Invoke(o, result, arguments); - } else { - m.Invoke(result, arguments); - } + std::vector<void*> arguments = build_args(nargs, args); + Reflex::StubFunction stub = (Reflex::StubFunction)method; + stub(&result, (void*)self, arguments, NULL /* stub context */); return cppstring_to_cstring(result); } +cppyy_object_t cppyy_call_o(cppyy_method_t method, cppyy_object_t self, int nargs, void* args, + cppyy_type_t result_type) { + void* result = (void*)cppyy_allocate(result_type); + std::vector<void*> arguments = build_args(nargs, args); + Reflex::StubFunction stub = (Reflex::StubFunction)method; + stub(result, (void*)self, arguments, NULL /* stub context */); + return (cppyy_object_t)result; +} + static cppyy_methptrgetter_t get_methptr_getter(Reflex::Member m) { Reflex::PropertyList plist = m.Properties(); if (plist.HasProperty("MethPtrGetter")) { @@ -184,7 +150,7 @@ return 0; } -cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_typehandle_t handle, int method_index) { +cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_type_t handle, int method_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.FunctionMemberAt(method_index); return get_methptr_getter(m); @@ -213,14 +179,14 @@ /* scope reflection information ------------------------------------------- */ -int cppyy_is_namespace(cppyy_typehandle_t handle) { +int cppyy_is_namespace(cppyy_scope_t handle) { Reflex::Scope s = scope_from_handle(handle); return s.IsNamespace(); } -/* type/class reflection information -------------------------------------- */ -char* cppyy_final_name(cppyy_typehandle_t handle) { +/* class reflection information ------------------------------------------- */ +char* cppyy_final_name(cppyy_type_t handle) { Reflex::Scope s = scope_from_handle(handle); std::string name = s.Name(Reflex::FINAL); return cppstring_to_cstring(name); @@ -245,36 +211,36 @@ return is_complex; } -int cppyy_has_complex_hierarchy(cppyy_typehandle_t handle) { +int cppyy_has_complex_hierarchy(cppyy_type_t handle) { Reflex::Type t = type_from_handle(handle); return cppyy_has_complex_hierarchy(t); } -int cppyy_num_bases(cppyy_typehandle_t handle) { +int cppyy_num_bases(cppyy_type_t handle) { Reflex::Type t = type_from_handle(handle); return t.BaseSize(); } -char* cppyy_base_name(cppyy_typehandle_t handle, int base_index) { +char* cppyy_base_name(cppyy_type_t handle, int base_index) { Reflex::Type t = type_from_handle(handle); Reflex::Base b = t.BaseAt(base_index); std::string name = b.Name(Reflex::FINAL|Reflex::SCOPED); return cppstring_to_cstring(name); } -int cppyy_is_subtype(cppyy_typehandle_t dh, cppyy_typehandle_t bh) { - Reflex::Type td = type_from_handle(dh); - Reflex::Type tb = type_from_handle(bh); - return (int)td.HasBase(tb); +int cppyy_is_subtype(cppyy_type_t derived_handle, cppyy_type_t base_handle) { + Reflex::Type derived_type = type_from_handle(derived_handle); + Reflex::Type base_type = type_from_handle(base_handle); + return (int)derived_type.HasBase(base_type); } -size_t cppyy_base_offset(cppyy_typehandle_t dh, cppyy_typehandle_t bh, cppyy_object_t address) { - Reflex::Type td = type_from_handle(dh); - Reflex::Type tb = type_from_handle(bh); +size_t cppyy_base_offset(cppyy_type_t derived_handle, cppyy_type_t base_handle, cppyy_object_t address) { + Reflex::Type derived_type = type_from_handle(derived_handle); + Reflex::Type base_type = type_from_handle(base_handle); // when dealing with virtual inheritance the only (reasonably) well-defined info is // in a Reflex internal base table, that contains all offsets within the hierarchy - Reflex::Member getbases = td.FunctionMemberByName( + Reflex::Member getbases = derived_type.FunctionMemberByName( "__getBasesTable", Reflex::Type(), 0, Reflex::INHERITEDMEMBERS_NO, Reflex::DELAYEDLOAD_OFF); if (getbases) { typedef std::vector<std::pair<Reflex::Base, int> > Bases_t; @@ -283,7 +249,7 @@ getbases.Invoke(&bases_holder); for (Bases_t::iterator ibase = bases->begin(); ibase != bases->end(); ++ibase) { - if (ibase->first.ToType() == tb) + if (ibase->first.ToType() == base_type) return (size_t)ibase->first.Offset((void*)address); } @@ -296,12 +262,12 @@ /* method/function reflection information --------------------------------- */ -int cppyy_num_methods(cppyy_typehandle_t handle) { +int cppyy_num_methods(cppyy_scope_t handle) { Reflex::Scope s = scope_from_handle(handle); return s.FunctionMemberSize(); } -char* cppyy_method_name(cppyy_typehandle_t handle, int method_index) { +char* cppyy_method_name(cppyy_scope_t handle, int method_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.FunctionMemberAt(method_index); std::string name; @@ -312,7 +278,7 @@ return cppstring_to_cstring(name); } -char* cppyy_method_result_type(cppyy_typehandle_t handle, int method_index) { +char* cppyy_method_result_type(cppyy_scope_t handle, int method_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.FunctionMemberAt(method_index); Reflex::Type rt = m.TypeOf().ReturnType(); @@ -320,19 +286,19 @@ return cppstring_to_cstring(name); } -int cppyy_method_num_args(cppyy_typehandle_t handle, int method_index) { +int cppyy_method_num_args(cppyy_scope_t handle, int method_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.FunctionMemberAt(method_index); return m.FunctionParameterSize(); } -int cppyy_method_req_args(cppyy_typehandle_t handle, int method_index) { +int cppyy_method_req_args(cppyy_scope_t handle, int method_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.FunctionMemberAt(method_index); return m.FunctionParameterSize(true); } -char* cppyy_method_arg_type(cppyy_typehandle_t handle, int method_index, int arg_index) { +char* cppyy_method_arg_type(cppyy_scope_t handle, int method_index, int arg_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.FunctionMemberAt(method_index); Reflex::Type at = m.TypeOf().FunctionParameterAt(arg_index); @@ -340,21 +306,29 @@ return cppstring_to_cstring(name); } -char* cppyy_method_arg_default(cppyy_typehandle_t handle, int method_index, int arg_index) { +char* cppyy_method_arg_default(cppyy_scope_t handle, int method_index, int arg_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.FunctionMemberAt(method_index); std::string dflt = m.FunctionParameterDefaultAt(arg_index); return cppstring_to_cstring(dflt); } +cppyy_method_t cppyy_get_method(cppyy_scope_t handle, int method_index) { + Reflex::Scope s = scope_from_handle(handle); + Reflex::Member m = s.FunctionMemberAt(method_index); + assert(m.IsFunctionMember()); + return (cppyy_method_t)m.Stubfunction(); +} -int cppyy_is_constructor(cppyy_typehandle_t handle, int method_index) { + +/* method properties ----------------------------------------------------- */ +int cppyy_is_constructor(cppyy_type_t handle, int method_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.FunctionMemberAt(method_index); return m.IsConstructor(); } -int cppyy_is_staticmethod(cppyy_typehandle_t handle, int method_index) { +int cppyy_is_staticmethod(cppyy_type_t handle, int method_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.FunctionMemberAt(method_index); return m.IsStatic(); @@ -362,39 +336,39 @@ /* data member reflection information ------------------------------------- */ -int cppyy_num_data_members(cppyy_typehandle_t handle) { +int cppyy_num_data_members(cppyy_scope_t handle) { Reflex::Scope s = scope_from_handle(handle); return s.DataMemberSize(); } -char* cppyy_data_member_name(cppyy_typehandle_t handle, int data_member_index) { +char* cppyy_data_member_name(cppyy_scope_t handle, int data_member_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.DataMemberAt(data_member_index); std::string name = m.Name(); return cppstring_to_cstring(name); } -char* cppyy_data_member_type(cppyy_typehandle_t handle, int data_member_index) { +char* cppyy_data_member_type(cppyy_scope_t handle, int data_member_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.DataMemberAt(data_member_index); std::string name = m.TypeOf().Name(Reflex::FINAL|Reflex::SCOPED|Reflex::QUALIFIED); return cppstring_to_cstring(name); } -size_t cppyy_data_member_offset(cppyy_typehandle_t handle, int data_member_index) { +size_t cppyy_data_member_offset(cppyy_scope_t handle, int data_member_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.DataMemberAt(data_member_index); return m.Offset(); } -int cppyy_is_publicdata(cppyy_typehandle_t handle, int data_member_index) { +int cppyy_is_publicdata(cppyy_scope_t handle, int data_member_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.DataMemberAt(data_member_index); return m.IsPublic(); } -int cppyy_is_staticdata(cppyy_typehandle_t handle, int data_member_index) { +int cppyy_is_staticdata(cppyy_scope_t handle, int data_member_index) { Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.DataMemberAt(data_member_index); return m.IsStatic(); _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit