[94] | 1 | /* ***** BEGIN LICENSE BLOCK *****
|
---|
| 2 | * Version: CDDL 1.0/LGPL 2.1
|
---|
| 3 | *
|
---|
| 4 | * The contents of this file are subject to the COMMON DEVELOPMENT AND
|
---|
| 5 | * DISTRIBUTION LICENSE (CDDL) Version 1.0 (the "License"); you may not use
|
---|
| 6 | * this file except in compliance with the License. You may obtain a copy of
|
---|
| 7 | * the License at http://www.sun.com/cddl/
|
---|
| 8 | *
|
---|
| 9 | * Software distributed under the License is distributed on an "AS IS" basis,
|
---|
| 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
---|
| 11 | * for the specific language governing rights and limitations under the
|
---|
| 12 | * License.
|
---|
| 13 | *
|
---|
| 14 | * The Original Code is "NOM" Netlabs Object Model
|
---|
| 15 | *
|
---|
| 16 | * The Initial Developer of the Original Code is
|
---|
| 17 | * netlabs.org: Chris Wohlgemuth <cinc-ml@netlabs.org>.
|
---|
[255] | 18 | * Portions created by the Initial Developer are Copyright (C) 2005-2007
|
---|
[94] | 19 | * the Initial Developer. All Rights Reserved.
|
---|
| 20 | *
|
---|
| 21 | * Contributor(s):
|
---|
| 22 | *
|
---|
| 23 | * Alternatively, the contents of this file may be used under the terms of
|
---|
| 24 | * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
|
---|
| 25 | * case the provisions of the LGPL are applicable instead of those above. If
|
---|
| 26 | * you wish to allow use of your version of this file only under the terms of
|
---|
| 27 | * the LGPL, and not to allow others to use your version of this file under
|
---|
| 28 | * the terms of the CDDL, indicate your decision by deleting the provisions
|
---|
| 29 | * above and replace them with the notice and other provisions required by the
|
---|
| 30 | * LGPL. If you do not delete the provisions above, a recipient may use your
|
---|
| 31 | * version of this file under the terms of any one of the CDDL or the LGPL.
|
---|
| 32 | *
|
---|
| 33 | * ***** END LICENSE BLOCK ***** */
|
---|
| 34 |
|
---|
[326] | 35 | #ifdef __OS2__
|
---|
| 36 | # define INCL_DOS
|
---|
| 37 | # define INCL_DOSERRORS
|
---|
| 38 | # include <os2.h>
|
---|
| 39 | #endif /* __OS2__ */
|
---|
[94] | 40 |
|
---|
| 41 | #include <stdio.h>
|
---|
| 42 |
|
---|
| 43 | #include <glib.h>
|
---|
| 44 | #define SOM_NO_OBJECTS /* Otherwise som.h includes the IBM SOM classes */
|
---|
| 45 |
|
---|
| 46 | /* For somToken etc. */
|
---|
| 47 | #include <nom.h>
|
---|
| 48 | #include <nomtk.h>
|
---|
| 49 | #include <nomobj.h>
|
---|
| 50 |
|
---|
| 51 | /********************************************************/
|
---|
| 52 |
|
---|
[221] | 53 | /* Define if you want to have messages from nomBuildClass() and friends */
|
---|
[94] | 54 | //#define DEBUG_NOMBUILDCLASS
|
---|
| 55 | /* Define if you want to have messages from building NOMObject */
|
---|
| 56 | //#define DEBUG_BUILDNOMOBJECT
|
---|
| 57 | /* Define if you want to have messages from building NOMClass */
|
---|
| 58 | //#define DEBUG_BUILDNOMCLASS
|
---|
| 59 |
|
---|
| 60 | #ifdef DEBUG_BUILDNOMCLASS
|
---|
| 61 | #define BUILDNOMCLASS_ENTER nomPrintf("\n%d: *** entering %s...\n",__LINE__, __FUNCTION__);
|
---|
| 62 | #define BUILDNOMCLASS_LEAVE nomPrintf("%d: *** Leaving %s...\n\n",__LINE__, __FUNCTION__);
|
---|
[221] | 63 | #define DBG_BUILDNOMCLASS(a, b,...) if(a) nomPrintf("%d: " b , __LINE__, __VA_ARGS__);
|
---|
[94] | 64 | #else
|
---|
| 65 | #define BUILDNOMCLASS_ENTER
|
---|
| 66 | #define BUILDNOMCLASS_LEAVE
|
---|
[326] | 67 | # ifdef _MSC_VER
|
---|
| 68 | void _inline DBG_BUILDNOMCLASS(gboolean a, const char *msg, ...)
|
---|
| 69 | {
|
---|
| 70 | /* sorry, nothing here. */
|
---|
| 71 | }
|
---|
| 72 | # else
|
---|
[221] | 73 | #define DBG_BUILDNOMCLASS(a, b,...)
|
---|
[326] | 74 | # endif
|
---|
[94] | 75 | #endif
|
---|
| 76 |
|
---|
| 77 | /********************************************************/
|
---|
| 78 |
|
---|
| 79 | /********************************************************/
|
---|
| 80 |
|
---|
| 81 | extern PNOM_ENV pGlobalNomEnv;
|
---|
[326] | 82 | extern gulong thunk[];
|
---|
| 83 | extern gulong mThunkCode[];
|
---|
[94] | 84 |
|
---|
| 85 | /********************************************************/
|
---|
| 86 |
|
---|
| 87 | /*
|
---|
| 88 | Create the SOMClassPriv structure and fill it with info
|
---|
| 89 | from the sci. This is a general function when building classes.
|
---|
| 90 |
|
---|
| 91 | This function does
|
---|
| 92 |
|
---|
| 93 | -allocate the memory for the struct depending on the sci info
|
---|
| 94 | -creates the mtab in this memory
|
---|
| 95 | -fills all the necessary pointers in the mtab
|
---|
| 96 | -fills the method addresses in the mtab
|
---|
| 97 |
|
---|
| 98 | It does not insert a class object pointer!
|
---|
| 99 |
|
---|
| 100 | */
|
---|
| 101 | static NOMClassPriv *buildNOMClassPrivStruct(nomStaticClassInfo *sci, NOMClassPriv *ncpParent)
|
---|
| 102 | {
|
---|
| 103 | gulong gulParentDataSize=0;
|
---|
| 104 | gulong mtabSize;
|
---|
| 105 | gulong gulMemSize=0;
|
---|
| 106 | NOMClassPriv *nClass;
|
---|
| 107 |
|
---|
| 108 | BUILDNOMCLASS_ENTER
|
---|
| 109 |
|
---|
| 110 | /* ulMemsize will be the size of our private class structure SOMClassPriv */
|
---|
| 111 | gulMemSize=sizeof(NOMClassPriv)-sizeof(nomMethodTab); /* start size class struct. somMethodTab will be calculated later */
|
---|
| 112 |
|
---|
| 113 | /* Calculate size of new class object */
|
---|
[221] | 114 | DBG_BUILDNOMCLASS(TRUE, "ncParent->mtab->mtabSize: %d\n", ncpParent->mtab->mtabSize);
|
---|
[94] | 115 |
|
---|
| 116 | mtabSize=ncpParent->mtab->mtabSize+sizeof(nomMethodProc*)*(sci->ulNumStaticMethods)+sizeof(NOMClass*);/* numStaticMethods is correct here!
|
---|
| 117 | NOT numStaticMethods-1!
|
---|
| 118 | entries[0] in fact contains the
|
---|
| 119 | class pointer not a method
|
---|
| 120 | pointer. */
|
---|
| 121 | gulMemSize+=mtabSize; /* add space for new procs and the new class pointer in addition to parent stuff */
|
---|
| 122 |
|
---|
| 123 | gulParentDataSize=ncpParent->mtab->ulInstanceSize; /* Parent instance size. This is the mtab pointer + instance vars */
|
---|
| 124 |
|
---|
[221] | 125 | DBG_BUILDNOMCLASS(TRUE,"mtabSize is: %d, ulParentDataSize is: %d (instance vars + mtab ptr)\n",
|
---|
| 126 | mtabSize, gulParentDataSize);
|
---|
| 127 | DBG_BUILDNOMCLASS(TRUE, "sci->numStaticMethods: %d\n", sci->ulNumStaticMethods);
|
---|
[94] | 128 |
|
---|
| 129 | /* Alloc private class struct using SOMCalloc. */
|
---|
[326] | 130 | if((nClass=(NOMClassPriv*)NOMCalloc(1, gulMemSize))==NULL)
|
---|
| 131 | return NULL;
|
---|
[94] | 132 |
|
---|
[221] | 133 | /* Get mem for method thunking code. This assembler code is needed so the indirect
|
---|
| 134 | jump to the methods from the object pointer which is known does work. For each class
|
---|
| 135 | an individual thunking code must be calculated because the number of instance
|
---|
| 136 | variables is not defined. */
|
---|
| 137 | #if 0
|
---|
| 138 | //Moved to addMethodAndDataToThisPrivClassStruct()
|
---|
| 139 | if(0!=sci->ulNumStaticMethods){
|
---|
| 140 | nClass->mThunk=NOMMalloc(sizeof(nomMethodThunk)*sci->ulNumStaticMethods);
|
---|
| 141 | if(!nClass->mThunk) {
|
---|
| 142 | NOMFree(nClass);
|
---|
[326] | 143 | return NULL;
|
---|
[221] | 144 | }
|
---|
[94] | 145 | }
|
---|
[221] | 146 | #endif
|
---|
[94] | 147 | /* The size of each instance of this class. A NOM object has a method tab pointer
|
---|
| 148 | at the beginning followed by the instance variables. */
|
---|
| 149 | nClass->ulClassSize=sci->ulInstanceDataSize+gulParentDataSize;
|
---|
| 150 | nClass->ulPrivClassSize=gulMemSize; /* This will not be seen by any user */
|
---|
| 151 |
|
---|
| 152 | /* Add class struct of this class and the parent one.
|
---|
| 153 | This includes resolving the method adresses of our new class
|
---|
| 154 | (parent ones are already resolved) including adding the thunking
|
---|
| 155 | code . This is essentially done by just copying the parents
|
---|
| 156 | mtab-entries[] to our new one before adding our own methods.
|
---|
| 157 | sci will be saved in nClass->sci */
|
---|
[221] | 158 | //#warning !!!!! Move mem alloc for thunking into this func !!!!!
|
---|
| 159 | if(!addMethodAndDataToThisPrivClassStruct( nClass, ncpParent, sci)){
|
---|
| 160 | NOMFree(nClass);
|
---|
[326] | 161 | return NULL;
|
---|
[221] | 162 | };
|
---|
[94] | 163 |
|
---|
| 164 | /**********************************/
|
---|
| 165 | /* Fill methodtable mtab */
|
---|
| 166 | /**********************************/
|
---|
| 167 | nClass->mtab->mtabSize=mtabSize;
|
---|
| 168 | nClass->mtab->nomClsInfo=(nomClassInfo*)nClass; /* Hold a pointer to the private data that is this NOMClassPriv */
|
---|
[326] | 169 | #ifndef _MSC_VER
|
---|
[94] | 170 | #warning !!!!! Change this when nomId is a GQuark !!!!!
|
---|
[326] | 171 | #endif
|
---|
[94] | 172 | nClass->mtab->nomClassName=*sci->nomClassId;
|
---|
| 173 | nClass->mtab->ulInstanceSize=sci->ulInstanceDataSize+gulParentDataSize; /* Size of instance data of this class and all
|
---|
| 174 | parent classes + size of mtab pointer. */
|
---|
| 175 |
|
---|
| 176 | //#warning !!!!!!!!! No overrride methods yet!!
|
---|
| 177 | /* Resolve ovverrides if any */
|
---|
| 178 | priv_resolveOverrideMethods(nClass, sci);
|
---|
| 179 |
|
---|
| 180 | BUILDNOMCLASS_LEAVE
|
---|
| 181 | return nClass;
|
---|
| 182 | }
|
---|
| 183 |
|
---|
| 184 |
|
---|
| 185 | /*
|
---|
| 186 | Build NOMClass. This function will only called once when bootstrapping the object system.
|
---|
| 187 |
|
---|
| 188 | NOMClass the root of all Meta classes. This will also become the meta class of NOMObject, we
|
---|
| 189 | already created. This is done by updating NOMObject when all the structures for NOMClass
|
---|
| 190 | are created and filled with info.
|
---|
| 191 | */
|
---|
| 192 | NOMClass * NOMLINK priv_buildNOMClass(gulong ulReserved,
|
---|
| 193 | nomStaticClassInfo *sci,
|
---|
| 194 | gulong majorVersion,
|
---|
| 195 | gulong minorVersion)
|
---|
| 196 | {
|
---|
| 197 | NOMClassPriv *nClass;
|
---|
[139] | 198 | gulong ulParentDataSize=0;
|
---|
[94] | 199 | NOMClassPriv *ncpParent;
|
---|
| 200 | NOMClass *nomClass;
|
---|
| 201 |
|
---|
| 202 | #ifdef DEBUG_BUILDNOMCLASS
|
---|
| 203 | nomParentMtabStructPtr pParentMtab;
|
---|
| 204 | nomMethodTabs psmTab;
|
---|
| 205 | nomPrintf("\n%d: Entering %s\n", __LINE__, __FUNCTION__);
|
---|
| 206 | _dumpSci(sci);
|
---|
| 207 | #endif
|
---|
| 208 |
|
---|
| 209 | /* We don't support replacing NOMObject so we don't have to search
|
---|
| 210 | the class list for the current parent but just take the NOMClassPriv
|
---|
| 211 | pointer of NOMObject we saved in the NOM env. Be aware that this structure
|
---|
| 212 | doesn't have a class object pointer yet. We won't use it but just
|
---|
| 213 | as a remark if you want to screw this code... */
|
---|
| 214 | if(pGlobalNomEnv->ncpNOMObject)
|
---|
| 215 | ncpParent=pGlobalNomEnv->ncpNOMObject;
|
---|
| 216 | else{
|
---|
| 217 | g_error("No NOMObject while trying to build NOMClass."); /* This will result in a termination of the app! */
|
---|
[326] | 218 | return NULL; /* NOMClass *must* have an object as parent!
|
---|
[94] | 219 | We won't reach this point */
|
---|
| 220 | }
|
---|
| 221 |
|
---|
| 222 | #ifdef DEBUG_BUILDNOMCLASS
|
---|
| 223 | pParentMtab=&ncpParent->parentMtabStruct;
|
---|
| 224 | nomPrintf(" %d: parent priv class: %s (%x), pParentMtab->mtab %x, next: %x\n",
|
---|
| 225 | __LINE__, ncpParent->mtab->nomClassName,
|
---|
| 226 | ncpParent, pParentMtab->mtab, pParentMtab->next);
|
---|
| 227 | /* climb parent list */
|
---|
| 228 | psmTab=pParentMtab->next;
|
---|
| 229 | while(psmTab) {
|
---|
| 230 | nomPrintf(" next class: %s\n", psmTab->mtab->nomClassName);
|
---|
| 231 | psmTab=psmTab->next;
|
---|
| 232 | }
|
---|
| 233 | #endif
|
---|
| 234 |
|
---|
| 235 | /* Build the NOMClassPriv for NOMClass */
|
---|
[326] | 236 | if((nClass=buildNOMClassPrivStruct(sci, ncpParent))==NULL)
|
---|
| 237 | return NULL;
|
---|
[94] | 238 |
|
---|
| 239 | ulParentDataSize=ncpParent->mtab->ulInstanceSize; /* Parent instance size. This is the mtab pointer + instance vars */
|
---|
| 240 | //nomPrintf("%s line %d: SOMClassPriv: %x ulParentDataSize %d\n", __FILE__, __LINE__, nClass, sci->ulInstanceDataSize+ulParentDataSize);
|
---|
| 241 |
|
---|
| 242 | /* And now the NOMClass struct. A NOMClass has a mTab pointer at the beginning and the instance data
|
---|
| 243 | following (including the parent instance data).*/
|
---|
[326] | 244 | if((nomClass=(NOMClass*)NOMCalloc(1, sci->ulInstanceDataSize+ulParentDataSize))==NULL) {
|
---|
[94] | 245 | NOMFree(nClass->mThunk);
|
---|
| 246 | NOMFree(nClass);
|
---|
[326] | 247 | return NULL;
|
---|
[94] | 248 | }
|
---|
| 249 |
|
---|
| 250 | nomClass->mtab=nClass->mtab; /* Now it's an object */
|
---|
| 251 |
|
---|
| 252 | nClass->mtab->nomClassObject=nomClass;
|
---|
| 253 | sci->nomCds->nomClassObject=nomClass; /* Put class pointer in static struct. Meta class of SOMClass is SOMClass */
|
---|
| 254 | *nClass->entries0=nomClass;
|
---|
| 255 | /* Mark that we are a metaclass */
|
---|
[210] | 256 | //nClass->ulIsMetaClass=1;
|
---|
| 257 | nClass->ulClassFlags|=NOM_FLG_IS_METACLASS;
|
---|
[94] | 258 |
|
---|
| 259 | fillCClassDataStructParentMtab(sci, nClass, nomClass);
|
---|
| 260 |
|
---|
| 261 | /*
|
---|
| 262 | Note:
|
---|
| 263 |
|
---|
| 264 | SOMClass is almost ready now. What's missing is the class object for SOMObject (which is SOMClass
|
---|
| 265 | derived from). The class object pointer must be found in mtab->entries[0]. We have to create
|
---|
| 266 | a class object for SOMObject now, update it properly put the pointer into our mtab and update
|
---|
| 267 | the already built SOMObject.
|
---|
| 268 | */
|
---|
| 269 |
|
---|
| 270 |
|
---|
| 271 | /* The NOMClass is built. Insert it as meta class into the NOMObject class.
|
---|
| 272 | The instance vars must be properly setup otherwise this object won't be
|
---|
| 273 | able to create instances. Put it as the class object into the static
|
---|
| 274 | class data sturcture of NOMObject. Update the mtab of our just built
|
---|
| 275 | SOMClass. */
|
---|
| 276 | nomClass->mtab->entries[0]=
|
---|
| 277 | (nomMethodProc*) createNOMObjectClassObjectAndUpdateNOMObject(nomClass, nClass,
|
---|
| 278 | sci->ulInstanceDataSize+ulParentDataSize);
|
---|
| 279 |
|
---|
| 280 | pGlobalNomEnv->nomObjectMetaClass=(NOMClass*)nomClass->mtab->entries[0];
|
---|
| 281 |
|
---|
[221] | 282 | DBG_BUILDNOMCLASS(TRUE, "mtab: %x New class ptr (class object SOMClass): %x (SOMClassPriv: %x) for %s\n",
|
---|
| 283 | nomClass->mtab, nomClass, nClass, *sci->nomClassId);
|
---|
[94] | 284 |
|
---|
| 285 | pGlobalNomEnv->defaultMetaClass=nomClass;
|
---|
| 286 |
|
---|
[326] | 287 | #ifndef _MSC_VER
|
---|
[94] | 288 | #warning !!!!! _nomSetInstanceSize() not called !!!!!
|
---|
[326] | 289 | #endif
|
---|
[94] | 290 | #if 0
|
---|
| 291 | /* Set this class size into instance var */
|
---|
| 292 | _somSetInstanceSize(somClass, sClass->ulClassSize /* sci->instanceDataSize+ulParentDataSize*/ ); /* This includes exactly one mtab pointer */
|
---|
| 293 | #endif
|
---|
| 294 |
|
---|
| 295 | /* Run initialization code if any */
|
---|
[326] | 296 | _nomInit(nomClass, NULL);
|
---|
[94] | 297 | return nomClass;
|
---|
| 298 | }
|
---|
| 299 |
|
---|
| 300 |
|
---|
| 301 |
|
---|
| 302 |
|
---|
| 303 |
|
---|