source: trunk/nom/src/nombuildnomcls.c@ 221

Last change on this file since 221 was 221, checked in by cinc, 19 years ago

Changes...

File size: 12.0 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-2006
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#define INCL_DOS
36#define INCL_DOSERRORS
37
38#include <os2.h>
39#include <stdio.h>
40
41#include <glib.h>
42#define SOM_NO_OBJECTS /* Otherwise som.h includes the IBM SOM classes */
43
44/* For somToken etc. */
45#include <nom.h>
46#include <nomtk.h>
47#include <nomobj.h>
48
49/********************************************************/
50
51/* Define if you want to have messages from nomBuildClass() and friends */
52//#define DEBUG_NOMBUILDCLASS
53/* Define if you want to have messages from building NOMObject */
54//#define DEBUG_BUILDNOMOBJECT
55/* Define if you want to have messages from building NOMClass */
56//#define DEBUG_BUILDNOMCLASS
57
58#ifdef DEBUG_BUILDNOMCLASS
59 #define BUILDNOMCLASS_ENTER nomPrintf("\n%d: *** entering %s...\n",__LINE__, __FUNCTION__);
60 #define BUILDNOMCLASS_LEAVE nomPrintf("%d: *** Leaving %s...\n\n",__LINE__, __FUNCTION__);
61 #define DBG_BUILDNOMCLASS(a, b,...) if(a) nomPrintf("%d: " b , __LINE__, __VA_ARGS__);
62#else
63 #define BUILDNOMCLASS_ENTER
64 #define BUILDNOMCLASS_LEAVE
65 #define DBG_BUILDNOMCLASS(a, b,...)
66#endif
67
68/********************************************************/
69
70/********************************************************/
71
72extern PNOM_ENV pGlobalNomEnv;
73extern ULONG thunk[];
74extern ULONG mThunkCode[];
75
76/********************************************************/
77
78/*
79 Create the SOMClassPriv structure and fill it with info
80 from the sci. This is a general function when building classes.
81
82 This function does
83
84 -allocate the memory for the struct depending on the sci info
85 -creates the mtab in this memory
86 -fills all the necessary pointers in the mtab
87 -fills the method addresses in the mtab
88
89 It does not insert a class object pointer!
90
91 */
92static NOMClassPriv *buildNOMClassPrivStruct(nomStaticClassInfo *sci, NOMClassPriv *ncpParent)
93{
94 gulong gulParentDataSize=0;
95 gulong mtabSize;
96 gulong gulMemSize=0;
97 NOMClassPriv *nClass;
98
99BUILDNOMCLASS_ENTER
100
101 /* ulMemsize will be the size of our private class structure SOMClassPriv */
102 gulMemSize=sizeof(NOMClassPriv)-sizeof(nomMethodTab); /* start size class struct. somMethodTab will be calculated later */
103
104 /* Calculate size of new class object */
105 DBG_BUILDNOMCLASS(TRUE, "ncParent->mtab->mtabSize: %d\n", ncpParent->mtab->mtabSize);
106
107 mtabSize=ncpParent->mtab->mtabSize+sizeof(nomMethodProc*)*(sci->ulNumStaticMethods)+sizeof(NOMClass*);/* numStaticMethods is correct here!
108 NOT numStaticMethods-1!
109 entries[0] in fact contains the
110 class pointer not a method
111 pointer. */
112 gulMemSize+=mtabSize; /* add space for new procs and the new class pointer in addition to parent stuff */
113
114 gulParentDataSize=ncpParent->mtab->ulInstanceSize; /* Parent instance size. This is the mtab pointer + instance vars */
115
116 DBG_BUILDNOMCLASS(TRUE,"mtabSize is: %d, ulParentDataSize is: %d (instance vars + mtab ptr)\n",
117 mtabSize, gulParentDataSize);
118 DBG_BUILDNOMCLASS(TRUE, "sci->numStaticMethods: %d\n", sci->ulNumStaticMethods);
119
120 /* Alloc private class struct using SOMCalloc. */
121 if((nClass=(NOMClassPriv*)NOMCalloc(1, gulMemSize))==NULLHANDLE)
122 return NULLHANDLE;
123
124 /* Get mem for method thunking code. This assembler code is needed so the indirect
125 jump to the methods from the object pointer which is known does work. For each class
126 an individual thunking code must be calculated because the number of instance
127 variables is not defined. */
128#if 0
129 //Moved to addMethodAndDataToThisPrivClassStruct()
130 if(0!=sci->ulNumStaticMethods){
131 nClass->mThunk=NOMMalloc(sizeof(nomMethodThunk)*sci->ulNumStaticMethods);
132 if(!nClass->mThunk) {
133 NOMFree(nClass);
134 return NULLHANDLE;
135 }
136 }
137#endif
138 /* The size of each instance of this class. A NOM object has a method tab pointer
139 at the beginning followed by the instance variables. */
140 nClass->ulClassSize=sci->ulInstanceDataSize+gulParentDataSize;
141 nClass->ulPrivClassSize=gulMemSize; /* This will not be seen by any user */
142
143 /* Add class struct of this class and the parent one.
144 This includes resolving the method adresses of our new class
145 (parent ones are already resolved) including adding the thunking
146 code . This is essentially done by just copying the parents
147 mtab-entries[] to our new one before adding our own methods.
148 sci will be saved in nClass->sci */
149 //#warning !!!!! Move mem alloc for thunking into this func !!!!!
150 if(!addMethodAndDataToThisPrivClassStruct( nClass, ncpParent, sci)){
151 NOMFree(nClass);
152 return NULLHANDLE;
153 };
154
155 /**********************************/
156 /* Fill methodtable mtab */
157 /**********************************/
158 nClass->mtab->mtabSize=mtabSize;
159 nClass->mtab->nomClsInfo=(nomClassInfo*)nClass; /* Hold a pointer to the private data that is this NOMClassPriv */
160#warning !!!!! Change this when nomId is a GQuark !!!!!
161 nClass->mtab->nomClassName=*sci->nomClassId;
162 nClass->mtab->ulInstanceSize=sci->ulInstanceDataSize+gulParentDataSize; /* Size of instance data of this class and all
163 parent classes + size of mtab pointer. */
164
165 //#warning !!!!!!!!! No overrride methods yet!!
166 /* Resolve ovverrides if any */
167 priv_resolveOverrideMethods(nClass, sci);
168
169 BUILDNOMCLASS_LEAVE
170 return nClass;
171}
172
173
174/*
175 Build NOMClass. This function will only called once when bootstrapping the object system.
176
177 NOMClass the root of all Meta classes. This will also become the meta class of NOMObject, we
178 already created. This is done by updating NOMObject when all the structures for NOMClass
179 are created and filled with info.
180 */
181NOMClass * NOMLINK priv_buildNOMClass(gulong ulReserved,
182 nomStaticClassInfo *sci,
183 gulong majorVersion,
184 gulong minorVersion)
185{
186 NOMClassPriv *nClass;
187 gulong ulParentDataSize=0;
188 NOMClassPriv *ncpParent;
189 NOMClass *nomClass;
190
191#ifdef DEBUG_BUILDNOMCLASS
192 nomParentMtabStructPtr pParentMtab;
193 nomMethodTabs psmTab;
194 nomPrintf("\n%d: Entering %s\n", __LINE__, __FUNCTION__);
195 _dumpSci(sci);
196#endif
197
198 /* We don't support replacing NOMObject so we don't have to search
199 the class list for the current parent but just take the NOMClassPriv
200 pointer of NOMObject we saved in the NOM env. Be aware that this structure
201 doesn't have a class object pointer yet. We won't use it but just
202 as a remark if you want to screw this code... */
203 if(pGlobalNomEnv->ncpNOMObject)
204 ncpParent=pGlobalNomEnv->ncpNOMObject;
205 else{
206 g_error("No NOMObject while trying to build NOMClass."); /* This will result in a termination of the app! */
207 return NULLHANDLE; /* NOMClass *must* have an object as parent!
208 We won't reach this point */
209 }
210
211#ifdef DEBUG_BUILDNOMCLASS
212 pParentMtab=&ncpParent->parentMtabStruct;
213 nomPrintf(" %d: parent priv class: %s (%x), pParentMtab->mtab %x, next: %x\n",
214 __LINE__, ncpParent->mtab->nomClassName,
215 ncpParent, pParentMtab->mtab, pParentMtab->next);
216 /* climb parent list */
217 psmTab=pParentMtab->next;
218 while(psmTab) {
219 nomPrintf(" next class: %s\n", psmTab->mtab->nomClassName);
220 psmTab=psmTab->next;
221 }
222#endif
223
224 /* Build the NOMClassPriv for NOMClass */
225 if((nClass=buildNOMClassPrivStruct(sci, ncpParent))==NULLHANDLE)
226 return NULLHANDLE;
227
228 ulParentDataSize=ncpParent->mtab->ulInstanceSize; /* Parent instance size. This is the mtab pointer + instance vars */
229 //nomPrintf("%s line %d: SOMClassPriv: %x ulParentDataSize %d\n", __FILE__, __LINE__, nClass, sci->ulInstanceDataSize+ulParentDataSize);
230
231 /* And now the NOMClass struct. A NOMClass has a mTab pointer at the beginning and the instance data
232 following (including the parent instance data).*/
233 if((nomClass=(NOMClass*)NOMCalloc(1, sci->ulInstanceDataSize+ulParentDataSize))==NULLHANDLE) {
234 NOMFree(nClass->mThunk);
235 NOMFree(nClass);
236 return NULLHANDLE;
237 }
238
239 nomClass->mtab=nClass->mtab; /* Now it's an object */
240
241 nClass->mtab->nomClassObject=nomClass;
242 sci->nomCds->nomClassObject=nomClass; /* Put class pointer in static struct. Meta class of SOMClass is SOMClass */
243 *nClass->entries0=nomClass;
244 /* Mark that we are a metaclass */
245 //nClass->ulIsMetaClass=1;
246 nClass->ulClassFlags|=NOM_FLG_IS_METACLASS;
247
248 fillCClassDataStructParentMtab(sci, nClass, nomClass);
249
250 /*
251 Note:
252
253 SOMClass is almost ready now. What's missing is the class object for SOMObject (which is SOMClass
254 derived from). The class object pointer must be found in mtab->entries[0]. We have to create
255 a class object for SOMObject now, update it properly put the pointer into our mtab and update
256 the already built SOMObject.
257 */
258
259
260 /* The NOMClass is built. Insert it as meta class into the NOMObject class.
261 The instance vars must be properly setup otherwise this object won't be
262 able to create instances. Put it as the class object into the static
263 class data sturcture of NOMObject. Update the mtab of our just built
264 SOMClass. */
265 nomClass->mtab->entries[0]=
266 (nomMethodProc*) createNOMObjectClassObjectAndUpdateNOMObject(nomClass, nClass,
267 sci->ulInstanceDataSize+ulParentDataSize);
268
269 pGlobalNomEnv->nomObjectMetaClass=(NOMClass*)nomClass->mtab->entries[0];
270
271 DBG_BUILDNOMCLASS(TRUE, "mtab: %x New class ptr (class object SOMClass): %x (SOMClassPriv: %x) for %s\n",
272 nomClass->mtab, nomClass, nClass, *sci->nomClassId);
273
274 pGlobalNomEnv->defaultMetaClass=nomClass;
275
276#warning !!!!! _nomSetInstanceSize() not called !!!!!
277#if 0
278 /* Set this class size into instance var */
279 _somSetInstanceSize(somClass, sClass->ulClassSize /* sci->instanceDataSize+ulParentDataSize*/ ); /* This includes exactly one mtab pointer */
280#endif
281
282 /* Run initialization code if any */
283 _nomInit(nomClass, NULLHANDLE);
284 return nomClass;
285}
286
287
288
289
290
Note: See TracBrowser for help on using the repository browser.