[pypy-commit] pypy reflex-support: o) on demand lookup of global operator== (only for CINT backend for now)
wlav
noreply at buildbot.pypy.org
Tue Jun 26 21:15:52 CEST 2012
Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r55838:3b63338d1a80
Date: 2012-06-25 15:19 -0700
http://bitbucket.org/pypy/pypy/changeset/3b63338d1a80/
Log: o) on demand lookup of global operator== (only for CINT backend for
now) o) reworking of method indexing to give more flexibility to
backend
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
@@ -23,6 +23,8 @@
C_NULL_OBJECT = rffi.cast(C_OBJECT, _C_OPAQUE_NULL)
C_METHOD = _C_OPAQUE_PTR
+C_INDEX = rffi.LONG
+WLAVC_INDEX = rffi.LONG
C_METHPTRGETTER = lltype.FuncType([C_OBJECT], rffi.VOIDP)
C_METHPTRGETTER_PTR = lltype.Ptr(C_METHPTRGETTER)
@@ -148,23 +150,22 @@
[C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], lltype.Void,
threadsafe=ts_call,
compilation_info=backend.eci)
-
_c_call_o = rffi.llexternal(
"cppyy_call_o",
[C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP, C_TYPE], rffi.LONG,
threadsafe=ts_call,
compilation_info=backend.eci)
-def c_call_o(method_index, cppobj, nargs, args, cppclass):
- return _c_call_o(method_index, cppobj, nargs, args, cppclass.handle)
+def c_call_o(method, cppobj, nargs, args, cppclass):
+ return _c_call_o(method, cppobj, nargs, args, cppclass.handle)
_c_get_methptr_getter = rffi.llexternal(
"cppyy_get_methptr_getter",
- [C_SCOPE, rffi.INT], C_METHPTRGETTER_PTR,
+ [C_SCOPE, C_INDEX], C_METHPTRGETTER_PTR,
threadsafe=ts_reflect,
compilation_info=backend.eci,
elidable_function=True)
-def c_get_methptr_getter(cppscope, method_index):
- return _c_get_methptr_getter(cppscope.handle, method_index)
+def c_get_methptr_getter(cppscope, index):
+ return _c_get_methptr_getter(cppscope.handle, index)
# handling of function argument buffer ---------------------------------------
c_allocate_function_args = rffi.llexternal(
@@ -236,7 +237,6 @@
compilation_info=backend.eci)
def c_base_name(cppclass, base_index):
return charp2str_free(_c_base_name(cppclass.handle, base_index))
-
_c_is_subtype = rffi.llexternal(
"cppyy_is_subtype",
[C_TYPE, C_TYPE], rffi.INT,
@@ -269,87 +269,102 @@
compilation_info=backend.eci)
def c_num_methods(cppscope):
return _c_num_methods(cppscope.handle)
+_c_method_index_at = rffi.llexternal(
+ "cppyy_method_index_at",
+ [C_SCOPE, rffi.INT], C_INDEX,
+ threadsafe=ts_reflect,
+ compilation_info=backend.eci)
+def c_method_index_at(cppscope, imethod):
+ return _c_method_index_at(cppscope.handle, imethod)
+_c_method_index_from_name = rffi.llexternal(
+ "cppyy_method_index_from_name",
+ [C_SCOPE, rffi.CCHARP], C_INDEX,
+ threadsafe=ts_reflect,
+ compilation_info=backend.eci)
+def c_method_index_from_name(cppscope, name):
+ return _c_method_index_from_name(cppscope.handle, name)
+
_c_method_name = rffi.llexternal(
"cppyy_method_name",
- [C_SCOPE, rffi.INT], rffi.CCHARP,
+ [C_SCOPE, C_INDEX], rffi.CCHARP,
threadsafe=ts_reflect,
compilation_info=backend.eci)
-def c_method_name(cppscope, method_index):
- return charp2str_free(_c_method_name(cppscope.handle, method_index))
+def c_method_name(cppscope, index):
+ return charp2str_free(_c_method_name(cppscope.handle, index))
_c_method_result_type = rffi.llexternal(
"cppyy_method_result_type",
- [C_SCOPE, rffi.INT], rffi.CCHARP,
+ [C_SCOPE, C_INDEX], rffi.CCHARP,
threadsafe=ts_reflect,
compilation_info=backend.eci)
-def c_method_result_type(cppscope, method_index):
- return charp2str_free(_c_method_result_type(cppscope.handle, method_index))
+def c_method_result_type(cppscope, index):
+ return charp2str_free(_c_method_result_type(cppscope.handle, index))
_c_method_num_args = rffi.llexternal(
"cppyy_method_num_args",
- [C_SCOPE, rffi.INT], rffi.INT,
+ [C_SCOPE, C_INDEX], rffi.INT,
threadsafe=ts_reflect,
compilation_info=backend.eci)
-def c_method_num_args(cppscope, method_index):
- return _c_method_num_args(cppscope.handle, method_index)
+def c_method_num_args(cppscope, index):
+ return _c_method_num_args(cppscope.handle, index)
_c_method_req_args = rffi.llexternal(
"cppyy_method_req_args",
- [C_SCOPE, rffi.INT], rffi.INT,
+ [C_SCOPE, C_INDEX], rffi.INT,
threadsafe=ts_reflect,
compilation_info=backend.eci)
-def c_method_req_args(cppscope, method_index):
- return _c_method_req_args(cppscope.handle, method_index)
+def c_method_req_args(cppscope, index):
+ return _c_method_req_args(cppscope.handle, index)
_c_method_arg_type = rffi.llexternal(
"cppyy_method_arg_type",
- [C_SCOPE, rffi.INT, rffi.INT], rffi.CCHARP,
+ [C_SCOPE, C_INDEX, rffi.INT], rffi.CCHARP,
threadsafe=ts_reflect,
compilation_info=backend.eci)
-def c_method_arg_type(cppscope, method_index, arg_index):
- return charp2str_free(_c_method_arg_type(cppscope.handle, method_index, arg_index))
+def c_method_arg_type(cppscope, index, arg_index):
+ return charp2str_free(_c_method_arg_type(cppscope.handle, index, arg_index))
_c_method_arg_default = rffi.llexternal(
"cppyy_method_arg_default",
- [C_SCOPE, rffi.INT, rffi.INT], rffi.CCHARP,
+ [C_SCOPE, C_INDEX, rffi.INT], rffi.CCHARP,
threadsafe=ts_reflect,
compilation_info=backend.eci)
-def c_method_arg_default(cppscope, method_index, arg_index):
- return charp2str_free(_c_method_arg_default(cppscope.handle, method_index, arg_index))
+def c_method_arg_default(cppscope, index, arg_index):
+ return charp2str_free(_c_method_arg_default(cppscope.handle, index, arg_index))
_c_method_signature = rffi.llexternal(
"cppyy_method_signature",
- [C_SCOPE, rffi.INT], rffi.CCHARP,
+ [C_SCOPE, C_INDEX], rffi.CCHARP,
threadsafe=ts_reflect,
compilation_info=backend.eci)
-def c_method_signature(cppscope, method_index):
- return charp2str_free(_c_method_signature(cppscope.handle, method_index))
-
-_c_method_index = rffi.llexternal(
- "cppyy_method_index",
- [C_SCOPE, rffi.CCHARP], rffi.INT,
- threadsafe=ts_reflect,
- compilation_info=backend.eci)
-def c_method_index(cppscope, name):
- return _c_method_index(cppscope.handle, name)
+def c_method_signature(cppscope, index):
+ return charp2str_free(_c_method_signature(cppscope.handle, index))
_c_get_method = rffi.llexternal(
"cppyy_get_method",
- [C_SCOPE, rffi.INT], C_METHOD,
+ [C_SCOPE, C_INDEX], C_METHOD,
threadsafe=ts_reflect,
compilation_info=backend.eci)
-def c_get_method(cppscope, method_index):
- return _c_get_method(cppscope.handle, method_index)
+def c_get_method(cppscope, index):
+ return _c_get_method(cppscope.handle, index)
+_c_get_global_operator = rffi.llexternal(
+ "cppyy_get_global_operator",
+ [C_SCOPE, C_SCOPE, rffi.CCHARP], WLAVC_INDEX,
+ threadsafe=ts_reflect,
+ compilation_info=backend.eci)
+ at jit.elidable_promote() # TODO: this is debatable
+def c_get_global_operator(lc, rc, op):
+ return _c_get_global_operator(lc.handle, rc.handle, op)
# method properties ----------------------------------------------------------
_c_is_constructor = rffi.llexternal(
"cppyy_is_constructor",
- [C_TYPE, rffi.INT], rffi.INT,
+ [C_TYPE, C_INDEX], rffi.INT,
threadsafe=ts_reflect,
compilation_info=backend.eci)
-def c_is_constructor(cppclass, method_index):
- return _c_is_constructor(cppclass.handle, method_index)
+def c_is_constructor(cppclass, index):
+ return _c_is_constructor(cppclass.handle, index)
_c_is_staticmethod = rffi.llexternal(
"cppyy_is_staticmethod",
- [C_TYPE, rffi.INT], rffi.INT,
+ [C_TYPE, C_INDEX], rffi.INT,
threadsafe=ts_reflect,
compilation_info=backend.eci)
-def c_is_staticmethod(cppclass, method_index):
- return _c_is_staticmethod(cppclass.handle, method_index)
+def c_is_staticmethod(cppclass, index):
+ return _c_is_staticmethod(cppclass.handle, index)
# data member reflection information -----------------------------------------
_c_num_datamembers = rffi.llexternal(
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
@@ -11,6 +11,7 @@
typedef cppyy_scope_t cppyy_type_t;
typedef long cppyy_object_t;
typedef long cppyy_method_t;
+ typedef long cppyy_index_t;
typedef void* (*cppyy_methptrgetter_t)(cppyy_object_t);
/* name to opaque C++ scope representation -------------------------------- */
@@ -41,7 +42,7 @@
void cppyy_constructor(cppyy_method_t method, cppyy_object_t self, int nargs, void* args);
cppyy_object_t cppyy_call_o(cppyy_method_t method, cppyy_object_t self, int nargs, void* args, cppyy_type_t result_type);
- cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_scope_t scope, int method_index);
+ cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_scope_t scope, cppyy_index_t idx);
/* handling of function argument buffer ----------------------------------- */
void* cppyy_allocate_function_args(size_t nargs);
@@ -66,21 +67,23 @@
/* 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 arg_index);
- char* cppyy_method_arg_default(cppyy_scope_t scope, int method_index, int arg_index);
- char* cppyy_method_signature(cppyy_scope_t scope, int method_index);
+ cppyy_index_t cppyy_method_index_at(cppyy_scope_t scope, int imeth);
+ cppyy_index_t cppyy_method_index_from_name(cppyy_scope_t scope, const char* name);
- int cppyy_method_index(cppyy_scope_t scope, const char* name);
+ char* cppyy_method_name(cppyy_scope_t scope, cppyy_index_t idx);
+ char* cppyy_method_result_type(cppyy_scope_t scope, cppyy_index_t idx);
+ int cppyy_method_num_args(cppyy_scope_t scope, cppyy_index_t idx);
+ int cppyy_method_req_args(cppyy_scope_t scope, cppyy_index_t idx);
+ char* cppyy_method_arg_type(cppyy_scope_t scope, cppyy_index_t idx, int arg_index);
+ char* cppyy_method_arg_default(cppyy_scope_t scope, cppyy_index_t idx, int arg_index);
+ char* cppyy_method_signature(cppyy_scope_t scope, cppyy_index_t idx);
- cppyy_method_t cppyy_get_method(cppyy_scope_t scope, int method_index);
+ cppyy_method_t cppyy_get_method(cppyy_scope_t scope, cppyy_index_t idx);
+ cppyy_index_t cppyy_get_global_operator(cppyy_scope_t lc, cppyy_scope_t rc, const char* op);
/* method properties ----------------------------------------------------- */
- int cppyy_is_constructor(cppyy_type_t type, int method_index);
- int cppyy_is_staticmethod(cppyy_type_t type, int method_index);
+ int cppyy_is_constructor(cppyy_type_t type, cppyy_index_t idx);
+ int cppyy_is_staticmethod(cppyy_type_t type, cppyy_index_t idx);
/* data member reflection information ------------------------------------ */
int cppyy_num_datamembers(cppyy_scope_t scope);
@@ -95,9 +98,9 @@
int cppyy_is_staticdata(cppyy_type_t type, int datamember_index);
/* misc helpers ----------------------------------------------------------- */
- void cppyy_free(void* ptr);
long long cppyy_strtoll(const char* str);
unsigned long long cppyy_strtuoll(const char* str);
+ void cppyy_free(void* ptr);
cppyy_object_t cppyy_charp2stdstring(const char* str);
cppyy_object_t cppyy_stdstring2stdstring(cppyy_object_t ptr);
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
@@ -59,7 +59,7 @@
cppscope = W_CPPClass(space, final_name, opaque_handle)
state.cppscope_cache[name] = cppscope
- cppscope._find_methods()
+ cppscope._build_methods()
cppscope._find_datamembers()
return cppscope
@@ -412,29 +412,29 @@
assert lltype.typeOf(opaque_handle) == capi.C_SCOPE
self.handle = opaque_handle
self.methods = {}
- # Do not call "self._find_methods()" here, so that a distinction can
+ # Do not call "self._build_methods()" here, so that a distinction can
# be made between testing for existence (i.e. existence in the cache
# of classes) and actual use. Point being that a class can use itself,
# e.g. as a return type or an argument to one of its methods.
self.datamembers = {}
- # Idem self.methods: a type could hold itself by pointer.
+ # Idem as for self.methods: a type could hold itself by pointer.
- def _find_methods(self):
- num_methods = capi.c_num_methods(self)
- args_temp = {}
- for i in range(num_methods):
- method_name = capi.c_method_name(self, i)
- pymethod_name = helper.map_operator_name(
- method_name, capi.c_method_num_args(self, i),
- capi.c_method_result_type(self, i))
- if not pymethod_name in self.methods:
- cppfunction = self._make_cppfunction(i)
- overload = args_temp.setdefault(pymethod_name, [])
- overload.append(cppfunction)
- for name, functions in args_temp.iteritems():
- overload = W_CPPOverload(self.space, self, functions[:])
- self.methods[name] = overload
+ def _build_methods(self):
+ assert len(self.methods) == 0
+ methods_temp = {}
+ N = capi.c_num_methods(self)
+ for i in range(N):
+ idx = capi.c_method_index_at(self, i)
+ pyname = helper.map_operator_name(
+ capi.c_method_name(self, idx),
+ capi.c_method_num_args(self, idx),
+ capi.c_method_result_type(self, idx))
+ cppmethod = self._make_cppfunction(idx)
+ methods_temp.setdefault(pyname, []).append(cppmethod)
+ for pyname, methods in methods_temp.iteritems():
+ overload = W_CPPOverload(self.space, self, methods[:])
+ self.methods[pyname] = overload
def get_method_names(self):
return self.space.newlist([self.space.wrap(name) for name in self.methods])
@@ -488,15 +488,15 @@
_immutable_ = True
kind = "namespace"
- def _make_cppfunction(self, method_index):
- num_args = capi.c_method_num_args(self, method_index)
- args_required = capi.c_method_req_args(self, method_index)
+ def _make_cppfunction(self, index):
+ num_args = capi.c_method_num_args(self, index)
+ args_required = capi.c_method_req_args(self, index)
arg_defs = []
for i in range(num_args):
- arg_type = capi.c_method_arg_type(self, method_index, i)
- arg_dflt = capi.c_method_arg_default(self, method_index, i)
+ arg_type = capi.c_method_arg_type(self, index, i)
+ arg_dflt = capi.c_method_arg_default(self, index, i)
arg_defs.append((arg_type, arg_dflt))
- return CPPFunction(self.space, self, method_index, arg_defs, args_required)
+ return CPPFunction(self.space, self, index, arg_defs, args_required)
def _make_datamember(self, dm_name, dm_idx):
type_name = capi.c_datamember_type(self, dm_idx)
@@ -516,8 +516,8 @@
def find_overload(self, meth_name):
# TODO: collect all overloads, not just the non-overloaded version
- meth_idx = capi.c_method_index(self, meth_name)
- if meth_idx < 0:
+ meth_idx = capi.c_method_index_from_name(self, meth_name)
+ if meth_idx == -1:
raise self.missing_attribute_error(meth_name)
cppfunction = self._make_cppfunction(meth_idx)
overload = W_CPPOverload(self.space, self, [cppfunction])
@@ -548,21 +548,21 @@
_immutable_ = True
kind = "class"
- def _make_cppfunction(self, method_index):
- num_args = capi.c_method_num_args(self, method_index)
- args_required = capi.c_method_req_args(self, method_index)
+ def _make_cppfunction(self, index):
+ num_args = capi.c_method_num_args(self, index)
+ args_required = capi.c_method_req_args(self, index)
arg_defs = []
for i in range(num_args):
- arg_type = capi.c_method_arg_type(self, method_index, i)
- arg_dflt = capi.c_method_arg_default(self, method_index, i)
+ arg_type = capi.c_method_arg_type(self, index, i)
+ arg_dflt = capi.c_method_arg_default(self, index, i)
arg_defs.append((arg_type, arg_dflt))
- if capi.c_is_constructor(self, method_index):
+ if capi.c_is_constructor(self, index):
cls = CPPConstructor
- elif capi.c_is_staticmethod(self, method_index):
+ elif capi.c_is_staticmethod(self, index):
cls = CPPFunction
else:
cls = CPPMethod
- return cls(self.space, self, method_index, arg_defs, args_required)
+ return cls(self.space, self, index, arg_defs, args_required)
def _find_datamembers(self):
num_datamembers = capi.c_num_datamembers(self)
@@ -693,7 +693,18 @@
def instance__eq__(self, w_other):
other = self.space.interp_w(W_CPPInstance, w_other, can_be_None=False)
- iseq = self._rawobject == other._rawobject
+ # get here if no class-specific overloaded operator is available
+ meth_idx = capi.c_get_global_operator(self.cppclass, other.cppclass, "==")
+ if meth_idx != -1:
+ gbl = scope_byname(self.space, "")
+ f = gbl._make_cppfunction(meth_idx)
+ ol = W_CPPOverload(self.space, scope_byname(self.space, ""), [f])
+ # TODO: cache this operator (currently cached by JIT in capi/__init__.py)
+ return ol.call(self, (self, w_other))
+
+ # fallback: direct pointer comparison (the class comparison is needed since the
+ # first data member in a struct and the struct have the same address)
+ iseq = (self._rawobject == other._rawobject) and (self.cppclass == other.cppclass)
return self.space.wrap(iseq)
def instance__ne__(self, w_other):
@@ -774,7 +785,7 @@
def wrap_cppobject_nocast(space, w_pycppclass, cppclass, rawobject, isref, python_owns):
obj = memory_regulator.retrieve(rawobject)
- if obj and obj.cppclass == cppclass:
+ if not (obj is None) and obj.cppclass is cppclass:
return obj
return wrap_new_cppobject_nocast(space, w_pycppclass, cppclass, rawobject, isref, python_owns)
diff --git a/pypy/module/cppyy/pythonify.py b/pypy/module/cppyy/pythonify.py
--- a/pypy/module/cppyy/pythonify.py
+++ b/pypy/module/cppyy/pythonify.py
@@ -329,10 +329,9 @@
# map begin()/end() protocol to iter protocol
if hasattr(pyclass, 'begin') and hasattr(pyclass, 'end'):
- # TODO: make gnu-independent
def __iter__(self):
iter = self.begin()
- while gbl.__gnu_cxx.__ne__(iter, self.end()):
+ while iter != self.end():
yield iter.__deref__()
iter.__preinc__()
iter.destruct()
diff --git a/pypy/module/cppyy/src/cintcwrapper.cxx b/pypy/module/cppyy/src/cintcwrapper.cxx
--- a/pypy/module/cppyy/src/cintcwrapper.cxx
+++ b/pypy/module/cppyy/src/cintcwrapper.cxx
@@ -141,6 +141,13 @@
/* local helpers ---------------------------------------------------------- */
+static inline const std::string resolve_typedef(const std::string& tname) {
+ G__TypeInfo ti(tname.c_str());
+ if (!ti.IsValid())
+ return tname;
+ return TClassEdit::ShortType(TClassEdit::CleanType(ti.TrueName(), 1).c_str(), 3);
+}
+
static inline char* cppstring_to_cstring(const std::string& name) {
char* name_char = (char*)malloc(name.size() + 1);
strcpy(name_char, name.c_str());
@@ -154,17 +161,17 @@
}
static inline TClassRef type_from_handle(cppyy_type_t handle) {
+ assert((ClassRefs_t::size_type)handle < g_classrefs.size());
return g_classrefs[(ClassRefs_t::size_type)handle];
}
-static inline TFunction* type_get_method(cppyy_type_t handle, int method_index) {
+static inline TFunction* type_get_method(cppyy_type_t handle, cppyy_index_t idx) {
TClassRef cr = type_from_handle(handle);
if (cr.GetClass())
- return (TFunction*)cr->GetListOfMethods()->At(method_index);
- return &g_globalfuncs[method_index];
+ return (TFunction*)cr->GetListOfMethods()->At(idx);
+ return (TFunction*)idx;
}
-
static inline void fixup_args(G__param* libp) {
for (int i = 0; i < libp->paran; ++i) {
libp->para[i].ref = libp->para[i].obj.i;
@@ -194,7 +201,6 @@
libp->para[i].ref = (long)&libp->para[i].obj.i;
libp->para[i].type = 'd';
break;
-
}
}
}
@@ -261,6 +267,7 @@
return klass;
}
+
/* memory management ------------------------------------------------------ */
cppyy_object_t cppyy_allocate(cppyy_type_t handle) {
TClassRef cr = type_from_handle(handle);
@@ -387,7 +394,7 @@
return G__int(result);
}
-cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_type_t /*handle*/, int /*method_index*/) {
+cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_type_t /*handle*/, cppyy_index_t /*idx*/) {
return (cppyy_methptrgetter_t)NULL;
}
@@ -533,47 +540,75 @@
return 0;
}
-char* cppyy_method_name(cppyy_scope_t handle, int method_index) {
- TFunction* f = type_get_method(handle, method_index);
+cppyy_index_t cppyy_method_index_at(cppyy_scope_t handle, int imeth) {
+ TClassRef cr = type_from_handle(handle);
+ if (cr.GetClass())
+ return (cppyy_index_t)imeth;
+ return (cppyy_index_t)&g_globalfuncs[imeth];
+}
+
+cppyy_index_t cppyy_method_index_from_name(cppyy_scope_t handle, const char* name) {
+ TClassRef cr = type_from_handle(handle);
+ if (cr.GetClass()) {
+ gInterpreter->UpdateListOfMethods(cr.GetClass());
+ int imeth = 0;
+ TFunction* func;
+ TIter next(cr->GetListOfMethods());
+ while ((func = (TFunction*)next())) {
+ if (strcmp(name, func->GetName()) == 0) {
+ if (func->Property() & G__BIT_ISPUBLIC)
+ return (cppyy_index_t)imeth;
+ return (cppyy_index_t)-1;
+ }
+ ++imeth;
+ }
+ }
+ TFunction* func = gROOT->GetGlobalFunction(name, NULL, kTRUE);
+ if (!func)
+ return (cppyy_index_t)-1; // (void*)-1 is in kernel space, so invalid
+ int idx = g_globalfuncs.size();
+ g_globalfuncs.push_back(*func);
+ return (cppyy_index_t)func;
+}
+
+
+char* cppyy_method_name(cppyy_scope_t handle, cppyy_index_t idx) {
+ TFunction* f = type_get_method(handle, idx);
return cppstring_to_cstring(f->GetName());
}
-char* cppyy_method_result_type(cppyy_scope_t handle, int method_index) {
- TFunction* f = 0;
+char* cppyy_method_result_type(cppyy_scope_t handle, cppyy_index_t idx) {
TClassRef cr = type_from_handle(handle);
- if (cr.GetClass()) {
- if (cppyy_is_constructor(handle, method_index))
- return cppstring_to_cstring("constructor");
- f = (TFunction*)cr->GetListOfMethods()->At(method_index);
- } else
- f = &g_globalfuncs[method_index];
+ if (cr.GetClass() && cppyy_is_constructor(handle, idx))
+ return cppstring_to_cstring("constructor");
+ TFunction* f = type_get_method(handle, idx);
return type_cppstring_to_cstring(f->GetReturnTypeName());
}
-int cppyy_method_num_args(cppyy_scope_t handle, int method_index) {
- TFunction* f = type_get_method(handle, method_index);
+int cppyy_method_num_args(cppyy_scope_t handle, cppyy_index_t idx) {
+ TFunction* f = type_get_method(handle, idx);
return f->GetNargs();
}
-int cppyy_method_req_args(cppyy_scope_t handle, int method_index) {
- TFunction* f = type_get_method(handle, method_index);
+int cppyy_method_req_args(cppyy_scope_t handle, cppyy_index_t idx) {
+ TFunction* f = type_get_method(handle, idx);
return f->GetNargs() - f->GetNargsOpt();
}
-char* cppyy_method_arg_type(cppyy_scope_t handle, int method_index, int arg_index) {
- TFunction* f = type_get_method(handle, method_index);
+char* cppyy_method_arg_type(cppyy_scope_t handle, cppyy_index_t idx, int arg_index) {
+ TFunction* f = type_get_method(handle, idx);
TMethodArg* arg = (TMethodArg*)f->GetListOfMethodArgs()->At(arg_index);
return type_cppstring_to_cstring(arg->GetFullTypeName());
}
-char* cppyy_method_arg_default(cppyy_scope_t, int, int) {
+char* cppyy_method_arg_default(cppyy_scope_t /*handle*/, cppyy_index_t /*idx*/, int /*arg_index*/) {
/* unused: libffi does not work with CINT back-end */
return cppstring_to_cstring("");
}
-char* cppyy_method_signature(cppyy_scope_t handle, int method_index) {
- TFunction* f = type_get_method(handle, method_index);
+char* cppyy_method_signature(cppyy_scope_t handle, cppyy_index_t idx) {
TClassRef cr = type_from_handle(handle);
+ TFunction* f = type_get_method(handle, idx);
std::ostringstream sig;
if (cr.GetClass() && cr->GetClassInfo()
&& strcmp(f->GetName(), ((G__ClassInfo*)cr->GetClassInfo())->Name()) != 0)
@@ -589,46 +624,53 @@
return cppstring_to_cstring(sig.str());
}
-int cppyy_method_index(cppyy_scope_t handle, const char* name) {
- TClassRef cr = type_from_handle(handle);
- if (cr.GetClass()) {
- gInterpreter->UpdateListOfMethods(cr.GetClass());
- int imeth = 0;
- TFunction* func;
- TIter next(cr->GetListOfMethods());
- while ((func = (TFunction*)next())) {
- if (strcmp(name, func->GetName()) == 0) {
- if (func->Property() & G__BIT_ISPUBLIC)
- return imeth;
- return -1;
- }
- ++imeth;
- }
- }
- TFunction* func = gROOT->GetGlobalFunction(name, NULL, kTRUE);
- if (!func)
- return -1;
- int idx = g_globalfuncs.size();
- g_globalfuncs.push_back(*func);
- return idx;
-}
-cppyy_method_t cppyy_get_method(cppyy_scope_t handle, int method_index) {
- TFunction* f = type_get_method(handle, method_index);
+cppyy_method_t cppyy_get_method(cppyy_scope_t handle, cppyy_index_t idx) {
+ TFunction* f = type_get_method(handle, idx);
return (cppyy_method_t)f->InterfaceMethod();
}
+cppyy_index_t cppyy_get_global_operator(cppyy_scope_t lc, cppyy_scope_t rc, const char* op) {
+ TClassRef lccr = type_from_handle(lc);
+ if (!lccr.GetClass())
+ return (cppyy_index_t)-1; // (void*)-1 is in kernel space, so invalid as a method handle
+ std::string lcname = lccr->GetName();
+
+ TClassRef rccr = type_from_handle(lc);
+ if (!rccr.GetClass())
+ return (cppyy_index_t)-1;
+ std::string rcname = rccr->GetName();
+
+ std::string opname = "operator";
+ opname += op;
+
+ for (int idx = 0; idx < (int)g_globalfuncs.size(); ++idx) {
+ TFunction* func = &g_globalfuncs[idx];
+ if (func->GetListOfMethodArgs()->GetSize() != 2)
+ continue;
+
+ if (func->GetName() == opname) {
+ if (lcname == resolve_typedef(((TMethodArg*)func->GetListOfMethodArgs()->At(0))->GetTypeName()) &&
+ rcname == resolve_typedef(((TMethodArg*)func->GetListOfMethodArgs()->At(1))->GetTypeName())) {
+ return (cppyy_index_t)func;
+ }
+ }
+ }
+
+ return (cppyy_index_t)-1;
+}
+
/* method properties ----------------------------------------------------- */
-int cppyy_is_constructor(cppyy_type_t handle, int method_index) {
+int cppyy_is_constructor(cppyy_type_t handle, cppyy_index_t idx) {
TClassRef cr = type_from_handle(handle);
- TMethod* m = (TMethod*)cr->GetListOfMethods()->At(method_index);
+ TMethod* m = (TMethod*)cr->GetListOfMethods()->At(idx);
return strcmp(m->GetName(), ((G__ClassInfo*)cr->GetClassInfo())->Name()) == 0;
}
-int cppyy_is_staticmethod(cppyy_type_t handle, int method_index) {
+int cppyy_is_staticmethod(cppyy_type_t handle, cppyy_index_t idx) {
TClassRef cr = type_from_handle(handle);
- TMethod* m = (TMethod*)cr->GetListOfMethods()->At(method_index);
+ TMethod* m = (TMethod*)cr->GetListOfMethods()->At(idx);
return m->Property() & G__BIT_ISSTATIC;
}
@@ -769,13 +811,14 @@
return (cppyy_object_t)new std::string(*(std::string*)ptr);
}
+void cppyy_assign2stdstring(cppyy_object_t ptr, const char* str) {
+ *((std::string*)ptr) = str;
+}
+
void cppyy_free_stdstring(cppyy_object_t ptr) {
delete (std::string*)ptr;
}
-void cppyy_assign2stdstring(cppyy_object_t ptr, const char* str) {
- *((std::string*)ptr) = str;
-}
void* cppyy_load_dictionary(const char* lib_name) {
if (0 <= gSystem->Load(lib_name))
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
@@ -188,7 +188,7 @@
return 0;
}
-cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_type_t handle, int method_index) {
+cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_type_t handle, cppyy_index_t method_index) {
Reflex::Scope s = scope_from_handle(handle);
Reflex::Member m = s.FunctionMemberAt(method_index);
return get_methptr_getter(m);
@@ -332,7 +332,28 @@
return s.FunctionMemberSize();
}
-char* cppyy_method_name(cppyy_scope_t handle, int method_index) {
+cppyy_index_t cppyy_method_index_at(cppyy_scope_t scope, int imeth) {
+ return (cppyy_index_t)imeth;
+}
+
+cppyy_index_t cppyy_method_index_from_name(cppyy_scope_t handle, const char* name) {
+ Reflex::Scope s = scope_from_handle(handle);
+ // the following appears dumb, but the internal storage for Reflex is an
+ // unsorted std::vector anyway, so there's no gain to be had in using the
+ // Scope::FunctionMemberByName() function
+ int num_meth = s.FunctionMemberSize();
+ for (int imeth = 0; imeth < num_meth; ++imeth) {
+ Reflex::Member m = s.FunctionMemberAt(imeth);
+ if (m.Name() == name) {
+ if (m.IsPublic())
+ return (cppyy_index_t)imeth;
+ return (cppyy_index_t)-1;
+ }
+ }
+ return (cppyy_index_t)-1;
+}
+
+char* cppyy_method_name(cppyy_scope_t handle, cppyy_index_t method_index) {
Reflex::Scope s = scope_from_handle(handle);
Reflex::Member m = s.FunctionMemberAt(method_index);
std::string name;
@@ -343,7 +364,7 @@
return cppstring_to_cstring(name);
}
-char* cppyy_method_result_type(cppyy_scope_t handle, int method_index) {
+char* cppyy_method_result_type(cppyy_scope_t handle, cppyy_index_t method_index) {
Reflex::Scope s = scope_from_handle(handle);
Reflex::Member m = s.FunctionMemberAt(method_index);
if (m.IsConstructor())
@@ -353,19 +374,19 @@
return cppstring_to_cstring(name);
}
-int cppyy_method_num_args(cppyy_scope_t handle, int method_index) {
+int cppyy_method_num_args(cppyy_scope_t handle, cppyy_index_t 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_scope_t handle, int method_index) {
+int cppyy_method_req_args(cppyy_scope_t handle, cppyy_index_t 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_scope_t handle, int method_index, int arg_index) {
+char* cppyy_method_arg_type(cppyy_scope_t handle, cppyy_index_t 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);
@@ -373,14 +394,14 @@
return cppstring_to_cstring(name);
}
-char* cppyy_method_arg_default(cppyy_scope_t handle, int method_index, int arg_index) {
+char* cppyy_method_arg_default(cppyy_scope_t handle, cppyy_index_t 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);
}
-char* cppyy_method_signature(cppyy_scope_t handle, int method_index) {
+char* cppyy_method_signature(cppyy_scope_t handle, cppyy_index_t method_index) {
Reflex::Scope s = scope_from_handle(handle);
Reflex::Member m = s.FunctionMemberAt(method_index);
Reflex::Type mt = m.TypeOf();
@@ -398,39 +419,26 @@
return cppstring_to_cstring(sig.str());
}
-int cppyy_method_index(cppyy_scope_t handle, const char* name) {
- Reflex::Scope s = scope_from_handle(handle);
- // the following appears dumb, but the internal storage for Reflex is an
- // unsorted std::vector anyway, so there's no gain to be had in using the
- // Scope::FunctionMemberByName() function
- int num_meth = s.FunctionMemberSize();
- for (int imeth = 0; imeth < num_meth; ++imeth) {
- Reflex::Member m = s.FunctionMemberAt(imeth);
- if (m.Name() == name) {
- if (m.IsPublic())
- return imeth;
- return -1;
- }
- }
- return -1;
-}
-
-cppyy_method_t cppyy_get_method(cppyy_scope_t handle, int method_index) {
+cppyy_method_t cppyy_get_method(cppyy_scope_t handle, cppyy_index_t 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();
}
+cppyy_index_t cppyy_get_global_operator(cppyy_scope_t lc, cppyy_scope_t rc, const char* op) {
+ return (cppyy_index_t)-1; /* not needed yet; covered in pythonify.py */
+}
+
/* method properties ----------------------------------------------------- */
-int cppyy_is_constructor(cppyy_type_t handle, int method_index) {
+int cppyy_is_constructor(cppyy_type_t handle, cppyy_index_t method_index) {
Reflex::Scope s = scope_from_handle(handle);
Reflex::Member m = s.FunctionMemberAt(method_index);
return m.IsConstructor();
}
-int cppyy_is_staticmethod(cppyy_type_t handle, int method_index) {
+int cppyy_is_staticmethod(cppyy_type_t handle, cppyy_index_t method_index) {
Reflex::Scope s = scope_from_handle(handle);
Reflex::Member m = s.FunctionMemberAt(method_index);
return m.IsStatic();
diff --git a/pypy/module/cppyy/test/test_stltypes.py b/pypy/module/cppyy/test/test_stltypes.py
--- a/pypy/module/cppyy/test/test_stltypes.py
+++ b/pypy/module/cppyy/test/test_stltypes.py
@@ -43,16 +43,14 @@
#-----
v = tv1(self.N)
- # TODO: get the following in order
- #assert v.begin().__eq__(v.begin())
- #assert v.begin() == v.begin()
- #assert v.end() == v.end()
- #assert v.begin() != v.end()
- #assert v.end() != v.begin()
+ assert v.begin().__eq__(v.begin())
+ assert v.begin() == v.begin()
+ assert v.end() == v.end()
+ assert v.begin() != v.end()
+ assert v.end() != v.begin()
#-----
for i in range(self.N):
- # TODO:
# v[i] = i
# assert v[i] == i
# assert v.at(i) == i
More information about the pypy-commit
mailing list