changeset 159 | 514c749165c3 |
parent 142 | c7844287bddf |
child 176 | 48061f8659aa |
158:be947d4e7fb2 | 159:514c749165c3 |
---|---|
1 " |
1 " |
2 COPYRIGHT (c) 1989 by Claus Gittinger |
2 COPYRIGHT (c) 1989 by Claus Gittinger |
3 All Rights Reserved |
3 All Rights Reserved |
4 |
4 |
5 This software is furnished under a license and may be used |
5 This software is furnished under a license and may be used |
6 only in accordance with the terms of that license and with the |
6 only in accordance with the terms of that license and with the |
7 inclusion of the above copyright notice. This software may not |
7 inclusion of the above copyright notice. This software may not |
8 be provided or otherwise made available to, or used by, any |
8 be provided or otherwise made available to, or used by, any |
17 category:'Kernel-Methods' |
17 category:'Kernel-Methods' |
18 ! |
18 ! |
19 |
19 |
20 Method comment:' |
20 Method comment:' |
21 COPYRIGHT (c) 1989 by Claus Gittinger |
21 COPYRIGHT (c) 1989 by Claus Gittinger |
22 All Rights Reserved |
22 All Rights Reserved |
23 |
23 |
24 $Header: /cvs/stx/stx/libbasic/Method.st,v 1.18 1994-08-23 23:09:46 claus Exp $ |
24 $Header: /cvs/stx/stx/libbasic/Method.st,v 1.19 1994-10-10 00:26:43 claus Exp $ |
25 '! |
25 '! |
26 |
26 |
27 !Method class methodsFor:'documentation'! |
27 !Method class methodsFor:'documentation'! |
28 |
28 |
29 copyright |
29 copyright |
30 " |
30 " |
31 COPYRIGHT (c) 1989 by Claus Gittinger |
31 COPYRIGHT (c) 1989 by Claus Gittinger |
32 All Rights Reserved |
32 All Rights Reserved |
33 |
33 |
34 This software is furnished under a license and may be used |
34 This software is furnished under a license and may be used |
35 only in accordance with the terms of that license and with the |
35 only in accordance with the terms of that license and with the |
36 inclusion of the above copyright notice. This software may not |
36 inclusion of the above copyright notice. This software may not |
37 be provided or otherwise made available to, or used by, any |
37 be provided or otherwise made available to, or used by, any |
40 " |
40 " |
41 ! |
41 ! |
42 |
42 |
43 version |
43 version |
44 " |
44 " |
45 $Header: /cvs/stx/stx/libbasic/Method.st,v 1.18 1994-08-23 23:09:46 claus Exp $ |
45 $Header: /cvs/stx/stx/libbasic/Method.st,v 1.19 1994-10-10 00:26:43 claus Exp $ |
46 " |
46 " |
47 ! |
47 ! |
48 |
48 |
49 documentation |
49 documentation |
50 " |
50 " |
65 Do not depend on any value in the flags field - it may change without |
65 Do not depend on any value in the flags field - it may change without |
66 notice. |
66 notice. |
67 |
67 |
68 Instance variables: |
68 Instance variables: |
69 |
69 |
70 source <String> the source itself (if sourcePosition isNil) |
70 source <String> the source itself (if sourcePosition isNil) |
71 or the fileName where the source is found |
71 or the fileName where the source is found |
72 |
72 |
73 sourcePosition <Integer> the position of the methods chunk in the file |
73 sourcePosition <Integer> the position of the methods chunk in the file |
74 |
74 |
75 category <Symbol> the methods category |
75 category <Symbol> the methods category |
76 package <Symbol> the package, in which the methods was defined |
76 package <Symbol> the package, in which the methods was defined |
77 (nil if its the standard system package) |
77 (nil if its the standard system package) |
78 |
78 |
79 WARNING: layout known by compiler and runtime system - dont change |
79 WARNING: layout known by compiler and runtime system - dont change |
80 " |
80 " |
81 ! ! |
81 ! ! |
82 |
82 |
83 !Method class methodsFor:'initialization'! |
83 !Method class methodsFor:'initialization'! |
84 |
84 |
85 initialize |
85 initialize |
86 PrivateMethodSignal isNil ifTrue:[ |
86 PrivateMethodSignal isNil ifTrue:[ |
87 "EXPERIMENTAL" |
87 ExecutableCodeObject initialize. |
88 PrivateMethodSignal := (Signal new) mayProceed:true. |
88 |
89 PrivateMethodSignal notifierString:'attempt to execute private method'. |
89 "EXPERIMENTAL" |
90 PrivateMethodSignal := ExecutionErrorSignal newSignalMayProceed:true. |
|
91 PrivateMethodSignal nameClass:self message:#privateMethodSignal. |
|
92 PrivateMethodSignal notifierString:'attempt to execute private method'. |
|
90 ] |
93 ] |
91 ! ! |
94 ! ! |
92 |
95 |
96 !Method class methodsFor:'signal access'! |
|
97 |
|
98 privateMethodSignal |
|
99 ^ PrivateMethodSignal |
|
100 ! ! |
|
101 |
|
93 !Method class methodsFor:'queries'! |
102 !Method class methodsFor:'queries'! |
94 |
103 |
95 isBuiltInClass |
104 isBuiltInClass |
96 "this class is known by the run-time-system" |
105 "this class is known by the run-time-system" |
97 |
106 |
110 "return the sourcestring for the receiver" |
119 "return the sourcestring for the receiver" |
111 |
120 |
112 |aStream junk| |
121 |aStream junk| |
113 |
122 |
114 source notNil ifTrue:[ |
123 source notNil ifTrue:[ |
115 sourcePosition isNil ifTrue:[^ source]. |
124 sourcePosition isNil ifTrue:[^ source]. |
116 aStream := Smalltalk systemFileStreamFor:('source/' , source). |
125 aStream := Smalltalk systemFileStreamFor:('source/' , source). |
117 aStream notNil ifTrue:[ |
126 aStream notNil ifTrue:[ |
118 aStream position:sourcePosition. |
127 aStream position:sourcePosition. |
119 junk := aStream nextChunk. |
128 junk := aStream nextChunk. |
120 aStream close |
129 aStream close |
121 ] |
130 ] |
122 ]. |
131 ]. |
123 ^ junk |
132 ^ junk |
124 ! |
133 ! |
125 |
134 |
126 source:aString |
135 source:aString |
151 ! |
160 ! |
152 |
161 |
153 comment |
162 comment |
154 "return the methods comment. |
163 "return the methods comment. |
155 This is done by searching for and returning the first comment |
164 This is done by searching for and returning the first comment |
156 from the methods source. |
165 from the methods source (excluding any double-quotes). |
157 Returns nil if there is no comment (or source is not available)." |
166 Returns nil if there is no comment (or source is not available)." |
158 |
167 |
159 |text lines line nQuote index i1 i2 commLines| |
168 |src stream| |
160 |
169 |
161 text := self source. |
170 src := self source. |
162 text isNil ifTrue:[^ nil]. |
171 src isNil ifTrue:[^ nil]. |
163 lines := text asCollectionOfLines. |
172 |
164 (lines size < 2) ifTrue:[^ nil]. |
173 stream := ReadStream on:src. |
165 |
174 (stream skipThrough:Character doubleQuote) isNil ifTrue:[^ nil]. |
166 index := 2. |
175 ^ stream upTo:Character doubleQuote. |
167 |
176 |
168 " |
177 " |
169 skip empty lines |
178 (Method compiledMethodAt:#comment) comment |
170 " |
|
171 line := (lines at:index). |
|
172 [line isBlank] whileTrue:[ |
|
173 index := index + 1. |
|
174 index > lines size ifTrue:[^ nil]. |
|
175 line := (lines at:index). |
|
176 ]. |
|
177 |
|
178 nQuote := line occurrencesOf:(Character doubleQuote). |
|
179 (nQuote == 0) ifTrue:[^ nil]. |
|
180 (nQuote == 2) ifTrue:[^ line]. |
|
181 (nQuote > 2) ifTrue:[ |
|
182 i1 := line indexOf:(Character doubleQuote). |
|
183 i2 := line indexOf:(Character doubleQuote) startingAt:(i1 + 1). |
|
184 ^ line copyFrom:i1+1 to:i2-1 |
|
185 ]. |
|
186 commLines := Text new. |
|
187 commLines add:line. |
|
188 [nQuote ~~ 1] whileTrue:[ |
|
189 index := index + 1. |
|
190 index > lines size ifTrue:[^ nil]. "unclosed comment - could warn here" |
|
191 line := lines at:index. |
|
192 nQuote := line occurrencesOf:(Character doubleQuote). |
|
193 commLines add:line. |
|
194 ]. |
|
195 ^ commLines asString |
|
196 |
|
197 " |
|
198 (Method compiledMethodAt:#comment) comment |
|
199 " |
179 " |
200 ! |
180 ! |
201 |
181 |
202 category |
182 category |
203 "return the methods category or nil" |
183 "return the methods category or nil" |
229 "set the flags (number of method variables, stacksize). |
209 "set the flags (number of method variables, stacksize). |
230 WARNING: for internal use by the compiler only." |
210 WARNING: for internal use by the compiler only." |
231 |
211 |
232 "protect myself a bit - putting in an object would crash me ..." |
212 "protect myself a bit - putting in an object would crash me ..." |
233 (newFlags isMemberOf:SmallInteger) ifTrue:[ |
213 (newFlags isMemberOf:SmallInteger) ifTrue:[ |
234 flags := newFlags |
214 flags := newFlags |
235 ] |
215 ] |
236 ! |
216 ! |
237 |
217 |
238 private:aBoolean |
218 private:aBoolean |
239 "set the flag bit stating that this method is private, and should only be |
219 "set the flag bit stating that this method is private, and should only be |
244 int f = _intVal(_INST(flags)); |
224 int f = _intVal(_INST(flags)); |
245 |
225 |
246 /* made this a primitive to get define in stc.h */ |
226 /* made this a primitive to get define in stc.h */ |
247 #ifdef F_PRIVATE |
227 #ifdef F_PRIVATE |
248 if (aBoolean == true) |
228 if (aBoolean == true) |
249 f = f | F_PRIVATE; |
229 f = f | F_PRIVATE; |
250 else |
230 else |
251 f = f & ~F_PRIVATE; |
231 f = f & ~F_PRIVATE; |
252 _INST(flags) = _MKSMALLINT(f); |
232 _INST(flags) = _MKSMALLINT(f); |
253 #endif |
233 #endif |
254 %} |
234 %} |
255 ! |
235 ! |
256 |
236 |
264 int f = _intVal(_INST(flags)); |
244 int f = _intVal(_INST(flags)); |
265 |
245 |
266 /* made this a primitive to get define in stc.h */ |
246 /* made this a primitive to get define in stc.h */ |
267 #ifdef F_PRIVATE |
247 #ifdef F_PRIVATE |
268 if (f & F_PRIVATE) { |
248 if (f & F_PRIVATE) { |
269 RETURN (true); |
249 RETURN (true); |
270 } |
250 } |
271 #endif |
251 #endif |
272 %}. |
252 %}. |
273 ^ false |
253 ^ false |
274 ! |
254 ! |
282 missing SENDxx functions in the VM and cases in #perform. This too |
262 missing SENDxx functions in the VM and cases in #perform. This too |
283 will be removed in a later release, allowing any number of arguments. |
263 will be removed in a later release, allowing any number of arguments. |
284 - for use by compiler only." |
264 - for use by compiler only." |
285 |
265 |
286 (aNumber between:0 and:self class maxNumberOfArguments) ifFalse:[ |
266 (aNumber between:0 and:self class maxNumberOfArguments) ifFalse:[ |
287 self error:('ST/X only supports up to a maximum of ' , |
267 self error:('ST/X only supports up to a maximum of ' , |
288 self class maxNumberOfArguments printString , |
268 self class maxNumberOfArguments printString , |
289 ' method arguments'). |
269 ' method arguments'). |
290 ^ self |
270 ^ self |
291 ]. |
271 ]. |
292 %{ |
272 %{ |
293 /* made this a primitive to get define in stc.h */ |
273 /* made this a primitive to get define in stc.h */ |
294 #ifdef F_NARGS |
274 #ifdef F_NARGS |
295 _INST(flags) = _MKSMALLINT( (_intVal(_INST(flags)) & ~F_NARGS) | (_intVal(aNumber) << F_NARGSHIFT) ); |
275 _INST(flags) = _MKSMALLINT( (_intVal(_INST(flags)) & ~F_NARGS) | (_intVal(aNumber) << F_NARGSHIFT) ); |
318 ! |
298 ! |
319 |
299 |
320 numberOfMethodVars:aNumber |
300 numberOfMethodVars:aNumber |
321 "set the number of method variables - for use by compiler only. |
301 "set the number of method variables - for use by compiler only. |
322 WARNING: playing around here with incorrect values |
302 WARNING: playing around here with incorrect values |
323 may crash smalltalk badly." |
303 may crash smalltalk badly." |
324 |
304 |
325 %{ /* NOCONTEXT */ |
305 %{ /* NOCONTEXT */ |
326 int f = _intVal(_INST(flags)); |
306 int f = _intVal(_INST(flags)); |
327 |
307 |
328 /* made this a primitive to get define in stc.h */ |
308 /* made this a primitive to get define in stc.h */ |
329 if (_isSmallInteger(aNumber)) { |
309 if (_isSmallInteger(aNumber)) { |
330 f = (f & ~F_NVARS) | (_intVal(aNumber) << F_NVARSHIFT); |
310 f = (f & ~F_NVARS) | (_intVal(aNumber) << F_NVARSHIFT); |
331 _INST(flags) = _MKSMALLINT(f); |
311 _INST(flags) = _MKSMALLINT(f); |
332 } |
312 } |
333 %} |
313 %} |
334 ! |
314 ! |
335 |
315 |
336 numberOfMethodVars |
316 numberOfMethodVars |
348 ! |
328 ! |
349 |
329 |
350 stackSize:aNumber |
330 stackSize:aNumber |
351 "set the depth of the local stack - for use by compiler only. |
331 "set the depth of the local stack - for use by compiler only. |
352 WARNING: playing around here with incorrect values |
332 WARNING: playing around here with incorrect values |
353 may crash smalltalk badly. |
333 may crash smalltalk badly. |
354 (if the runtime library was compiled with DEBUG, |
334 (if the runtime library was compiled with DEBUG, |
355 a bad stack will be detected and triggers an error)" |
335 a bad stack will be detected and triggers an error)" |
356 |
336 |
357 %{ /* NOCONTEXT */ |
337 %{ /* NOCONTEXT */ |
358 int f = _intVal(_INST(flags)); |
338 int f = _intVal(_INST(flags)); |
359 |
339 |
360 /* made this a primitive to get define in stc.h */ |
340 /* made this a primitive to get define in stc.h */ |
361 if (_isSmallInteger(aNumber)) { |
341 if (_isSmallInteger(aNumber)) { |
362 f = (f & ~F_NSTACK) | (_intVal(aNumber) << F_NSTACKSHIFT); |
342 f = (f & ~F_NSTACK) | (_intVal(aNumber) << F_NSTACKSHIFT); |
363 _INST(flags) = _MKSMALLINT(f); |
343 _INST(flags) = _MKSMALLINT(f); |
364 } |
344 } |
365 %} |
345 %} |
366 ! |
346 ! |
367 |
347 |
368 stackSize |
348 stackSize |
378 %} |
358 %} |
379 ! ! |
359 ! ! |
380 |
360 |
381 !Method methodsFor:'queries'! |
361 !Method methodsFor:'queries'! |
382 |
362 |
363 who |
|
364 "return the class and selector of where I am defined in. |
|
365 Since there is no information of the containing class |
|
366 in the method, we have to do a search here. |
|
367 |
|
368 Normally, this is not a problem, except when a method is |
|
369 accepted in the debugger or redefined from within a method |
|
370 (maybe done indirectly, if doIt is done recursively) |
|
371 - the information about which class the original method was |
|
372 defined in is lost in this case. |
|
373 |
|
374 Q: should we add a backref from the method to the class ?" |
|
375 |
|
376 " |
|
377 first, limit the search to global classes only - |
|
378 since probability is high, that the receiver is found in there ... |
|
379 " |
|
380 Smalltalk allBehaviorsDo:[:aClass | |
|
381 |sel| |
|
382 |
|
383 sel := aClass selectorForMethod:self. |
|
384 sel notNil ifTrue:[^ Array with:aClass with:sel]. |
|
385 sel := aClass class selectorForMethod:self. |
|
386 sel notNil ifTrue:[^ Array with:aClass class with:sel]. |
|
387 ]. |
|
388 " |
|
389 mhmh - must be a method of some anonymous class (i.e. one not |
|
390 in the Smalltalk dictionary; search all instances of Behavior |
|
391 " |
|
392 Behavior allDerivedInstancesDo:[:someClass | |
|
393 |sel| |
|
394 |
|
395 sel := someClass selectorForMethod:self. |
|
396 sel notNil ifTrue:[^ Array with:someClass with:sel] |
|
397 ]. |
|
398 " |
|
399 none found - sorry |
|
400 " |
|
401 ^ nil |
|
402 |
|
403 "typical situation: some well-known class" |
|
404 " |
|
405 |m| |
|
406 m := Object compiledMethodAt:#copy. |
|
407 m who |
|
408 " |
|
409 |
|
410 "untypical situation: an anonymous class" |
|
411 " |
|
412 |m cls| |
|
413 |
|
414 Object |
|
415 subclass:#FunnyClass |
|
416 instanceVariableNames:'foo' |
|
417 classVariableNames:'' |
|
418 poolDictionaries:'' |
|
419 category:'testing'. |
|
420 cls := Smalltalk at:#FunnyClass. |
|
421 Smalltalk removeClass:cls. |
|
422 |
|
423 cls compile:'testMethod1:arg foo:=arg'. |
|
424 cls compile:'testMethod2 ^ foo'. |
|
425 m := cls compiledMethodAt:#testMethod1:. |
|
426 |
|
427 m who |
|
428 " |
|
429 ! |
|
430 |
|
383 containingClass |
431 containingClass |
384 "return the class I am defined in. |
432 "return the class I am defined in. |
385 Since there is no information of the containing class |
433 See comment in who." |
386 in the method, we have to search here. |
434 |
387 |
435 "based on who, which has been added for ST-80 compatibility" |
388 Normally, this is not a problem, except when a method is |
436 |
389 accepted in the debugger - the information about which |
437 |pair| |
390 class the original method was in is then lost. |
438 |
391 |
439 pair := self who. |
392 Q: should we add a backref from the method to the class ?" |
440 pair notNil ifTrue:[^ pair at:1]. |
393 |
|
394 Smalltalk allBehaviorsDo:[:aClass | |
|
395 (aClass containsMethod:self) ifTrue:[^ aClass]. |
|
396 (aClass class containsMethod:self) ifTrue:[^ aClass class] |
|
397 ]. |
|
398 " |
|
399 mhmh - must be a method of some anonymous class (i.e. one not |
|
400 in the Smalltalk dictionary; search all instances of Behavior |
|
401 " |
|
402 Behavior allDerivedInstancesDo:[:someClass | |
|
403 (someClass containsMethod:self) ifTrue:[ |
|
404 ^ someClass |
|
405 ]. |
|
406 ]. |
|
407 " |
441 " |
408 none found - sorry |
442 none found - sorry |
409 " |
443 " |
410 ^ nil |
444 ^ nil |
411 ! |
445 ! |
416 |
450 |
417 |parser sourceString| |
451 |parser sourceString| |
418 |
452 |
419 sourceString := self source. |
453 sourceString := self source. |
420 sourceString notNil ifTrue:[ |
454 sourceString notNil ifTrue:[ |
421 parser := Parser parseMethodSpecification:sourceString. |
455 parser := Parser parseMethodSpecification:sourceString. |
422 (parser isNil or:[parser == #Error]) ifTrue:[^ nil]. |
456 (parser isNil or:[parser == #Error]) ifTrue:[^ nil]. |
423 ^ parser methodArgs |
457 ^ parser methodArgs |
424 ]. |
458 ]. |
425 ^ nil |
459 ^ nil |
426 |
460 |
427 " |
461 " |
428 (Method compiledMethodAt:#printOn:) methodArgNames |
462 (Method compiledMethodAt:#printOn:) methodArgNames |
435 |
469 |
436 |parser sourceString| |
470 |parser sourceString| |
437 |
471 |
438 sourceString := self source. |
472 sourceString := self source. |
439 sourceString notNil ifTrue:[ |
473 sourceString notNil ifTrue:[ |
440 parser := Parser parseMethodArgAndVarSpecification:sourceString. |
474 parser := Parser parseMethodArgAndVarSpecification:sourceString. |
441 (parser isNil or:[parser == #Error]) ifTrue:[^ nil]. |
475 (parser isNil or:[parser == #Error]) ifTrue:[^ nil]. |
442 ^ parser methodVars |
476 ^ parser methodVars |
443 ]. |
477 ]. |
444 ^ nil |
478 ^ nil |
445 |
479 |
446 " |
480 " |
447 (Method compiledMethodAt:#printOn:) methodVarNames |
481 (Method compiledMethodAt:#printOn:) methodVarNames |
454 |
488 |
455 |parser sourceString argNames varNames| |
489 |parser sourceString argNames varNames| |
456 |
490 |
457 sourceString := self source. |
491 sourceString := self source. |
458 sourceString notNil ifTrue:[ |
492 sourceString notNil ifTrue:[ |
459 parser := Parser parseMethodArgAndVarSpecification:sourceString. |
493 parser := Parser parseMethodArgAndVarSpecification:sourceString. |
460 (parser isNil or:[parser == #Error]) ifTrue:[^ nil]. |
494 (parser isNil or:[parser == #Error]) ifTrue:[^ nil]. |
461 argNames := parser methodArgs. |
495 argNames := parser methodArgs. |
462 varNames := parser methodVars. |
496 varNames := parser methodVars. |
463 argNames isNil ifTrue:[^ varNames]. |
497 argNames isNil ifTrue:[^ varNames]. |
464 varNames isNil ifTrue:[^ argNames]. |
498 varNames isNil ifTrue:[^ argNames]. |
465 ^ (argNames , varNames) |
499 ^ (argNames , varNames) |
466 ]. |
500 ]. |
467 ^ nil |
501 ^ nil |
468 |
502 |
469 " |
503 " |
470 (Method compiledMethodAt:#printOn:) methodArgAndVarNames |
504 (Method compiledMethodAt:#printOn:) methodArgAndVarNames |
481 (text size < 2) ifTrue:[^nil]. |
515 (text size < 2) ifTrue:[^nil]. |
482 |
516 |
483 line := (text at:2). |
517 line := (text at:2). |
484 nQuote := line occurrencesOf:(Character doubleQuote). |
518 nQuote := line occurrencesOf:(Character doubleQuote). |
485 (nQuote == 2) ifTrue:[ |
519 (nQuote == 2) ifTrue:[ |
486 qIndex := line indexOf:(Character doubleQuote). |
520 qIndex := line indexOf:(Character doubleQuote). |
487 qIndex2 := line indexOf:(Character doubleQuote) startingAt:(qIndex + 1). |
521 qIndex2 := line indexOf:(Character doubleQuote) startingAt:(qIndex + 1). |
488 ^ line copyFrom:(qIndex + 1) to:(qIndex2 - 1) |
522 ^ line copyFrom:(qIndex + 1) to:(qIndex2 - 1) |
489 ]. |
523 ]. |
490 (nQuote == 1) ifTrue:[ |
524 (nQuote == 1) ifTrue:[ |
491 qIndex := line indexOf:(Character doubleQuote). |
525 qIndex := line indexOf:(Character doubleQuote). |
492 comment := line copyFrom:(qIndex + 1). |
526 comment := line copyFrom:(qIndex + 1). |
493 |
527 |
494 index := 3. |
528 index := 3. |
495 line := text at:index. |
529 line := text at:index. |
496 nQuote := line occurrencesOf:(Character doubleQuote). |
530 nQuote := line occurrencesOf:(Character doubleQuote). |
497 [nQuote ~~ 1] whileTrue:[ |
531 [nQuote ~~ 1] whileTrue:[ |
498 comment := comment , Character cr asString , line withoutSpaces. |
532 comment := comment , Character cr asString , line withoutSpaces. |
499 index := index + 1. |
533 index := index + 1. |
500 line := text at:index. |
534 line := text at:index. |
501 nQuote := line occurrencesOf:(Character doubleQuote) |
535 nQuote := line occurrencesOf:(Character doubleQuote) |
502 ]. |
536 ]. |
503 qIndex := line indexOf:(Character doubleQuote). |
537 qIndex := line indexOf:(Character doubleQuote). |
504 ^ comment , Character cr asString , (line copyTo:(qIndex - 1)) withoutSpaces |
538 ^ comment , Character cr asString , (line copyTo:(qIndex - 1)) withoutSpaces |
505 ]. |
539 ]. |
506 ^ nil |
540 ^ nil |
507 |
541 |
508 " |
542 " |
509 (Method compiledMethodAt:#methodComment) methodComment |
543 (Method compiledMethodAt:#methodComment) methodComment |
570 Thus, we arrive here, when playing around in a classes methodArray, |
604 Thus, we arrive here, when playing around in a classes methodArray, |
571 or compiler/runtime system is broken :-(, |
605 or compiler/runtime system is broken :-(, |
572 or you ignore the error messages during some recompile." |
606 or you ignore the error messages during some recompile." |
573 |
607 |
574 ^ InvalidCodeSignal |
608 ^ InvalidCodeSignal |
575 raiseRequestWith:self |
609 raiseRequestWith:self |
576 errorString:'invalid method - not executable'. |
610 errorString:'invalid method - not executable'. |
577 ! |
611 ! |
578 |
612 |
579 wrongNumberOfArguments:numberGiven |
613 wrongNumberOfArguments:numberGiven |
580 "this error is triggered, if a method is called with a wrong number |
614 "this error is triggered, if a method is called with a wrong number |
581 of arguments. This only applies to #valueWithReceiverXXX - sends. |
615 of arguments. This only applies to #valueWithReceiverXXX - sends. |
582 With a normal send, this error cannot happen." |
616 With a normal send, this error cannot happen." |
583 |
617 |
584 ^ ArgumentSignal |
618 ^ ArgumentSignal |
585 raiseRequestWith:self |
619 raiseRequestWith:self |
586 errorString:('method got ' , numberGiven printString , |
620 errorString:('method got ' , numberGiven printString , |
587 ' args while ' , self numberOfMethodArgs printString , ' where expected') |
621 ' args while ' , self numberOfMethodArgs printString , ' where expected') |
588 ! |
622 ! |
589 |
623 |
590 privateMethodCalled |
624 privateMethodCalled |
591 "this error is triggered, if a private method is called from |
625 "this error is triggered, if a private method is called from |
592 outside (i.e. not via a self-send and not via a super-send. |
626 outside (i.e. not via a self-send and not via a super-send. |
658 int nargs; |
692 int nargs; |
659 OBJ *ap; |
693 OBJ *ap; |
660 extern OBJ interpret(); |
694 extern OBJ interpret(); |
661 |
695 |
662 if (__isArray(argArray)) { |
696 if (__isArray(argArray)) { |
663 nargs = _arraySize(argArray); |
697 nargs = _arraySize(argArray); |
664 ap = _ArrayInstPtr(argArray)->a_element; |
698 ap = _ArrayInstPtr(argArray)->a_element; |
665 } else { |
699 } else { |
666 if (argArray == nil) { |
700 if (argArray == nil) { |
667 nargs = 0; |
701 nargs = 0; |
668 } else |
702 } else |
669 nargs = -1; |
703 nargs = -1; |
670 } |
704 } |
671 |
705 |
672 #ifdef F_NARGS |
706 #ifdef F_NARGS |
673 if (((_intVal(_INST(flags)) & F_NARGS) >> F_NARGSHIFT) == nargs) |
707 if (((_intVal(_INST(flags)) & F_NARGS) >> F_NARGSHIFT) == nargs) |
674 #endif |
708 #endif |
675 { |
709 { |
676 code = _MethodInstPtr(self)->m_code; |
710 code = _MethodInstPtr(self)->m_code; |
677 if (aClass == nil) { |
711 if (aClass == nil) { |
678 searchClass = dummy.ilc_class = _Class(anObject); |
712 searchClass = dummy.ilc_class = _Class(anObject); |
679 } else { |
713 } else { |
680 searchClass = dummy.ilc_class = aClass; |
714 searchClass = dummy.ilc_class = aClass; |
681 } |
715 } |
682 |
716 |
683 if (code) { |
717 if (code) { |
684 /* compiled code */ |
718 /* compiled code */ |
685 switch (nargs) { |
719 switch (nargs) { |
686 case 0: |
720 case 0: |
687 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy) ); |
721 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy) ); |
688 |
722 |
689 case 1: |
723 case 1: |
690 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, ap[0]) ); |
724 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, ap[0]) ); |
691 |
725 |
692 case 2: |
726 case 2: |
693 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, ap[0], ap[1]) ); |
727 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, ap[0], ap[1]) ); |
694 |
728 |
695 case 3: |
729 case 3: |
696 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, ap[0], ap[1], ap[2]) ); |
730 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, ap[0], ap[1], ap[2]) ); |
697 |
731 |
698 case 4: |
732 case 4: |
699 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
733 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
700 ap[0], ap[1], ap[2], ap[3]) ); |
734 ap[0], ap[1], ap[2], ap[3]) ); |
701 |
735 |
702 case 5: |
736 case 5: |
703 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
737 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
704 ap[0], ap[1], ap[2], ap[3], ap[4]) ); |
738 ap[0], ap[1], ap[2], ap[3], ap[4]) ); |
705 |
739 |
706 case 6: |
740 case 6: |
707 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
741 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
708 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5]) ); |
742 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5]) ); |
709 |
743 |
710 case 7: |
744 case 7: |
711 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
745 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
712 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6]) ); |
746 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6]) ); |
713 |
747 |
714 case 8: |
748 case 8: |
715 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
749 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
716 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7]) ); |
750 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7]) ); |
717 |
751 |
718 case 9: |
752 case 9: |
719 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
753 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
720 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8]) ); |
754 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8]) ); |
721 |
755 |
722 case 10: |
756 case 10: |
723 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
757 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
724 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], |
758 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], |
725 ap[9]) ); |
759 ap[9]) ); |
726 |
760 |
727 case 11: |
761 case 11: |
728 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
762 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
729 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], |
763 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], |
730 ap[9], ap[10]) ); |
764 ap[9], ap[10]) ); |
731 |
765 |
732 case 12: |
766 case 12: |
733 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
767 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
734 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], |
768 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], |
735 ap[9], ap[10], ap[11]) ); |
769 ap[9], ap[10], ap[11]) ); |
736 |
770 |
737 case 13: |
771 case 13: |
738 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
772 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
739 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], |
773 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], |
740 ap[9], ap[10], ap[11], ap[12]) ); |
774 ap[9], ap[10], ap[11], ap[12]) ); |
741 |
775 |
742 case 14: |
776 case 14: |
743 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
777 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
744 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], |
778 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], |
745 ap[9], ap[10], ap[11], ap[12], ap[13]) ); |
779 ap[9], ap[10], ap[11], ap[12], ap[13]) ); |
746 |
780 |
747 case 15: |
781 case 15: |
748 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
782 RETURN ( (*code)(anObject, aSymbol, SND_COMMA searchClass, &dummy, |
749 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], |
783 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], |
750 ap[9], ap[10], ap[11], ap[12], ap[13], ap[14]) ); |
784 ap[9], ap[10], ap[11], ap[12], ap[13], ap[14]) ); |
751 } |
785 } |
752 } else { |
786 } else { |
753 /* interpreted code */ |
787 /* interpreted code */ |
754 switch (nargs) { |
788 switch (nargs) { |
755 case 0: |
789 case 0: |
756 RETURN ( interpret(self, 0, anObject, aSymbol, SND_COMMA searchClass) ); |
790 RETURN ( interpret(self, 0, anObject, aSymbol, SND_COMMA searchClass) ); |
757 |
791 |
758 case 1: |
792 case 1: |
759 RETURN ( interpret(self, 1, anObject, aSymbol, SND_COMMA searchClass, |
793 RETURN ( interpret(self, 1, anObject, aSymbol, SND_COMMA searchClass, |
760 ap[0]) ); |
794 ap[0]) ); |
761 |
795 |
762 case 2: |
796 case 2: |
763 RETURN ( interpret(self, 2, anObject, aSymbol, SND_COMMA searchClass, |
797 RETURN ( interpret(self, 2, anObject, aSymbol, SND_COMMA searchClass, |
764 ap[0], ap[1]) ); |
798 ap[0], ap[1]) ); |
765 |
799 |
766 case 3: |
800 case 3: |
767 RETURN ( interpret(self, 3, anObject, aSymbol, SND_COMMA searchClass, |
801 RETURN ( interpret(self, 3, anObject, aSymbol, SND_COMMA searchClass, |
768 ap[0], ap[1], ap[2]) ); |
802 ap[0], ap[1], ap[2]) ); |
769 |
803 |
770 case 4: |
804 case 4: |
771 RETURN ( interpret(self, 4, anObject, aSymbol, SND_COMMA searchClass, |
805 RETURN ( interpret(self, 4, anObject, aSymbol, SND_COMMA searchClass, |
772 ap[0], ap[1], ap[2], ap[3]) ); |
806 ap[0], ap[1], ap[2], ap[3]) ); |
773 |
807 |
774 case 5: |
808 case 5: |
775 RETURN ( interpret(self, 5, anObject, aSymbol, SND_COMMA searchClass, |
809 RETURN ( interpret(self, 5, anObject, aSymbol, SND_COMMA searchClass, |
776 ap[0], ap[1], ap[2], ap[3], ap[4]) ); |
810 ap[0], ap[1], ap[2], ap[3], ap[4]) ); |
777 |
811 |
778 case 6: |
812 case 6: |
779 RETURN ( interpret(self, 6, anObject, aSymbol, SND_COMMA searchClass, |
813 RETURN ( interpret(self, 6, anObject, aSymbol, SND_COMMA searchClass, |
780 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5]) ); |
814 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5]) ); |
781 |
815 |
782 case 7: |
816 case 7: |
783 RETURN ( interpret(self, 7, anObject, aSymbol, SND_COMMA searchClass, |
817 RETURN ( interpret(self, 7, anObject, aSymbol, SND_COMMA searchClass, |
784 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6]) ); |
818 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6]) ); |
785 |
819 |
786 case 8: |
820 case 8: |
787 RETURN ( interpret(self, 8, anObject, aSymbol, SND_COMMA searchClass, |
821 RETURN ( interpret(self, 8, anObject, aSymbol, SND_COMMA searchClass, |
788 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
822 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
789 ap[7]) ); |
823 ap[7]) ); |
790 |
824 |
791 case 9: |
825 case 9: |
792 RETURN ( interpret(self, 9, anObject, aSymbol, SND_COMMA searchClass, |
826 RETURN ( interpret(self, 9, anObject, aSymbol, SND_COMMA searchClass, |
793 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
827 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
794 ap[7], ap[8]) ); |
828 ap[7], ap[8]) ); |
795 |
829 |
796 case 10: |
830 case 10: |
797 RETURN ( interpret(self, 10, anObject, aSymbol, SND_COMMA searchClass, |
831 RETURN ( interpret(self, 10, anObject, aSymbol, SND_COMMA searchClass, |
798 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
832 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
799 ap[7], ap[8], ap[9]) ); |
833 ap[7], ap[8], ap[9]) ); |
800 |
834 |
801 case 11: |
835 case 11: |
802 RETURN ( interpret(self, 11, anObject, aSymbol, SND_COMMA searchClass, |
836 RETURN ( interpret(self, 11, anObject, aSymbol, SND_COMMA searchClass, |
803 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
837 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
804 ap[7], ap[8], ap[9], ap[10]) ); |
838 ap[7], ap[8], ap[9], ap[10]) ); |
805 |
839 |
806 case 12: |
840 case 12: |
807 RETURN ( interpret(self, 12, anObject, aSymbol, SND_COMMA searchClass, |
841 RETURN ( interpret(self, 12, anObject, aSymbol, SND_COMMA searchClass, |
808 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
842 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
809 ap[7], ap[8], ap[9], ap[11]) ); |
843 ap[7], ap[8], ap[9], ap[11]) ); |
810 |
844 |
811 case 13: |
845 case 13: |
812 RETURN ( interpret(self, 13, anObject, aSymbol, SND_COMMA searchClass, |
846 RETURN ( interpret(self, 13, anObject, aSymbol, SND_COMMA searchClass, |
813 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
847 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
814 ap[7], ap[8], ap[9], ap[11], ap[12]) ); |
848 ap[7], ap[8], ap[9], ap[11], ap[12]) ); |
815 |
849 |
816 case 14: |
850 case 14: |
817 RETURN ( interpret(self, 14, anObject, aSymbol, SND_COMMA searchClass, |
851 RETURN ( interpret(self, 14, anObject, aSymbol, SND_COMMA searchClass, |
818 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
852 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
819 ap[7], ap[8], ap[9], ap[11], ap[12], ap[13]) ); |
853 ap[7], ap[8], ap[9], ap[11], ap[12], ap[13]) ); |
820 |
854 |
821 case 15: |
855 case 15: |
822 RETURN ( interpret(self, 15, anObject, aSymbol, SND_COMMA searchClass, |
856 RETURN ( interpret(self, 15, anObject, aSymbol, SND_COMMA searchClass, |
823 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
857 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], |
824 ap[7], ap[8], ap[9], ap[11], ap[12], ap[13], ap[14]) ); |
858 ap[7], ap[8], ap[9], ap[11], ap[12], ap[13], ap[14]) ); |
825 } |
859 } |
826 } |
860 } |
827 } |
861 } |
828 %} |
862 %} |
829 . |
863 . |
830 (argArray isMemberOf:Array) ifFalse:[ |
864 (argArray isMemberOf:Array) ifFalse:[ |
831 " |
865 " |
832 arguments must be either nil or an array |
866 arguments must be either nil or an array |
833 " |
867 " |
834 ^ self badArgumentArray |
868 ^ self badArgumentArray |
835 ]. |
869 ]. |
836 (argArray size ~~ self numberOfMethodArgs) ifTrue:[ |
870 (argArray size ~~ self numberOfMethodArgs) ifTrue:[ |
837 " |
871 " |
838 the method expects a different number of arguments |
872 the method expects a different number of arguments |
839 " |
873 " |
840 ^ self wrongNumberOfArguments:argArray size |
874 ^ self wrongNumberOfArguments:argArray size |
841 ]. |
875 ]. |
842 " |
876 " |
843 the VM only supports a limited number of arguments in sends |
877 the VM only supports a limited number of arguments in sends |
844 " |
878 " |
845 ^ self tooManyArguments |
879 ^ self tooManyArguments |
846 |
880 |
847 " |
881 " |
848 (Float compiledMethodAt:#+) |
882 (Float compiledMethodAt:#+) |
849 valueWithReceiver:1.0 arguments:#(2.0) |
883 valueWithReceiver:1.0 arguments:#(2.0) |
850 |
884 |
851 'the next example is a wrong one - which is detected by True's method ...'. |
885 'the next example is a wrong one - which is detected by True's method ...'. |
852 (True compiledMethodAt:#printString) |
886 (True compiledMethodAt:#printString) |
853 valueWithReceiver:false arguments:nil |
887 valueWithReceiver:false arguments:nil |
854 |
888 |
855 'the next example is a wrong one - it is nowhere detected |
889 'the next example is a wrong one - it is nowhere detected |
856 and a wrong value returned ...'. |
890 and a wrong value returned ...'. |
857 (Point compiledMethodAt:#x) |
891 (Point compiledMethodAt:#x) |
858 valueWithReceiver:(1->2) arguments:nil |
892 valueWithReceiver:(1->2) arguments:nil |
859 |
893 |
860 'the next example is VERY bad one - it is nowhere detected |
894 'the next example is VERY bad one - it is nowhere detected |
861 and may crash the system WARNING: save your work before doing this ...'. |
895 and may crash the system WARNING: save your work before doing this ...'. |
862 (Point compiledMethodAt:#x) |
896 (Point compiledMethodAt:#x) |
863 valueWithReceiver:(Object new) arguments:nil |
897 valueWithReceiver:(Object new) arguments:nil |
864 |
898 |
865 'the next example is a wrong one - which is detected here ...'. |
899 'the next example is a wrong one - which is detected here ...'. |
866 (Object compiledMethodAt:#printOn:) |
900 (Object compiledMethodAt:#printOn:) |
867 valueWithReceiver:false arguments:nil |
901 valueWithReceiver:false arguments:nil |
868 |
902 |
869 'the next example is a wrong one - which is detected here ...'. |
903 'the next example is a wrong one - which is detected here ...'. |
870 (Object compiledMethodAt:#printOn:) |
904 (Object compiledMethodAt:#printOn:) |
871 valueWithReceiver:false arguments:#() |
905 valueWithReceiver:false arguments:#() |
872 " |
906 " |
873 ! ! |
907 ! ! |
874 |
908 |
875 !Method methodsFor:'printing & storing'! |
909 !Method methodsFor:'printing & storing'! |
876 |
910 |
879 Since methods do not store their class/selector, we have to search |
913 Since methods do not store their class/selector, we have to search |
880 for it here." |
914 for it here." |
881 |
915 |
882 |myClass| |
916 |myClass| |
883 |
917 |
884 aStream nextPutAll:'a Method('. |
918 aStream nextPutAll:(self classNameWithArticle). |
919 aStream nextPut:$(. |
|
885 myClass := self containingClass. |
920 myClass := self containingClass. |
886 myClass notNil ifTrue:[ |
921 myClass notNil ifTrue:[ |
887 myClass name printOn:aStream. |
922 myClass name printOn:aStream. |
888 aStream nextPutAll:' '. |
923 aStream nextPutAll:' '. |
889 (myClass selectorForMethod:self) printOn:aStream |
924 (myClass selectorForMethod:self) printOn:aStream |
890 ] ifFalse:[ |
925 ] ifFalse:[ |
891 aStream nextPutAll:'???' |
926 aStream nextPutAll:'no class' |
892 ]. |
927 ]. |
893 aStream nextPut:$) |
928 aStream nextPut:$) |
929 ! ! |
|
930 |
|
931 !Method class methodsFor:'binary storage'! |
|
932 |
|
933 binaryDefinitionFrom: stream manager: manager |
|
934 "read my definition from stream." |
|
935 |
|
936 |cls sel| |
|
937 |
|
938 "type-byte" |
|
939 stream nextByte == 0 ifTrue:[ |
|
940 " |
|
941 built-in method |
|
942 " |
|
943 cls := manager nextObject. |
|
944 sel := manager nextObject. |
|
945 |
|
946 " |
|
947 mhmh - on the source system, this was a machinecode |
|
948 method, while here its an interpreted one ... |
|
949 " |
|
950 cls isLoaded ifFalse:[ |
|
951 cls autoload |
|
952 ]. |
|
953 ^ cls compiledMethodAt:sel |
|
954 ]. |
|
955 " |
|
956 bytecode method |
|
957 " |
|
958 ^ super binaryDefinitionFrom:stream manager:manager |
|
894 ! ! |
959 ! ! |
895 |
960 |
896 !Method methodsFor:'binary storage'! |
961 !Method methodsFor:'binary storage'! |
897 |
962 |
898 asByteCodeMethod |
963 asByteCodeMethod |
901 Otherwise, return the receiver. The new method is not installed in |
966 Otherwise, return the receiver. The new method is not installed in |
902 the methodDictionary of any class - just returned. |
967 the methodDictionary of any class - just returned. |
903 Can be used to obtain a bytecode version of a machine-code method |
968 Can be used to obtain a bytecode version of a machine-code method |
904 for binary storage or dynamic recompilation (which is not yet finished)." |
969 for binary storage or dynamic recompilation (which is not yet finished)." |
905 |
970 |
906 |temporaryMethod cls sourceString upd silent| |
971 |temporaryMethod cls sourceString upd silent lazy| |
907 |
972 |
908 byteCode notNil ifTrue:[ |
973 byteCode notNil ifTrue:[ |
909 ^ self |
974 " |
975 is already a bytecoded method |
|
976 " |
|
977 ^ self |
|
910 ]. |
978 ]. |
911 |
979 |
912 cls := self containingClass. |
980 cls := self containingClass. |
981 cls isNil ifTrue:[ |
|
982 'cannot generate bytecode (no class for compilation)' errorPrintNL. |
|
983 ^ nil |
|
984 ]. |
|
913 sourceString := self source. |
985 sourceString := self source. |
914 sourceString isNil ifTrue:[ |
986 sourceString isNil ifTrue:[ |
915 'cannot generate bytecode (no source for compilation)' errorPrintNL. |
987 'cannot generate bytecode (no source for compilation)' errorPrintNL. |
916 ^ nil |
988 ^ nil |
917 ]. |
989 ]. |
918 " |
990 " |
919 dont want this to go into the changes file |
991 dont want this to go into the changes file, |
992 dont want output on Transcript and definitely |
|
993 dont want a lazy method ... |
|
920 " |
994 " |
921 upd := Class updateChanges:false. |
995 upd := Class updateChanges:false. |
922 silent := Smalltalk silentLoading:true. |
996 silent := Smalltalk silentLoading:true. |
997 lazy := Compiler compileLazy:false. |
|
998 |
|
923 [ |
999 [ |
924 temporaryMethod := cls compiler compile:sourceString |
1000 temporaryMethod := cls compiler compile:sourceString |
925 forClass:cls |
1001 forClass:cls |
926 inCategory:(self category) |
1002 inCategory:(self category) |
927 notifying:nil |
1003 notifying:nil |
928 install:false. |
1004 install:false. |
929 ] valueNowOrOnUnwindDo:[ |
1005 ] valueNowOrOnUnwindDo:[ |
930 Class updateChanges:upd. |
1006 Class updateChanges:upd. |
931 Smalltalk silentLoading:silent. |
1007 Compiler compileLazy:lazy. |
1008 Smalltalk silentLoading:silent. |
|
932 ]. |
1009 ]. |
933 (temporaryMethod isNil or:[temporaryMethod == #Error]) ifTrue:[ |
1010 (temporaryMethod isNil or:[temporaryMethod == #Error]) ifTrue:[ |
934 'cannot generate bytecode (contains primitive code or error)' errorPrintNL. |
1011 'cannot generate bytecode (contains primitive code or error)' errorPrintNL. |
935 ^ nil. |
1012 ^ nil. |
936 ]. |
1013 ]. |
937 " |
1014 " |
938 try to save a bit of memory, by sharing the source (whatever it is) |
1015 try to save a bit of memory, by sharing the source (whatever it is) |
939 " |
1016 " |
944 (LargeInteger compiledMethodAt:#normalize) asByteCodeMethod |
1021 (LargeInteger compiledMethodAt:#normalize) asByteCodeMethod |
945 (SmallInteger compiledMethodAt:#+) asByteCodeMethod |
1022 (SmallInteger compiledMethodAt:#+) asByteCodeMethod |
946 " |
1023 " |
947 ! |
1024 ! |
948 |
1025 |
949 storeBinaryDefinitionOn: stream manager: manager |
1026 storeBinaryDefinitionOn:stream manager:manager |
950 "can only store bytecode - machine code is not storable. |
1027 "only store bytecode-methods - machinecode methods are stored |
1028 as class/selector pair and a lookup is done when restored. |
|
1029 |
|
951 If the receiver method is a built-in (i.e. machine coded) |
1030 If the receiver method is a built-in (i.e. machine coded) |
952 method, a temporary interpreted byte code method is created, |
1031 method, a temporary interpreted byte code method is created, |
953 and its bytecode stored. |
1032 and its bytecode stored. |
954 This works only, if the source of the method is available and the |
1033 This works only, if the source of the method is available and the |
955 method does not contain primitive code." |
1034 method does not contain primitive code." |
956 |
1035 |
957 |storedMethod| |
1036 |storedMethod who| |
958 |
1037 |
959 byteCode isNil ifTrue:[ |
1038 byteCode isNil ifTrue:[ |
960 storedMethod := self asByteCodeMethod. |
1039 self code notNil ifTrue:[ |
961 storedMethod isNil ifTrue:[ |
1040 (who := self who) notNil ifTrue:[ |
962 self error:'store of built-in method failed'. |
1041 " |
963 ^ nil |
1042 machine code only - assume its a built-in method, |
964 ]. |
1043 and store the class/selector information. |
965 ^ storedMethod storeBinaryDefinitionOn:stream manager:manager |
1044 The restored method may not be exactly the same ... |
966 ]. |
1045 " |
967 ^ super storeBinaryDefinitionOn:stream manager:manager |
1046 manager putIdOf:(self class) on:stream. |
1047 stream nextPutByte:0. "means built-in method" |
|
1048 manager putIdOf:(who at:1) on:stream. |
|
1049 manager putIdOf:(who at:2) on:stream. |
|
1050 ^ self |
|
1051 ] |
|
1052 ]. |
|
1053 |
|
1054 storedMethod := self asByteCodeMethod. |
|
1055 storedMethod isNil ifTrue:[ |
|
1056 self error:'store of built-in method failed'. |
|
1057 ^ nil |
|
1058 ]. |
|
1059 ^ storedMethod storeBinaryDefinitionOn:stream manager:manager |
|
1060 ]. |
|
1061 |
|
1062 manager putIdOf:(self class) on:stream. |
|
1063 stream nextPutByte:1. "means byte-coded method" |
|
1064 self storeBinaryDefinitionBodyOn:stream manager:manager |
|
1065 ! |
|
1066 |
|
1067 readBinaryContentsFrom: stream manager: manager |
|
1068 "tell the newly restored Font about restoration" |
|
1069 |
|
1070 self code notNil ifTrue:[ |
|
1071 "built-in method - already complete" |
|
1072 ^ self |
|
1073 ]. |
|
1074 |
|
1075 ^ super readBinaryContentsFrom: stream manager: manager |
|
968 ! ! |
1076 ! ! |
969 |
|
970 !Method methodsFor:'obsolete binary fileOut'! |
|
971 |
|
972 binaryFileOutLiteralsOn:aStream |
|
973 |index n| |
|
974 |
|
975 literals isNil ifTrue:[ |
|
976 aStream nextPutAll:'0'. |
|
977 aStream nextPut:$!!. |
|
978 ^ self |
|
979 ]. |
|
980 aStream nextPutAll:literals size printString. |
|
981 aStream nextPut:$!!. |
|
982 |
|
983 index := 1. |
|
984 literals do:[:lit | |
|
985 lit isNumber ifTrue:[ |
|
986 lit storeOn:aStream |
|
987 ] ifFalse:[ |
|
988 ((lit isKindOf:String) or:[lit isKindOf:Character]) ifTrue:[ |
|
989 lit storeOn:aStream |
|
990 ] ifFalse:[ |
|
991 (lit isKindOf:Array) ifTrue:[ |
|
992 aStream nextPut:$(. |
|
993 lit storeOn:aStream. |
|
994 aStream nextPut:$) |
|
995 ] ifFalse:[ |
|
996 lit isBehavior ifTrue:[ |
|
997 aStream nextPutAll:'(Smalltalk at:#'. |
|
998 n := lit name. |
|
999 lit isMeta ifTrue:[ |
|
1000 n := (n copyTo:(n size - 5)) , ') class' |
|
1001 ] ifFalse:[ |
|
1002 n := n , ')' |
|
1003 ]. |
|
1004 aStream nextPutAll:n |
|
1005 ] ifFalse:[ |
|
1006 self error:('invalid literal ' , lit class name) |
|
1007 ] |
|
1008 ] |
|
1009 ] |
|
1010 ]. |
|
1011 aStream nextPut:$!!. |
|
1012 index := index + 1 |
|
1013 ] |
|
1014 ! |
|
1015 |
|
1016 binaryFileOutOn:aStream |
|
1017 byteCode isNil ifTrue:[ |
|
1018 self notify:'no bytecodes to fileout'. |
|
1019 ^ self |
|
1020 ]. |
|
1021 self binaryFileOutLiteralsOn:aStream. |
|
1022 |
|
1023 flags storeOn:aStream. |
|
1024 aStream nextPut:$!!. |
|
1025 |
|
1026 byteCode size storeOn:aStream. |
|
1027 aStream nextPut:$!!. |
|
1028 aStream nextPutBytes:(byteCode size) from:byteCode |
|
1029 ! ! |