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 |
|
---|
70 | extern PNOM_ENV pGlobalNomEnv;
|
---|
71 | extern ULONG thunk[];
|
---|
72 | extern 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 | */
|
---|
90 | static NOMClassPriv *buildNOMClassPrivStruct(nomStaticClassInfo *sci, NOMClassPriv *ncpParent)
|
---|
91 | {
|
---|
92 | gulong gulParentDataSize=0;
|
---|
93 | gulong mtabSize;
|
---|
94 | gulong gulMemSize=0;
|
---|
95 | NOMClassPriv *nClass;
|
---|
96 |
|
---|
97 | BUILDNOMCLASS_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 | */
|
---|
173 | NOMClass * 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 | nClass->ulClassFlags|=NOM_FLG_IS_METACLASS;
|
---|
239 |
|
---|
240 | fillCClassDataStructParentMtab(sci, nClass, nomClass);
|
---|
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 |
|
---|