Revision 2029f0eb6ccd57468ba64b629d8ab2b5a8ddb80b authored by Rene Brun on 14 March 2004, 18:15:47 UTC, committed by Rene Brun on 14 March 2004, 18:15:47 UTC
for the case kExpo (shift by 1 in the use of parameters) git-svn-id: http://root.cern.ch/svn/root/trunk@8400 27541ba8-7e3a-0410-8455-c3a389f83636
1 parent 4c44cc3
Method.cxx
/* /% C++ %/ */
/***********************************************************************
* cint (C/C++ interpreter)
************************************************************************
* Source file Method.cxx
************************************************************************
* Description:
* Extended Run Time Type Identification API
************************************************************************
* Author Masaharu Goto
* Copyright(c) 1995~1999 Masaharu Goto
*
* Permission to use, copy, modify and distribute this software and its
* documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. The author makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
************************************************************************/
#include "Api.h"
#include "common.h"
/*********************************************************************
* class G__MethodInfo
*
*
*********************************************************************/
///////////////////////////////////////////////////////////////////////////
void G__MethodInfo::Init()
{
handle = (long)(&G__ifunc);
index = -1;
belongingclass=(G__ClassInfo*)NULL;
}
///////////////////////////////////////////////////////////////////////////
void G__MethodInfo::Init(G__ClassInfo &a)
{
if(a.IsValid()) {
handle=(long)G__struct.memfunc[a.Tagnum()];
index = -1;
belongingclass = &a;
G__incsetup_memfunc((int)a.Tagnum());
}
else {
handle=0;
index = -1;
belongingclass=(G__ClassInfo*)NULL;
}
}
///////////////////////////////////////////////////////////////////////////
void G__MethodInfo::Init(long handlein,long indexin
,G__ClassInfo *belongingclassin)
{
if(handlein) {
handle = handlein;
index = indexin;
if(belongingclassin->IsValid()) belongingclass = belongingclassin;
else belongingclass=(G__ClassInfo*)NULL;
/* Set return type */
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
type.type=ifunc->type[index];
type.tagnum=ifunc->p_tagtable[index];
type.typenum=ifunc->p_typetable[index];
type.reftype=ifunc->reftype[index];
type.isconst=ifunc->isconst[index];
#ifndef G__OLDIMPLEMENTATION1227
type.class_property=0;
#endif
}
#ifndef G__FONS72
else { /* initialize if handlein==0 */
handle=0;
index=-1;
belongingclass=(G__ClassInfo*)NULL;
}
#endif
}
///////////////////////////////////////////////////////////////////////////
#ifndef G__OLDIMPLEMENTATION644
void G__MethodInfo::Init(G__ClassInfo *belongingclassin
,long funcpage,long indexin)
{
struct G__ifunc_table *ifunc;
int i=0;
if(belongingclassin->IsValid()) {
// member function
belongingclass = belongingclassin;
ifunc = G__struct.memfunc[belongingclassin->Tagnum()];
}
else {
// global function
belongingclass=(G__ClassInfo*)NULL;
ifunc = G__p_ifunc;
}
// reach to desired page
for(i=0;i<funcpage&&ifunc;i++) ifunc=ifunc->next;
G__ASSERT(ifunc->page == funcpage);
if(ifunc) {
handle = (long)ifunc;
index = indexin;
// Set return type
type.type=ifunc->type[index];
type.tagnum=ifunc->p_tagtable[index];
type.typenum=ifunc->p_typetable[index];
type.reftype=ifunc->reftype[index];
type.isconst=ifunc->isconst[index];
#ifndef G__OLDIMPLEMENTATION1227
type.class_property=0;
#endif
}
else { /* initialize if handlein==0 */
handle=0;
index=-1;
belongingclass=(G__ClassInfo*)NULL;
}
}
#endif
///////////////////////////////////////////////////////////////////////////
const char* G__MethodInfo::Name()
{
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
return(ifunc->funcname[index]);
}
else {
return((char*)NULL);
}
}
///////////////////////////////////////////////////////////////////////////
int G__MethodInfo::Hash()
{
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
return(ifunc->hash[index]);
}
else {
return(0);
}
}
///////////////////////////////////////////////////////////////////////////
struct G__ifunc_table* G__MethodInfo::ifunc()
{
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
return(ifunc);
}
else {
return((struct G__ifunc_table*)NULL);
}
}
///////////////////////////////////////////////////////////////////////////
const char* G__MethodInfo::Title()
{
static char buf[G__INFO_TITLELEN];
buf[0]='\0';
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
G__getcomment(buf,&ifunc->comment[index],ifunc->tagnum);
return(buf);
}
else {
return((char*)NULL);
}
}
///////////////////////////////////////////////////////////////////////////
long G__MethodInfo::Property()
{
if(IsValid()) {
long property=0;
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
switch(ifunc->access[index]) {
case G__PUBLIC: property|=G__BIT_ISPUBLIC; break;
case G__PROTECTED: property|=G__BIT_ISPROTECTED; break;
case G__PRIVATE: property|=G__BIT_ISPRIVATE; break;
}
#ifndef G__OLDIMPLEMENTATION1189
if(ifunc->isconst[index]&G__CONSTFUNC) property|=G__BIT_ISCONSTANT;
#endif
if(ifunc->isconst[index]&G__CONSTVAR) property|=G__BIT_ISCONSTANT;
if(ifunc->isconst[index]&G__PCONSTVAR) property|=G__BIT_ISPCONSTANT;
if(isupper(ifunc->type[index])) property|=G__BIT_ISPOINTER;
if(ifunc->staticalloc[index]) property|=G__BIT_ISSTATIC;
if(ifunc->isvirtual[index]) property|=G__BIT_ISVIRTUAL;
if(ifunc->ispurevirtual[index]) property|=G__BIT_ISPUREVIRTUAL;
if(ifunc->pentry[index]->filenum<0) property|=G__BIT_ISCOMPILED;
if(ifunc->pentry[index]->bytecode) property|=G__BIT_ISBYTECODE;
#ifndef G__OLDIMPLEMENTATION1287
if(ifunc->isexplicit[index]) property|=G__BIT_ISEXPLICIT;
#endif
return(property);
}
else {
return(0);
}
}
///////////////////////////////////////////////////////////////////////////
int G__MethodInfo::NArg()
{
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
return(ifunc->para_nu[index]);
}
else {
return(-1);
}
}
///////////////////////////////////////////////////////////////////////////
int G__MethodInfo::NDefaultArg()
{
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
if(ifunc->para_nu[index]) {
int i,defaultnu=0;
for(i=ifunc->para_nu[index]-1;i>=0;i--) {
if(ifunc->para_default[index][i]) ++defaultnu;
else return(defaultnu);
}
return(defaultnu);
}
else {
return(0);
}
}
else {
return(-1);
}
return(-1); // dummy
}
///////////////////////////////////////////////////////////////////////////
int G__MethodInfo::HasVarArgs()
{
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
return(2==ifunc->ansi[index]?1:0);
}
else {
return(-1);
}
}
///////////////////////////////////////////////////////////////////////////
G__InterfaceMethod G__MethodInfo::InterfaceMethod()
{
#ifndef G__OLDIMPLEMENTATION1035
G__LockCriticalSection();
#endif
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
if(-1==ifunc->pentry[index]->filenum) {
#ifndef G__OLDIMPLEMENTATION1035
G__UnlockCriticalSection();
#endif
return((G__InterfaceMethod)ifunc->pentry[index]->p);
}
else {
#ifndef G__OLDIMPLEMENTATION1035
G__UnlockCriticalSection();
#endif
return((G__InterfaceMethod)NULL);
}
}
else {
#ifndef G__OLDIMPLEMENTATION1035
G__UnlockCriticalSection();
#endif
return((G__InterfaceMethod)NULL);
}
}
#ifdef G__ASM_WHOLEFUNC
///////////////////////////////////////////////////////////////////////////
struct G__bytecodefunc *G__MethodInfo::GetBytecode()
{
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
if(!ifunc->pentry[index]->bytecode &&
-1!=ifunc->pentry[index]->filenum &&
G__BYTECODE_NOTYET==ifunc->pentry[index]->bytecodestatus
#ifndef G__OLDIMPLEMENTATION1842
&& G__asm_loopcompile>=4
#endif
) {
G__compile_bytecode(ifunc,(int)index);
}
return(ifunc->pentry[index]->bytecode);
}
else {
return((struct G__bytecodefunc*)NULL);
}
}
#endif
/* #ifndef G__OLDIMPLEMENTATION1163 */
///////////////////////////////////////////////////////////////////////////
G__DataMemberInfo G__MethodInfo::GetLocalVariable()
{
G__DataMemberInfo localvar;
localvar.Init((long)0,(long)(-1),(G__ClassInfo*)NULL);
if(IsValid()) {
#ifndef G__OLDIMPLEMENTATION1164
int store_fixedscope=G__fixedscope;
extern int G__xrefflag;
G__xrefflag=1;
G__fixedscope=1;
#endif
struct G__bytecodefunc* pbc = GetBytecode();
#ifndef G__OLDIMPLEMENTATION1164
G__xrefflag=0;
G__fixedscope=store_fixedscope;
#endif
if(!pbc) {
if(Property()&G__BIT_ISCOMPILED) {
G__fprinterr(G__serr,"Limitation: can not get local variable information for compiled function %s\n",Name());
}
else {
G__fprinterr(G__serr,"Limitation: function %s , failed to get local variable information\n",Name());
}
return(localvar);
}
localvar.Init((long)pbc->var,(long)(-1),(G__ClassInfo*)NULL);
return(localvar);
}
else {
return(localvar);
}
}
/* #endif */
///////////////////////////////////////////////////////////////////////////
#ifdef G__TRUEP2F
void* G__MethodInfo::PointerToFunc()
{
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
if(-1!=ifunc->pentry[index]->filenum &&
G__BYTECODE_NOTYET==ifunc->pentry[index]->bytecodestatus
#ifndef G__OLDIMPLEMENTATION1842
&& G__asm_loopcompile>=4
#endif
) {
G__compile_bytecode(ifunc,(int)index);
}
#ifndef G__OLDIMPLEMENTATION1846
if(G__BYTECODE_SUCCESS==ifunc->pentry[index]->bytecodestatus)
return((void*)ifunc->pentry[index]->bytecode);
#endif
return(ifunc->pentry[index]->tp2f);
}
else {
return((void*)NULL);
}
}
#endif
///////////////////////////////////////////////////////////////////////////
void G__MethodInfo::SetGlobalcomp(int globalcomp)
{
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
ifunc->globalcomp[index]=globalcomp;
#ifndef G__OLDIMPLEMENTATION912
if(G__NOLINK==globalcomp) ifunc->access[index]=G__PRIVATE;
else ifunc->access[index]=G__PUBLIC;
#endif
}
}
///////////////////////////////////////////////////////////////////////////
int G__MethodInfo::IsValid()
{
if(handle) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
if(0<=index&&index<ifunc->allifunc) {
return(1);
}
else {
return(0);
}
}
else {
return(0);
}
}
///////////////////////////////////////////////////////////////////////////
int G__MethodInfo::SetFilePos(const char* fname)
{
struct G__dictposition* dict=G__get_dictpos((char*)fname);
if(!dict) return(0);
handle = (long)dict->ifunc;
index = (long)(dict->ifn-1);
belongingclass=(G__ClassInfo*)NULL;
return(1);
}
///////////////////////////////////////////////////////////////////////////
int G__MethodInfo::Next()
{
if(handle) {
struct G__ifunc_table *ifunc;
#ifndef G__OLDIMPLEMENTATION1706
nextone:
#endif
ifunc = (struct G__ifunc_table*)handle;
++index;
if(ifunc->allifunc<=index) {
#ifndef G__FONS75
int t = ifunc->tagnum;
#endif
ifunc=ifunc->next;
if(ifunc) {
#ifndef G__FONS75
ifunc->tagnum=t;
#endif
handle=(long)ifunc;
index = 0;
}
else {
handle=0;
index = -1;
}
}
if(IsValid()) {
#ifndef G__OLDIMPLEMENTATION1706
if(0==ifunc->hash[index]) goto nextone;
#endif
type.type=ifunc->type[index];
type.tagnum=ifunc->p_tagtable[index];
type.typenum=ifunc->p_typetable[index];
type.reftype=ifunc->reftype[index];
type.isconst=ifunc->isconst[index];
#ifndef G__OLDIMPLEMENTATION1227
type.class_property=0;
#endif
return(1);
}
else {
return(0);
}
}
else {
return(0);
}
}
///////////////////////////////////////////////////////////////////////////
const char* G__MethodInfo::FileName()
{
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
if(ifunc->pentry[index]->filenum>=0) {
return(G__srcfile[ifunc->pentry[index]->filenum].filename);
}
else {
return("(compiled)");
}
}
else {
return((char*)NULL);
}
}
///////////////////////////////////////////////////////////////////////////
#ifndef G__OLDIMPLEMENTATION644
FILE* G__MethodInfo::FilePointer()
{
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
if(ifunc->pentry[index]->filenum>=0) {
return(G__srcfile[ifunc->pentry[index]->filenum].fp);
}
else {
return((FILE*)NULL);
}
}
else {
return((FILE*)NULL);
}
}
#endif
///////////////////////////////////////////////////////////////////////////
int G__MethodInfo::LineNumber()
{
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
if(ifunc->pentry[index]->filenum>=0) {
return(ifunc->pentry[index]->line_number);
}
else {
return(0);
}
}
else {
return(-1);
}
}
///////////////////////////////////////////////////////////////////////////
#ifndef G__OLDIMPLEMENTATION644
long G__MethodInfo::FilePosition()
{
// returns 'type fname(type p1,type p2)'
// ^
long invalid=0L;
if(IsValid()) {
#ifdef G__VMS
//Changed so that pos can be a long.
struct G__ifunc_table_VMS *ifunc;
ifunc = (struct G__ifunc_table_VMS*)handle;
#else
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
#endif
if(ifunc->pentry[index]->filenum>=0) {
#if defined(G__NONSCALARFPOS2)
return((long)ifunc->pentry[index]->pos.__pos);
#else
return((long)ifunc->pentry[index]->pos);
#endif
}
else {
return(invalid);
}
}
else {
return(invalid);
}
}
#endif
///////////////////////////////////////////////////////////////////////////
int G__MethodInfo::Size()
{
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
if(ifunc->pentry[index]->filenum>=0) {
return(ifunc->pentry[index]->size);
}
else {
return(0);
}
}
else {
return(-1);
}
}
///////////////////////////////////////////////////////////////////////////
int G__MethodInfo::IsBusy()
{
if(IsValid()) {
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
return(ifunc->busy[index]);
}
else {
return(-1);
}
}
///////////////////////////////////////////////////////////////////////////
static char G__buf[G__LONGLINE];
char* G__MethodInfo::GetPrototype()
{
strcpy(G__buf,Type()->Name());
strcat(G__buf," ");
if(belongingclass && belongingclass->IsValid()) {
strcat(G__buf,belongingclass->Name());
strcat(G__buf,"::");
}
strcat(G__buf,Name());
strcat(G__buf,"(");
G__MethodArgInfo arg(*this);
int flag=0;
while(arg.Next()) {
if(flag) strcat(G__buf,",");
flag=1;
strcat(G__buf,arg.Type()->Name());
strcat(G__buf," ");
if(arg.Name()) strcat(G__buf,arg.Name());
if(arg.DefaultValue()) {
strcat(G__buf,"=");
strcat(G__buf,arg.DefaultValue());
}
}
strcat(G__buf,")");
return(G__buf);
}
///////////////////////////////////////////////////////////////////////////
char* G__MethodInfo::GetMangledName()
{
return(G__map_cpp_name(GetPrototype()));
}
///////////////////////////////////////////////////////////////////////////
#ifndef G__OLDIMPLEMENTATION1908
extern "C" int G__DLL_direct_globalfunc(G__value *result7
,G__CONST char *funcname
,struct G__param *libp,int hash) ;
extern "C" void* G__FindSym(const char* filename,const char* funcname);
int G__MethodInfo::LoadDLLDirect(const char* filename,const char* funcname)
{
void* p2f;
struct G__ifunc_table *ifunc;
ifunc = (struct G__ifunc_table*)handle;
p2f = G__FindSym(filename,funcname);
if(p2f) {
ifunc->pentry[index]->tp2f = p2f;
ifunc->pentry[index]->p = (void*)G__DLL_direct_globalfunc;
ifunc->pentry[index]->filenum = -1;
ifunc->pentry[index]->line_number = -1;
return 1;
}
return 0;
}
#endif
///////////////////////////////////////////////////////////////////////////
#ifndef G__OLDIMPLEMENTATION1294
///////////////////////////////////////////////////////////////////////////
// Global function to set precompiled library linkage
///////////////////////////////////////////////////////////////////////////
extern "C" int G__SetGlobalcomp(char *funcname,char *param,int globalcomp)
{
G__ClassInfo globalscope;
G__MethodInfo method;
long dummy=0;
#ifndef G__OLDIMPLEMENTATION912
char classname[G__LONGLINE];
// Actually find the last :: to get the full classname, including
// namespace and/or containing classes.
strcpy(classname,funcname);
char *fname = 0;
char * tmp = classname;
while ( (tmp = strstr(tmp,"::")) ) {
fname = tmp;
tmp += 2;
}
if(fname) {
*fname=0;
fname+=2;
globalscope.Init(classname);
}
else {
fname = funcname;
}
if(strcmp(fname,"*")==0) {
method.Init(globalscope);
while(method.Next()) {
method.SetGlobalcomp(globalcomp);
}
return(0);
}
method=globalscope.GetMethod(fname,param,&dummy);
#else
method=globalscope.GetMethod(funcname,param,&dummy);
#endif
if(method.IsValid()) {
method.SetGlobalcomp(globalcomp);
return(0);
}
else {
G__fprinterr(G__serr,"Warning: #pragma link, function %s(%s) not found"
#ifndef G__OLDIMPLEMENTATION912
,fname,param);
#else
,funcname,param);
#endif
G__printlinenum();
return(1);
}
}
#else
///////////////////////////////////////////////////////////////////////////
// Global function to set precompiled library linkage
///////////////////////////////////////////////////////////////////////////
extern "C" int G__SetGlobalcomp(char *funcname,char *param,int globalcomp)
{
G__ClassInfo globalscope;
G__MethodInfo method;
long dummy=0;
#ifndef G__OLDIMPLEMENTATION912
char classname[G__LONGLINE];
strcpy(classname,funcname);
char *fname = strstr(classname,"::");
if(fname) {
*fname=0;
fname+=2;
globalscope.Init(classname);
}
else {
fname = funcname;
}
if(strcmp(fname,"*")==0) {
method.Init(globalscope);
while(method.Next()) {
method.SetGlobalcomp(globalcomp);
}
return(0);
}
method=globalscope.GetMethod(fname,param,&dummy);
#else
method=globalscope.GetMethod(funcname,param,&dummy);
#endif
if(method.IsValid()) {
method.SetGlobalcomp(globalcomp);
return(0);
}
else {
G__fprinterr(G__serr,"Warning: #pragma link, function %s(%s) not found"
#ifndef G__OLDIMPLEMENTATION912
,fname,param);
#else
,funcname,param);
#endif
G__printlinenum();
return(1);
}
}
#endif
///////////////////////////////////////////////////////////////////////////
#ifndef G__OLDIMPLEMENTATION1781
///////////////////////////////////////////////////////////////////////////
// Global function to set precompiled library linkage
///////////////////////////////////////////////////////////////////////////
extern "C" int G__ForceBytecodecompilation(char *funcname,char *param)
{
G__ClassInfo globalscope;
G__MethodInfo method;
long dummy=0;
char classname[G__LONGLINE];
// Actually find the last :: to get the full classname, including
// namespace and/or containing classes.
strcpy(classname,funcname);
char *fname = 0;
char * tmp = classname;
while ( (tmp = strstr(tmp,"::")) ) {
fname = tmp;
tmp += 2;
}
if(fname) {
*fname=0;
fname+=2;
globalscope.Init(classname);
}
else {
fname = funcname;
}
method=globalscope.GetMethod(fname,param,&dummy);
if(method.IsValid()) {
struct G__ifunc_table *ifunc = method.ifunc();
int ifn = method.Index();
#ifndef G__OLDIMPLEMENTATION1842
int stat;
int store_asm_loopcompile = G__asm_loopcompile;
int store_asm_loopcompile_mode = G__asm_loopcompile_mode;
G__asm_loopcompile_mode=G__asm_loopcompile=4;
stat = G__compile_bytecode(ifunc,ifn);
G__asm_loopcompile=store_asm_loopcompile;
G__asm_loopcompile_mode=store_asm_loopcompile_mode;
#else
int stat = G__compile_bytecode(ifunc,ifn);
#endif
if(stat) return 0;
else return 1;
}
else {
G__fprinterr(G__serr,"Warning: function %s(%s) not found"
#ifndef G__OLDIMPLEMENTATION912
,fname,param);
#else
,funcname,param);
#endif
G__printlinenum();
return(1);
}
}
#endif
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...