36 instSize <SmallInteger> the number of instance variables |
36 instSize <SmallInteger> the number of instance variables |
37 flags <SmallInteger> special flag bits coded in a number |
37 flags <SmallInteger> special flag bits coded in a number |
38 |
38 |
39 NOTICE: layout known by compiler and runtime system; be careful when changing |
39 NOTICE: layout known by compiler and runtime system; be careful when changing |
40 |
40 |
41 $Header: /cvs/stx/stx/libbasic/Behavior.st,v 1.5 1993-11-08 02:29:06 claus Exp $ |
41 $Header: /cvs/stx/stx/libbasic/Behavior.st,v 1.6 1993-12-11 00:41:45 claus Exp $ |
42 written Dec 88 by claus |
42 written Dec 88 by claus |
43 '! |
43 '! |
44 |
44 |
45 !Behavior class methodsFor:'queries'! |
45 !Behavior class methodsFor:'queries'! |
46 |
46 |
78 "to catch reinitialize for classes which do not" |
78 "to catch reinitialize for classes which do not" |
79 |
79 |
80 ^ self |
80 ^ self |
81 ! ! |
81 ! ! |
82 |
82 |
|
83 !Behavior methodsFor:'copying'! |
|
84 |
|
85 deepCopy |
|
86 "return a deep copy of the receiver |
|
87 - return the receiver here - time will show if this is ok" |
|
88 |
|
89 ^ self |
|
90 ! |
|
91 |
|
92 deepCopyUsing:aDictionary |
|
93 "return a deep copy of the receiver |
|
94 - return the receiver here - time will show if this is ok" |
|
95 |
|
96 ^ self |
|
97 ! |
|
98 |
|
99 simpleDeepCopy |
|
100 "return a deep copy of the receiver |
|
101 - return the receiver here - time will show if this is ok" |
|
102 |
|
103 ^ self |
|
104 ! ! |
|
105 |
83 !Behavior methodsFor:'creating an instance of myself'! |
106 !Behavior methodsFor:'creating an instance of myself'! |
84 |
107 |
85 uninitializedNew |
108 uninitializedNew |
86 "same as new - only redefined in ByteArray" |
109 "same as new - only redefined in ByteArray" |
87 |
110 |
113 ** Do not redefine this method in any class **" |
136 ** Do not redefine this method in any class **" |
114 |
137 |
115 %{ /* NOCONTEXT */ |
138 %{ /* NOCONTEXT */ |
116 |
139 |
117 extern char *newNextPtr, *newEndPtr; |
140 extern char *newNextPtr, *newEndPtr; |
|
141 OBJ new(); |
118 OBJ newobj; |
142 OBJ newobj; |
119 int instsize; |
143 int instsize; |
120 REGISTER int nInstVars; |
144 REGISTER int nInstVars; |
121 #if !defined(memset4) |
145 #if !defined(memset4) |
122 # if !defined(FAST_MEMSET) || defined(NEGATIVE_ADDRESSES) |
146 # if !defined(FAST_MEMSET) || defined(NEGATIVE_ADDRESSES) |
124 # endif |
148 # endif |
125 #endif |
149 #endif |
126 |
150 |
127 nInstVars = _intVal(_INST(instSize)); |
151 nInstVars = _intVal(_INST(instSize)); |
128 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ); |
152 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ); |
129 PROTECT(self); |
153 if (_CanDoQuickAlignedNew(instsize)) { |
130 _qAlignedNew(newobj, instsize, SENDER); |
154 _qCheckedAlignedNew(newobj, instsize); |
131 UNPROTECT(self); |
155 /* stupid: c-compilers should find this out themselfes ... */ |
|
156 goto ok; |
|
157 } else { |
|
158 PROTECT_CONTEXT |
|
159 newobj = new(instsize, SENDER); |
|
160 UNPROTECT_CONTEXT |
|
161 } |
|
162 |
132 if (newobj != nil) { |
163 if (newobj != nil) { |
|
164 ok: |
133 _InstPtr(newobj)->o_class = self; |
165 _InstPtr(newobj)->o_class = self; |
134 |
166 |
135 if (nInstVars) { |
167 if (nInstVars) { |
136 #if defined(memset4) |
168 #if defined(memset4) |
137 memset4(_InstPtr(newobj)->i_instvars, nil, nInstVars); |
169 memset4(_InstPtr(newobj)->i_instvars, nil, nInstVars); |
178 extern OBJ new(); |
210 extern OBJ new(); |
179 |
211 |
180 if (_isSmallInteger(anInteger)) { |
212 if (_isSmallInteger(anInteger)) { |
181 nindexedinstvars = _intVal(anInteger); |
213 nindexedinstvars = _intVal(anInteger); |
182 if (nindexedinstvars >= 0) { |
214 if (nindexedinstvars >= 0) { |
|
215 PROTECT_CONTEXT |
183 nInstVars = _intVal(_INST(instSize)); |
216 nInstVars = _intVal(_INST(instSize)); |
184 flags = _intVal(_INST(flags)) & ARRAYMASK; |
217 flags = _intVal(_INST(flags)) & ARRAYMASK; |
185 switch (flags) { |
218 switch (flags) { |
186 case BYTEARRAY: |
219 case BYTEARRAY: |
187 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ) + nindexedinstvars * sizeof(char); |
220 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ) + nindexedinstvars * sizeof(char); |
188 PROTECT(self); |
|
189 _qNew(newobj, instsize, SENDER); |
221 _qNew(newobj, instsize, SENDER); |
190 UNPROTECT(self); |
222 UNPROTECT_CONTEXT |
191 if (newobj == nil) { |
223 if (newobj == nil) { |
192 break; |
224 break; |
193 } |
225 } |
194 _InstPtr(newobj)->o_class = self; |
226 _InstPtr(newobj)->o_class = self; |
195 #if defined(FAST_MEMSET) && ! defined(NEGATIVE_ADDRESSES) |
227 #if defined(FAST_MEMSET) && ! defined(NEGATIVE_ADDRESSES) |
213 RETURN ( newobj ); |
245 RETURN ( newobj ); |
214 break; |
246 break; |
215 |
247 |
216 case WORDARRAY: |
248 case WORDARRAY: |
217 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ) + nindexedinstvars * sizeof(short); |
249 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ) + nindexedinstvars * sizeof(short); |
218 PROTECT(self); |
|
219 _qNew(newobj, instsize, SENDER); |
250 _qNew(newobj, instsize, SENDER); |
220 UNPROTECT(self); |
251 UNPROTECT_CONTEXT |
221 if (newobj == nil) { |
252 if (newobj == nil) { |
222 break; |
253 break; |
223 } |
254 } |
224 _InstPtr(newobj)->o_class = self; |
255 _InstPtr(newobj)->o_class = self; |
225 #if defined(FAST_MEMSET) && ! defined(NEGATIVE_ADDRESSES) |
256 #if defined(FAST_MEMSET) && ! defined(NEGATIVE_ADDRESSES) |
238 RETURN ( newobj ); |
269 RETURN ( newobj ); |
239 break; |
270 break; |
240 |
271 |
241 case LONGARRAY: |
272 case LONGARRAY: |
242 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ) + nindexedinstvars * sizeof(long); |
273 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ) + nindexedinstvars * sizeof(long); |
243 PROTECT(self); |
|
244 _qAlignedNew(newobj, instsize, SENDER); |
274 _qAlignedNew(newobj, instsize, SENDER); |
245 UNPROTECT(self); |
275 UNPROTECT_CONTEXT |
246 if (newobj == nil) { |
276 if (newobj == nil) { |
247 break; |
277 break; |
248 } |
278 } |
249 _InstPtr(newobj)->o_class = self; |
279 _InstPtr(newobj)->o_class = self; |
250 #if defined(memset4) && ! defined(NEGATIVE_ADDRESSES) |
280 #if defined(memset4) && ! defined(NEGATIVE_ADDRESSES) |
270 RETURN ( newobj ); |
300 RETURN ( newobj ); |
271 break; |
301 break; |
272 |
302 |
273 case FLOATARRAY: |
303 case FLOATARRAY: |
274 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ) + nindexedinstvars * sizeof(float); |
304 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ) + nindexedinstvars * sizeof(float); |
275 PROTECT(self); |
|
276 _qNew(newobj, instsize, SENDER); |
305 _qNew(newobj, instsize, SENDER); |
277 UNPROTECT(self); |
306 UNPROTECT_CONTEXT |
278 if (newobj == nil) { |
307 if (newobj == nil) { |
279 break; |
308 break; |
280 } |
309 } |
281 _InstPtr(newobj)->o_class = self; |
310 _InstPtr(newobj)->o_class = self; |
282 op = _InstPtr(newobj)->i_instvars; |
311 op = _InstPtr(newobj)->i_instvars; |
288 RETURN ( newobj ); |
317 RETURN ( newobj ); |
289 break; |
318 break; |
290 |
319 |
291 case DOUBLEARRAY: |
320 case DOUBLEARRAY: |
292 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ) + nindexedinstvars * sizeof(double); |
321 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ) + nindexedinstvars * sizeof(double); |
293 PROTECT(self); |
|
294 _qNew(newobj, instsize, SENDER); |
322 _qNew(newobj, instsize, SENDER); |
295 UNPROTECT(self); |
323 UNPROTECT_CONTEXT |
296 if (newobj == nil) { |
324 if (newobj == nil) { |
297 break; |
325 break; |
298 } |
326 } |
299 _InstPtr(newobj)->o_class = self; |
327 _InstPtr(newobj)->o_class = self; |
300 op = _InstPtr(newobj)->i_instvars; |
328 op = _InstPtr(newobj)->i_instvars; |
308 |
336 |
309 case WKPOINTERARRAY: |
337 case WKPOINTERARRAY: |
310 case POINTERARRAY: |
338 case POINTERARRAY: |
311 nInstVars += nindexedinstvars; |
339 nInstVars += nindexedinstvars; |
312 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ); |
340 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ); |
313 PROTECT(self); |
|
314 _qAlignedNew(newobj, instsize, SENDER); |
341 _qAlignedNew(newobj, instsize, SENDER); |
315 UNPROTECT(self); |
342 UNPROTECT_CONTEXT |
316 if (newobj == nil) { |
343 if (newobj == nil) { |
317 break; |
344 break; |
318 } |
345 } |
319 _InstPtr(newobj)->o_class = self; |
346 _InstPtr(newobj)->o_class = self; |
320 #if defined(memset4) |
347 #if defined(memset4) |
339 * new:n for non-variable classes only allowed if |
366 * new:n for non-variable classes only allowed if |
340 * n == 0 |
367 * n == 0 |
341 */ |
368 */ |
342 if (nindexedinstvars == 0) { |
369 if (nindexedinstvars == 0) { |
343 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ); |
370 instsize = OHDR_SIZE + nInstVars * sizeof(OBJ); |
344 PROTECT(self); |
|
345 _qAlignedNew(newobj, instsize, SENDER); |
371 _qAlignedNew(newobj, instsize, SENDER); |
346 UNPROTECT(self); |
372 UNPROTECT_CONTEXT |
347 if (newobj == nil) { |
373 if (newobj == nil) { |
348 break; |
374 break; |
349 } |
375 } |
350 _InstPtr(newobj)->o_class = self; |
376 _InstPtr(newobj)->o_class = self; |
351 if (nInstVars) { |
377 if (nInstVars) { |
371 } |
397 } |
372 } |
398 } |
373 } |
399 } |
374 %} |
400 %} |
375 . |
401 . |
|
402 "arrive here if something went wrong ... |
|
403 figure out what" |
|
404 |
376 (anInteger isMemberOf:SmallInteger) ifFalse:[ |
405 (anInteger isMemberOf:SmallInteger) ifFalse:[ |
377 self error:'argument to new: must be Integer' |
406 self error:'argument to new: must be Integer' |
378 ] ifTrue:[ |
407 ] ifTrue:[ |
379 (anInteger >= 0) ifTrue:[ |
408 (anInteger < 0) ifTrue:[ |
380 "sorry but this class has no indexed instvars - need 'new' " |
409 self error:'bad (negative) argument to new' |
|
410 ] ifFalse:[ |
381 self isVariable ifFalse:[ |
411 self isVariable ifFalse:[ |
382 self error:'not indexed - cannot create with new:' |
412 self error:'class has no indexed instvars - cannot create with new:' |
383 ] ifTrue:[ |
413 ] ifTrue:[ |
384 ObjectMemory allocationFailureSignal raise |
414 ObjectMemory allocationFailureSignal raise |
385 ] |
415 ] |
386 ] ifFalse:[ |
|
387 self error:'bad (negative) argument to new' |
|
388 ] |
416 ] |
389 ] |
417 ] |
|
418 ! |
|
419 |
|
420 readFrom:aStream |
|
421 "read an objects printed representation from the argument, aStream and return it. |
|
422 The read object must be a kind of myself |
|
423 - to get any object, use 'Object readFrom:...' since everything is kindOf:Object. |
|
424 This is the reverse operation to 'storeOn:'. |
|
425 Notice, that storeOn: does not handle circular references and |
|
426 multiple references to the same object - use storeBinary: for this." |
|
427 |
|
428 |newObject| |
|
429 |
|
430 newObject := Compiler evaluate:aStream. |
|
431 (newObject isKindOf:self) ifFalse:[ |
|
432 self error:('expected ' , self name) |
|
433 ]. |
|
434 ^ newObject |
|
435 |
|
436 "|s| |
|
437 s := WriteStream on:String new. |
|
438 #(1 2 3 4) storeOn:s. |
|
439 Object readFrom:(ReadStream on:s contents) |
|
440 " |
|
441 ! |
|
442 |
|
443 readFromString:aString |
|
444 "create an object from its printed representation |
|
445 (i.e. stored using storeOn: or storeString)" |
|
446 |
|
447 ^ self readFrom:(ReadStream on:aString) |
390 ! ! |
448 ! ! |
391 |
449 |
392 !Behavior methodsFor:'autoload check'! |
450 !Behavior methodsFor:'autoload check'! |
393 |
451 |
394 isLoaded |
452 isLoaded |
919 theClass := theClass superclass |
977 theClass := theClass superclass |
920 ] |
978 ] |
921 ! ! |
979 ! ! |
922 |
980 |
923 !Behavior methodsFor: 'binary storage'! |
981 !Behavior methodsFor: 'binary storage'! |
|
982 |
|
983 readBinaryFrom:aStream |
|
984 "read an objects binary representation from the argument, |
|
985 aStream and return it. |
|
986 The read object must be a kind of myself |
|
987 - to get any object, use 'Object readFrom:...' |
|
988 This is the reverse operation to 'storeBinaryOn:'. " |
|
989 |
|
990 |newObject| |
|
991 |
|
992 newObject := (BinaryInputManager new:1024) readFrom:aStream. |
|
993 (newObject isKindOf:self) ifFalse:[ |
|
994 self error:('expected ' , self name) |
|
995 ]. |
|
996 ^ newObject |
|
997 |
|
998 "|s| |
|
999 s := WriteStream on:ByteArray new. |
|
1000 #(1 2 3 4) storeBinaryOn:s. |
|
1001 Object readBinaryFrom:(ReadStream on:s contents) |
|
1002 " |
|
1003 ! |
924 |
1004 |
925 binaryDefinitionFrom: stream manager: manager |
1005 binaryDefinitionFrom: stream manager: manager |
926 | obj basicSize i | |
1006 | obj basicSize i | |
927 |
1007 |
928 self isPointers ifTrue: [ |
1008 self isPointers ifTrue: [ |