Method.st
changeset 159 514c749165c3
parent 142 c7844287bddf
child 176 48061f8659aa
equal deleted inserted replaced
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 ! !