Ignore:
Timestamp:
Jan 19, 2007, 7:36:51 PM (19 years ago)
Author:
cinc
Message:

Fixes for explicit metaclass handling

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/nom/src/nombuildclass.c

    r196 r199  
    5151#include <nomclassmanager.h>
    5252
    53 /* Define if you want to have messages from somBuildClass() and friends */
     53/* Define if you want to have messages from nomBuildClass() and friends */
    5454//#define DEBUG_NOMBUILDCLASS
    5555/* Define if you want to have messages from building NOMObject */
     
    6464    #define BUILDNOMCLASS_ENTER
    6565    #define BUILDNOMCLASS_LEAVE
     66#endif
     67
     68#ifdef DEBUG_NOMBUILDCLASS
     69#define DBG_NOMBUILDCLASS(a, b, ...)   if(a) nomPrintf("%d: " b , __LINE__, __VA_ARGS__);
     70#else
     71#define DBG_NOMBUILDCLASS(a, b, ...)
    6672#endif
    6773
     
    457463
    458464#ifdef DEBUG_NOMBUILDCLASS
    459   nomPrintf("  ncpParent->mtab->mtabSize: %d. Parent is: %x (priv) %s\n",
    460             ncpParent->mtab->mtabSize, ncpParent, ncpParent->mtab->nomClassName);
     465  nomPrintf("  %d: ncpParent->mtab->mtabSize: %d. Parent is: %x (priv) %s\n",
     466            __LINE__, ncpParent->mtab->mtabSize, ncpParent, ncpParent->mtab->nomClassName);
    461467#endif
    462468  mtabSize=ncpParent->mtab->mtabSize+sizeof(nomMethodProc*)*(sci->ulNumStaticMethods)+
     
    469475  ulParentDataSize=ncpParent->mtab->ulInstanceSize; /* Parent instance size */
    470476#ifdef DEBUG_NOMBUILDCLASS
    471   nomPrintf("  %s: mtabSize will be: %d, ulParentDataSize is: %d\n", __FUNCTION__, mtabSize, ulParentDataSize);
    472 #endif
    473   /* Alloc object struct using NOMCalloc. */
     477  nomPrintf("  %d: %s: mtabSize will be: %d, ulParentDataSize is: %d\n", __LINE__, __FUNCTION__, mtabSize, ulParentDataSize);
     478#endif
     479  /* Alloc private class struct using NOMCalloc. */
    474480  if((nClass=(NOMClassPriv*)NOMCalloc(1, ulMemSize))==NULLHANDLE)
    475481    return NULLHANDLE;
    476482
    477483  /* Get mem for method thunking code */
    478   nClass->mThunk=NOMMalloc(sizeof(nomMethodThunk)*sci->ulNumStaticMethods);
    479   if(!nClass->mThunk) {
    480     NOMFree(nClass);
    481     return NULLHANDLE;
    482   }
    483 
     484  if(0!=sci->ulNumStaticMethods){
     485    nClass->mThunk=NOMMalloc(sizeof(nomMethodThunk)*sci->ulNumStaticMethods);
     486    if(!nClass->mThunk) {
     487      NOMFree(nClass);
     488      return NULLHANDLE;
     489    }
     490  }
    484491  /* Add class struct of this class.
    485492     This includes
     
    490497
    491498#ifdef DEBUG_NOMBUILDCLASS
    492   nomPrintf("%s:  mtab: %x\n", __FUNCTION__, nClass->mtab);
     499  nomPrintf("%d: %s:  mtab: %x\n", __LINE__, __FUNCTION__, nClass->mtab);
    493500#endif
    494501  /*
    495     We don't create a class object here so the following isn't done:
    496     sci->cds->classObject=somClass;
     502    Note: We don't create a class object here so the following isn't done:
     503          sci->cds->classObject=nomClass;
    497504  */
    498505
     
    514521
    515522#ifdef DEBUG_NOMBUILDCLASS
    516   nomPrintf("  New NOMClassPriv*: %x\n", nClass);
     523  nomPrintf("  %d: New NOMClassPriv*: %x\n", __LINE__, nClass);
    517524#endif
    518525
     
    530537                                                    gulong minorVersion)
    531538{
    532   NOMClass *nomClass, *nomClassParent;
     539  NOMClass *nomClass, *nomClassMeta;
    533540 
    534541  if(NULL==NOMClassMgrObject)
     
    537544  /* Search for meta class. */
    538545#warning !!!!! Change this when nomID is a GQuark !!!!!
    539   nomClassParent=_nomFindClassFromName(NOMClassMgrObject, *sci->nomExplicitMetaId, majorVersion, minorVersion, NULLHANDLE);
    540     printf("  2 ----------------- %d %x %s %s\n", __LINE__, nomClassParent, *sci->nomClassId, *sci->nomExplicitMetaId);
    541   if(!nomClassParent)
     546  nomClassMeta=_nomFindClassFromName(NOMClassMgrObject, *sci->nomExplicitMetaId, majorVersion, minorVersion, NULLHANDLE);
     547
     548#ifdef DEBUG_NOMBUILDCLASS
     549  nomPrintf("%d: %x %s %s\n", __LINE__, nomClassMeta, *sci->nomClassId, *sci->nomExplicitMetaId);
     550#endif
     551
     552  if(!nomClassMeta)
    542553    return NULLHANDLE;
    543554
     
    546557     sizes, methods etc. I wonder how IBM SOM manages to use the same metaclass
    547558     for different classes without (apparently) copying it for different uses... */
    548   if((nomClass=(NOMClass*)NOMCalloc(1, _nomGetSize(nomClassParent, NULLHANDLE)))==NULLHANDLE)
    549     return NULLHANDLE;
    550 
    551   /* Mabe we should just copy the whole struct here? */
    552   nomClass->mtab=nomClassParent->mtab;
     559  if((nomClass=(NOMClass*)NOMCalloc(1, _nomGetSize(nomClassMeta, NULLHANDLE)))==NULLHANDLE)
     560    return NULLHANDLE;
     561
     562  /* Maybe we should just copy the whole struct here? */
     563  nomClass->mtab=nomClassMeta->mtab;
    553564#warning !!!!! No call of _nomSetInstanceSize  !!!!!
    554565#warning !!!!! No call of _nomSetObjectsSCI   !!!!!
    555566#if 0
    556567  /* Set object data */
    557   _nomSetInstanceSize(nomClass, _nomGetSize(nomClassParent));
     568  _nomSetInstanceSize(nomClass, _nomGetSize(nomClassMeta));
    558569  /* Save objects sci pointer. We need it when we create instances  */
    559570  _nomSetObjectsSCI(somClass, sci);
     
    570581 
    571582#ifdef DEBUG_NOMBUILDCLASS
    572   nomPrintf("New class Object (SOMClass): %x \n", nomClass);
     583  nomPrintf("%d: New class Object (child of NOMClass): %x \n", __LINE__, nomClass);
    573584#endif
    574585
     
    577588}
    578589
     590/*
     591  This function climbs the chain of parents and looks for a parent introducing
     592  an explicit metaclass. If found, this metaclass is returned otherwise NOMClass.
     593 */
     594static
     595NOMClass * NOMLINK priv_findExplicitMetaClassFromParents(nomStaticClassInfo *sci)
     596{
     597  int a;
     598
     599  if(1==sci->ulNumParentsInChain)
     600    {
     601      /* One parent only. That must be NOMObject and NOMObject has NOMClass
     602         as metaclass. */
     603      return pGlobalNomEnv->defaultMetaClass;;
     604    }
     605
     606  /* Climb the list of parents... */
     607
     608  /* NOMClassMgrObject==NULL shouldn't ever happen here! */
     609  g_assert(NOMClassMgrObject);
     610
     611  for(a=sci->ulNumParentsInChain-1;a>=0; a--)
     612    {
     613      NOMObject *nObject;
     614      nObject=_nomFindClassFromName(NOMClassMgrObject, sci->chrParentClassNames[a], 0, 0, NULLHANDLE);
     615
     616      DBG_NOMBUILDCLASS( TRUE , "  %s %x %x\n" , sci->chrParentClassNames[a], nObject, NOMClassMgrObject);
     617
     618      if(nObject){
     619        DBG_NOMBUILDCLASS( TRUE , " %s\n" , nObject->mtab->nomClassName);
     620        if(strcmp(nObject->mtab->nomClassName, "NOMClass"))
     621          return nObject; /* Not NOMClass return */
     622      } /* if(nObject) */
     623    } /* for() */
     624  return pGlobalNomEnv->defaultMetaClass;;;
     625}
    579626
    580627/*
    581628  This function is called when a class for a given sci should be build with a parent
    582    which isn't derived from SOMClass. In that case SOMClass is the class to be used for
    583    the class object. This doesn't mean we reuse the SOMClass structs. Instead a new
    584    copy is created so individula overriding is possible.
     629   which isn't derived from NOMClass. In that case some NOMClass ccild is the class to
     630   be used for the class object. We have to climb the parent list of this object class
     631   to check if one parent introduced an explicit metaclass. If yes, we have to use that
     632   one as the metaclass. If no parent did that we just use NOMClass.
     633   This doesn't mean we reuse the found structs directly. Instead a new copy is created
     634   so individula overriding is possible.
    585635*/
    586636static
    587 NOMClass * NOMLINK priv_buildWithNOMClassAsMeta(gulong ulReserved,
    588                                                 nomStaticClassInfo *sci,
    589                                                 long majorVersion,
    590                                                 long minorVersion)
     637NOMClass * NOMLINK priv_buildWithNOMClassChildAsMeta(gulong ulReserved,
     638                                                     nomStaticClassInfo *sci,
     639                                                     long majorVersion,
     640                                                     long minorVersion)
    591641{
    592642  NOMClass  *nomClass, *nomClassDefault;
     
    595645#ifdef DEBUG_NOMBUILDCLASS
    596646#warning !!!!! Change this when nomId is a GQuark !!!!!
    597   nomPrintf("\n\n\nEntering %s to build %s\n", __FUNCTION__, *sci->nomClassId);
    598 #endif
     647  nomPrintf("\n\n%d: Entering %s to build %s\n", __LINE__, __FUNCTION__, *sci->nomClassId);
     648#endif
     649
     650  /* Search parents for a an explicit metaclass. If no explicit metaclass return
     651     NOMClass. */
     652  nomClassDefault=priv_findExplicitMetaClassFromParents(sci);// this gives a NOMClass* not a NOMClassPriv*
    599653
    600654  /**** Create the meta class object ****/
    601   nomClassDefault=pGlobalNomEnv->defaultMetaClass; // this gives a NOMClass* not a NOMClassPriv*
     655  //nomClassDefault=pGlobalNomEnv->defaultMetaClass; // this gives a NOMClass* not a NOMClassPriv*
    602656
    603657  if(!nomClassDefault)
     
    712766  nomMethodTabs psmTab;
    713767  /* Print some info for debbuging */
    714   nomPrintf("\n%d: Entering %s to build class %s. ---> SCMO: 0x%x (NOMClassManagerObject)\n",
     768  nomPrintf("\n%d: Entering %s to build class %s. ---> NOMClassManagerObject: 0x%x\n",
    715769            __LINE__, __FUNCTION__, *sci->nomClassId, NOMClassMgrObject);
    716   nomPrintf("d: cds: 0x%x nomClassObject: 0x%x\n", __LINE__, sci->nomCds, sci->nomCds->nomClassObject);
     770  nomPrintf("%d: cds: 0x%x nomClassObject: 0x%x\n", __LINE__, sci->nomCds, sci->nomCds->nomClassObject);
    717771#endif
    718772
     
    830884  /* Check if parent is a class object (derived from NOMClass). */
    831885  if(!priv_nomIsA((NOMObject*)ncpParent, pGlobalNomEnv->defaultMetaClass)) {
    832     /* No parent is normal object so we have either to use NOMClass as parent
    833        or an explicit meta class if given. */
     886    /* No, parent of class to build is normal object so we have to use either an explicit meta class if given or
     887       another NOMClass derived class for the class object. */
    834888#ifdef DEBUG_NOMBUILDCLASS
    835889    nomPrintf("%d: Class %x (ncpParent->mtab->nomClassName: %s) is not a NOMClass\n",
     
    840894      {
    841895        /* The explicit metaclass is created at this point. Now it will be filled
    842            with the info how to create objects.
    843            sClass=(SOMClassPriv*)priv_findClassInClassList(pGlobalSomEnv, *(sci->explicitMetaId));
    844            
    845            if(!scParent)
    846            return NULLHANDLE;  Every class except SOMObject must have a parent!! */
    847 #ifdef DEBUG_NOMBUILDCLASS
    848         nomPrintf("sci->nomExplicitMetaId is set\n");
     896           with the info how to create objects. */
     897
     898#ifdef DEBUG_NOMBUILDCLASS
     899        nomPrintf("%d: sci->nomExplicitMetaId is set. Calling priv_buildWithExplicitMetaClass().\n", __LINE__);
    849900#endif
    850901   
     
    862913      }/* nomExplicitMetaId */
    863914    else {
    864       /* Use NOMClass as meta class. The following call will create the
    865          class object and will also fill in the necessary object info for
     915      /* Use NOMClass derived class as meta class. We have to climb the parent list of this object class
     916         to check if one parent introduced an explicit metaclass. If yes, we have to use that one as
     917         the metaclass. IF no parent did that we just use NOMClass.
     918         The following call will create the class object and will also fill in the necessary object info for
    866919         creating instances. */
    867       nomClass= priv_buildWithNOMClassAsMeta(ulReserved, sci,
    868                                              ulMajorVersion, ulMinorVersion);
     920      nomClass= priv_buildWithNOMClassChildAsMeta(ulReserved, sci,
     921                                                  ulMajorVersion, ulMinorVersion);
    869922
    870923      if(nomClass){
     
    903956
    904957
    905   /* Alloc class struct using NOMCalloc. This means the struct is allocated in shared mem */
     958  /* Alloc class struct using NOMCalloc. */
    906959  if((nClass=(NOMClassPriv*)NOMCalloc(1, ulMemSize))==NULLHANDLE)
    907960    return NULLHANDLE;
     
    926979  nClass->ulPrivClassSize=ulMemSize;
    927980
    928  
    929981  /* Add class struct of this class. This includes resolving the method adresses. */
    930982  addMethodAndDataToThisPrivClassStruct( nClass, ncpParent, sci) ;
     
    935987  nomClass->mtab=nClass->mtab; 
    936988#ifdef DEBUG_NOMBUILDCLASS
    937   nomPrintf("%d: mtab: %x\n", __LINE__, nClass->mtab);
     989  nomPrintf("%d: mtab: %x, nClass: 0x%x, nomClass: 0x%x\n", __LINE__, nClass->mtab, nClass, nomClass);
    938990#endif
    939991  sci->nomCds->nomClassObject=nomClass; /* Put class pointer in static struct */
Note: See TracChangeset for help on using the changeset viewer.