source: trunk/nom/src/nombuildnomcls.c

Last change on this file was 326, checked in by cinc, 17 years ago

Portability patches for Windows, Linux, Darwin by Bird.

File size: 12.2 KB
Line 
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>.
18* Portions created by the Initial Developer are Copyright (C) 2005-2007
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
35#ifdef __OS2__
36# define INCL_DOS
37# define INCL_DOSERRORS
38# include <os2.h>
39#endif /* __OS2__ */
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
53/* Define if you want to have messages from nomBuildClass() and friends */
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__);
63 #define DBG_BUILDNOMCLASS(a, b,...) if(a) nomPrintf("%d: " b , __LINE__, __VA_ARGS__);
64#else
65 #define BUILDNOMCLASS_ENTER
66 #define BUILDNOMCLASS_LEAVE
67# ifdef _MSC_VER
68void _inline DBG_BUILDNOMCLASS(gboolean a, const char *msg, ...)
69{
70 /* sorry, nothing here. */
71}
72# else
73 #define DBG_BUILDNOMCLASS(a, b,...)
74# endif
75#endif
76
77/********************************************************/
78
79/********************************************************/
80
81extern PNOM_ENV pGlobalNomEnv;
82extern gulong thunk[];
83extern gulong mThunkCode[];
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 */
101static NOMClassPriv *buildNOMClassPrivStruct(nomStaticClassInfo *sci, NOMClassPriv *ncpParent)
102{
103 gulong gulParentDataSize=0;
104 gulong mtabSize;
105 gulong gulMemSize=0;
106 NOMClassPriv *nClass;
107
108BUILDNOMCLASS_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 */
114 DBG_BUILDNOMCLASS(TRUE, "ncParent->mtab->mtabSize: %d\n", ncpParent->mtab->mtabSize);
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
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);
128
129 /* Alloc private class struct using SOMCalloc. */
130 if((nClass=(NOMClassPriv*)NOMCalloc(1, gulMemSize))==NULL)
131 return NULL;
132
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);
143 return NULL;
144 }
145 }
146#endif
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 */
158 //#warning !!!!! Move mem alloc for thunking into this func !!!!!
159 if(!addMethodAndDataToThisPrivClassStruct( nClass, ncpParent, sci)){
160 NOMFree(nClass);
161 return NULL;
162 };
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 */
169#ifndef _MSC_VER
170#warning !!!!! Change this when nomId is a GQuark !!!!!
171#endif
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 */
192NOMClass * NOMLINK priv_buildNOMClass(gulong ulReserved,
193 nomStaticClassInfo *sci,
194 gulong majorVersion,
195 gulong minorVersion)
196{
197 NOMClassPriv *nClass;
198 gulong ulParentDataSize=0;
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! */
218 return NULL; /* NOMClass *must* have an object as parent!
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 */
236 if((nClass=buildNOMClassPrivStruct(sci, ncpParent))==NULL)
237 return NULL;
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).*/
244 if((nomClass=(NOMClass*)NOMCalloc(1, sci->ulInstanceDataSize+ulParentDataSize))==NULL) {
245 NOMFree(nClass->mThunk);
246 NOMFree(nClass);
247 return NULL;
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 */
256 //nClass->ulIsMetaClass=1;
257 nClass->ulClassFlags|=NOM_FLG_IS_METACLASS;
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
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);
284
285 pGlobalNomEnv->defaultMetaClass=nomClass;
286
287#ifndef _MSC_VER
288#warning !!!!! _nomSetInstanceSize() not called !!!!!
289#endif
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 */
296 _nomInit(nomClass, NULL);
297 return nomClass;
298}
299
300
301
302
303
Note: See TracBrowser for help on using the repository browser.