[pypy-commit] pypy reflex-support: o) support for virtual base offset calculations in CINT backend
wlav
noreply at buildbot.pypy.org
Tue Aug 30 22:55:39 CEST 2011
Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r46933:369f8794f266
Date: 2011-08-30 12:52 -0700
http://bitbucket.org/pypy/pypy/changeset/369f8794f266/
Log: o) support for virtual base offset calculations in CINT backend o)
some refactoring in Reflex backend
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
@@ -305,19 +305,40 @@
}
int cppyy_is_subtype(cppyy_typehandle_t dh, cppyy_typehandle_t bh) {
- if (dh == bh)
- return 1;
TClassRef crd = type_from_handle(dh);
TClassRef crb = type_from_handle(bh);
return crd->GetBaseClass(crb) != 0;
}
-size_t cppyy_base_offset(cppyy_typehandle_t dh, cppyy_typehandle_t bh, cppyy_object_t) {
- if (dh == bh)
- return 0;
+size_t cppyy_base_offset(cppyy_typehandle_t dh, cppyy_typehandle_t bh, cppyy_object_t address) {
TClassRef crd = type_from_handle(dh);
TClassRef crb = type_from_handle(bh);
- return (size_t)crd->GetBaseClassOffset(crb);
+
+ size_t offset = 0;
+
+ if (crd && crb) {
+ G__ClassInfo* bci = (G__ClassInfo*)crb->GetClassInfo();
+ G__ClassInfo* dci = (G__ClassInfo*)crd->GetClassInfo();
+
+ if (bci && dci) {
+#ifdef WIN32
+ // Windows cannot cast-to-derived for virtual inheritance
+ // with CINT's (or Reflex's) interfaces.
+ long baseprop = dci->IsBase(*bci);
+ if (!baseprop || (baseprop & G__BIT_ISVIRTUALBASE))
+ offset = (size_t)crd->GetBaseClassOffset(crb);
+ else
+#endif
+ offset = G__isanybase(bci->Tagnum(), dci->Tagnum(), (long)address);
+ } else {
+ offset = (size_t)crd->GetBaseClassOffset(crb);
+ }
+ }
+
+ if (offset < 0) // error return of G__isanybase()
+ return 0;
+
+ return offset;
}
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
@@ -43,29 +43,6 @@
return arguments;
}
-static inline size_t base_offset(const Reflex::Type& td, const Reflex::Type& tb, void* address) {
- // 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(
- "__getBasesTable", Reflex::Type(), 0, Reflex::INHERITEDMEMBERS_NO, Reflex::DELAYEDLOAD_OFF);
- if (getbases) {
- typedef std::vector<std::pair<Reflex::Base, int> > Bases_t;
- Bases_t* bases;
- Reflex::Object bases_holder(Reflex::Type::ByTypeInfo(typeid(Bases_t)), &bases);
- getbases.Invoke(&bases_holder);
-
- for (Bases_t::iterator ibase = bases->begin(); ibase != bases->end(); ++ibase) {
- if (ibase->first.ToType() == tb)
- return ibase->first.Offset(address);
- }
-
- // contrary to typical invoke()s, the result of the internal getbases function
- // is a pointer to a function static, so no delete
- }
-
- return 0;
-}
-
/* name to handle --------------------------------------------------------- */
cppyy_typehandle_t cppyy_get_typehandle(const char* class_name) {
@@ -242,19 +219,35 @@
}
int cppyy_is_subtype(cppyy_typehandle_t dh, cppyy_typehandle_t bh) {
- if (dh == bh)
- return 1;
Reflex::Type td = type_from_handle(dh);
Reflex::Type tb = type_from_handle(bh);
return (int)td.HasBase(tb);
}
size_t cppyy_base_offset(cppyy_typehandle_t dh, cppyy_typehandle_t bh, cppyy_object_t address) {
- if (dh == bh)
- return 0;
Reflex::Type td = type_from_handle(dh);
Reflex::Type tb = type_from_handle(bh);
- return (size_t)base_offset(td, tb, (void*)address);
+
+ // 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(
+ "__getBasesTable", Reflex::Type(), 0, Reflex::INHERITEDMEMBERS_NO, Reflex::DELAYEDLOAD_OFF);
+ if (getbases) {
+ typedef std::vector<std::pair<Reflex::Base, int> > Bases_t;
+ Bases_t* bases;
+ Reflex::Object bases_holder(Reflex::Type::ByTypeInfo(typeid(Bases_t)), &bases);
+ getbases.Invoke(&bases_holder);
+
+ for (Bases_t::iterator ibase = bases->begin(); ibase != bases->end(); ++ibase) {
+ if (ibase->first.ToType() == tb)
+ return (size_t)ibase->first.Offset(address);
+ }
+
+ // contrary to typical invoke()s, the result of the internal getbases function
+ // is a pointer to a function static, so no delete
+ }
+
+ return 0;
}
More information about the pypy-commit
mailing list