From c1c0f1f0bdca08887db217b1cfeab0651fc888c4 Mon Sep 17 00:00:00 2001 From: Axel Naumann <Axel.Naumann@cern.ch> Date: Wed, 16 May 2007 16:40:17 +0000 Subject: [PATCH] Prevent creation of function call stubs for virtual functions that are implemented in the base class. For this to work, this ptrs of derived objects must be adjusted to the non-left-most base class for multiple inheritance. G__funcentry now contains a field holding this offset. G__MethodInfo has new member func GetThisPointerOffset() returning this offset. The bytecode representation of a function call (G__LDFUNC) is extended to store this offset. To prevent the setup of derived classes' functions, a stack of dictionary setup routines needed to be implemented. Inheritance chains now translate to recursive memfunc_setup calls; thus the "stored" globals needed to be converted into a stack (each call has its own "previous" set of globals). git-svn-id: http://root.cern.ch/svn/root/trunk@18805 27541ba8-7e3a-0410-8455-c3a389f83636 --- cint/inc/Method.h | 1 + cint/src/Api.cxx | 17 +- cint/src/CallFunc.cxx | 7 +- cint/src/Method.cxx | 13 + cint/src/bc_exec_asm.h | 18 +- cint/src/bc_inst.cxx | 39 ++- cint/src/bc_inst.h | 3 +- cint/src/common.h | 13 +- cint/src/fproto.h | 2 + cint/src/v6_cast.cxx | 213 ++++++++------ cint/src/v6_func.cxx | 15 +- cint/src/v6_ifunc.cxx | 8 +- cint/src/v6_init.cxx | 9 + cint/src/v6_newlink.cxx | 610 ++++++++++++++++++++++++++++++---------- cint/src/v6_pause.cxx | 2 +- cint/src/v6_pcode.cxx | 6 +- cint/src/v6_scrupto.cxx | 5 +- cint/src/v6_struct.cxx | 9 +- cint/src/v6_var.cxx | 11 +- 19 files changed, 712 insertions(+), 289 deletions(-) diff --git a/cint/inc/Method.h b/cint/inc/Method.h index 819eb7d1695..100b7139e22 100644 --- a/cint/inc/Method.h +++ b/cint/inc/Method.h @@ -98,6 +98,7 @@ G__MethodInfo { void SetUserParam(void*); void *GetUserParam(); + long GetThisPointerOffset(); protected: long handle; diff --git a/cint/src/Api.cxx b/cint/src/Api.cxx index 7db494d8e31..b5b327d4f8c 100644 --- a/cint/src/Api.cxx +++ b/cint/src/Api.cxx @@ -17,7 +17,7 @@ #include "common.h" #include "bc_eh.h" - +#include <string> /********************************************************************* * $xxx object resolution function Generic form @@ -349,11 +349,18 @@ int Cint::G__ExceptionWrapper(G__InterfaceMethod funcp ,struct G__param *libp ,int hash) { + if(!G__catchexception) { - return((*funcp)(result7,funcname,libp,hash)); + + // Stub Calling + return (*funcp)(result7,funcname,libp,hash); + } try { - return((*funcp)(result7,funcname,libp,hash)); + + // Stub Calling + return (*funcp)(result7,funcname,libp,hash); + } catch(G__bc_exception& /* x */) { throw; @@ -413,7 +420,7 @@ int Cint::G__ExceptionWrapper(G__InterfaceMethod funcp G__return = G__RETURN_TRY; G__no_exec = 1; } - catch(string x) { + catch(std::string x) { G__fprinterr(G__serr,"Exception: %s\n",x.c_str()); G__genericerror((char*)NULL); //G__return = G__RETURN_TRY; @@ -426,7 +433,7 @@ int Cint::G__ExceptionWrapper(G__InterfaceMethod funcp } G__genericerror("Error: C++ exception caught"); } - return 0; + return 0; } #endif //////////////////////////////////////////////////////////////////// diff --git a/cint/src/CallFunc.cxx b/cint/src/CallFunc.cxx index 6fe89b3c9fb..1cc57e2d99b 100644 --- a/cint/src/CallFunc.cxx +++ b/cint/src/CallFunc.cxx @@ -396,8 +396,12 @@ G__value Cint::G__CallFunc::Execute(void *pobject) G__LockCriticalSection(); // Set object address store_struct_offset = G__store_struct_offset; - G__store_struct_offset = (long)pobject; + + // This-pointer in case of non left-most multiple inheritance + G__store_struct_offset = (long)pobject + method.GetThisPointerOffset(); + SetFuncType(); + // Call function long index = method.Index(); G__CurrentCall(G__SETMEMFUNCENV, method.ifunc(), &index); @@ -460,5 +464,4 @@ void Cint::G__CallFunc::SetFuncType() { } } } -/////////////////////////////////////////////////////////////////////////// diff --git a/cint/src/Method.cxx b/cint/src/Method.cxx index 3e7e4b48417..f0dac3af15f 100644 --- a/cint/src/Method.cxx +++ b/cint/src/Method.cxx @@ -785,3 +785,16 @@ void *Cint::G__MethodInfo::GetUserParam() } else return 0; } +/////////////////////////////////////////////////////////////////////////// +// GetThisPointerOffset +// Return: Return the this-pointer offset, to adjust it in case of non left-most +// multiple inheritance +/////////////////////////////////////////////////////////////////////////// +long Cint::G__MethodInfo::GetThisPointerOffset() +{ + if (IsValid()) { + struct G__ifunc_table_internal* ifunc_internal = G__get_ifunc_internal((struct G__ifunc_table*)ifunc()); + return ifunc_internal->entry[0].ptradjust; + } + else return 0; +} diff --git a/cint/src/bc_exec_asm.h b/cint/src/bc_exec_asm.h index 0469a0e83db..53d4fbba33b 100644 --- a/cint/src/bc_exec_asm.h +++ b/cint/src/bc_exec_asm.h @@ -603,6 +603,7 @@ long localmem; * 2 hash * 3 paran * 4 (*func)() + * 5 this ptr offset for multiple inheritance * stack * sp-paran+1 <- sp-paran+1 * sp-2 @@ -653,6 +654,9 @@ long localmem; store_step=G__step; G__step=0; } + // This-pointer adjustment in case the multiple inheritance + G__store_struct_offset += G__asm_inst[pc+5]; + #ifdef G__EXCEPTIONWRAPPER G__asm_exec=0; dtorfreeoffset = @@ -661,8 +665,12 @@ long localmem; #else dtorfreeoffset = (*pfunc)(result,funcname,&fpara,G__asm_inst[pc+2]); #endif + + // restore previous G__store_struct_offset + G__store_struct_offset -= G__asm_inst[pc+5]; + if(G__stepover) G__step |= store_step; - pc+=5; + pc+=6; if(result->type) ++sp; if(G__return==G__RETURN_TRY) { if(G__CATCH!=G__dasm(G__serr,1)) { @@ -1390,9 +1398,11 @@ long localmem; G__asm_inst[pc] = G__LD_FUNC; G__asm_inst[pc+1] = (long)(ifunc->pentry[G__asm_index]->bytecode); G__asm_inst[pc+4] = (long)G__exec_bytecode; - G__asm_inst[pc+5] = G__JMP; - G__asm_inst[pc+6] = pc+8; - G__asm_inst[pc+7] = G__NOP; + G__asm_inst[pc+5] = 0; + if (ifunc && ifunc->pentry[G__asm_index]) G__asm_inst[pc+5] = ifunc->pentry[G__asm_index]->ptradjust; + G__asm_inst[pc+6] = G__JMP; + G__asm_inst[pc+7] = pc+8; + //G__asm_inst[pc+7] = G__NOP; goto ld_func; } #endif diff --git a/cint/src/bc_inst.cxx b/cint/src/bc_inst.cxx index 2bd52666c41..01079cbe658 100644 --- a/cint/src/bc_inst.cxx +++ b/cint/src/bc_inst.cxx @@ -42,9 +42,11 @@ extern "C" int G__LD_IFUNC_optimize(struct G__ifunc_table_internal* ifunc,int if G__asm_inst[pc+1] = (long)m.Name(); // preserve hash:2 and paran:3 G__asm_inst[pc+4] = (long)m.InterfaceMethod(); - G__asm_inst[pc+5] = G__JMP; - G__asm_inst[pc+6] = pc+8; - G__asm_inst[pc+7] = G__NOP; + G__asm_inst[pc+5] = 0; + if (ifunc && ifunc->pentry[ifn]) G__asm_inst[pc+5] = ifunc->pentry[ifn]->ptradjust; + G__asm_inst[pc+6] = G__JMP; + G__asm_inst[pc+7] = pc+8; + // G__asm_inst[pc+8] = G__NOP; return(1); } else if(m.Property()&G__BIT_ISBYTECODE) { @@ -55,9 +57,11 @@ extern "C" int G__LD_IFUNC_optimize(struct G__ifunc_table_internal* ifunc,int if G__asm_inst[pc+1] = (long)m.GetBytecode(); // preserve hash:2 and paran:3 G__asm_inst[pc+4] = (long)G__exec_bytecode; - G__asm_inst[pc+5] = G__JMP; - G__asm_inst[pc+6] = pc+8; - G__asm_inst[pc+7] = G__NOP; + G__asm_inst[pc+5] = 0; + if (ifunc && ifunc->pentry[ifn]) G__asm_inst[pc+5] = ifunc->pentry[ifn]->ptradjust; + G__asm_inst[pc+6] = G__JMP; + G__asm_inst[pc+7] = pc+8; + //G__asm_inst[pc+7] = G__NOP; return(1); } return(0); @@ -258,7 +262,7 @@ void G__bc_inst::POP() { /************************************************************************** * LD_FUNC **************************************************************************/ -void G__bc_inst::LD_FUNC(const char* funcname,int hash,int paran,void* pfunc) { +void G__bc_inst::LD_FUNC(const char* funcname,int hash,int paran,void* pfunc, G__ifunc_table_internal* ifunc, int ifn) { #ifdef G__ASM_DBG if(G__asm_dbg) G__fprinterr(G__serr, "%3x: LD_FUNC compiled %s paran=%d\n" @@ -273,10 +277,12 @@ void G__bc_inst::LD_FUNC(const char* funcname,int hash,int paran,void* pfunc) { G__asm_inst[G__asm_cp+2]=hash; G__asm_inst[G__asm_cp+3]=paran; G__asm_inst[G__asm_cp+4]=(long)pfunc; + G__asm_inst[G__asm_cp+5] = 0; + if (ifunc && ifunc->pentry[ifn]) G__asm_inst[G__asm_cp+5] = ifunc->pentry[ifn]->ptradjust; if(G__asm_name_p+strlen(funcname)+1<G__ASM_FUNCNAMEBUF) { strcpy(G__asm_name+G__asm_name_p,funcname); G__asm_name_p += strlen(funcname)+1; - inc_cp_asm(5,0); + inc_cp_asm(6,0); } else { G__abortbytecode(); @@ -292,18 +298,21 @@ void G__bc_inst::LD_FUNC(const char* funcname,int hash,int paran,void* pfunc) { /************************************************************************** * LD_FUNC_BC **************************************************************************/ -void G__bc_inst::LD_FUNC_BC(struct G__ifunc_table* ifunc,int ifn,int paran,void* pfunc) { +void G__bc_inst::LD_FUNC_BC(struct G__ifunc_table* iref,int ifn,int paran,void* pfunc) { + G__ifunc_table_internal* ifunc = G__get_ifunc_internal(iref); #ifdef G__ASM_DBG if(G__asm_dbg) G__fprinterr(G__serr, "%3x: LD_FUNC bytecode %s paran=%d\n" - ,G__asm_cp,G__get_ifunc_internal(ifunc)->funcname[ifn],paran); + ,G__asm_cp,iref->funcname[ifn],paran); #endif G__asm_inst[G__asm_cp]=G__LD_FUNC; G__asm_inst[G__asm_cp+1]=(long)ifunc; G__asm_inst[G__asm_cp+2]= ifn; G__asm_inst[G__asm_cp+3]=paran; G__asm_inst[G__asm_cp+4]=(long)pfunc; - inc_cp_asm(5,0); + G__asm_inst[G__asm_cp+5] = 0; + if (ifunc && ifunc->pentry[ifn]) G__asm_inst[G__asm_cp+5] = ifunc->pentry[ifn]->ptradjust; + inc_cp_asm(6,0); } /************************************************************************** @@ -322,7 +331,9 @@ void G__bc_inst::LD_FUNC_VIRTUAL(struct G__ifunc_table* iref,int ifn,int paran,v +(ifunc->vtblbasetagnum[ifn]*0x10000); G__asm_inst[G__asm_cp+3]=paran; G__asm_inst[G__asm_cp+4]=(long)pfunc; - inc_cp_asm(5,0); + G__asm_inst[G__asm_cp+5] = 0; + if (ifunc && ifunc->pentry[ifn]) G__asm_inst[G__asm_cp+5] = ifunc->pentry[ifn]->ptradjust; + inc_cp_asm(6,0); } /************************************************************************** @@ -712,7 +723,9 @@ void G__bc_inst::LD_IFUNC(struct G__ifunc_table *iref,int ifn,int hash LD_FUNC((char*)(p_ifunc->pentry[ifn]->bytecode) ,hash ,paran - ,(void*)G__exec_bytecode); + ,(void*)G__exec_bytecode, + p_ifunc, + ifn); } else { G__asm_inst[G__asm_cp]=G__LD_IFUNC; diff --git a/cint/src/bc_inst.h b/cint/src/bc_inst.h index 2baefc3759c..986faf63077 100644 --- a/cint/src/bc_inst.h +++ b/cint/src/bc_inst.h @@ -100,7 +100,8 @@ public: int CNDJMP(int addr=0); int JMP(int addr=0); void POP(void); - void LD_FUNC(const char* fname,int hash,int paran,void* pfunc); + void LD_FUNC(const char* fname,int hash,int paran,void* pfunc, + struct G__ifunc_table_internal* ifunc, int ifn); void LD_FUNC_BC(struct G__ifunc_table* ifunc,int ifn,int paran,void *pfunc); void LD_FUNC_VIRTUAL(struct G__ifunc_table* ifunc,int ifn,int paran,void *pfunc); void RETURN(void); diff --git a/cint/src/common.h b/cint/src/common.h index a8b00645201..e2cf7b86eda 100644 --- a/cint/src/common.h +++ b/cint/src/common.h @@ -908,6 +908,10 @@ struct G__funcentry { * (void*)NULL if no function body */ int line_number; /* -1 if no function body or compiled function */ short filenum; /* -1 if compiled function, otherwise interpreted func */ + + // Object Pointer Adjustement to call the stub function (entry) + long ptradjust; + #ifdef G__ASM_FUNC int size; /* size (number of lines) of function */ #endif @@ -954,6 +958,7 @@ struct G__paramfunc { }; struct G__params { #ifdef __cplusplus + G__params() { fparams = 0; } ~G__params() { free((void*)fparams); } struct G__paramfunc* operator[](int idx) { if (!fparams) { @@ -1273,8 +1278,12 @@ struct G__tagtable { struct G__comment_info comment[G__MAXSTRUCT]; - G__incsetup incsetup_memvar[G__MAXSTRUCT]; - G__incsetup incsetup_memfunc[G__MAXSTRUCT]; +#ifdef __cplusplus + + std::list<G__incsetup> *incsetup_memvar[G__MAXSTRUCT]; + std::list<G__incsetup> *incsetup_memfunc[G__MAXSTRUCT]; + +#endif char rootflag[G__MAXSTRUCT]; struct G__RootSpecial *rootspecial[G__MAXSTRUCT]; diff --git a/cint/src/fproto.h b/cint/src/fproto.h index 4f3da6ae713..db40876ba71 100644 --- a/cint/src/fproto.h +++ b/cint/src/fproto.h @@ -57,6 +57,8 @@ int G__matchregex(char *pattern,char *string); #endif void G__castclass(G__value *result3,int tagnum,int castflag,int *ptype,int reftype); G__value G__castvalue(char *casttype,G__value result3); +G__value G__castvalue_bc(char *casttype,G__value result3, int i); + void G__this_adjustment(struct G__ifunc_table_internal *ifunc, int ifn); void G__asm_cast(int type,G__value *buf,int tagnum,int reftype); /* void G__setdebugcond(void); */ int G__findposition(char *string,struct G__input_file view,int *pline,int *pfnum); diff --git a/cint/src/v6_cast.cxx b/cint/src/v6_cast.cxx index 99bf0f65c82..27b78f7be2b 100644 --- a/cint/src/v6_cast.cxx +++ b/cint/src/v6_cast.cxx @@ -145,13 +145,116 @@ unsigned long G__uint_cast(G__value buf) /* used to be int */ } /****************************************************************** -* G__value G__castvalue() +* char *G__asm_cast() * +* Called by +* G__exec_asm() * ******************************************************************/ -G__value G__castvalue(char *casttype,G__value result3) +void G__asm_cast(int type,G__value *buf,int tagnum,int reftype) +{ + switch((char)type) { + case 'd': + if(type!=buf->type) buf->ref = 0; /* questionable */ + G__letdouble(buf,(char)type ,(double)G__double(*buf)); + break; + case 'f': + if(type!=buf->type) buf->ref = 0; /* questionable */ + G__letdouble(buf,(char)type ,(float)G__double(*buf)); + break; + case 'b': + if(type!=buf->type) buf->ref = 0; /* questionable */ + G__letint(buf,(char)type ,(unsigned char)G__int_cast(*buf)); + break; + case 'c': + if(type!=buf->type) buf->ref = 0; /* questionable */ + G__letint(buf,(char)type ,(char)G__int_cast(*buf)); + break; + case 'r': + if(type!=buf->type) buf->ref = 0; /* questionable */ + G__letint(buf,(char)type ,(unsigned short)G__int_cast(*buf)); + break; + case 's': + if(type!=buf->type) buf->ref = 0; /* questionable */ + G__letint(buf,(char)type ,(short)G__int_cast(*buf)); + break; + case 'h': + if(type!=buf->type) buf->ref = 0; /* questionable */ + G__letint(buf,(char)type ,(unsigned int)G__int_cast(*buf)); + break; + case 'i': + if(type!=buf->type) buf->ref = 0; /* questionable */ + G__letint(buf,(char)type ,(int)G__int_cast(*buf)); + break; + case 'k': + if(type!=buf->type) buf->ref = 0; /* questionable */ + G__letint(buf,(char)type ,(unsigned long)G__int_cast(*buf)); + break; + case 'l': + if(type!=buf->type) buf->ref = 0; /* questionable */ + G__letint(buf,(char)type ,(long)G__int_cast(*buf)); + break; + case 'g': + if(type!=buf->type) buf->ref = 0; /* questionable */ + G__letint(buf,(char)type ,(unsigned char)(G__int_cast(*buf)?1:0)); + break; + case 'U': + { + int offset = G__ispublicbase(buf->tagnum,tagnum,buf->obj.i); + if(-1!=offset) buf->obj.i += offset; + } + case 'u': + if(G__PARAREFERENCE==reftype) { + int offset = G__ispublicbase(buf->tagnum,tagnum,buf->obj.i); + if(-1!=offset) { + buf->obj.i += offset; + buf->ref += offset; + } + } + default: + G__letint(buf,(char)type ,G__int(*buf)); + buf->ref = buf->obj.i; + break; + } +} + +} /* extern "C" */ + +/* + * Local Variables: + * c-tab-always-indent:nil + * c-indent-level:2 + * c-continued-statement-offset:2 + * c-brace-offset:-2 + * c-brace-imaginary-offset:0 + * c-argdecl-indent:0 + * c-label-offset:-2 + * compile-command:"make -k" + * End: + */ + +/****************************************************************** +* G__value G__this_adjustment() +* +* +******************************************************************/ +void G__this_adjustment(G__ifunc_table_internal *ifunc, int ifn) { - int lenitem,castflag,type; + + if (ifunc && ifunc->pentry[ifn]) + G__store_struct_offset += ifunc->pentry[ifn]->ptradjust; + +} + +/****************************************************************** +* G__value G__castvalue_bc() +* +* +******************************************************************/ +G__value G__castvalue_bc(char *casttype,G__value result3, int bc) +{ + + int lenitem,castflag,type; int tagnum; long offset; int reftype=G__PARANORMAL; @@ -625,12 +728,17 @@ G__value G__castvalue(char *casttype,G__value result3) G__fprinterr(G__serr,"%3x: CAST to %c\n",G__asm_cp,type); } #endif - G__asm_inst[G__asm_cp]=G__CAST; - G__asm_inst[G__asm_cp+1]=type; - G__asm_inst[G__asm_cp+2]=result3.typenum; - G__asm_inst[G__asm_cp+3]=result3.tagnum; - G__asm_inst[G__asm_cp+4]=reftype; - G__inc_cp_asm(5,0); + + if (bc){ + + G__asm_inst[G__asm_cp]=G__CAST; + G__asm_inst[G__asm_cp+1]=type; + G__asm_inst[G__asm_cp+2]=result3.typenum; + G__asm_inst[G__asm_cp+3]=result3.tagnum; + G__asm_inst[G__asm_cp+4]=reftype; + G__inc_cp_asm(5,0); + + } } #endif /* G__ASM */ @@ -694,94 +802,15 @@ G__value G__castvalue(char *casttype,G__value result3) break; } return(result3); -} +} /****************************************************************** -* char *G__asm_cast() +* G__value G__castvalue() * -* Called by -* G__exec_asm() * ******************************************************************/ -void G__asm_cast(int type,G__value *buf,int tagnum,int reftype) +G__value G__castvalue(char *casttype,G__value result3) { - switch((char)type) { - case 'd': - if(type!=buf->type) buf->ref = 0; /* questionable */ - G__letdouble(buf,(char)type ,(double)G__double(*buf)); - break; - case 'f': - if(type!=buf->type) buf->ref = 0; /* questionable */ - G__letdouble(buf,(char)type ,(float)G__double(*buf)); - break; - case 'b': - if(type!=buf->type) buf->ref = 0; /* questionable */ - G__letint(buf,(char)type ,(unsigned char)G__int_cast(*buf)); - break; - case 'c': - if(type!=buf->type) buf->ref = 0; /* questionable */ - G__letint(buf,(char)type ,(char)G__int_cast(*buf)); - break; - case 'r': - if(type!=buf->type) buf->ref = 0; /* questionable */ - G__letint(buf,(char)type ,(unsigned short)G__int_cast(*buf)); - break; - case 's': - if(type!=buf->type) buf->ref = 0; /* questionable */ - G__letint(buf,(char)type ,(short)G__int_cast(*buf)); - break; - case 'h': - if(type!=buf->type) buf->ref = 0; /* questionable */ - G__letint(buf,(char)type ,(unsigned int)G__int_cast(*buf)); - break; - case 'i': - if(type!=buf->type) buf->ref = 0; /* questionable */ - G__letint(buf,(char)type ,(int)G__int_cast(*buf)); - break; - case 'k': - if(type!=buf->type) buf->ref = 0; /* questionable */ - G__letint(buf,(char)type ,(unsigned long)G__int_cast(*buf)); - break; - case 'l': - if(type!=buf->type) buf->ref = 0; /* questionable */ - G__letint(buf,(char)type ,(long)G__int_cast(*buf)); - break; - case 'g': - if(type!=buf->type) buf->ref = 0; /* questionable */ - G__letint(buf,(char)type ,(unsigned char)(G__int_cast(*buf)?1:0)); - break; - case 'U': - { - int offset = G__ispublicbase(buf->tagnum,tagnum,buf->obj.i); - if(-1!=offset) buf->obj.i += offset; - } - case 'u': - if(G__PARAREFERENCE==reftype) { - int offset = G__ispublicbase(buf->tagnum,tagnum,buf->obj.i); - if(-1!=offset) { - buf->obj.i += offset; - buf->ref += offset; - } - } - default: - G__letint(buf,(char)type ,G__int(*buf)); - buf->ref = buf->obj.i; - break; - } + return G__castvalue_bc(casttype,result3, 1); } - -} /* extern "C" */ - -/* - * Local Variables: - * c-tab-always-indent:nil - * c-indent-level:2 - * c-continued-statement-offset:2 - * c-brace-offset:-2 - * c-brace-imaginary-offset:0 - * c-argdecl-indent:0 - * c-label-offset:-2 - * compile-command:"make -k" - * End: - */ diff --git a/cint/src/v6_func.cxx b/cint/src/v6_func.cxx index ebb6b5a426d..a89ba7f48c9 100644 --- a/cint/src/v6_func.cxx +++ b/cint/src/v6_func.cxx @@ -1491,10 +1491,11 @@ G__value G__getfunction_libp(char *item,char *funcname G__asm_inst[G__asm_cp+2]=hash; G__asm_inst[G__asm_cp+3]=libp->paran; G__asm_inst[G__asm_cp+4]=(long)G__compiled_func; + G__asm_inst[G__asm_cp+5]=0; // cos() doesn't have "this->" if(G__asm_name_p+strlen(funcname)+1<G__ASM_FUNCNAMEBUF) { strcpy(G__asm_name+G__asm_name_p,funcname); G__asm_name_p += strlen(funcname)+1; - G__inc_cp_asm(5,0); + G__inc_cp_asm(6,0); } else { G__abortbytecode(); @@ -1550,10 +1551,11 @@ G__value G__getfunction_libp(char *item,char *funcname G__asm_inst[G__asm_cp+2]=hash; G__asm_inst[G__asm_cp+3]=libp->paran; G__asm_inst[G__asm_cp+4]=(long)G__library_func; + G__asm_inst[G__asm_cp+5]=0; if(G__asm_name_p+strlen(funcname)+1<G__ASM_FUNCNAMEBUF) { strcpy(G__asm_name+G__asm_name_p,funcname); G__asm_name_p += strlen(funcname)+1; - G__inc_cp_asm(5,0); + G__inc_cp_asm(6,0); } else { G__abortbytecode(); @@ -2879,10 +2881,11 @@ G__value G__getfunction(char *item,int *known3,int memfunc_flag) G__asm_inst[G__asm_cp+2]=hash; G__asm_inst[G__asm_cp+3]=fpara.paran; G__asm_inst[G__asm_cp+4]=(long)G__compiled_func; + G__asm_inst[G__asm_cp+5]=0; if(G__asm_name_p+strlen(funcname)+1<G__ASM_FUNCNAMEBUF) { strcpy(G__asm_name+G__asm_name_p,funcname); G__asm_name_p += strlen(funcname)+1; - G__inc_cp_asm(5,0); + G__inc_cp_asm(6,0); } else { G__abortbytecode(); @@ -2938,10 +2941,11 @@ G__value G__getfunction(char *item,int *known3,int memfunc_flag) G__asm_inst[G__asm_cp+2]=hash; G__asm_inst[G__asm_cp+3]=fpara.paran; G__asm_inst[G__asm_cp+4]=(long)G__library_func; + G__asm_inst[G__asm_cp+5]=0; if(G__asm_name_p+strlen(funcname)+1<G__ASM_FUNCNAMEBUF) { strcpy(G__asm_name+G__asm_name_p,funcname); G__asm_name_p += strlen(funcname)+1; - G__inc_cp_asm(5,0); + G__inc_cp_asm(6,0); } else { G__abortbytecode(); @@ -3485,10 +3489,11 @@ int G__special_func(G__value *result7,char *funcname,G__param *libp,int hash) G__asm_inst[G__asm_cp+2]=hash; G__asm_inst[G__asm_cp+3]=1; G__asm_inst[G__asm_cp+4]=(long)G__special_func; + G__asm_inst[G__asm_cp+5]=0; if(G__asm_name_p+strlen(funcname)+1<G__ASM_FUNCNAMEBUF) { strcpy(G__asm_name+G__asm_name_p,funcname); G__asm_name_p += strlen(funcname)+1; - G__inc_cp_asm(5,0); + G__inc_cp_asm(6,0); } else { G__abortbytecode(); diff --git a/cint/src/v6_ifunc.cxx b/cint/src/v6_ifunc.cxx index 5f5b8b32bf6..cfaac822742 100644 --- a/cint/src/v6_ifunc.cxx +++ b/cint/src/v6_ifunc.cxx @@ -5247,7 +5247,9 @@ asm_ifunc_start: /* loop compilation execution label */ +(p_ifunc->vtblbasetagnum[ifn]*0x10000); G__asm_inst[G__asm_cp+3]=libp->paran; G__asm_inst[G__asm_cp+4]=(long)G__bc_exec_virtual_bytecode; - G__inc_cp_asm(5,0); + G__asm_inst[G__asm_cp+5] = 0; + if (ifunc && p_ifunc->pentry[ifn]) G__asm_inst[G__asm_cp+5] = p_ifunc->pentry[ifn]->ptradjust; + G__inc_cp_asm(6,0); } else { #ifdef G__ASM_DBG @@ -5267,7 +5269,9 @@ asm_ifunc_start: /* loop compilation execution label */ else { G__asm_inst[G__asm_cp+4]=(long)G__bc_exec_normal_bytecode; } - G__inc_cp_asm(5,0); + G__asm_inst[G__asm_cp+5] = 0; + if (ifunc && p_ifunc->pentry[ifn]) G__asm_inst[G__asm_cp+5] = p_ifunc->pentry[ifn]->ptradjust; + G__inc_cp_asm(6,0); } } else { diff --git a/cint/src/v6_init.cxx b/cint/src/v6_init.cxx index 1d453046200..17d3007b3ed 100644 --- a/cint/src/v6_init.cxx +++ b/cint/src/v6_init.cxx @@ -48,6 +48,7 @@ typedef struct { static G__setup_func_struct **G__setup_func_list; static int G__max_libs; static int G__nlibs; +static char G__memsetup_init; typedef void G__parse_hook_t (); static G__parse_hook_t* G__afterparse_hook; static G__parse_hook_t* G__beforeparse_hook; @@ -64,6 +65,14 @@ void G__add_setup_func(const char *libname,G__incsetup func) { int i, islot = -1; + if (!G__memsetup_init){ + for (int i = 0; i < G__MAXSTRUCT; i++){ + G__struct.incsetup_memvar[i] = new std::list<G__incsetup>(); + G__struct.incsetup_memfunc[i] = new std::list<G__incsetup>(); + G__memsetup_init=1; + } + } + if (!G__setup_func_list) { G__max_libs = 10; G__setup_func_list = (G__setup_func_struct**)calloc(G__max_libs,sizeof(G__setup_func_struct*)); diff --git a/cint/src/v6_newlink.cxx b/cint/src/v6_newlink.cxx index ff38d131947..1471d9934d8 100644 --- a/cint/src/v6_newlink.cxx +++ b/cint/src/v6_newlink.cxx @@ -20,6 +20,7 @@ #include "common.h" #include "dllrev.h" #include "Api.h" +#include <stack> #ifndef G__TESTMAIN #include <sys/stat.h> #endif @@ -132,30 +133,60 @@ static int G__privateaccess = 0; /************************************************************************** -* Following static variables must be protected by semaphoe for +* Following static variables must be protected by semaphore for * multi-threading. **************************************************************************/ -static struct G__ifunc_table_internal *G__incset_p_ifunc; -static int G__incset_tagnum; -static int G__incset_func_now; -static int G__incset_func_page; -static struct G__var_array *G__incset_p_local; -static int G__incset_def_struct_member; -static int G__incset_tagdefining; -static int G__incset_def_tagnum; -static long G__incset_globalvarpointer; -static int G__incset_var_type; -static int G__incset_typenum; -static int G__incset_static_alloc; -static int G__incset_access; -static int G__suppress_methods = 0; -static int G__nestedclass = 0; -static int G__nestedtypedef = 0; -static int G__store_asm_noverflow; -static int G__store_no_exec_compile; -static int G__store_asm_exec; -static int G__extra_inc_n = 0; -static char** G__extra_include = 0; /* [G__MAXFILENAME] = NULL; */ +// Class to store several variables +// Due to recursion problems these variables are not global anymore + class G__IncSetupStack { + + public: + + struct G__ifunc_table_internal *G__incset_p_ifunc; + int G__incset_tagnum; + int G__incset_func_now; + int G__incset_func_page; + struct G__var_array *G__incset_p_local; + int G__incset_def_struct_member; + int G__incset_tagdefining; + int G__incset_def_tagnum; + long G__incset_globalvarpointer; + int G__incset_var_type; + int G__incset_typenum; + int G__incset_static_alloc; + int G__incset_access; + + }; + +/************************************************************************** +* G__stack_instance +* Several problems in the mefunc_setup recursive calling, due to global variables using, +* was introduced. Now a stack stores the variables (G__IncSetupStack class) +* Each memfunc_setup call will have its own copy of the variables in the stack +* RETURN: This function return a pointer to the static variable stack +**************************************************************************/ + std::stack<G__IncSetupStack>* G__stack_instance(){ + + // Variables Stack + static std::stack<G__IncSetupStack>* G__stack = 0; + + // If the stack has not been initialized yet + if (G__stack==0) + G__stack = new std::stack<G__IncSetupStack>(); + + return G__stack; + + } + + // Supress Stub Functions + static int G__suppress_methods = 0; + static int G__nestedclass = 0; + static int G__nestedtypedef = 0; + static int G__store_asm_noverflow; + static int G__store_no_exec_compile; + static int G__store_asm_exec; + static int G__extra_inc_n = 0; + static char** G__extra_include = 0; /* [G__MAXFILENAME] = NULL; */ /************************************************************************** * G__CurrentCall @@ -377,6 +408,7 @@ int G__call_cppfunc(G__value *result7,G__param *libp,G__ifunc_table_internal *if cppfunc = (G__InterfaceMethod)ifunc->pentry[ifn]->p; + #ifdef G__ASM if(G__asm_noverflow) { /**************************************** @@ -393,7 +425,9 @@ int G__call_cppfunc(G__value *result7,G__param *libp,G__ifunc_table_internal *if G__asm_inst[G__asm_cp+2]= ifn; G__asm_inst[G__asm_cp+3]=libp->paran; G__asm_inst[G__asm_cp+4]=(long)cppfunc; - G__inc_cp_asm(5,0); + G__asm_inst[G__asm_cp+5] = 0; + if (ifunc && ifunc->pentry[ifn]) G__asm_inst[G__asm_cp+5] = ifunc->pentry[ifn]->ptradjust; + G__inc_cp_asm(6,0); } else { #ifdef G__ASM_DBG @@ -406,7 +440,9 @@ int G__call_cppfunc(G__value *result7,G__param *libp,G__ifunc_table_internal *if G__asm_inst[G__asm_cp+2]= - ifunc->type[ifn]; G__asm_inst[G__asm_cp+3]=libp->paran; G__asm_inst[G__asm_cp+4]=(long)cppfunc; - G__inc_cp_asm(5,0); + G__asm_inst[G__asm_cp+5] = 0; + if (ifunc && ifunc->pentry[ifn]) G__asm_inst[G__asm_cp+5] = ifunc->pentry[ifn]->ptradjust; + G__inc_cp_asm(6,0); } } #endif /* of G__ASM */ @@ -462,11 +498,27 @@ int G__call_cppfunc(G__value *result7,G__param *libp,G__ifunc_table_internal *if long lifn = ifn; G__CurrentCall(G__SETMEMFUNCENV, ifunc, &lifn); + + // We store the this-pointer + long save_offset = G__store_struct_offset; + + // this-pointer adjustment + G__this_adjustment(ifunc, ifn); + #ifdef G__EXCEPTIONWRAPPER + G__ExceptionWrapper((G__InterfaceMethod)cppfunc,result7,(char*)ifunc,libp,ifn); + #else + + // Stub calling (*cppfunc)(result7,(char*)ifunc,libp,ifn); + #endif + + // This-pointer restoring + G__store_struct_offset = save_offset; + G__CurrentCall(G__NOP, 0, 0); result = 1; @@ -709,6 +761,8 @@ void G__gen_cpplink() fprintf(hfp,"\n#ifndef G__MEMFUNCBODY\n"); + // Member Function Interface Method Ej: G__G__Hist_95_0_2() + // Stub Functions if (!G__suppress_methods) { G__cppif_memfunc(fp,hfp); } @@ -2849,14 +2903,14 @@ static void G__x8664_vararg_epilog(FILE *fp, int ifn, G__ifunc_table_internal *i break; case 'u': switch (G__struct.type[tagnum]) { - case 'c': - case 's': - case 'u': + case 'c': + case 's': + case 'u': typestring = G__type2string(type, tagnum, typenum, 0, 0); if (reftype) { fprintf(fp, "(%s&) u[0].lval", typestring); } else { - if (G__globalcomp == G__CPPLINK) { + if (G__globalcomp == G__CPPLINK) { fprintf(fp, "*(%s*) u[0].lval", typestring); } else { fprintf(fp, "(%s*) u[0].lval", typestring); @@ -3990,12 +4044,65 @@ void G__cppif_gendefault(FILE *fp, FILE* /*hfp*/, int tagnum, #endif // G__SMALLOBJECT } + +/************************************************************************** +* G__method_inbase() +* This function search for the method ifn (index in ifunc) in the ifunc->tagnum's +* base classes +* RETURN -> NULL Method not found +* NOT NULL Method Found. Method's ifunc table pointer +**************************************************************************/ + +G__ifunc_table_internal* G__method_inbase(int ifn, G__ifunc_table_internal *ifunc) +{ + + // tagnum's Base Classes structure + G__inheritance* cbases = G__struct.baseclass[ifunc->tagnum]; + + // if Method 'ifn' exists in any Base Class -> base not null + G__ifunc_table_internal* found = 0; + + int base=0; + + // If there are still base classes + if (cbases){ + + // Go through the base tagnums (tagnum = index in G__struct structure) + for (int idx=0; idx < cbases->basen; ++idx){ + + // Current tagnum + int basetagnum=cbases->herit[idx]->basetagnum; + + // Current tagnum's ifunc table + G__ifunc_table_internal * ifunct = G__struct.memfunc[basetagnum]; + + // Continue if there are still ifuncs and the method 'ifn' is not found yet + while(ifunct&&!found){ + + // Does the Method 'ifn' (in ifunc) exist in the current ifunct? + found = G__ifunc_exist(ifunc, ifn, ifunct, &base, 0xffff); + + // Next ifunct + ifunct=ifunct->next; + } + } + } + + return found; +} + /************************************************************************** * G__cppif_genfunc() * **************************************************************************/ void G__cppif_genfunc(FILE *fp, FILE * /* hfp */, int tagnum, int ifn, G__ifunc_table_internal *ifunc) { + + // If the virtual method 'ifn' (in ifunc) exists in any Base Clase then we have + // an overridden virtual method,so the stub function for it is not generated + if ((ifunc->isvirtual[ifn])&&(G__method_inbase(ifn, ifunc))) + return; + #ifndef G__SMALLOBJECT int k, m; @@ -4322,18 +4429,18 @@ int G__cppif_returntype(FILE *fp, int ifn, G__ifunc_table_internal *ifunc, char switch (type) { case 'd': case 'f': - sprintf(endoffunc, ";\n%s result7->ref = (long) (&obj);\n%s result7->obj.d = (double) (obj);\n%s}", indent, indent, indent); - break; + sprintf(endoffunc, ";\n%s result7->ref = (long) (&obj);\n%s result7->obj.d = (double) (obj);\n%s}", indent, indent, indent); + break; case 'u': - if (G__struct.type[tagnum] == 'e') { - sprintf(endoffunc, ";\n%s result7->ref = (long) (&obj);\n%s result7->obj.i = (long) (obj);\n%s}", indent, indent, indent); + if (G__struct.type[tagnum] == 'e') { + sprintf(endoffunc, ";\n%s result7->ref = (long) (&obj);\n%s result7->obj.i = (long) (obj);\n%s}", indent, indent, indent); } else { - sprintf(endoffunc, ";\n%s result7->ref = (long) (&obj);\n%s result7->obj.i = (long) (&obj);\n%s}", indent, indent, indent); + sprintf(endoffunc, ";\n%s result7->ref = (long) (&obj);\n%s result7->obj.i = (long) (&obj);\n%s}", indent, indent, indent); } - break; + break; default: - sprintf(endoffunc, ";\n%s result7->ref = (long) (&obj);\n%s result7->obj.i = (long) (obj);\n%s}", indent, indent, indent); - break; + sprintf(endoffunc, ";\n%s result7->ref = (long) (&obj);\n%s result7->obj.i = (long) (obj);\n%s}", indent, indent, indent); + break; } return 0; } @@ -5651,7 +5758,20 @@ void G__cpplink_memfunc(FILE *fp) (G__PRIVATEACCESS&G__struct.protectedaccess[i])) && '~'!=ifunc->funcname[j][0]) ) { - fprintf(fp, "%s, ", G__map_cpp_funcname(i, ifunc->funcname[j], j, ifunc->page)); + + // If the method is virtual. Is it overridden? -> Does it exist in the base classes? + // Virtual method found in the base classes(we have an overridden virtual method)so it + // has not stub function in its dictionary + if ((ifunc->isvirtual[j])&&(G__method_inbase(j, ifunc))) + + // Null Stub Pointer + fprintf(fp, "(G__InterfaceMethod) NULL," ); + + else + // If the method isn't virtual or it belongs to a base class. + // The method has its own Stub Function in its dictionary + // Normal Stub Pointer + fprintf(fp, "%s, ", G__map_cpp_funcname(i, ifunc->funcname[j], j, ifunc->page)); } else { fprintf(fp, "(G__InterfaceMethod) NULL, "); @@ -6424,6 +6544,19 @@ void G__cpplink_func(FILE *fp) ************************************************************************** **************************************************************************/ +char G__incsetup_exist(std::list<G__incsetup> *incsetuplist, G__incsetup incsetup) +{ + + std::list<G__incsetup>::iterator iter; + if(incsetuplist->size()) + for (iter=incsetuplist->begin(); iter != incsetuplist->end(); ++iter) + if (*iter==incsetup) + return 1; + + return 0; +} + + /************************************************************************** * G__tagtable_setup() * @@ -6447,20 +6580,16 @@ int G__tagtable_setup(int tagnum,int size,int cpplink,int isabstract,const char && 'n'!=G__struct.type[tagnum] ) { #ifndef G__OLDIMPLEMENTATION1656 - if(G__struct.incsetup_memvar[tagnum]) - (*G__struct.incsetup_memvar[tagnum])(); - if(G__struct.incsetup_memfunc[tagnum]) - (*G__struct.incsetup_memfunc[tagnum])(); - if(G__struct.incsetup_memvar[tagnum] != setup_memvar) - G__struct.incsetup_memvar[tagnum] = setup_memvar; - else - G__struct.incsetup_memvar[tagnum] = (G__incsetup)NULL; + char found = G__incsetup_exist(G__struct.incsetup_memvar[tagnum],setup_memvar); + // If setup_memvar is not NULL we push the G__setup_memvarXXX pointer into the list + if (setup_memvar&&!found) + G__struct.incsetup_memvar[tagnum]->push_back(setup_memvar); - if(G__struct.incsetup_memfunc[tagnum] != setup_memfunc) - G__struct.incsetup_memfunc[tagnum] = setup_memfunc; - else - G__struct.incsetup_memfunc[tagnum] = (G__incsetup)NULL; + found = G__incsetup_exist(G__struct.incsetup_memfunc[tagnum],setup_memfunc); + // If setup_memfunc is not NULL we push the G__setup_memfuncXXX pointer into the list + if (setup_memfunc&&!found) + G__struct.incsetup_memfunc[tagnum]->push_back(setup_memfunc); #endif /* 1656 */ if(G__asm_dbg ) { @@ -6486,15 +6615,17 @@ int G__tagtable_setup(int tagnum,int size,int cpplink,int isabstract,const char G__struct.comment[tagnum].p.com = (char*)comment; if(comment) G__struct.comment[tagnum].filenum = -2; else G__struct.comment[tagnum].filenum = -1; - if(G__struct.incsetup_memvar[tagnum]) - (*G__struct.incsetup_memvar[tagnum])(); - if(G__struct.incsetup_memfunc[tagnum]) - (*G__struct.incsetup_memfunc[tagnum])(); - if(0==G__struct.memvar[tagnum]->allvar - || 'n'==G__struct.type[tagnum]) - G__struct.incsetup_memvar[tagnum] = setup_memvar; - else - G__struct.incsetup_memvar[tagnum] = 0; + + if(0==G__struct.memvar[tagnum]->allvar + || 'n'==G__struct.type[tagnum]){ + char found = G__incsetup_exist(G__struct.incsetup_memvar[tagnum],setup_memvar); + // If setup_memvar is not NULL we push the G__setup_memvarXXX pointer into the list + if (setup_memvar&&!found) + G__struct.incsetup_memvar[tagnum]->push_back(setup_memvar); + } + else + G__struct.incsetup_memvar[tagnum]->clear(); + if( #ifndef G__OLDIMPLEMENTATION2027 1==G__struct.memfunc[tagnum]->allifunc @@ -6508,11 +6639,14 @@ int G__tagtable_setup(int tagnum,int size,int cpplink,int isabstract,const char #else -1!=G__struct.memfunc[tagnum]->pentry[0]->size #endif - && 2>=G__struct.memfunc[tagnum]->allifunc)) - G__struct.incsetup_memfunc[tagnum] = setup_memfunc; - else - G__struct.incsetup_memfunc[tagnum] = 0; - + && 2>=G__struct.memfunc[tagnum]->allifunc)){ + char found = 0; + found = G__incsetup_exist(G__struct.incsetup_memfunc[tagnum], setup_memfunc); + if (setup_memfunc&&!found) + G__struct.incsetup_memfunc[tagnum]->push_back(setup_memfunc); + else + G__struct.incsetup_memfunc[tagnum]->clear(); + } /* add template names */ #ifndef G__OLDIMPLEMENTATION1823 if(strlen(G__struct.name[tagnum])>G__BUFLEN-10) { @@ -6575,24 +6709,34 @@ int G__inheritance_setup(int tagnum,int basetagnum **************************************************************************/ int G__tag_memvar_setup(int tagnum) { + #ifndef G__OLDIMPLEMENTATON285 - G__incset_tagnum = G__tagnum; - G__incset_p_local = G__p_local; - G__incset_def_struct_member = G__def_struct_member; - G__incset_tagdefining = G__tagdefining; - G__incset_globalvarpointer = G__globalvarpointer ; - G__incset_var_type = G__var_type ; - G__incset_typenum = G__typenum ; - G__incset_static_alloc = G__static_alloc ; - G__incset_access = G__access ; + + /* Variables stack storing */ + G__IncSetupStack incsetup_stack; + std::stack<G__IncSetupStack> *var_stack = G__stack_instance(); + + incsetup_stack.G__incset_tagnum = G__tagnum; + incsetup_stack.G__incset_p_local = G__p_local; + incsetup_stack.G__incset_def_struct_member = G__def_struct_member; + incsetup_stack.G__incset_tagdefining = G__tagdefining; + incsetup_stack.G__incset_globalvarpointer = G__globalvarpointer; + incsetup_stack.G__incset_var_type = G__var_type ; + incsetup_stack.G__incset_typenum = G__typenum ; + incsetup_stack.G__incset_static_alloc = G__static_alloc ; + incsetup_stack.G__incset_access = G__access ; + #endif - G__tagnum = tagnum; - G__p_local=G__struct.memvar[G__tagnum]; - G__def_struct_member = 1; - G__incset_def_tagnum = G__def_tagnum; - G__def_tagnum = G__struct.parent_tagnum[G__tagnum]; - G__tagdefining=G__tagnum; - return(0); + G__tagnum = tagnum; + G__p_local=G__struct.memvar[G__tagnum]; + G__def_struct_member = 1; + incsetup_stack.G__incset_def_tagnum = G__def_tagnum; + G__def_tagnum = G__struct.parent_tagnum[G__tagnum]; + G__tagdefining=G__tagnum; + + var_stack->push(incsetup_stack); + + return(0); } /************************************************************************** @@ -6660,18 +6804,28 @@ int G__memvar_setup(void *p,int type **************************************************************************/ int G__tag_memvar_reset() { - G__p_local = G__incset_p_local ; - G__def_struct_member = G__incset_def_struct_member ; - G__tagdefining = G__incset_tagdefining ; - G__def_tagnum = G__incset_def_tagnum; - - G__globalvarpointer = G__incset_globalvarpointer ; - G__var_type = G__incset_var_type ; - G__tagnum = G__incset_tagnum ; - G__typenum = G__incset_typenum ; - G__static_alloc = G__incset_static_alloc ; - G__access = G__incset_access ; + + /* Variables stack restoring */ + std::stack<G__IncSetupStack> *var_stack = G__stack_instance(); + + G__IncSetupStack *incsetup_stack = &var_stack->top(); + + G__p_local = incsetup_stack->G__incset_p_local ; + G__def_struct_member = incsetup_stack->G__incset_def_struct_member ; + G__tagdefining = incsetup_stack->G__incset_tagdefining ; + G__def_tagnum = incsetup_stack->G__incset_def_tagnum; + + G__globalvarpointer = incsetup_stack->G__incset_globalvarpointer ; + G__var_type = incsetup_stack->G__incset_var_type ; + G__tagnum = incsetup_stack->G__incset_tagnum ; + G__typenum = incsetup_stack->G__incset_typenum ; + G__static_alloc = incsetup_stack->G__incset_static_alloc ; + G__access = incsetup_stack->G__incset_access ; + + var_stack->pop(); + return(0); + } /************************************************************************** @@ -6704,13 +6858,21 @@ int G__usermemfunc_setup(char *funcname,int hash,int (*funcp)(),int type, **************************************************************************/ int G__tag_memfunc_setup(int tagnum) { - G__incset_tagnum = G__tagnum; - G__incset_p_ifunc = G__p_ifunc; - G__incset_func_now = G__func_now; - G__incset_func_page = G__func_page; - G__incset_var_type = G__var_type; - G__incset_tagdefining = G__tagdefining; - G__incset_def_tagnum = G__def_tagnum; + + /* Variables stack storing */ + G__IncSetupStack incsetup_stack; + std::stack<G__IncSetupStack>* var_stack = G__stack_instance(); + + incsetup_stack.G__incset_p_ifunc = G__p_ifunc; + incsetup_stack.G__incset_tagnum = G__tagnum; + incsetup_stack.G__incset_func_now = G__func_now; + incsetup_stack.G__incset_func_page = G__func_page; + incsetup_stack.G__incset_tagdefining = G__tagdefining; + incsetup_stack.G__incset_var_type = G__var_type; + incsetup_stack.G__incset_def_tagnum = G__def_tagnum; + + var_stack->push(incsetup_stack); + G__tagdefining = G__struct.parent_tagnum[tagnum]; G__def_tagnum = G__tagdefining; G__tagnum = tagnum; @@ -6764,9 +6926,6 @@ int G__memfunc_setup(const char *funcname,int hash,G__InterfaceMethod funcp G__savestring(&G__p_ifunc->funcname[G__func_now],(char*)funcname); G__p_ifunc->hash[G__func_now] = hash; - /* set entry pointer */ - G__p_ifunc->pentry[G__func_now] = &G__p_ifunc->entry[G__func_now]; - G__p_ifunc->entry[G__func_now].p=(void*)funcp; #ifndef G__OLDIMLEMENTATION2012 if(-1!=G__p_ifunc->tagnum) G__p_ifunc->entry[G__func_now].filenum=G__struct.filenum[G__p_ifunc->tagnum]; @@ -6780,7 +6939,8 @@ int G__memfunc_setup(const char *funcname,int hash,G__InterfaceMethod funcp G__p_ifunc->entry[G__func_now].bytecode = (struct G__bytecodefunc*)NULL; #endif #ifdef G__TRUEP2F - if(truep2f) G__p_ifunc->entry[G__func_now].tp2f=truep2f; + if(truep2f) + G__p_ifunc->entry[G__func_now].tp2f=truep2f; else G__p_ifunc->entry[G__func_now].tp2f=(void*)funcp; #endif @@ -6824,6 +6984,88 @@ int G__memfunc_setup(const char *funcname,int hash,G__InterfaceMethod funcp /* end */ + /* set entry pointer */ + G__p_ifunc->pentry[G__func_now] = &G__p_ifunc->entry[G__func_now]; + G__p_ifunc->entry[G__func_now].p=(void*)funcp; + + /* Stub Pointer Adjustement */ + G__p_ifunc->entry[G__func_now].ptradjust = 0; + + // Stub Pointer initialisation. + // If funcp parameter is null. It means that the stub is in a base class. + // We have to look for the stub pointer in the base classes. + if (!funcp&&(G__p_ifunc->isvirtual[G__func_now])){ + + // tagnum's Base Classes structure + G__inheritance* cbases = G__struct.baseclass[G__p_ifunc->tagnum]; + + // If there's any base class + if (cbases){ + + // Ifunc Method's index in the base class + int base = 0; + + // if Method 'ifn' exists in any Base Class -> base not null + G__ifunc_table_internal* found = 0; + + // Stub function pointer + void * basefuncp = 0; + + // Go through the bases tagnums if there are base classes and a valid stub is not found yet + for (int idx=0; (idx < cbases->basen)&&(!basefuncp); ++idx){ + + // Current tagnum + int basetagnum=cbases->herit[idx]->basetagnum; + + // Warning: Global G__p_ifunc is modified in G__incsetup_memfunc + // We save and later we restore the G__p_ifunc's value + G__ifunc_table_internal* store_ifunc = G__p_ifunc; + + // We force memfunc_setup for the base classes + G__incsetup_memfunc(basetagnum); + + // Restore G__p_ifunc + G__p_ifunc = store_ifunc; + + // Current Base Class ifunc table + G__ifunc_table_internal* ifunct = G__struct.memfunc[basetagnum]; + + // Look for the method in the base class + found = G__ifunc_exist(G__p_ifunc, G__func_now, ifunct, &base, 0xffff); + + // Method found + if(found){ + + // Method's stub pointer + basefuncp = found->entry[base].p; + + G__value ptr; + + ptr.tagnum = G__p_ifunc->tagnum; + ptr.type = 'C'; + ptr.typenum = -1; + ptr.obj.i = 0; + + ptr = G__castvalue_bc(G__fulltagname(found->tagnum, 0),ptr, 0); + + // Pointer Adjustement + G__p_ifunc->entry[G__func_now].ptradjust = found->entry[base].ptradjust + ptr.obj.i; + + // Method's stub pointer found. + // We update the current method stub pointer + G__p_ifunc->entry[G__func_now].p= (void *) basefuncp; + + if(truep2f) + G__p_ifunc->entry[G__func_now].tp2f=truep2f; + else G__p_ifunc->entry[G__func_now].tp2f=(void*) basefuncp; + + } + + } + + } + + } #ifndef G__OLDIMPLEMENTATION1702 { struct G__ifunc_table_internal *ifunc; @@ -7168,13 +7410,20 @@ int G__memfunc_next() **************************************************************************/ int G__tag_memfunc_reset() { - G__tagnum = G__incset_tagnum; - G__p_ifunc = G__incset_p_ifunc; - G__func_now = G__incset_func_now; - G__func_page = G__incset_func_page; - G__var_type = G__incset_var_type; - G__tagdefining = G__incset_tagdefining; - G__def_tagnum = G__incset_def_tagnum; + /* Variables stack restoring */ + std::stack<G__IncSetupStack> *var_stack = G__stack_instance(); + G__IncSetupStack *incsetup_stack = &var_stack->top(); + + G__tagnum = incsetup_stack->G__incset_tagnum; + G__p_ifunc = incsetup_stack->G__incset_p_ifunc; + G__func_now = incsetup_stack->G__incset_func_now; + G__func_page = incsetup_stack->G__incset_func_page; + G__var_type = incsetup_stack->G__incset_var_type; + G__tagdefining = incsetup_stack->G__incset_tagdefining; + G__def_tagnum = incsetup_stack->G__incset_def_tagnum; + + var_stack->pop(); + return(0); } #ifdef G__NEVER @@ -7376,7 +7625,6 @@ void G__specify_link(int link_stub) char *p; int done=0; - /* Get link language interface */ c = G__fgetname_template(buf,";\n\r"); @@ -8440,7 +8688,7 @@ void G__incsetup_memvar(int tagnum) char store_var_type; int store_static_alloc = G__static_alloc; int store_constvar = G__constvar; - if(G__struct.incsetup_memvar[tagnum]) { + if(G__struct.incsetup_memvar[tagnum]->size()) { store_asm_exec = G__asm_exec; G__asm_exec=0; store_var_type = G__var_type; @@ -8460,12 +8708,26 @@ void G__incsetup_memvar(int tagnum) #ifdef G__OLDIMPLEMENTATION1125_YET if(0==G__struct.memvar[tagnum]->allvar - || 'n'==G__struct.type[tagnum]) - (*G__struct.incsetup_memvar[tagnum])(); + || 'n'==G__struct.type[tagnum]){ + + // G__setup_memvarXXX execution + std::list<G__incsetup>::iterator iter; + if(G__struct.incsetup_memvar[tagnum]->size()) + for (iter=G__struct.incsetup_memvar[tagnum]->begin(); iter != G__struct.incsetup_memvar[tagnum]->end(); iter ++) + (*iter)(); + } + #else - (*G__struct.incsetup_memvar[tagnum])(); + + // G__setup_memvarXXX execution + std::list<G__incsetup>::iterator iter; + if(G__struct.incsetup_memvar[tagnum]->size()) + for (iter=G__struct.incsetup_memvar[tagnum]->begin(); iter != G__struct.incsetup_memvar[tagnum]->end(); iter ++) + (*iter)(); #endif - G__struct.incsetup_memvar[tagnum] = (G__incsetup)NULL; + // The G__setup_memvarXXX functions have been executed. We don't need the pointers anymore. We clean the list + G__struct.incsetup_memvar[tagnum]->clear(); + #ifdef G__DEBUG if(G__var_type!=store_var_type) G__fprinterr(G__serr,"Cint internal error: G__incsetup_memvar %c %c\n" @@ -8487,7 +8749,7 @@ void G__incsetup_memfunc(int tagnum) { char store_var_type; int store_asm_exec; - if(G__struct.incsetup_memfunc[tagnum]) { + if(G__struct.incsetup_memfunc[tagnum]->size()) { store_asm_exec = G__asm_exec; G__asm_exec=0; store_var_type = G__var_type; @@ -8509,18 +8771,35 @@ void G__incsetup_memfunc(int tagnum) || 'n'==G__struct.type[tagnum] || ( -1!=G__struct.memfunc[tagnum]->pentry[0]->size - && 2>=G__struct.memfunc[tagnum]->allifunc)) - (*G__struct.incsetup_memfunc[tagnum])(); + && 2>=G__struct.memfunc[tagnum]->allifunc)){ + + // G__setup_memfuncXXX execution + std::list<G__incsetup>::iterator iter; + if(G__struct.incsetup_memfunc[tagnum]->size()) + for (iter=G__struct.incsetup_memfunc[tagnum]->begin(); iter != G__struct.incsetup_memfunc[tagnum]->end(); iter ++) + (*iter)(); + } + #else - (*G__struct.incsetup_memfunc[tagnum])(); + // G__setup_memfuncXXX execution + std::list<G__incsetup>::iterator iter; + if(G__struct.incsetup_memfunc[tagnum]->size()){ + for (iter=G__struct.incsetup_memfunc[tagnum]->begin(); iter != G__struct.incsetup_memfunc[tagnum]->end(); iter ++) + (*iter)(); + } + #endif - G__struct.incsetup_memfunc[tagnum] = (G__incsetup)NULL; + // The G__setup_memfuncXXX functions have been executed. We don't need the pointers anymore. We clean the list + G__struct.incsetup_memfunc[tagnum]->clear(); + G__var_type = store_var_type; G__asm_exec = store_asm_exec; G__ifile = store_ifile; } } + + /************************************************************************** * G__getnumbaseclass() * @@ -8592,16 +8871,20 @@ void G__setgvp(long gvp) **************************************************************************/ void G__resetplocal() { + /* Variables stack storing */ + G__IncSetupStack incsetup_stack; + std::stack<G__IncSetupStack> *var_stack = G__stack_instance(); + if(G__def_struct_member && 'n'==G__struct.type[G__tagdefining]) { - G__incset_tagnum = G__tagnum; - G__incset_p_local = G__p_local; - G__incset_def_struct_member = G__def_struct_member; - G__incset_tagdefining = G__tagdefining; - G__incset_globalvarpointer = G__globalvarpointer ; - G__incset_var_type = G__var_type ; - G__incset_typenum = G__typenum ; - G__incset_static_alloc = G__static_alloc ; - G__incset_access = G__access ; + incsetup_stack.G__incset_tagnum = G__tagnum; + incsetup_stack.G__incset_p_local = G__p_local; + incsetup_stack.G__incset_def_struct_member = G__def_struct_member; + incsetup_stack.G__incset_tagdefining = G__tagdefining; + incsetup_stack.G__incset_globalvarpointer = G__globalvarpointer ; + incsetup_stack.G__incset_var_type = G__var_type ; + incsetup_stack.G__incset_typenum = G__typenum ; + incsetup_stack.G__incset_static_alloc = G__static_alloc ; + incsetup_stack.G__incset_access = G__access ; G__tagnum = G__tagdefining; G__p_local=G__struct.memvar[G__tagnum]; @@ -8612,8 +8895,11 @@ void G__resetplocal() } else { G__p_local = (struct G__var_array*)NULL; - G__incset_def_struct_member =0; + incsetup_stack.G__incset_def_struct_member =0; } + + var_stack->push(incsetup_stack); + } /************************************************************************** @@ -8622,17 +8908,22 @@ void G__resetplocal() **************************************************************************/ void G__resetglobalenv() { - if(G__incset_def_struct_member && 'n'==G__struct.type[G__incset_tagdefining]){ - G__p_local = G__incset_p_local ; - G__def_struct_member = G__incset_def_struct_member ; - G__tagdefining = G__incset_tagdefining ; + /* Variables stack restoring */ + std::stack<G__IncSetupStack> *var_stack = G__stack_instance(); + G__IncSetupStack *incsetup_stack = &var_stack->top(); - G__globalvarpointer = G__incset_globalvarpointer ; - G__var_type = G__incset_var_type ; - G__tagnum = G__incset_tagnum ; - G__typenum = G__incset_typenum ; - G__static_alloc = G__incset_static_alloc ; - G__access = G__incset_access ; + if(incsetup_stack->G__incset_def_struct_member && 'n'==G__struct.type[incsetup_stack->G__incset_tagdefining]){ + G__p_local = incsetup_stack->G__incset_p_local; + G__def_struct_member = incsetup_stack->G__incset_def_struct_member ; + G__tagdefining = incsetup_stack->G__incset_tagdefining ; + + G__globalvarpointer = incsetup_stack->G__incset_globalvarpointer ; + G__var_type = incsetup_stack->G__incset_var_type ; + G__tagnum = incsetup_stack->G__incset_tagnum ; + G__typenum = incsetup_stack->G__incset_typenum ; + G__static_alloc = incsetup_stack->G__incset_static_alloc ; + G__access = incsetup_stack->G__incset_access ; + } else { G__globalvarpointer = G__PVOID; @@ -8642,6 +8933,8 @@ void G__resetglobalenv() G__static_alloc = 0; G__access = G__PUBLIC; } + + var_stack->pop(); } /************************************************************************** @@ -8650,12 +8943,17 @@ void G__resetglobalenv() **************************************************************************/ void G__lastifuncposition() { + +/* Variables stack storing */ + std::stack<G__IncSetupStack> *var_stack = G__stack_instance(); + G__IncSetupStack incsetup_stack; + if(G__def_struct_member && 'n'==G__struct.type[G__tagdefining]) { - G__incset_tagnum = G__tagnum; - G__incset_p_ifunc = G__p_ifunc; - G__incset_func_now = G__func_now; - G__incset_func_page = G__func_page; - G__incset_var_type = G__var_type; + incsetup_stack.G__incset_tagnum = G__tagnum; + incsetup_stack.G__incset_p_ifunc = G__p_ifunc; + incsetup_stack.G__incset_func_now = G__func_now; + incsetup_stack.G__incset_func_page = G__func_page; + incsetup_stack.G__incset_var_type = G__var_type; G__tagnum = G__tagdefining; G__p_ifunc = G__struct.memfunc[G__tagnum]; while(G__p_ifunc->next) G__p_ifunc=G__p_ifunc->next; @@ -8663,8 +8961,11 @@ void G__lastifuncposition() else { G__p_ifunc = &G__ifunc; while(G__p_ifunc->next) G__p_ifunc=G__p_ifunc->next; - G__incset_def_struct_member = 0; + incsetup_stack.G__incset_def_struct_member = 0; } + + var_stack->push(incsetup_stack); + } /************************************************************************** @@ -8673,12 +8974,17 @@ void G__lastifuncposition() **************************************************************************/ void G__resetifuncposition() { - if(G__incset_def_struct_member && 'n'==G__struct.type[G__incset_tagdefining]){ - G__tagnum = G__incset_tagnum; - G__p_ifunc = G__incset_p_ifunc; - G__func_now = G__incset_func_now; - G__func_page = G__incset_func_page; - G__var_type = G__incset_var_type; + + /* Variables stack restoring */ + std::stack<G__IncSetupStack>* var_stack = G__stack_instance(); + G__IncSetupStack *incsetup_stack = &var_stack->top(); + + if(incsetup_stack->G__incset_def_struct_member && 'n'==G__struct.type[incsetup_stack->G__incset_tagdefining]){ + G__tagnum = incsetup_stack->G__incset_tagnum; + G__p_ifunc = incsetup_stack->G__incset_p_ifunc; + G__func_now = incsetup_stack->G__incset_func_now; + G__func_page = incsetup_stack->G__incset_func_page; + G__var_type = incsetup_stack->G__incset_var_type; } else { G__tagnum = -1; @@ -8691,6 +8997,8 @@ void G__resetifuncposition() G__static_alloc = 0; G__access = G__PUBLIC; G__typenum = -1; + + var_stack->pop(); } /************************************************************************** diff --git a/cint/src/v6_pause.cxx b/cint/src/v6_pause.cxx index 82b9fc2969f..f25cf49c9e4 100644 --- a/cint/src/v6_pause.cxx +++ b/cint/src/v6_pause.cxx @@ -1548,7 +1548,7 @@ static void G__create_input_tmpfile(G__input_file& ftemp) { ftemp.fp = fopen(ftemp.name, "w+bTD"); // write and read (but write first), binary, temp, and delete when closed #else ftemp.fp = tmpfile(); - strcmp(ftemp.name, "(tmpfile)"); + strcpy(ftemp.name, "(tmpfile)"); #endif } diff --git a/cint/src/v6_pcode.cxx b/cint/src/v6_pcode.cxx index a1d08a2c81c..7ff7ffa6101 100644 --- a/cint/src/v6_pcode.cxx +++ b/cint/src/v6_pcode.cxx @@ -6790,6 +6790,7 @@ int G__asm_optimize3(int *start) * 2 hash * 3 paran * 4 (*func)() + * 5 this ptr offset for multiple inheritance * stack * sp-paran+1 <- sp-paran+1 * sp-2 @@ -6807,7 +6808,7 @@ int G__asm_optimize3(int *start) } #endif /* no optimization */ - pc+=5; + pc+=6; break; case G__RETURN: @@ -8479,6 +8480,7 @@ int G__dasm(FILE *fout,int isthrow) * 2 hash * 3 paran * 4 (*func)() + * 5 this ptr offset for multiple inheritance * stack * sp-paran+1 <- sp-paran+1 * sp-2 @@ -8493,7 +8495,7 @@ int G__dasm(FILE *fout,int isthrow) fprintf(fout,"%3x: LD_FUNC %s paran=%ld\n" ,pc ,(char *)G__asm_inst[pc+1],G__asm_inst[pc+3]); } - pc+=5; + pc+=6; break; case G__RETURN: diff --git a/cint/src/v6_scrupto.cxx b/cint/src/v6_scrupto.cxx index 314ba5c302b..ee0ba4dd96c 100644 --- a/cint/src/v6_scrupto.cxx +++ b/cint/src/v6_scrupto.cxx @@ -846,8 +846,9 @@ void G__close_inputfiles_upto(G__dictposition* pos) G__struct.comment[itag].p.com = NULL; G__struct.comment[itag].filenum = -1; G__struct.friendtag[itag] = 0; - G__struct.incsetup_memvar[itag] = 0; - G__struct.incsetup_memfunc[itag] = 0; + // Clean up G__setup_memfunc and G__setup_memvar pointers list + G__struct.incsetup_memvar[itag]->clear(); + G__struct.incsetup_memfunc[itag]->clear(); G__struct.rootflag[itag] = 0; G__struct.rootspecial[itag] = 0; G__struct.isctor[itag] = 0; diff --git a/cint/src/v6_struct.cxx b/cint/src/v6_struct.cxx index 4ddc668a5b6..950407e8833 100644 --- a/cint/src/v6_struct.cxx +++ b/cint/src/v6_struct.cxx @@ -941,8 +941,10 @@ int G__search_tagname(const char *tagname,int type) G__struct.comment[i].p.com = (char*)NULL; G__struct.comment[i].filenum = -1; - G__struct.incsetup_memvar[i] = (G__incsetup)NULL; - G__struct.incsetup_memfunc[i] = (G__incsetup)NULL; + // G__setup_memfunc and G__setup_memvar pointers list initialisation + G__struct.incsetup_memvar[i] = new std::list<G__incsetup>(); + G__struct.incsetup_memfunc[i] = new std::list<G__incsetup>(); + G__struct.rootflag[i] = 0; G__struct.rootspecial[i] = (struct G__RootSpecial*)NULL; @@ -1870,6 +1872,9 @@ int G__callfunc0(G__value *result, G__ifunc_table *iref, int ifn store_asm_exec = G__asm_exec; G__asm_exec = 0; + // this-pointer adjustment + G__this_adjustment(ifunc, ifn); + #ifdef G__EXCEPTIONWRAPPER if(-1==ifunc->pentry[ifn]->size) { /* compiled function. should be stub */ diff --git a/cint/src/v6_var.cxx b/cint/src/v6_var.cxx index 58641123190..91db0abfd8b 100644 --- a/cint/src/v6_var.cxx +++ b/cint/src/v6_var.cxx @@ -4674,10 +4674,10 @@ void G__letstruct(G__value* result, int linear_index, G__var_array* var, int ig1 if(ig2 && G__asm_noverflow) { int x; G__asm_dt = store_dt; - if(G__LD_FUNC==G__asm_inst[G__asm_cp-5]) { - for(x=0;x<5;x++) - G__asm_inst[store_cp+x] = G__asm_inst[G__asm_cp-5+x]; - G__asm_cp = store_cp + 5; + if(G__LD_FUNC==G__asm_inst[G__asm_cp-6]) { + for(x=0;x<6;x++) + G__asm_inst[store_cp+x] = G__asm_inst[G__asm_cp-6+x]; + G__asm_cp = store_cp + 6; } else if(G__LD_IFUNC==G__asm_inst[G__asm_cp-8]) { for(x=0;x<8;x++) @@ -6128,7 +6128,8 @@ G__value G__allocvariable(G__value result, G__value para[], G__var_array* varglo G__asm_inst[G__asm_cp+2] = 677; G__asm_inst[G__asm_cp+3] = 2; G__asm_inst[G__asm_cp+4] = (long) G__compiled_func; - G__inc_cp_asm(5, 0); + G__asm_inst[G__asm_cp+5] = 0; + G__inc_cp_asm(6, 0); } } break; -- GitLab