[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