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

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

Only use GLib types.

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