Author: Wim Lavrijsen <wlavrij...@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; } _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit