Behavior.st
changeset 620 c7353f86a302
parent 528 a083413dfbe8
child 642 dbf407bedf64
equal deleted inserted replaced
619:95efb21c1fac 620:c7353f86a302
     9  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
    13 Object subclass:#Behavior
    13 Object subclass:#Behavior
    14        instanceVariableNames:'superclass flags selectorArray methodArray
    14 	 instanceVariableNames:'superclass flags selectorArray methodArray otherSuperclasses
    15 			      otherSuperclasses instSize'
    15                 instSize'
    16        classVariableNames:'SubclassInfo'
    16 	 classVariableNames:'SubclassInfo'
    17        poolDictionaries:''
    17 	 poolDictionaries:''
    18        category:'Kernel-Classes'
    18 	 category:'Kernel-Classes'
    19 !
    19 !
    20 
    20 
    21 !Behavior class methodsFor:'documentation'!
    21 !Behavior class methodsFor:'documentation'!
    22 
    22 
    23 copyright
    23 copyright
    30  inclusion of the above copyright notice.   This software may not
    30  inclusion of the above copyright notice.   This software may not
    31  be provided or otherwise made available to, or used by, any
    31  be provided or otherwise made available to, or used by, any
    32  other person.  No title to or ownership of the software is
    32  other person.  No title to or ownership of the software is
    33  hereby transferred.
    33  hereby transferred.
    34 "
    34 "
    35 !
       
    36 
       
    37 version
       
    38     ^ '$Header: /cvs/stx/stx/libbasic/Behavior.st,v 1.52 1995-11-11 14:26:59 cg Exp $'
       
    39 !
    35 !
    40 
    36 
    41 documentation
    37 documentation
    42 "
    38 "
    43     Every class in the system inherits from Behavior (via Class, ClassDescription);
    39     Every class in the system inherits from Behavior (via Class, ClassDescription);
    88 
    84 
    89     NOTICE: layout known by compiler and runtime system; be careful when changing
    85     NOTICE: layout known by compiler and runtime system; be careful when changing
    90 "
    86 "
    91 !
    87 !
    92 
    88 
       
    89 version
       
    90     ^ '$Header: /cvs/stx/stx/libbasic/Behavior.st,v 1.53 1995-11-23 10:45:04 cg Exp $'
       
    91 !
       
    92 
    93 virtualMachineRelationship 
    93 virtualMachineRelationship 
    94 "
    94 "
    95     NOTICE: 
    95     NOTICE: 
    96 	the stuff described below may not be available on other
    96 	the stuff described below may not be available on other
    97 	Smalltalk implementations; be aware that these error mechanisms
    97 	Smalltalk implementations; be aware that these error mechanisms
   252 	with: 
   252 	with: 
   253 		'Smalltalk debugPrinting:false'
   253 		'Smalltalk debugPrinting:false'
   254 	and: 
   254 	and: 
   255 		'Smalltalk infoPrinting:false'
   255 		'Smalltalk infoPrinting:false'
   256 "
   256 "
   257 ! !
       
   258 
       
   259 !Behavior class methodsFor:'queries'!
       
   260 
       
   261 isBuiltInClass
       
   262     "this class is known by the run-time-system"
       
   263 
       
   264     ^ true
       
   265 ! !
   257 ! !
   266 
   258 
   267 !Behavior class methodsFor:'creating new classes'!
   259 !Behavior class methodsFor:'creating new classes'!
   268 
   260 
   269 new
   261 new
   297      Metaclass new new          <- an instance (i.e. a class) of it
   289      Metaclass new new          <- an instance (i.e. a class) of it
   298      Metaclass new new new      <- an instance of this new class
   290      Metaclass new new new      <- an instance of this new class
   299     "
   291     "
   300 ! !
   292 ! !
   301 
   293 
       
   294 !Behavior class methodsFor:'flag bit constants'!
       
   295 
       
   296 flagBehavior
       
   297     "return the flag code which marks Behavior-like instances.
       
   298      You have to check this single bit in the flag value when
       
   299      checking for behaviors."
       
   300 
       
   301 %{  /* NOCONTEXT */
       
   302     /* this is defined as a primitive to get defines from stc.h */
       
   303 
       
   304     RETURN ( _MKSMALLINT(BEHAVIOR_INSTS) );
       
   305 %}
       
   306 
       
   307     "consistency check:
       
   308      all class-entries must be behaviors;
       
   309      all behaviors must be flagged so (in its class's flags)
       
   310      (otherwise, VM will bark)
       
   311      all non-behaviors may not be flagged
       
   312 
       
   313      |bit|
       
   314      bit := Class flagBehavior.
       
   315 
       
   316      ObjectMemory allObjectsDo:[:o|
       
   317        o isBehavior ifTrue:[
       
   318 	 (o class flags bitTest:bit) ifFalse:[
       
   319 	     self halt
       
   320 	 ].
       
   321        ] ifFalse:[
       
   322 	 (o class flags bitTest:bit) ifTrue:[
       
   323 	     self halt
       
   324 	 ].
       
   325        ].
       
   326        o class isBehavior ifFalse:[
       
   327 	 self halt
       
   328        ] ifTrue:[
       
   329 	 (o class class flags bitTest:bit) ifFalse:[
       
   330 	     self halt
       
   331 	 ]
       
   332        ]
       
   333      ]
       
   334     "
       
   335 !
       
   336 
       
   337 flagBlock
       
   338     "return the flag code which marks Block-like instances.
       
   339      You have to check this single bit in the flag value when
       
   340      checking for blocks."
       
   341 
       
   342 %{  /* NOCONTEXT */
       
   343     /* this is defined as a primitive to get defines from stc.h */
       
   344 
       
   345     RETURN ( _MKSMALLINT(BLOCK_INSTS) );
       
   346 %}
       
   347 !
       
   348 
       
   349 flagBlockContext
       
   350     "return the flag code which marks BlockContext-like instances.
       
   351      You have to check this single bit in the flag value when
       
   352      checking for blockContexts."
       
   353 
       
   354 %{  /* NOCONTEXT */
       
   355     /* this is defined as a primitive to get defines from stc.h */
       
   356 
       
   357     RETURN ( _MKSMALLINT(BCONTEXT_INSTS) );
       
   358 %}
       
   359 !
       
   360 
       
   361 flagBytes
       
   362     "return the flag code for byte-valued indexed instances.
       
   363      You have to mask the flag value with indexMask when comparing
       
   364      it with flagBytes."
       
   365 
       
   366 %{  /* NOCONTEXT */
       
   367     /* this is defined as a primitive to get defines from stc.h */
       
   368 
       
   369     RETURN ( _MKSMALLINT(BYTEARRAY) );
       
   370 %}
       
   371     "
       
   372      Behavior flagBytes    
       
   373     "
       
   374 !
       
   375 
       
   376 flagContext
       
   377     "return the flag code which marks Context-like instances.
       
   378      You have to check this single bit in the flag value when
       
   379      checking for contexts."
       
   380 
       
   381 %{  /* NOCONTEXT */
       
   382     /* this is defined as a primitive to get defines from stc.h */
       
   383 
       
   384     RETURN ( _MKSMALLINT(CONTEXT_INSTS) );
       
   385 %}
       
   386 !
       
   387 
       
   388 flagDoubles
       
   389     "return the flag code for double-valued indexed instances (i.e. 8-byte reals).
       
   390      You have to mask the flag value with indexMask when comparing
       
   391      it with flagDoubles."
       
   392 
       
   393 %{  /* NOCONTEXT */
       
   394     /* this is defined as a primitive to get defines from stc.h */
       
   395 
       
   396     RETURN ( _MKSMALLINT(DOUBLEARRAY) );
       
   397 %}
       
   398     "
       
   399      Behavior flagDoubles    
       
   400     "
       
   401 !
       
   402 
       
   403 flagFloat
       
   404     "return the flag code which marks Float-like instances.
       
   405      You have to check this single bit in the flag value when
       
   406      checking for floats."
       
   407 
       
   408 %{  /* NOCONTEXT */
       
   409     /* this is defined as a primitive to get defines from stc.h */
       
   410 
       
   411     RETURN ( _MKSMALLINT(FLOAT_INSTS) );
       
   412 %}
       
   413 !
       
   414 
       
   415 flagFloats
       
   416     "return the flag code for float-valued indexed instances (i.e. 4-byte reals).
       
   417      You have to mask the flag value with indexMask when comparing
       
   418      it with flagFloats."
       
   419 
       
   420 %{  /* NOCONTEXT */
       
   421     /* this is defined as a primitive to get defines from stc.h */
       
   422 
       
   423     RETURN ( _MKSMALLINT(FLOATARRAY) );
       
   424 %}
       
   425     "
       
   426      Behavior flagFloats    
       
   427     "
       
   428 !
       
   429 
       
   430 flagLongs
       
   431     "return the flag code for long-valued indexed instances (i.e. 4-byte).
       
   432      You have to mask the flag value with indexMask when comparing
       
   433      it with flagLongs."
       
   434 
       
   435 %{  /* NOCONTEXT */
       
   436     /* this is defined as a primitive to get defines from stc.h */
       
   437 
       
   438     RETURN ( _MKSMALLINT(LONGARRAY) );
       
   439 %}
       
   440     "
       
   441      Behavior flagLongs    
       
   442     "
       
   443 !
       
   444 
       
   445 flagMethod
       
   446     "return the flag code which marks Method-like instances.
       
   447      You have to check this single bit in the flag value when
       
   448      checking for methods."
       
   449 
       
   450 %{  /* NOCONTEXT */
       
   451     /* this is defined as a primitive to get defines from stc.h */
       
   452 
       
   453     RETURN ( _MKSMALLINT(METHOD_INSTS) );
       
   454 %}
       
   455 !
       
   456 
       
   457 flagNonObjectInst
       
   458     "return the flag code which marks instances which have a
       
   459      non-object instance variable (in slot 1).
       
   460      (these are ignored by the garbage collector)"
       
   461 
       
   462 %{  /* NOCONTEXT */
       
   463     /* this is defined as a primitive to get defines from stc.h */
       
   464 
       
   465     RETURN ( _MKSMALLINT(NONOBJECT_INSTS) );
       
   466 %}
       
   467 !
       
   468 
       
   469 flagNotIndexed
       
   470     "return the flag code for non-indexed instances.
       
   471      You have to mask the flag value with indexMask when comparing
       
   472      it with flagNotIndexed."
       
   473 
       
   474     ^ 0
       
   475 !
       
   476 
       
   477 flagPointers
       
   478     "return the flag code for pointer indexed instances (i.e. Array of object).
       
   479      You have to mask the flag value with indexMask when comparing
       
   480      it with flagPointers."
       
   481 
       
   482 %{  /* NOCONTEXT */
       
   483     /* this is defined as a primitive to get defines from stc.h */
       
   484 
       
   485     RETURN ( _MKSMALLINT(POINTERARRAY) );
       
   486 %}
       
   487     "
       
   488      Behavior flagPointers    
       
   489     "
       
   490 !
       
   491 
       
   492 flagSymbol
       
   493     "return the flag code which marks Symbol-like instances.
       
   494      You have to check this single bit in the flag value when
       
   495      checking for symbols."
       
   496 
       
   497 %{  /* NOCONTEXT */
       
   498     /* this is defined as a primitive to get defines from stc.h */
       
   499 
       
   500     RETURN ( _MKSMALLINT(SYMBOL_INSTS) );
       
   501 %}
       
   502 !
       
   503 
       
   504 flagWeakPointers
       
   505     "return the flag code for weak pointer indexed instances (i.e. WeakArray).
       
   506      You have to mask the flag value with indexMask when comparing
       
   507      it with flagWeakPointers."
       
   508 
       
   509 %{  /* NOCONTEXT */
       
   510     /* this is defined as a primitive to get defines from stc.h */
       
   511 
       
   512     RETURN ( _MKSMALLINT(WKPOINTERARRAY) );
       
   513 %}
       
   514 !
       
   515 
       
   516 flagWords
       
   517     "return the flag code for word-valued indexed instances (i.e. 2-byte).
       
   518      You have to mask the flag value with indexMask when comparing
       
   519      it with flagWords."
       
   520 
       
   521 %{  /* NOCONTEXT */
       
   522     /* this is defined as a primitive to get defines from stc.h */
       
   523 
       
   524     RETURN ( _MKSMALLINT(WORDARRAY) );
       
   525 %}
       
   526     "
       
   527      Behavior flagWords    
       
   528     "
       
   529 !
       
   530 
       
   531 maskIndexType
       
   532     "return a mask to extract all index-type bits"
       
   533 
       
   534 %{  /* NOCONTEXT */
       
   535     /* this is defined as a primitive to get defines from stc.h */
       
   536 
       
   537     RETURN ( _MKSMALLINT(ARRAYMASK) );
       
   538 %}
       
   539 ! !
       
   540 
   302 !Behavior class methodsFor:'private '!
   541 !Behavior class methodsFor:'private '!
       
   542 
       
   543 flushSubclassInfo
       
   544     SubclassInfo := nil.
       
   545 
       
   546     "
       
   547      Class flushSubclassInfo
       
   548     "
       
   549 !
   303 
   550 
   304 subclassInfo
   551 subclassInfo
   305     |d|
   552     |d|
   306 
   553 
   307     SubclassInfo notNil ifTrue:[^ SubclassInfo].
   554     SubclassInfo notNil ifTrue:[^ SubclassInfo].
   325     ^ d
   572     ^ d
   326 
   573 
   327     "
   574     "
   328      Class subclassInfo
   575      Class subclassInfo
   329     "
   576     "
   330 !
   577 ! !
   331 
   578 
   332 flushSubclassInfo
   579 !Behavior class methodsFor:'queries'!
       
   580 
       
   581 isBuiltInClass
       
   582     "this class is known by the run-time-system"
       
   583 
       
   584     ^ true
       
   585 ! !
       
   586 
       
   587 !Behavior methodsFor:'accessing'!
       
   588 
       
   589 addSelector:newSelector withLazyMethod:newMethod
       
   590     "add the method given by 2nd argument under the selector given by
       
   591      1st argument to the methodDictionary. Since it does not flush
       
   592      any caches, this is only allowed for lazy methods."
       
   593 
       
   594     newMethod isLazyMethod ifFalse:[
       
   595 	self error:'operation only allowed for lazy methods'.
       
   596 	^ false
       
   597     ].
       
   598     "/ oops: we must flush, if this method already exists ...
       
   599     (selectorArray includes:newSelector) ifTrue:[
       
   600 	ObjectMemory flushCaches
       
   601     ].
       
   602     (self primAddSelector:newSelector withMethod:newMethod) ifTrue:[
       
   603 	self changed:#methodDictionary with:newSelector.
       
   604 	^ true
       
   605     ].
       
   606     ^ false
       
   607 !
       
   608 
       
   609 addSelector:newSelector withMethod:newMethod
       
   610     "add the method given by 2nd argument under the selector given by
       
   611      1st argument to the methodDictionary. Flush all caches."
       
   612 
       
   613     |nargs|
       
   614 
       
   615     (self primAddSelector:newSelector withMethod:newMethod) ifFalse:[^ false].
       
   616     self changed:#methodDictionary with:newSelector.
       
   617 
       
   618     "
       
   619      if I have no subclasses, all we have to flush is cached
       
   620      data for myself ... (actually, in any case all that needs
       
   621      to be flushed is info for myself and all of my subclasses)
       
   622     "
       
   623 "
       
   624     problem: this is slower; since looking for all subclasses is (currently)
       
   625 	     a bit slow :-(
       
   626 	     We need the hasSubclasses-info bit in Behavior; now
       
   627 
       
   628     self withAllSubclassesDo:[:aClass |
       
   629 	ObjectMemory flushInlineCachesFor:aClass withArgs:nargs.
       
   630 	ObjectMemory flushMethodCacheFor:aClass
       
   631     ].
       
   632 "
       
   633 
       
   634     "
       
   635      actually, we would do better with less flushing ...
       
   636     "
       
   637     nargs := newSelector numArgs.
       
   638 
       
   639     ObjectMemory flushMethodCache.
       
   640     ObjectMemory flushInlineCachesWithArgs:nargs.
       
   641 
       
   642     ^ true
       
   643 !
       
   644 
       
   645 addSuperclass:aClass
       
   646     "EXPERIMENTAL MI support: add aClass to the set of classes, from which instances
       
   647      inherit protocol."
       
   648 
       
   649     "first, check if the class is abstract - 
       
   650      allows abstract mixins are allowed in the current implementation"
       
   651 
       
   652     aClass instSize == 0 ifFalse:[
       
   653 	self error:'only abstract mixins allowed'.
       
   654 	^ self
       
   655     ].
       
   656     otherSuperclasses isNil ifTrue:[
       
   657 	otherSuperclasses := Array with:aClass
       
   658     ] ifFalse:[
       
   659 	otherSuperclasses := otherSuperclasses copyWith:aClass
       
   660     ].
   333     SubclassInfo := nil.
   661     SubclassInfo := nil.
   334 
   662     ObjectMemory flushCaches
   335     "
   663 !
   336      Class flushSubclassInfo
   664 
   337     "
   665 category
       
   666     "return the category of the class. 
       
   667      Returning nil here, since Behavior does not define a category
       
   668      (only ClassDescriptions do)."
       
   669 
       
   670     ^ nil
       
   671 
       
   672     "
       
   673      Point category                
       
   674      Behavior new category           
       
   675     "
       
   676 !
       
   677 
       
   678 displayString
       
   679     "although behaviors have no name, we return something
       
   680      useful here - there are many places (inspectors) where
       
   681      a classes name is asked for.
       
   682      Implementing this message here allows instances of anonymous classes
       
   683      to show a reasonable name."
       
   684 
       
   685     ^ 'someBehavior'
       
   686 !
       
   687 
       
   688 flags
       
   689     "return the receivers flag bits"
       
   690 
       
   691     ^ flags
       
   692 !
       
   693 
       
   694 implicit_methodDict 
       
   695     "ST-80 compatibility.
       
   696      This allows subclasses to assume there is an instance variable
       
   697      named methodDict."
       
   698 
       
   699     ^ self methodDictionary
       
   700 !
       
   701 
       
   702 implicit_methodDict:aDictionary 
       
   703     "ST-80 compatibility.
       
   704      This allows subclasses to assume there is an instance variable
       
   705      named methodDict."
       
   706 
       
   707     ^ self error:'not allowed to set the methodDictionary'
       
   708 !
       
   709 
       
   710 instSize
       
   711     "return the number of instance variables of the receiver.
       
   712      This includes all superclass instance variables."
       
   713 
       
   714     ^ instSize
       
   715 !
       
   716 
       
   717 methodArray
       
   718     "return the receivers method array.
       
   719      Notice: this is not compatible with ST-80."
       
   720 
       
   721     ^ methodArray
       
   722 !
       
   723 
       
   724 methodDictionary
       
   725     "return the receivers method dictionary. 
       
   726      Since no dictionary is actually present, create one for ST-80 compatibility."
       
   727 
       
   728     |dict n "{ Class: SmallInteger }"|
       
   729 
       
   730     dict := IdentityDictionary new.
       
   731     n := selectorArray size.
       
   732     1 to:n do:[:index |
       
   733 	dict at:(selectorArray at:index) put:(methodArray at:index)
       
   734     ].
       
   735     ^ dict
       
   736 !
       
   737 
       
   738 name
       
   739     "although behaviors have no name, we return something
       
   740      useful here - there are many places (inspectors) where
       
   741      a classes name is asked for.
       
   742      Implementing this message here allows anonymous classes
       
   743      and instances of them to be inspected."
       
   744 
       
   745     ^ 'someBehavior'
       
   746 !
       
   747 
       
   748 removeSelector:aSelector
       
   749     "remove the selector, aSelector and its associated method 
       
   750      from the methodDictionary"
       
   751 
       
   752     |index oldSelectorArray oldMethodArray newSelectorArray newMethodArray|
       
   753 
       
   754     index := selectorArray identityIndexOf:aSelector startingAt:1.
       
   755     (index == 0) ifTrue:[^ false].
       
   756 
       
   757     newSelectorArray := selectorArray copyWithoutIndex:index.
       
   758     newMethodArray := methodArray copyWithoutIndex:index.
       
   759     oldSelectorArray := selectorArray.
       
   760     oldMethodArray := methodArray.
       
   761     selectorArray := newSelectorArray.
       
   762     methodArray := newMethodArray.
       
   763 "
       
   764     [
       
   765 	|nargs|
       
   766 	nargs := aSelector numArgs.
       
   767 	ObjectMemory flushMethodCache.
       
   768 	ObjectMemory flushInlineCachesWithArgs:nargs.
       
   769     ] value
       
   770 "
       
   771     "
       
   772      actually, we would do better with less flushing ...
       
   773     "
       
   774     ObjectMemory flushCaches.
       
   775     ^ true
       
   776 !
       
   777 
       
   778 removeSuperclass:aClass
       
   779     "EXPERIMENTAL MI support: remove aClass from the set of classes, from which instances
       
   780      inherit protocol."
       
   781 
       
   782     otherSuperclasses notNil ifTrue:[
       
   783 	otherSuperclasses := otherSuperclasses copyWithout:aClass.
       
   784 	otherSuperclasses isEmpty ifTrue:[
       
   785 	    otherSuperclasses := nil
       
   786 	].
       
   787 	SubclassInfo := nil.
       
   788 	ObjectMemory flushCaches
       
   789     ].
       
   790 !
       
   791 
       
   792 selectorArray 
       
   793     "return the receivers selector array.
       
   794      Notice: this is not compatible with ST-80."
       
   795 
       
   796     ^ selectorArray
       
   797 !
       
   798 
       
   799 selectors
       
   800     "return the receivers selector array as an orderedCollection.
       
   801      Notice: this may not be compatible with ST-80.
       
   802      (should we return a Set ?)"
       
   803 
       
   804     ^ selectorArray asOrderedCollection
       
   805 !
       
   806 
       
   807 selectors:newSelectors methods:newMethods
       
   808     "set both selector array and method array of the receiver,
       
   809      and flush caches"
       
   810 
       
   811     ObjectMemory flushCaches.
       
   812     selectorArray := newSelectors.
       
   813     methodArray := newMethods
       
   814 !
       
   815 
       
   816 superclass
       
   817     "return the receivers superclass"
       
   818 
       
   819     ^ superclass
       
   820 !
       
   821 
       
   822 superclass:aClass
       
   823     "set the superclass - this actually creates a new class,
       
   824      recompiling all methods for the new one. The receiving class stays
       
   825      around anonymous to allow existing instances some life.
       
   826      This may change in the future (adjusting existing instances)"
       
   827 
       
   828     SubclassInfo := nil.
       
   829 
       
   830     "must flush caches since lookup chain changes"
       
   831     ObjectMemory flushCaches.
       
   832 
       
   833 "
       
   834     superclass := aClass
       
   835 "
       
   836     "for correct recompilation, just create a new class ..."
       
   837 
       
   838     aClass subclass:(self name)
       
   839 	   instanceVariableNames:(self instanceVariableString)
       
   840 	   classVariableNames:(self classVariableString)
       
   841 	   poolDictionaries:''
       
   842 	   category:self category
   338 ! !
   843 ! !
   339 
   844 
       
   845 !Behavior methodsFor:'autoload check'!
       
   846 
       
   847 autoload
       
   848     "force autoloading - do nothing here; 
       
   849      redefined in Autoload; see comment there"
       
   850 
       
   851     ^ self
       
   852 !
       
   853 
       
   854 isLoaded
       
   855     "return true, if the class has been loaded; 
       
   856      redefined in Autoload; see comment there"
       
   857 
       
   858     ^ true
       
   859 ! !
       
   860 
       
   861 !Behavior methodsFor:'binary storage'!
       
   862 
       
   863 binaryDefinitionFrom:stream manager:manager
       
   864     "sent during a binary read by the input manager.
       
   865      Read the definition on an empty instance (of my class) from stream.
       
   866      All pointer instances are left nil, while all bits are read in here.
       
   867      return the new object."
       
   868 
       
   869     |obj t
       
   870      basicSize "{ Class: SmallInteger }" |
       
   871 
       
   872     self isPointers ifTrue: [
       
   873 	"/
       
   874 	"/ inst size not needed - if you uncomment the line below,
       
   875 	"/ also uncomment the corresponding line in
       
   876 	"/ Object>>storeBinaryDefinitionOn:manager:
       
   877 	"/
       
   878 	"/ stream next. "skip instSize"
       
   879 	self isVariable ifTrue: [
       
   880 	    ^ self basicNew:(stream nextNumber:3)
       
   881 	].
       
   882 	^ self basicNew
       
   883     ].
       
   884 
       
   885     "
       
   886      an object with bit-valued instance variables.
       
   887      These are read here.
       
   888     "
       
   889     basicSize := stream nextNumber:4.
       
   890     obj := self basicNew:basicSize.
       
   891 
       
   892     self isBytes ifTrue: [
       
   893 	stream nextBytes:basicSize into:obj
       
   894     ] ifFalse: [
       
   895 	self isWords ifTrue: [
       
   896 	    1 to:basicSize do:[:i |
       
   897 		obj basicAt:i put:(stream nextNumber:2)
       
   898 	    ]
       
   899 	] ifFalse:[
       
   900 	    self isLongs ifTrue: [
       
   901 		1 to:basicSize do:[:i |
       
   902 		    obj basicAt:i put:(stream nextNumber:4)
       
   903 		]
       
   904 	    ] ifFalse:[
       
   905 		self isFloats ifTrue: [
       
   906 		    "could do it in one big read on machines which use IEEE floats ..."
       
   907 		    t := Float basicNew.
       
   908 		    1 to:basicSize do:[:i |
       
   909 			Float readBinaryIEEESingleFrom:stream into:t.
       
   910 			obj basicAt:i put: t
       
   911 		    ]
       
   912 		] ifFalse:[
       
   913 		    self isDoubles ifTrue: [
       
   914 			"could do it in one big read on machines which use IEEE doubles ..."
       
   915 			t := Float basicNew.
       
   916 			1 to:basicSize do:[:i |
       
   917 			    Float readBinaryIEEEDoubleFrom:stream into:t.
       
   918 			    obj basicAt:i put: t
       
   919 			]
       
   920 		    ]
       
   921 		]
       
   922 	    ]
       
   923 	]
       
   924     ].
       
   925     ^obj
       
   926 !
       
   927 
       
   928 canCloneFrom:anObject 
       
   929     "return true, if this class can clone an obsolete object as retrieved
       
   930      by a binary load. Subclasses which do not want to have obsolete objects
       
   931      be converted, should redefine this method to return false.
       
   932      (However, conversion is never done silently in a binary load; you
       
   933       have to have a handler for the binaryload errors and for the conversion
       
   934       request signal.)"
       
   935 
       
   936     ^ true
       
   937 !
       
   938 
       
   939 cloneFrom:aPrototype
       
   940     "return an instance of myself with variables initialized from
       
   941      a prototype. This is used when instances of obsolete classes are
       
   942      binary loaded and a conversion is done on the obsolete object. 
       
   943      UserClasses may redefine this for better conversions."
       
   944 
       
   945     |newInst indexed myInfo otherInfo varIndexAssoc|
       
   946 
       
   947     indexed := false.
       
   948     aPrototype class isVariable ifTrue:[
       
   949 	self isVariable ifTrue:[
       
   950 	    indexed := true.
       
   951 	].
       
   952 	"otherwise, these are lost ..."
       
   953     ].
       
   954     indexed ifTrue:[
       
   955 	newInst := self basicNew:aPrototype basicSize
       
   956     ] ifFalse:[
       
   957 	newInst := self basicNew
       
   958     ].
       
   959 
       
   960     myInfo := self instanceVariableOffsets.
       
   961     otherInfo := aPrototype class instanceVariableOffsets.
       
   962     myInfo keysAndValuesDo:[:name :index |
       
   963 	varIndexAssoc := otherInfo at:name ifAbsent:[].
       
   964 	varIndexAssoc notNil ifTrue:[
       
   965 	    newInst instVarAt:index put:(aPrototype instVarAt:(varIndexAssoc value))
       
   966 	]
       
   967     ].
       
   968     indexed ifTrue:[
       
   969 	1 to:aPrototype basicSize do:[:index |
       
   970 	    newInst basicAt:index put:(aPrototype basicAt:index)
       
   971 	].
       
   972     ].
       
   973     ^ newInst
       
   974 
       
   975     "
       
   976      Class withoutUpdatingChangesDo:[
       
   977 	 Point subclass:#Point3D
       
   978 	   instanceVariableNames:'z'
       
   979 	   classVariableNames:''
       
   980 	   poolDictionaries:''
       
   981 	   category:'testing'.
       
   982 	 (Point3D cloneFrom:1@2) inspect.
       
   983      ]
       
   984     "
       
   985 
       
   986     "
       
   987      Class withoutUpdatingChangesDo:[
       
   988 	 Point variableSubclass:#Point3D
       
   989 	   instanceVariableNames:'z'
       
   990 	   classVariableNames:''
       
   991 	   poolDictionaries:''
       
   992 	   category:'testing'.
       
   993 	 (Point3D cloneFrom:#(1 2 3)) inspect.
       
   994      ]
       
   995     "
       
   996 
       
   997     "
       
   998      |someObject|
       
   999 
       
  1000      Class withoutUpdatingChangesDo:[
       
  1001 	 Object subclass:#TestClass1 
       
  1002 	   instanceVariableNames:'foo bar'
       
  1003 	   classVariableNames:''
       
  1004 	   poolDictionaries:''
       
  1005 	   category:'testing'.
       
  1006 	 someObject := TestClass1 new.
       
  1007 	 someObject instVarAt:1 put:'foo'; instVarAt:2 put:'bar'.
       
  1008 	 Object subclass:#TestClass2 
       
  1009 	   instanceVariableNames:'bar foo'
       
  1010 	   classVariableNames:''
       
  1011 	   poolDictionaries:''
       
  1012 	   category:'testing'.
       
  1013 	 (TestClass2 cloneFrom:someObject) inspect.
       
  1014      ]
       
  1015     "
       
  1016 !
       
  1017 
       
  1018 readBinaryFrom:aStream
       
  1019     "read an objects binary representation from the argument,
       
  1020      aStream and return it. 
       
  1021      The read object must be a kind of myself, otherwise an error is raised. 
       
  1022      To get any object, use 'Object readBinaryFrom:...',
       
  1023      To get any number, use 'Number readBinaryFrom:...' and so on.
       
  1024      This is the reverse operation to 'storeBinaryOn:'. "
       
  1025 
       
  1026     ^ self readBinaryFrom:aStream onError:[self error:('expected ' , self name)]
       
  1027 
       
  1028     "
       
  1029      |s|
       
  1030      s := WriteStream on:(ByteArray new).
       
  1031      #(1 2 3 4) storeBinaryOn:s.
       
  1032      Object readBinaryFrom:(ReadStream on:s contents)  
       
  1033     "
       
  1034     "
       
  1035      |s|
       
  1036      s := 'testFile' asFilename writeStream binary.
       
  1037      #(1 2 3 4) storeBinaryOn:s.
       
  1038      'hello world' storeBinaryOn:s.
       
  1039      s close.
       
  1040 
       
  1041      s := 'testFile' asFilename readStream binary.
       
  1042      Transcript showCr:(Object readBinaryFrom:s).
       
  1043      Transcript showCr:(Object readBinaryFrom:s).
       
  1044      s close.
       
  1045     "
       
  1046 !
       
  1047 
       
  1048 readBinaryFrom:aStream onError:exceptionBlock
       
  1049     "read an objects binary representation from the argument,
       
  1050      aStream and return it. 
       
  1051      The read object must be a kind of myself, otherwise the value of
       
  1052      the exceptionBlock is returned.
       
  1053      To get any object, use 'Object readBinaryFrom:...',
       
  1054      To get any number, use 'Number readBinaryFrom:...' and so on.
       
  1055      This is the reverse operation to 'storeBinaryOn:'. "
       
  1056 
       
  1057     |newObject|
       
  1058 
       
  1059     newObject := (BinaryInputManager new:1024) readFrom:aStream.
       
  1060     (newObject isKindOf:self) ifFalse:[^ exceptionBlock value].
       
  1061     ^ newObject
       
  1062 
       
  1063     "
       
  1064      |s|
       
  1065      s := WriteStream on:(ByteArray new).
       
  1066      #(1 2 3 4) storeBinaryOn:s.
       
  1067      Object readBinaryFrom:(ReadStream on:s contents) onError:['oops'] 
       
  1068     "
       
  1069     "
       
  1070      |s|
       
  1071      s := WriteStream on:(ByteArray new).
       
  1072      #[1 2 3 4] storeBinaryOn:s.
       
  1073      Array readBinaryFrom:(ReadStream on:s contents)  onError:['oops']  
       
  1074     "
       
  1075 !
       
  1076 
       
  1077 storeBinaryDefinitionOn: stream manager: manager
       
  1078     "binary store of a classes definition.
       
  1079      Classes will store the name only and restore by looking for
       
  1080      that name in the Smalltalk dictionary."
       
  1081 
       
  1082     | myName |
       
  1083 
       
  1084     myName := self name.
       
  1085     stream nextNumber:4 put:self signature.
       
  1086     stream nextNumber:2 put:0.
       
  1087     stream nextNumber:2 put:myName size.
       
  1088     myName do:[:c| 
       
  1089 	stream nextPut:c asciiValue
       
  1090     ]
       
  1091 
       
  1092     "
       
  1093      |s|
       
  1094      s := WriteStream on:ByteArray new.
       
  1095      #(1 2 3 4) storeBinaryOn:s.
       
  1096      Object readBinaryFrom:(ReadStream on:s contents)  
       
  1097 
       
  1098      |s|
       
  1099      s := WriteStream on:ByteArray new.
       
  1100      Rectangle storeBinaryOn:s.
       
  1101      Object readBinaryFrom:(ReadStream on:s contents)  
       
  1102     "
       
  1103 ! !
       
  1104 
       
  1105 !Behavior methodsFor:'compiler interface'!
       
  1106 
       
  1107 compiler
       
  1108     "return the compiler to use for this class.
       
  1109      OBSOLETE: This is the old ST/X interface, kept for migration. 
       
  1110 	       Dont use it - it will vanish."
       
  1111 
       
  1112     ^ self compilerClass
       
  1113 !
       
  1114 
       
  1115 compilerClass
       
  1116     "return the compiler to use for this class - 
       
  1117      this can be redefined in special classes, to get classes with
       
  1118      Lisp, Prolog, ASN1, Basic :-) or whatever syntax."
       
  1119 
       
  1120     ^ Compiler
       
  1121 !
       
  1122 
       
  1123 evaluatorClass
       
  1124     "return the compiler to use for expression evaluation for this class - 
       
  1125      this can be redefined in special classes, to get classes with
       
  1126      Lisp, Prolog, ASN1, Basic :-) or whatever syntax."
       
  1127 
       
  1128     ^ Compiler
       
  1129 ! !
       
  1130 
       
  1131 !Behavior methodsFor:'copying'!
       
  1132 
       
  1133 deepCopy
       
  1134     "return a deep copy of the receiver
       
  1135      - return the receiver here - time will show if this is ok"
       
  1136 
       
  1137     ^ self
       
  1138 !
       
  1139 
       
  1140 deepCopyUsing:aDictionary
       
  1141     "return a deep copy of the receiver
       
  1142      - return the receiver here - time will show if this is ok"
       
  1143 
       
  1144     ^ self
       
  1145 !
       
  1146 
       
  1147 simpleDeepCopy
       
  1148     "return a deep copy of the receiver
       
  1149      - return the receiver here - time will show if this is ok"
       
  1150 
       
  1151     ^ self
       
  1152 ! !
       
  1153 
       
  1154 !Behavior methodsFor:'enumerating'!
       
  1155 
       
  1156 allDerivedInstancesDo:aBlock
       
  1157     "evaluate aBlock for all of my instances and all instances of subclasses.
       
  1158      This method is going to be removed for protocol compatibility with
       
  1159      other STs; use allSubInstancesDo:"
       
  1160 
       
  1161     self obsoleteMethodWarning:'please use #allSubInstancesDo:'.
       
  1162     self allSubInstancesDo:aBlock
       
  1163 
       
  1164     "
       
  1165      StandardSystemView allDerivedInstancesDo:[:v | Transcript showCr:(v name)]
       
  1166     "
       
  1167 !
       
  1168 
       
  1169 allInstancesDo:aBlock
       
  1170     "evaluate aBlock for all of my instances"
       
  1171 
       
  1172 "/    ObjectMemory allObjectsDo:[:anObject |
       
  1173 "/        (anObject class == self) ifTrue:[
       
  1174 "/            aBlock value:anObject
       
  1175 "/        ]
       
  1176 "/    ]
       
  1177 
       
  1178     ObjectMemory allInstancesOf:self do:[:anObject |
       
  1179 	aBlock value:anObject
       
  1180     ]
       
  1181 
       
  1182     "
       
  1183      StandardSystemView allInstancesDo:[:v | Transcript showCr:(v name)]
       
  1184     "
       
  1185 !
       
  1186 
       
  1187 allSubInstancesDo:aBlock
       
  1188     "evaluate aBlock for all of my instances and all instances of subclasses"
       
  1189 
       
  1190     ObjectMemory allObjectsDo:[:anObject |
       
  1191 	(anObject isKindOf:self) ifTrue:[
       
  1192 	    aBlock value:anObject
       
  1193 	]
       
  1194     ]
       
  1195 
       
  1196     "
       
  1197      StandardSystemView allSubInstancesDo:[:v | Transcript showCr:(v name)]
       
  1198     "
       
  1199 !
       
  1200 
       
  1201 allSubclassesDo:aBlock
       
  1202     "evaluate aBlock for all of my subclasses.
       
  1203      There is no specific order, in which the entries are enumerated.
       
  1204      This will only enumerate globally known classes - for anonymous
       
  1205      behaviors, you have to walk over all instances of Behavior."
       
  1206 
       
  1207     Smalltalk allBehaviorsDo:[:aClass |
       
  1208 	(aClass isSubclassOf:self) ifTrue:[
       
  1209 	    aBlock value:aClass
       
  1210 	]
       
  1211     ]
       
  1212 
       
  1213     "
       
  1214      Collection allSubclassesDo:[:c | Transcript showCr:(c name)]
       
  1215     "
       
  1216 !
       
  1217 
       
  1218 allSubclassesInOrderDo:aBlock
       
  1219     "evaluate aBlock for all of my subclasses.
       
  1220      Higher level subclasses will be enumerated before the deeper ones,
       
  1221      so the order in which aBlock gets called is ok to fileOut classes in
       
  1222      correct order for later fileIn.
       
  1223      This will only enumerate globally known classes - for anonymous
       
  1224      behaviors, you have to walk over all instances of Behavior"
       
  1225 
       
  1226     self subclassesDo:[:aClass |
       
  1227 	aBlock value:aClass.
       
  1228 	aClass allSubclassesInOrderDo:aBlock
       
  1229     ]
       
  1230 
       
  1231     "
       
  1232      Collection allSubclassesInOrderDo:[:c | Transcript showCr:(c name)]
       
  1233     "
       
  1234 !
       
  1235 
       
  1236 allSuperclassesDo:aBlock
       
  1237     "evaluate aBlock for all of my superclasses"
       
  1238 
       
  1239     |theClass|
       
  1240 
       
  1241     theClass := superclass.
       
  1242     [theClass notNil] whileTrue:[
       
  1243 	aBlock value:theClass.
       
  1244 	theClass := theClass superclass
       
  1245     ]
       
  1246 
       
  1247     "
       
  1248      String allSuperclassesDo:[:c | Transcript showCr:(c name)]
       
  1249     "
       
  1250 !
       
  1251 
       
  1252 subclassesDo:aBlock
       
  1253     "evaluate the argument, aBlock for all immediate subclasses.
       
  1254      This will only enumerate globally known classes - for anonymous
       
  1255      behaviors, you have to walk over all instances of Behavior."
       
  1256 
       
  1257     |coll|
       
  1258 
       
  1259     SubclassInfo isNil ifTrue:[
       
  1260 	Behavior subclassInfo
       
  1261     ].
       
  1262     SubclassInfo notNil ifTrue:[
       
  1263 	coll := SubclassInfo at:self ifAbsent:nil.
       
  1264 	coll notNil ifTrue:[
       
  1265 	    coll do:aBlock.
       
  1266 	].
       
  1267 	^ self
       
  1268     ].
       
  1269 
       
  1270     Smalltalk allBehaviorsDo:[:aClass |
       
  1271 	(aClass superclass == self) ifTrue:[
       
  1272 	    aBlock value:aClass
       
  1273 	]
       
  1274     ]
       
  1275 
       
  1276     "
       
  1277      Collection subclassesDo:[:c | Transcript showCr:(c name)]
       
  1278     "
       
  1279 ! !
       
  1280 
   340 !Behavior methodsFor:'initialization'!
  1281 !Behavior methodsFor:'initialization'!
       
  1282 
       
  1283 deinitialize
       
  1284     "deinitialize is sent to a class before it is physically unloaded.
       
  1285      This is only done with classes which have been loaded in from a binary
       
  1286      file. Classes may release any primitive memory or other stuff which is
       
  1287      not visible to smalltalk (for example, release internal memory).
       
  1288      The default action here is to do nothing."
       
  1289 
       
  1290     ^ self
       
  1291 !
   341 
  1292 
   342 initialize
  1293 initialize
   343     "initialize is sent to a class either during startup,
  1294     "initialize is sent to a class either during startup,
   344      (for all statically compiled-in classes) or after a class
  1295      (for all statically compiled-in classes) or after a class
   345      has been loaded into the system (either bytecodes or machinecode).
  1296      has been loaded into the system (either bytecodes or machinecode).
   365      This gives classes a chance to flush any device dependent or otherwise
  1316      This gives classes a chance to flush any device dependent or otherwise
   366      obsolete data which may be a leftover from the previous live.
  1317      obsolete data which may be a leftover from the previous live.
   367      The default action here is to do nothing."
  1318      The default action here is to do nothing."
   368 
  1319 
   369     ^ self
  1320     ^ self
   370 !
       
   371 
       
   372 deinitialize
       
   373     "deinitialize is sent to a class before it is physically unloaded.
       
   374      This is only done with classes which have been loaded in from a binary
       
   375      file. Classes may release any primitive memory or other stuff which is
       
   376      not visible to smalltalk (for example, release internal memory).
       
   377      The default action here is to do nothing."
       
   378 
       
   379     ^ self
       
   380 ! !
  1321 ! !
   381 
  1322 
   382 !Behavior methodsFor:'copying'!
       
   383 
       
   384 deepCopy
       
   385     "return a deep copy of the receiver
       
   386      - return the receiver here - time will show if this is ok"
       
   387 
       
   388     ^ self
       
   389 !
       
   390 
       
   391 deepCopyUsing:aDictionary
       
   392     "return a deep copy of the receiver
       
   393      - return the receiver here - time will show if this is ok"
       
   394 
       
   395     ^ self
       
   396 !
       
   397 
       
   398 simpleDeepCopy
       
   399     "return a deep copy of the receiver
       
   400      - return the receiver here - time will show if this is ok"
       
   401 
       
   402     ^ self
       
   403 ! !
       
   404 
       
   405 !Behavior methodsFor:'instance creation'!
  1323 !Behavior methodsFor:'instance creation'!
   406 
       
   407 uninitializedNew
       
   408     "create an instance of myself with uninitialized contents.
       
   409      For all classes except ByteArray, this is the same as #basicNew."
       
   410 
       
   411     ^ self basicNew
       
   412 !
       
   413 
       
   414 uninitializedNew:anInteger
       
   415     "create an instance of myself with uninitialized contents.
       
   416      For all classes except ByteArray, this is the same as #basicNew:."
       
   417 
       
   418     ^ self basicNew:anInteger
       
   419 !
       
   420 
       
   421 niceBasicNew:anInteger
       
   422     "same as basicNew:anInteger, but tries to avoid long pauses
       
   423      due to garbage collection. This method checks to see if
       
   424      allocation is possible without a pause, and does a background
       
   425      incremental garbage collect first if there is not enough memory
       
   426      available at the moment for fast allocation. 
       
   427      This is useful in low-priority background processes which like to 
       
   428      avoid disturbing any higher priority foreground process while allocating
       
   429      big amounts of memory. Of course, using this method only makes
       
   430      sense for big or huge objects (say > 200k).
       
   431 
       
   432      EXPERIMENTAL: this is a non-standard interface and should only 
       
   433      be used for special applications. There is no guarantee, that this
       
   434      method will be available in future ST/X releases."
       
   435 
       
   436     |size|
       
   437 
       
   438     size := self sizeOfInst:anInteger.
       
   439     (ObjectMemory checkForFastNew:size) ifFalse:[
       
   440 	"
       
   441 	 incrementally collect garbage
       
   442 	"
       
   443 	ObjectMemory incrementalGC.
       
   444     ].
       
   445     ^ self basicNew:anInteger
       
   446 !
       
   447 
       
   448 new
       
   449     "return an instance of myself without indexed variables"
       
   450 
       
   451     ^ self basicNew
       
   452 !
       
   453 
       
   454 new:anInteger
       
   455     "return an instance of myself with anInteger indexed variables"
       
   456 
       
   457     ^ self basicNew:anInteger
       
   458 !
       
   459 
  1324 
   460 basicNew
  1325 basicNew
   461     "return an instance of myself without indexed variables.
  1326     "return an instance of myself without indexed variables.
   462      If the receiver-class has indexed instvars, the new object will have
  1327      If the receiver-class has indexed instvars, the new object will have
   463      a basicSize of zero - 
  1328      a basicSize of zero - 
  1009      Bad luck - you should increase the swap space on your machine.
  1874      Bad luck - you should increase the swap space on your machine.
  1010     "
  1875     "
  1011     ^ ObjectMemory allocationFailureSignal raise.
  1876     ^ ObjectMemory allocationFailureSignal raise.
  1012 !
  1877 !
  1013 
  1878 
       
  1879 new
       
  1880     "return an instance of myself without indexed variables"
       
  1881 
       
  1882     ^ self basicNew
       
  1883 !
       
  1884 
       
  1885 new:anInteger
       
  1886     "return an instance of myself with anInteger indexed variables"
       
  1887 
       
  1888     ^ self basicNew:anInteger
       
  1889 !
       
  1890 
       
  1891 niceBasicNew:anInteger
       
  1892     "same as basicNew:anInteger, but tries to avoid long pauses
       
  1893      due to garbage collection. This method checks to see if
       
  1894      allocation is possible without a pause, and does a background
       
  1895      incremental garbage collect first if there is not enough memory
       
  1896      available at the moment for fast allocation. 
       
  1897      This is useful in low-priority background processes which like to 
       
  1898      avoid disturbing any higher priority foreground process while allocating
       
  1899      big amounts of memory. Of course, using this method only makes
       
  1900      sense for big or huge objects (say > 200k).
       
  1901 
       
  1902      EXPERIMENTAL: this is a non-standard interface and should only 
       
  1903      be used for special applications. There is no guarantee, that this
       
  1904      method will be available in future ST/X releases."
       
  1905 
       
  1906     |size|
       
  1907 
       
  1908     size := self sizeOfInst:anInteger.
       
  1909     (ObjectMemory checkForFastNew:size) ifFalse:[
       
  1910 	"
       
  1911 	 incrementally collect garbage
       
  1912 	"
       
  1913 	ObjectMemory incrementalGC.
       
  1914     ].
       
  1915     ^ self basicNew:anInteger
       
  1916 !
       
  1917 
  1014 readFrom:aStream
  1918 readFrom:aStream
  1015     "read an objects printed representation from the argument, aStream 
  1919     "read an objects printed representation from the argument, aStream 
  1016      and return it. 
  1920      and return it. 
  1017      The read object must be a kind of myself if its not, an error is raised.
  1921      The read object must be a kind of myself if its not, an error is raised.
  1018      This is the reverse operation to 'storeOn:'.
  1922      This is the reverse operation to 'storeOn:'.
  1105      Integer readFromString:'abc' onError:0
  2009      Integer readFromString:'abc' onError:0
  1106      Point readFromString:'1@2'  
  2010      Point readFromString:'1@2'  
  1107      Point readFromString:'0'   
  2011      Point readFromString:'0'   
  1108      Point readFromString:'0' onError:[0@0]  
  2012      Point readFromString:'0' onError:[0@0]  
  1109     "
  2013     "
       
  2014 !
       
  2015 
       
  2016 uninitializedNew
       
  2017     "create an instance of myself with uninitialized contents.
       
  2018      For all classes except ByteArray, this is the same as #basicNew."
       
  2019 
       
  2020     ^ self basicNew
       
  2021 !
       
  2022 
       
  2023 uninitializedNew:anInteger
       
  2024     "create an instance of myself with uninitialized contents.
       
  2025      For all classes except ByteArray, this is the same as #basicNew:."
       
  2026 
       
  2027     ^ self basicNew:anInteger
  1110 ! !
  2028 ! !
  1111 
  2029 
  1112 !Behavior methodsFor:'autoload check'!
       
  1113 
       
  1114 isLoaded
       
  1115     "return true, if the class has been loaded; 
       
  1116      redefined in Autoload; see comment there"
       
  1117 
       
  1118     ^ true
       
  1119 !
       
  1120 
       
  1121 autoload
       
  1122     "force autoloading - do nothing here; 
       
  1123      redefined in Autoload; see comment there"
       
  1124 
       
  1125     ^ self
       
  1126 ! !
       
  1127 
       
  1128 !Behavior methodsFor:'snapshots'!
       
  1129 
       
  1130 preSnapshot
       
  1131     "sent by ObjectMemory, before a snapshot is written.
       
  1132      Nothing done here."
       
  1133 !
       
  1134 
       
  1135 postSnapshot
       
  1136     "sent by ObjectMemory, after a snapshot has been written.
       
  1137      Nothing done here."
       
  1138 ! !
       
  1139 
       
  1140 !Behavior class methodsFor:'flag bit constants'!
       
  1141 
       
  1142 flagNotIndexed
       
  1143     "return the flag code for non-indexed instances.
       
  1144      You have to mask the flag value with indexMask when comparing
       
  1145      it with flagNotIndexed."
       
  1146 
       
  1147     ^ 0
       
  1148 ! 
       
  1149 
       
  1150 flagBytes
       
  1151     "return the flag code for byte-valued indexed instances.
       
  1152      You have to mask the flag value with indexMask when comparing
       
  1153      it with flagBytes."
       
  1154 
       
  1155 %{  /* NOCONTEXT */
       
  1156     /* this is defined as a primitive to get defines from stc.h */
       
  1157 
       
  1158     RETURN ( _MKSMALLINT(BYTEARRAY) );
       
  1159 %}
       
  1160     "
       
  1161      Behavior flagBytes    
       
  1162     "
       
  1163 ! 
       
  1164 
       
  1165 flagWords
       
  1166     "return the flag code for word-valued indexed instances (i.e. 2-byte).
       
  1167      You have to mask the flag value with indexMask when comparing
       
  1168      it with flagWords."
       
  1169 
       
  1170 %{  /* NOCONTEXT */
       
  1171     /* this is defined as a primitive to get defines from stc.h */
       
  1172 
       
  1173     RETURN ( _MKSMALLINT(WORDARRAY) );
       
  1174 %}
       
  1175     "
       
  1176      Behavior flagWords    
       
  1177     "
       
  1178 ! 
       
  1179 
       
  1180 flagLongs
       
  1181     "return the flag code for long-valued indexed instances (i.e. 4-byte).
       
  1182      You have to mask the flag value with indexMask when comparing
       
  1183      it with flagLongs."
       
  1184 
       
  1185 %{  /* NOCONTEXT */
       
  1186     /* this is defined as a primitive to get defines from stc.h */
       
  1187 
       
  1188     RETURN ( _MKSMALLINT(LONGARRAY) );
       
  1189 %}
       
  1190     "
       
  1191      Behavior flagLongs    
       
  1192     "
       
  1193 ! 
       
  1194 
       
  1195 flagFloats
       
  1196     "return the flag code for float-valued indexed instances (i.e. 4-byte reals).
       
  1197      You have to mask the flag value with indexMask when comparing
       
  1198      it with flagFloats."
       
  1199 
       
  1200 %{  /* NOCONTEXT */
       
  1201     /* this is defined as a primitive to get defines from stc.h */
       
  1202 
       
  1203     RETURN ( _MKSMALLINT(FLOATARRAY) );
       
  1204 %}
       
  1205     "
       
  1206      Behavior flagFloats    
       
  1207     "
       
  1208 ! 
       
  1209 
       
  1210 flagDoubles
       
  1211     "return the flag code for double-valued indexed instances (i.e. 8-byte reals).
       
  1212      You have to mask the flag value with indexMask when comparing
       
  1213      it with flagDoubles."
       
  1214 
       
  1215 %{  /* NOCONTEXT */
       
  1216     /* this is defined as a primitive to get defines from stc.h */
       
  1217 
       
  1218     RETURN ( _MKSMALLINT(DOUBLEARRAY) );
       
  1219 %}
       
  1220     "
       
  1221      Behavior flagDoubles    
       
  1222     "
       
  1223 ! 
       
  1224 
       
  1225 flagPointers
       
  1226     "return the flag code for pointer indexed instances (i.e. Array of object).
       
  1227      You have to mask the flag value with indexMask when comparing
       
  1228      it with flagPointers."
       
  1229 
       
  1230 %{  /* NOCONTEXT */
       
  1231     /* this is defined as a primitive to get defines from stc.h */
       
  1232 
       
  1233     RETURN ( _MKSMALLINT(POINTERARRAY) );
       
  1234 %}
       
  1235     "
       
  1236      Behavior flagPointers    
       
  1237     "
       
  1238 ! 
       
  1239 
       
  1240 flagWeakPointers
       
  1241     "return the flag code for weak pointer indexed instances (i.e. WeakArray).
       
  1242      You have to mask the flag value with indexMask when comparing
       
  1243      it with flagWeakPointers."
       
  1244 
       
  1245 %{  /* NOCONTEXT */
       
  1246     /* this is defined as a primitive to get defines from stc.h */
       
  1247 
       
  1248     RETURN ( _MKSMALLINT(WKPOINTERARRAY) );
       
  1249 %}
       
  1250 ! 
       
  1251 
       
  1252 maskIndexType
       
  1253     "return a mask to extract all index-type bits"
       
  1254 
       
  1255 %{  /* NOCONTEXT */
       
  1256     /* this is defined as a primitive to get defines from stc.h */
       
  1257 
       
  1258     RETURN ( _MKSMALLINT(ARRAYMASK) );
       
  1259 %}
       
  1260 ! 
       
  1261 
       
  1262 flagBehavior
       
  1263     "return the flag code which marks Behavior-like instances.
       
  1264      You have to check this single bit in the flag value when
       
  1265      checking for behaviors."
       
  1266 
       
  1267 %{  /* NOCONTEXT */
       
  1268     /* this is defined as a primitive to get defines from stc.h */
       
  1269 
       
  1270     RETURN ( _MKSMALLINT(BEHAVIOR_INSTS) );
       
  1271 %}
       
  1272 
       
  1273     "consistency check:
       
  1274      all class-entries must be behaviors;
       
  1275      all behaviors must be flagged so (in its class's flags)
       
  1276      (otherwise, VM will bark)
       
  1277      all non-behaviors may not be flagged
       
  1278 
       
  1279      |bit|
       
  1280      bit := Class flagBehavior.
       
  1281 
       
  1282      ObjectMemory allObjectsDo:[:o|
       
  1283        o isBehavior ifTrue:[
       
  1284 	 (o class flags bitTest:bit) ifFalse:[
       
  1285 	     self halt
       
  1286 	 ].
       
  1287        ] ifFalse:[
       
  1288 	 (o class flags bitTest:bit) ifTrue:[
       
  1289 	     self halt
       
  1290 	 ].
       
  1291        ].
       
  1292        o class isBehavior ifFalse:[
       
  1293 	 self halt
       
  1294        ] ifTrue:[
       
  1295 	 (o class class flags bitTest:bit) ifFalse:[
       
  1296 	     self halt
       
  1297 	 ]
       
  1298        ]
       
  1299      ]
       
  1300     "
       
  1301 ! 
       
  1302 
       
  1303 flagBlock
       
  1304     "return the flag code which marks Block-like instances.
       
  1305      You have to check this single bit in the flag value when
       
  1306      checking for blocks."
       
  1307 
       
  1308 %{  /* NOCONTEXT */
       
  1309     /* this is defined as a primitive to get defines from stc.h */
       
  1310 
       
  1311     RETURN ( _MKSMALLINT(BLOCK_INSTS) );
       
  1312 %}
       
  1313 ! 
       
  1314 
       
  1315 flagMethod
       
  1316     "return the flag code which marks Method-like instances.
       
  1317      You have to check this single bit in the flag value when
       
  1318      checking for methods."
       
  1319 
       
  1320 %{  /* NOCONTEXT */
       
  1321     /* this is defined as a primitive to get defines from stc.h */
       
  1322 
       
  1323     RETURN ( _MKSMALLINT(METHOD_INSTS) );
       
  1324 %}
       
  1325 ! 
       
  1326 
       
  1327 flagNonObjectInst
       
  1328     "return the flag code which marks instances which have a
       
  1329      non-object instance variable (in slot 1).
       
  1330      (these are ignored by the garbage collector)"
       
  1331 
       
  1332 %{  /* NOCONTEXT */
       
  1333     /* this is defined as a primitive to get defines from stc.h */
       
  1334 
       
  1335     RETURN ( _MKSMALLINT(NONOBJECT_INSTS) );
       
  1336 %}
       
  1337 !
       
  1338 
       
  1339 flagContext
       
  1340     "return the flag code which marks Context-like instances.
       
  1341      You have to check this single bit in the flag value when
       
  1342      checking for contexts."
       
  1343 
       
  1344 %{  /* NOCONTEXT */
       
  1345     /* this is defined as a primitive to get defines from stc.h */
       
  1346 
       
  1347     RETURN ( _MKSMALLINT(CONTEXT_INSTS) );
       
  1348 %}
       
  1349 ! 
       
  1350 
       
  1351 flagBlockContext
       
  1352     "return the flag code which marks BlockContext-like instances.
       
  1353      You have to check this single bit in the flag value when
       
  1354      checking for blockContexts."
       
  1355 
       
  1356 %{  /* NOCONTEXT */
       
  1357     /* this is defined as a primitive to get defines from stc.h */
       
  1358 
       
  1359     RETURN ( _MKSMALLINT(BCONTEXT_INSTS) );
       
  1360 %}
       
  1361 ! 
       
  1362 
       
  1363 flagFloat
       
  1364     "return the flag code which marks Float-like instances.
       
  1365      You have to check this single bit in the flag value when
       
  1366      checking for floats."
       
  1367 
       
  1368 %{  /* NOCONTEXT */
       
  1369     /* this is defined as a primitive to get defines from stc.h */
       
  1370 
       
  1371     RETURN ( _MKSMALLINT(FLOAT_INSTS) );
       
  1372 %}
       
  1373 ! 
       
  1374 
       
  1375 flagSymbol
       
  1376     "return the flag code which marks Symbol-like instances.
       
  1377      You have to check this single bit in the flag value when
       
  1378      checking for symbols."
       
  1379 
       
  1380 %{  /* NOCONTEXT */
       
  1381     /* this is defined as a primitive to get defines from stc.h */
       
  1382 
       
  1383     RETURN ( _MKSMALLINT(SYMBOL_INSTS) );
       
  1384 %}
       
  1385 ! !
       
  1386 
       
  1387 !Behavior methodsFor:'accessing'!
       
  1388 
       
  1389 name
       
  1390     "although behaviors have no name, we return something
       
  1391      useful here - there are many places (inspectors) where
       
  1392      a classes name is asked for.
       
  1393      Implementing this message here allows anonymous classes
       
  1394      and instances of them to be inspected."
       
  1395 
       
  1396     ^ 'someBehavior'
       
  1397 !
       
  1398 
       
  1399 displayString
       
  1400     "although behaviors have no name, we return something
       
  1401      useful here - there are many places (inspectors) where
       
  1402      a classes name is asked for.
       
  1403      Implementing this message here allows instances of anonymous classes
       
  1404      to show a reasonable name."
       
  1405 
       
  1406     ^ 'someBehavior'
       
  1407 !
       
  1408 
       
  1409 category
       
  1410     "return the category of the class. 
       
  1411      Returning nil here, since Behavior does not define a category
       
  1412      (only ClassDescriptions do)."
       
  1413 
       
  1414     ^ nil
       
  1415 
       
  1416     "
       
  1417      Point category                
       
  1418      Behavior new category           
       
  1419     "
       
  1420 !
       
  1421 
       
  1422 superclass
       
  1423     "return the receivers superclass"
       
  1424 
       
  1425     ^ superclass
       
  1426 !
       
  1427 
       
  1428 selectorArray 
       
  1429     "return the receivers selector array.
       
  1430      Notice: this is not compatible with ST-80."
       
  1431 
       
  1432     ^ selectorArray
       
  1433 !
       
  1434 
       
  1435 selectors
       
  1436     "return the receivers selector array as an orderedCollection.
       
  1437      Notice: this may not be compatible with ST-80.
       
  1438      (should we return a Set ?)"
       
  1439 
       
  1440     ^ selectorArray asOrderedCollection
       
  1441 !
       
  1442 
       
  1443 methodArray
       
  1444     "return the receivers method array.
       
  1445      Notice: this is not compatible with ST-80."
       
  1446 
       
  1447     ^ methodArray
       
  1448 !
       
  1449 
       
  1450 methodDictionary
       
  1451     "return the receivers method dictionary. 
       
  1452      Since no dictionary is actually present, create one for ST-80 compatibility."
       
  1453 
       
  1454     |dict n "{ Class: SmallInteger }"|
       
  1455 
       
  1456     dict := IdentityDictionary new.
       
  1457     n := selectorArray size.
       
  1458     1 to:n do:[:index |
       
  1459 	dict at:(selectorArray at:index) put:(methodArray at:index)
       
  1460     ].
       
  1461     ^ dict
       
  1462 !
       
  1463 
       
  1464 implicit_methodDict 
       
  1465     "ST-80 compatibility.
       
  1466      This allows subclasses to assume there is an instance variable
       
  1467      named methodDict."
       
  1468 
       
  1469     ^ self methodDictionary
       
  1470 !
       
  1471 
       
  1472 implicit_methodDict:aDictionary 
       
  1473     "ST-80 compatibility.
       
  1474      This allows subclasses to assume there is an instance variable
       
  1475      named methodDict."
       
  1476 
       
  1477     ^ self error:'not allowed to set the methodDictionary'
       
  1478 !
       
  1479 
       
  1480 instSize
       
  1481     "return the number of instance variables of the receiver.
       
  1482      This includes all superclass instance variables."
       
  1483 
       
  1484     ^ instSize
       
  1485 !
       
  1486 
       
  1487 flags
       
  1488     "return the receivers flag bits"
       
  1489 
       
  1490     ^ flags
       
  1491 !
       
  1492 
       
  1493 superclass:aClass
       
  1494     "set the superclass - this actually creates a new class,
       
  1495      recompiling all methods for the new one. The receiving class stays
       
  1496      around anonymous to allow existing instances some life.
       
  1497      This may change in the future (adjusting existing instances)"
       
  1498 
       
  1499     SubclassInfo := nil.
       
  1500 
       
  1501     "must flush caches since lookup chain changes"
       
  1502     ObjectMemory flushCaches.
       
  1503 
       
  1504 "
       
  1505     superclass := aClass
       
  1506 "
       
  1507     "for correct recompilation, just create a new class ..."
       
  1508 
       
  1509     aClass subclass:(self name)
       
  1510 	   instanceVariableNames:(self instanceVariableString)
       
  1511 	   classVariableNames:(self classVariableString)
       
  1512 	   poolDictionaries:''
       
  1513 	   category:self category
       
  1514 !
       
  1515 
       
  1516 addSuperclass:aClass
       
  1517     "EXPERIMENTAL MI support: add aClass to the set of classes, from which instances
       
  1518      inherit protocol."
       
  1519 
       
  1520     "first, check if the class is abstract - 
       
  1521      allows abstract mixins are allowed in the current implementation"
       
  1522 
       
  1523     aClass instSize == 0 ifFalse:[
       
  1524 	self error:'only abstract mixins allowed'.
       
  1525 	^ self
       
  1526     ].
       
  1527     otherSuperclasses isNil ifTrue:[
       
  1528 	otherSuperclasses := Array with:aClass
       
  1529     ] ifFalse:[
       
  1530 	otherSuperclasses := otherSuperclasses copyWith:aClass
       
  1531     ].
       
  1532     SubclassInfo := nil.
       
  1533     ObjectMemory flushCaches
       
  1534 !
       
  1535 
       
  1536 removeSuperclass:aClass
       
  1537     "EXPERIMENTAL MI support: remove aClass from the set of classes, from which instances
       
  1538      inherit protocol."
       
  1539 
       
  1540     otherSuperclasses notNil ifTrue:[
       
  1541 	otherSuperclasses := otherSuperclasses copyWithout:aClass.
       
  1542 	otherSuperclasses isEmpty ifTrue:[
       
  1543 	    otherSuperclasses := nil
       
  1544 	].
       
  1545 	SubclassInfo := nil.
       
  1546 	ObjectMemory flushCaches
       
  1547     ].
       
  1548 !
       
  1549 
       
  1550 selectors:newSelectors methods:newMethods
       
  1551     "set both selector array and method array of the receiver,
       
  1552      and flush caches"
       
  1553 
       
  1554     ObjectMemory flushCaches.
       
  1555     selectorArray := newSelectors.
       
  1556     methodArray := newMethods
       
  1557 !
       
  1558 
       
  1559 addSelector:newSelector withMethod:newMethod
       
  1560     "add the method given by 2nd argument under the selector given by
       
  1561      1st argument to the methodDictionary. Flush all caches."
       
  1562 
       
  1563     |nargs|
       
  1564 
       
  1565     (self primAddSelector:newSelector withMethod:newMethod) ifFalse:[^ false].
       
  1566     self changed:#methodDictionary with:newSelector.
       
  1567 
       
  1568     "
       
  1569      if I have no subclasses, all we have to flush is cached
       
  1570      data for myself ... (actually, in any case all that needs
       
  1571      to be flushed is info for myself and all of my subclasses)
       
  1572     "
       
  1573 "
       
  1574     problem: this is slower; since looking for all subclasses is (currently)
       
  1575 	     a bit slow :-(
       
  1576 	     We need the hasSubclasses-info bit in Behavior; now
       
  1577 
       
  1578     self withAllSubclassesDo:[:aClass |
       
  1579 	ObjectMemory flushInlineCachesFor:aClass withArgs:nargs.
       
  1580 	ObjectMemory flushMethodCacheFor:aClass
       
  1581     ].
       
  1582 "
       
  1583 
       
  1584     "
       
  1585      actually, we would do better with less flushing ...
       
  1586     "
       
  1587     nargs := newSelector numArgs.
       
  1588 
       
  1589     ObjectMemory flushMethodCache.
       
  1590     ObjectMemory flushInlineCachesWithArgs:nargs.
       
  1591 
       
  1592     ^ true
       
  1593 !
       
  1594 
       
  1595 addSelector:newSelector withLazyMethod:newMethod
       
  1596     "add the method given by 2nd argument under the selector given by
       
  1597      1st argument to the methodDictionary. Since it does not flush
       
  1598      any caches, this is only allowed for lazy methods."
       
  1599 
       
  1600     newMethod isLazyMethod ifFalse:[
       
  1601 	self error:'operation only allowed for lazy methods'.
       
  1602 	^ false
       
  1603     ].
       
  1604     "/ oops: we must flush, if this method already exists ...
       
  1605     (selectorArray includes:newSelector) ifTrue:[
       
  1606 	ObjectMemory flushCaches
       
  1607     ].
       
  1608     (self primAddSelector:newSelector withMethod:newMethod) ifTrue:[
       
  1609 	self changed:#methodDictionary with:newSelector.
       
  1610 	^ true
       
  1611     ].
       
  1612     ^ false
       
  1613 !
       
  1614 
       
  1615 removeSelector:aSelector
       
  1616     "remove the selector, aSelector and its associated method 
       
  1617      from the methodDictionary"
       
  1618 
       
  1619     |index oldSelectorArray oldMethodArray newSelectorArray newMethodArray|
       
  1620 
       
  1621     index := selectorArray identityIndexOf:aSelector startingAt:1.
       
  1622     (index == 0) ifTrue:[^ false].
       
  1623 
       
  1624     newSelectorArray := selectorArray copyWithoutIndex:index.
       
  1625     newMethodArray := methodArray copyWithoutIndex:index.
       
  1626     oldSelectorArray := selectorArray.
       
  1627     oldMethodArray := methodArray.
       
  1628     selectorArray := newSelectorArray.
       
  1629     methodArray := newMethodArray.
       
  1630 "
       
  1631     [
       
  1632 	|nargs|
       
  1633 	nargs := aSelector numArgs.
       
  1634 	ObjectMemory flushMethodCache.
       
  1635 	ObjectMemory flushInlineCachesWithArgs:nargs.
       
  1636     ] value
       
  1637 "
       
  1638     "
       
  1639      actually, we would do better with less flushing ...
       
  1640     "
       
  1641     ObjectMemory flushCaches.
       
  1642     ^ true
       
  1643 ! !
       
  1644 
       
  1645 !Behavior methodsFor:'queries'!
       
  1646 
       
  1647 sizeOfInst:n
       
  1648     "return the number of bytes required for an instance of
       
  1649      myself with n indexed instance variables. The argument n 
       
  1650      should be zero for classes without indexed instance variables.
       
  1651      See Behavior>>niceNew: for an application of this."
       
  1652 
       
  1653     |nInstvars|
       
  1654 
       
  1655     nInstvars := self instSize.
       
  1656 %{
       
  1657     int nBytes;
       
  1658 
       
  1659     nBytes = _intVal(nInstvars) * sizeof(OBJ) + OHDR_SIZE; 
       
  1660     if (__isSmallInteger(n)) {
       
  1661 	int nIndex;
       
  1662 
       
  1663 	nIndex = _intVal(n);
       
  1664 	switch (_intVal(_INST(flags)) & ARRAYMASK) {
       
  1665 	    case BYTEARRAY:
       
  1666 		nBytes += nIndex;
       
  1667 		if (nBytes & (ALIGN - 1)) {
       
  1668 		    nBytes = (nBytes & ~(ALIGN - 1)) + ALIGN;
       
  1669 		}
       
  1670 		break;
       
  1671 
       
  1672 	    case WORDARRAY:
       
  1673 		nBytes += nIndex * sizeof(short);
       
  1674 		if (nBytes & (ALIGN - 1)) {
       
  1675 		    nBytes = (nBytes & ~(ALIGN - 1)) + ALIGN;
       
  1676 		}
       
  1677 		break;
       
  1678 
       
  1679 	    case LONGARRAY:
       
  1680 		nBytes += nIndex * sizeof(long);
       
  1681 		break;
       
  1682 
       
  1683 	    case FLOATARRAY:
       
  1684 		nBytes += nIndex * sizeof(float);
       
  1685 		break;
       
  1686 
       
  1687 	    case DOUBLEARRAY:
       
  1688 		nBytes += nIndex * sizeof(double);
       
  1689 		break;
       
  1690 
       
  1691 	    default:
       
  1692 		nBytes += nIndex * sizeof(OBJ);
       
  1693 		break;
       
  1694 	}
       
  1695     }
       
  1696     RETURN (_MKSMALLINT(nBytes));
       
  1697 %}
       
  1698 !
       
  1699 
       
  1700 isVariable
       
  1701     "return true, if instances have indexed instance variables"
       
  1702 
       
  1703     "this could also be defined as:
       
  1704 	^ (flags bitAnd:(Behavior maskIndexType)) ~~ 0
       
  1705      "
       
  1706 
       
  1707 %{  /* NOCONTEXT */
       
  1708 
       
  1709     RETURN ( (_intVal(_INST(flags)) & ARRAYMASK) ? true : false ); 
       
  1710 %}
       
  1711 !
       
  1712 
       
  1713 isFixed
       
  1714     "return true, if instances do not have indexed instance variables"
       
  1715 
       
  1716     "this could also be defined as:
       
  1717 	^ self isVariable not
       
  1718     "
       
  1719 
       
  1720 %{  /* NOCONTEXT */
       
  1721 
       
  1722     RETURN ( (_intVal(_INST(flags)) & ARRAYMASK) ? false : true ); 
       
  1723 %}
       
  1724 !
       
  1725 
       
  1726 isBits
       
  1727     "return true, if instances have indexed byte or short instance variables.
       
  1728      Ignore long, float and double arrays, since ST-80 code using isBits are probably
       
  1729      not prepared to handle them correctly."
       
  1730 
       
  1731 %{  /* NOCONTEXT */
       
  1732 
       
  1733     REGISTER int flags;
       
  1734 
       
  1735     RETURN ( (((flags = (_intVal(_INST(flags)) & ARRAYMASK)) == BYTEARRAY)
       
  1736 	     || (flags == WORDARRAY)) ? true : false ); 
       
  1737 %}
       
  1738 !
       
  1739 
       
  1740 isBytes
       
  1741     "return true, if instances have indexed byte instance variables"
       
  1742 
       
  1743     "this could also be defined as:
       
  1744 	^ (flags bitAnd:(Behavior maskIndexType)) == Behavior flagBytes
       
  1745     "
       
  1746 %{  /* NOCONTEXT */
       
  1747 
       
  1748     RETURN ( ((_intVal(_INST(flags)) & ARRAYMASK) == BYTEARRAY) ? true : false ); 
       
  1749 %}
       
  1750 !
       
  1751 
       
  1752 isWords
       
  1753     "return true, if instances have indexed short instance variables"
       
  1754 
       
  1755     "this could also be defined as:
       
  1756 	^ (flags bitAnd:(Behavior maskIndexType)) == Behavior flagWords
       
  1757     "
       
  1758 %{  /* NOCONTEXT */
       
  1759 
       
  1760     RETURN ( ((_intVal(_INST(flags)) & ARRAYMASK) == WORDARRAY) ? true : false ); 
       
  1761 %}
       
  1762 !
       
  1763 
       
  1764 isLongs
       
  1765     "return true, if instances have indexed long instance variables"
       
  1766 
       
  1767     "this could also be defined as:
       
  1768 	^ (flags bitAnd:(Behavior maskIndexType)) == Behavior flagLongs
       
  1769     "
       
  1770 %{  /* NOCONTEXT */
       
  1771 
       
  1772     RETURN ( ((_intVal(_INST(flags)) & ARRAYMASK) == LONGARRAY) ? true : false ); 
       
  1773 %}
       
  1774 !
       
  1775 
       
  1776 isFloats
       
  1777     "return true, if instances have indexed float instance variables"
       
  1778 
       
  1779     "this could also be defined as:
       
  1780 	^ (flags bitAnd:(Behavior maskIndexType)) == Behavior flagFloats
       
  1781     "
       
  1782 %{  /* NOCONTEXT */
       
  1783 
       
  1784     RETURN ( ((_intVal(_INST(flags)) & ARRAYMASK) == FLOATARRAY) ? true : false ); 
       
  1785 %}
       
  1786 !
       
  1787 
       
  1788 isDoubles
       
  1789     "return true, if instances have indexed double instance variables"
       
  1790 
       
  1791     "this could also be defined as:
       
  1792 	^ (flags bitAnd:(Behavior maskIndexType)) == Behavior flagDoubles
       
  1793     "
       
  1794 %{  /* NOCONTEXT */
       
  1795 
       
  1796     RETURN ( ((_intVal(_INST(flags)) & ARRAYMASK) == DOUBLEARRAY) ? true : false ); 
       
  1797 %}
       
  1798 !
       
  1799 
       
  1800 isPointers
       
  1801     "return true, if instances have pointer instance variables 
       
  1802      i.e. are either non-indexed or have indexed pointer variables"
       
  1803 
       
  1804     "QUESTION: should we ignore WeakPointers ?"
       
  1805 
       
  1806 %{  /* NOCONTEXT */
       
  1807 
       
  1808     REGISTER int flags;
       
  1809 
       
  1810     flags = _intVal(_INST(flags)) & ARRAYMASK;
       
  1811     switch (flags) {
       
  1812 	default:
       
  1813 	    /* normal objects */
       
  1814 	    RETURN ( true );
       
  1815 
       
  1816 	case BYTEARRAY:
       
  1817 	case WORDARRAY:
       
  1818 	case LONGARRAY:
       
  1819 	case FLOATARRAY:
       
  1820 	case DOUBLEARRAY:
       
  1821 	    RETURN (false );
       
  1822 
       
  1823 	case WKPOINTERARRAY:
       
  1824 	    /* what about those ? */
       
  1825 	    RETURN (true );
       
  1826     }
       
  1827 %}
       
  1828 !
       
  1829 
       
  1830 isBehavior
       
  1831     "return true, if the receiver is describing another objects behavior,
       
  1832      i.e. is a class. Defined to avoid the need to use isKindOf:"
       
  1833 
       
  1834     ^ true
       
  1835 
       
  1836     "
       
  1837      True isBehavior   
       
  1838      true isBehavior
       
  1839     "
       
  1840 !
       
  1841 
       
  1842 canBeSubclassed
       
  1843     "return true, if its allowed to create subclasses of the receiver.
       
  1844      This method is redefined in SmallInteger and UndefinedObject, since
       
  1845      instances are detected by their pointer-fields, i.e. they do not have
       
  1846      a class entry (you dont have to understand this :-)"
       
  1847 
       
  1848     ^ true
       
  1849 !
       
  1850 
       
  1851 hasMultipleSuperclasses
       
  1852     "Return true, if this class inherits from other classes 
       
  1853      (beside its primary superclass). 
       
  1854      This method is a preparation for a future multiple inheritance extension 
       
  1855      - currently it is not supported by the VM"
       
  1856 
       
  1857     ^ otherSuperclasses notNil
       
  1858 !
       
  1859 
       
  1860 superclasses
       
  1861     "return a collection of the receivers immediate superclasses.
       
  1862      This method is a preparation for a future multiple inheritance extension 
       
  1863      - currently it is not supported by the VM"
       
  1864 
       
  1865     |a|
       
  1866 
       
  1867     a := Array with:superclass.
       
  1868     otherSuperclasses notNil ifTrue:[
       
  1869 	^ a , otherSuperclasses
       
  1870     ].
       
  1871     ^ a
       
  1872 
       
  1873     "
       
  1874      String superclasses  
       
  1875     "
       
  1876 !
       
  1877 
       
  1878 allSuperclasses
       
  1879     "return a collection of the receivers accumulated superclasses"
       
  1880 
       
  1881     |aCollection theSuperClass|
       
  1882 
       
  1883     theSuperClass := superclass.
       
  1884     theSuperClass notNil ifTrue:[
       
  1885 	aCollection := OrderedCollection new.
       
  1886 	[theSuperClass notNil] whileTrue:[
       
  1887 	    aCollection add:theSuperClass.
       
  1888 	    theSuperClass := theSuperClass superclass
       
  1889 	]
       
  1890     ].
       
  1891     ^ aCollection
       
  1892 
       
  1893     "
       
  1894      String allSuperclasses 
       
  1895     "
       
  1896 !
       
  1897 
       
  1898 withAllSuperclasses
       
  1899     "return a collection containing the receiver and all
       
  1900      of the receivers accumulated superclasses"
       
  1901 
       
  1902     |aCollection theSuperClass|
       
  1903 
       
  1904     aCollection := OrderedCollection with:self.
       
  1905     theSuperClass := superclass.
       
  1906     [theSuperClass notNil] whileTrue:[
       
  1907 	aCollection add:theSuperClass.
       
  1908 	theSuperClass := theSuperClass superclass
       
  1909     ].
       
  1910     ^ aCollection
       
  1911 
       
  1912     "
       
  1913      String withAllSuperclasses 
       
  1914     "
       
  1915 !
       
  1916 
       
  1917 subclasses
       
  1918     "return a collection of the direct subclasses of the receiver"
       
  1919 
       
  1920     |newColl|
       
  1921 
       
  1922     SubclassInfo notNil ifTrue:[
       
  1923 	newColl := SubclassInfo at:self ifAbsent:nil.
       
  1924 	newColl notNil ifTrue:[^ newColl asOrderedCollection]
       
  1925     ].
       
  1926 
       
  1927     newColl := OrderedCollection new.
       
  1928     self subclassesDo:[:aClass |
       
  1929 	newColl add:aClass
       
  1930     ].
       
  1931     ^ newColl
       
  1932 
       
  1933     "
       
  1934      Collection subclasses
       
  1935     "
       
  1936 !
       
  1937 
       
  1938 allSubclasses
       
  1939     "return a collection of all subclasses (direct AND indirect) of
       
  1940      the receiver. There will be no specific order, in which entries
       
  1941      are returned."
       
  1942 
       
  1943     |newColl|
       
  1944 
       
  1945     newColl := OrderedCollection new.
       
  1946     self allSubclassesDo:[:aClass |
       
  1947 	newColl add:aClass
       
  1948     ].
       
  1949     ^ newColl
       
  1950 
       
  1951     "
       
  1952      Collection allSubclasses
       
  1953     "
       
  1954 !
       
  1955 
       
  1956 allSubclassesInOrder
       
  1957     "return a collection of all subclasses (direct AND indirect) of
       
  1958      the receiver. Higher level subclasses will come before lower ones."
       
  1959 
       
  1960     |newColl|
       
  1961 
       
  1962     newColl := OrderedCollection new.
       
  1963     self allSubclassesInOrderDo:[:aClass |
       
  1964 	newColl add:aClass
       
  1965     ].
       
  1966     ^ newColl
       
  1967 
       
  1968     "
       
  1969      Collection allSubclassesInOrder
       
  1970     "
       
  1971 !
       
  1972 
       
  1973 withAllSubclasses
       
  1974     "return a collection containing the receiver and 
       
  1975      all subclasses (direct AND indirect) of the receiver"
       
  1976 
       
  1977     |newColl|
       
  1978 
       
  1979     newColl := OrderedCollection with:self.
       
  1980     self allSubclassesDo:[:aClass |
       
  1981 	newColl add:aClass
       
  1982     ].
       
  1983     ^ newColl
       
  1984 
       
  1985     "
       
  1986      Collection withAllSubclasses
       
  1987     "
       
  1988 !
       
  1989 
       
  1990 isSubclassOf:aClass
       
  1991     "return true, if I am a subclass of the argument, aClass"
       
  1992 
       
  1993     |theClass|
       
  1994 
       
  1995     theClass := superclass.
       
  1996     [theClass notNil] whileTrue:[
       
  1997 	(theClass == aClass) ifTrue:[^ true].
       
  1998 %{
       
  1999 	if (__isBehaviorLike(theClass)) {
       
  2000 	    theClass = __ClassInstPtr(theClass)->c_superclass;
       
  2001 	} else {
       
  2002 	    theClass = nil;
       
  2003 	}
       
  2004 %}.
       
  2005 "/        theClass := theClass superclass.
       
  2006     ].
       
  2007     ^ false
       
  2008 
       
  2009     "
       
  2010      String isSubclassOf:Collection  
       
  2011      LinkedList isSubclassOf:Array   
       
  2012      1 isSubclassOf:Number              <- will fail since 1 is no class
       
  2013     "     
       
  2014 !
       
  2015 
       
  2016 allInstVarNames
       
  2017     "return a collection of all the instance variable name-strings
       
  2018      this includes all superclass-instance variables.
       
  2019      Since Behavior has no idea of instvar-names, return an empty collection
       
  2020      here. Redefined in ClassDescription."
       
  2021 
       
  2022     ^ #()
       
  2023 !
       
  2024 
       
  2025 allClassVarNames
       
  2026     "return a collection of all the class variable name-strings
       
  2027      this includes all superclass-class variables.
       
  2028      Since Behavior has no idea of classvar-names, return an empty collection
       
  2029      here. Redefined in ClassDescription."
       
  2030 
       
  2031     ^ #()
       
  2032 !
       
  2033 
       
  2034 allInstances
       
  2035     "return a collection of all my instances"
       
  2036 
       
  2037     "Read the documentation on why there seem to be no
       
  2038      instances of SmallInteger and UndefinedObject"
       
  2039 
       
  2040     |coll|
       
  2041 
       
  2042     coll := OrderedCollection new:100.
       
  2043     self allInstancesDo:[:anObject |
       
  2044 	coll add:anObject
       
  2045     ].
       
  2046     ^ coll 
       
  2047 
       
  2048     "
       
  2049      ScrollBar allInstances
       
  2050     "
       
  2051 !
       
  2052 
       
  2053 allSubInstances
       
  2054     "return a collection of all instances of myself and 
       
  2055      instances of all subclasses of myself."
       
  2056 
       
  2057     |coll|
       
  2058 
       
  2059     coll := OrderedCollection new:100.
       
  2060     self allSubInstancesDo:[:anObject |
       
  2061 	(anObject isKindOf:self) ifTrue:[
       
  2062 	    coll add:anObject
       
  2063 	]
       
  2064     ].
       
  2065     ^ coll 
       
  2066 
       
  2067     "
       
  2068      View allSubInstances
       
  2069     "
       
  2070 !
       
  2071 
       
  2072 allDerivedInstances
       
  2073     "return a collection of all instances of myself and 
       
  2074      instances of all subclasses of myself.
       
  2075      This method is going to be removed for protocol compatibility with
       
  2076      other STs; use allSubInstances"
       
  2077 
       
  2078     self obsoleteMethodWarning:'please use #allSubInstances'.
       
  2079     ^ self allSubInstances
       
  2080 !
       
  2081 
       
  2082 hasInstances
       
  2083     "return true, if there are any instances of myself"
       
  2084 
       
  2085     "Read the documentation on why there seem to be no
       
  2086      instances of SmallInteger and UndefinedObject"
       
  2087 
       
  2088 "/    ObjectMemory allObjectsDo:[:anObject |
       
  2089 "/        (anObject class == self) ifTrue:[
       
  2090 "/            ^ true
       
  2091 "/        ]
       
  2092 "/    ].
       
  2093     ObjectMemory allInstancesOf:self do:[:anObject |
       
  2094 	    ^ true
       
  2095     ].
       
  2096     ^ false
       
  2097 
       
  2098     "
       
  2099      Object hasInstances
       
  2100      SequenceableCollection hasInstances
       
  2101      Float hasInstances
       
  2102      SmallInteger hasInstances
       
  2103     "
       
  2104 !
       
  2105 
       
  2106 instanceCount
       
  2107     "return the number of instances of myself."
       
  2108 
       
  2109     "Read the documentation on why there seem to be no
       
  2110      instances of SmallInteger and UndefinedObject"
       
  2111 
       
  2112     |count|
       
  2113 
       
  2114     count := 0.
       
  2115 "/    ObjectMemory allObjectsDo:[:anObject |
       
  2116 "/        (anObject class == self) ifTrue:[
       
  2117 "/            count := count + 1
       
  2118 "/        ]
       
  2119 "/    ].
       
  2120     ObjectMemory allInstancesOf:self do:[:anObject |
       
  2121 	count := count + 1
       
  2122     ].
       
  2123     ^ count
       
  2124 
       
  2125     "
       
  2126      View instanceCount
       
  2127      Object instanceCount
       
  2128      Float instanceCount
       
  2129      SequenceableCollection instanceCount
       
  2130      SmallInteger instanceCount   .... mhmh - hear, hear
       
  2131     "
       
  2132 !
       
  2133 
       
  2134 derivedInstanceCount
       
  2135     "return the number of instances of myself and of subclasses"
       
  2136 
       
  2137     |count|
       
  2138 
       
  2139     count := 0.
       
  2140     ObjectMemory allObjectsDo:[:anObject |
       
  2141 	(anObject isKindOf:self) ifTrue:[
       
  2142 	    count := count + 1
       
  2143 	]
       
  2144     ].
       
  2145     ^ count
       
  2146 
       
  2147     "
       
  2148      View derivedInstanceCount
       
  2149      SequenceableCollection derivedInstanceCount
       
  2150     "
       
  2151 !
       
  2152 
       
  2153 selectorIndex:aSelector
       
  2154     "return the index in the arrays for given selector aSelector"
       
  2155 
       
  2156     ^ selectorArray identityIndexOf:aSelector startingAt:1
       
  2157 !
       
  2158 
       
  2159 includesSelector:aSelector
       
  2160     "for ST-80 compatibility"
       
  2161 
       
  2162     ^ self implements:aSelector
       
  2163 !
       
  2164 
       
  2165 compiledMethodAt:aSelector
       
  2166     "return the method for given selector aSelector or nil.
       
  2167      Only methods in the receiver - not in the superclass chain are tested."
       
  2168 
       
  2169     |index|
       
  2170 
       
  2171     selectorArray isNil ifTrue:[
       
  2172 	('oops: nil selectorArray in ' , self name) errorPrintNL.
       
  2173 	^ nil
       
  2174     ].
       
  2175 
       
  2176     index := selectorArray identityIndexOf:aSelector startingAt:1.
       
  2177     (index == 0) ifTrue:[^ nil].
       
  2178     ^ methodArray at:index
       
  2179 
       
  2180     "
       
  2181      Object compiledMethodAt:#==
       
  2182      (Object compiledMethodAt:#==) category
       
  2183     "
       
  2184 !
       
  2185 
       
  2186 sourceCodeAt:aSelector
       
  2187     "return the methods source for given selector aSelector or nil.
       
  2188      Only methods in the receiver - not in the superclass chain are tested."
       
  2189 
       
  2190     |method|
       
  2191 
       
  2192     method := self compiledMethodAt:aSelector.
       
  2193     method isNil ifTrue:[^ nil].
       
  2194     ^ method source
       
  2195 
       
  2196     "
       
  2197      True sourceCodeAt:#ifTrue:
       
  2198      Object sourceCodeAt:#==
       
  2199      Behavior sourceCodeAt:#sourceCodeAt:
       
  2200     "
       
  2201 !
       
  2202 
       
  2203 lookupMethodFor:aSelector
       
  2204     "return the method, which would be executed if aSelector was sent to
       
  2205      an instance of the receiver. I.e. the selector arrays of the receiver
       
  2206      and all of its superclasses are searched for aSelector.
       
  2207      Return the method, or nil if instances do not understand aSelector.
       
  2208      EXPERIMENTAL: take care of multiple superclasses."
       
  2209 
       
  2210     |m cls|
       
  2211 
       
  2212     cls := self.
       
  2213     [cls notNil] whileTrue:[
       
  2214 	m := cls compiledMethodAt:aSelector.
       
  2215 	m notNil ifTrue:[^ m].
       
  2216 	cls hasMultipleSuperclasses ifTrue:[
       
  2217 	    cls superclasses do:[:aSuperClass |
       
  2218 		m := aSuperClass lookupMethodFor:aSelector.
       
  2219 		m notNil ifTrue:[^ m].
       
  2220 	    ].
       
  2221 	    ^ nil
       
  2222 	] ifFalse:[
       
  2223 	    cls := cls superclass
       
  2224 	]
       
  2225     ].
       
  2226     ^ nil
       
  2227 !
       
  2228 
       
  2229 cachedLookupMethodFor:aSelector
       
  2230     "return the method, which would be executed if aSelector was sent to
       
  2231      an instance of the receiver. I.e. the selector arrays of the receiver
       
  2232      and all of its superclasses are searched for aSelector.
       
  2233      Return the method, or nil if instances do not understand aSelector.
       
  2234      This interface provides exactly the same information as #lookupMethodFor:,
       
  2235      but uses the lookup-cache in the VM for faster search. 
       
  2236      However, keep in mind, that doing a lookup through the cache also adds new
       
  2237      entries and can thus slow down the system by polluting the cache with 
       
  2238      irrelevant entries. (do NOT loop over all objects calling this method).
       
  2239      Does NOT (currently) handle MI"
       
  2240 
       
  2241 %{  /* NOCONTEXT */
       
  2242     extern OBJ __lookup();
       
  2243 
       
  2244     RETURN ( __lookup(self, aSelector, SENDER) );
       
  2245 %}
       
  2246 
       
  2247     "
       
  2248      String cachedLookupMethodFor:#=
       
  2249      String cachedLookupMethodFor:#asOrderedCollection
       
  2250     "
       
  2251 !
       
  2252 
       
  2253 hasMethods
       
  2254     "return true, if there are any (local) methods in this class"
       
  2255 
       
  2256     ^ (methodArray size ~~ 0)
       
  2257 
       
  2258     "
       
  2259      True hasMethods
       
  2260      True class hasMethods
       
  2261     "
       
  2262 !
       
  2263 
       
  2264 implements:aSelector
       
  2265     "return true, if the receiver implements aSelector.
       
  2266      (i.e. implemented in THIS class - NOT in a superclass).
       
  2267      Dont use this method to check if someone responds to a message -
       
  2268      use #canUnderstand: on the class or #respondsTo: on the instance
       
  2269      to do this."
       
  2270 
       
  2271     ^ (selectorArray identityIndexOf:aSelector startingAt:1) ~~ 0
       
  2272 
       
  2273     "
       
  2274      True implements:#ifTrue:
       
  2275      True implements:#==
       
  2276     "
       
  2277 !
       
  2278 
       
  2279 canUnderstand:aSelector
       
  2280     "return true, if the receiver or one of its superclasses implements aSelector.
       
  2281      (i.e. true if my instances understand aSelector)"
       
  2282 
       
  2283     ^ (self lookupMethodFor:aSelector) notNil
       
  2284 
       
  2285     "
       
  2286      True canUnderstand:#ifTrue:
       
  2287      True canUnderstand:#==
       
  2288      True canUnderstand:#do:
       
  2289     "
       
  2290 !
       
  2291 
       
  2292 whichClassImplements:aSelector
       
  2293     "obsolete interface;
       
  2294      use whichClassIncludesSelector: for ST-80 compatibility."
       
  2295 
       
  2296     ^ self whichClassIncludesSelector:aSelector
       
  2297 !
       
  2298 
       
  2299 whichClassIncludesSelector:aSelector
       
  2300     "return the class in the inheritance chain, which implements the method
       
  2301      for aSelector; return nil if none.
       
  2302      EXPERIMENTAL: handle multiple superclasses"
       
  2303 
       
  2304     |cls|
       
  2305 
       
  2306     cls := self.
       
  2307     [cls notNil] whileTrue:[
       
  2308 	(cls implements:aSelector) ifTrue:[^ cls].
       
  2309 	cls hasMultipleSuperclasses ifTrue:[
       
  2310 	    cls superclasses do:[:aSuperClass |
       
  2311 		|implementingClass|
       
  2312 
       
  2313 		implementingClass := aSuperClass whichClassIncludesSelector:aSelector.
       
  2314 		implementingClass notNil ifTrue:[^ implementingClass].
       
  2315 	    ].
       
  2316 	    ^ nil
       
  2317 	] ifFalse:[
       
  2318 	    cls := cls superclass
       
  2319 	]
       
  2320     ].
       
  2321     ^ nil
       
  2322 
       
  2323     "
       
  2324      String whichClassIncludesSelector:#==
       
  2325      String whichClassIncludesSelector:#collect:
       
  2326     "
       
  2327 !
       
  2328 
       
  2329 inheritsFrom:aClass
       
  2330     "return true, if the receiver inherits methods from aClass"
       
  2331 
       
  2332     ^ self isSubclassOf:aClass
       
  2333 
       
  2334     "
       
  2335      True inheritsFrom:Object
       
  2336      LinkedList inheritsFrom:Array
       
  2337     "
       
  2338 !
       
  2339 
       
  2340 selectorAtMethod:aMethod ifAbsent:failBlock
       
  2341     "return the selector for given method aMethod
       
  2342      or the value of failBlock, if not found."
       
  2343 
       
  2344     |index|
       
  2345 
       
  2346     index := methodArray identityIndexOf:aMethod startingAt:1.
       
  2347     (index == 0) ifTrue:[^ failBlock value].
       
  2348     ^ selectorArray at:index
       
  2349 
       
  2350     "
       
  2351      |m|
       
  2352 
       
  2353      m := Object compiledMethodAt:#copy.
       
  2354      Object selectorAtMethod:m ifAbsent:['oops'].
       
  2355     "
       
  2356     "
       
  2357      |m|
       
  2358 
       
  2359      m := Object compiledMethodAt:#copy.
       
  2360      Fraction selectorAtMethod:m ifAbsent:['oops'].
       
  2361     "
       
  2362 !
       
  2363 
       
  2364 selectorAtMethod:aMethod
       
  2365     "Return the selector for given method aMethod."
       
  2366 
       
  2367     ^ self selectorAtMethod:aMethod ifAbsent:[nil]
       
  2368 
       
  2369     "
       
  2370      |m|
       
  2371 
       
  2372      m := Object compiledMethodAt:#copy.
       
  2373      Fraction selectorAtMethod:m.
       
  2374     "
       
  2375     "
       
  2376      |m|
       
  2377 
       
  2378      m := Object compiledMethodAt:#copy.
       
  2379      Object selectorAtMethod:m.
       
  2380     "
       
  2381 !
       
  2382 
       
  2383 containsMethod:aMethod
       
  2384     "Return true, if the argument, aMethod is a method of myself"
       
  2385 
       
  2386     methodArray isNil ifTrue:[^ false].  "degenerated class"
       
  2387     ^ (methodArray identityIndexOf:aMethod startingAt:1) ~~ 0
       
  2388 ! !
       
  2389 
       
  2390 !Behavior methodsFor:'private accessing'!
  2030 !Behavior methodsFor:'private accessing'!
  2391 
  2031 
  2392 setSuperclass:sup selectors:sels methods:m instSize:i flags:f
  2032 flags:aNumber
  2393     "set some inst vars. 
  2033     "set the flags.
  2394      this method is for special uses only - there will be no recompilation
       
  2395      and no change record is written here. Also, if the receiver class has 
       
  2396      already been in use, future operation of the system is not guaranteed to
       
  2397      be correct, since no caches are flushed.
       
  2398      Therefore: do NOT use it; use Behavior>>superclass: (or flush the caches, at least)"
       
  2399 
       
  2400     SubclassInfo := nil.
       
  2401     superclass := sup.
       
  2402     selectorArray := sels.
       
  2403     methodArray := m.
       
  2404     instSize := i.
       
  2405     flags := f
       
  2406 !
       
  2407 
       
  2408 setSuperclass:aClass
       
  2409     "set the superclass of the receiver.
       
  2410      this method is for special uses only - there will be no recompilation
       
  2411      and no change record written here. Also, if the receiver class has
       
  2412      already been in use, future operation of the system is not guaranteed to
       
  2413      be correct, since no caches are flushed.
       
  2414      Therefore: do NOT use it; use Behavior>>superclass: (or flush the caches, at least)"
       
  2415 
       
  2416     SubclassInfo := nil.
       
  2417     superclass := aClass
       
  2418 !
       
  2419 
       
  2420 setOtherSuperclasses:anArrayOfClasses
       
  2421     "EXPERIMENTAL: set the other superclasses of the receiver.
       
  2422      this method is for special uses only - there will be no recompilation
  2034      this method is for special uses only - there will be no recompilation
  2423      and no change record written here; 
  2035      and no change record written here; 
  2424      Do NOT use it."
  2036      Do NOT use it."
  2425 
  2037 
  2426     SubclassInfo := nil.
  2038     flags := aNumber
  2427     otherSuperclasses := anArrayOfClasses
       
  2428 !
  2039 !
  2429 
  2040 
  2430 instSize:aNumber
  2041 instSize:aNumber
  2431     "set the instance size.
  2042     "set the instance size.
  2432      this method is for special uses only - there will be no recompilation
  2043      this method is for special uses only - there will be no recompilation
  2433      and no change record written here; 
  2044      and no change record written here; 
  2434      Do NOT use it."
  2045      Do NOT use it."
  2435 
  2046 
  2436     instSize := aNumber
  2047     instSize := aNumber
  2437 !
       
  2438 
       
  2439 flags:aNumber
       
  2440     "set the flags.
       
  2441      this method is for special uses only - there will be no recompilation
       
  2442      and no change record written here; 
       
  2443      Do NOT use it."
       
  2444 
       
  2445     flags := aNumber
       
  2446 !
       
  2447 
       
  2448 setSelectors:sels methods:m
       
  2449     "set some inst vars. 
       
  2450      this method is for special uses only - there will be no recompilation
       
  2451      and no change record written here; 
       
  2452      Do NOT use it."
       
  2453 
       
  2454     selectorArray := sels.
       
  2455     methodArray := m.
       
  2456 !
       
  2457 
       
  2458 setSelectorArray:anArray
       
  2459     "set the selector array of the receiver.
       
  2460      this method is for special uses only - there will be no recompilation
       
  2461      and no change record written here.
       
  2462      NOT for general use."
       
  2463 
       
  2464     selectorArray := anArray
       
  2465 !
       
  2466 
       
  2467 setMethodArray:anArray
       
  2468     "set the method array of the receiver.
       
  2469      this method is for special uses only - there will be no recompilation
       
  2470      and no change record written here.
       
  2471      NOT for general use."
       
  2472 
       
  2473     methodArray := anArray
       
  2474 !
       
  2475 
       
  2476 setMethodDictionary:aDictionary
       
  2477     "set the receivers method dictionary. 
       
  2478      Since no dictionary is actually used, decompose into selector- and
       
  2479      method arrays and set those. For ST-80 compatibility.
       
  2480      NOT for general use."
       
  2481 
       
  2482     |n newSelectorArray newMethodArray idx|
       
  2483 
       
  2484     n := aDictionary size.
       
  2485     newSelectorArray := Array basicNew:n.
       
  2486     newMethodArray := Array basicNew:n.
       
  2487     idx := 1.
       
  2488     aDictionary keysAndValuesDo:[:sel :method |
       
  2489 	newSelectorArray at:idx put:sel.
       
  2490 	newMethodArray at:idx put:method.
       
  2491 	idx := idx + 1
       
  2492     ].
       
  2493     selectorArray := newSelectorArray.
       
  2494     methodArray := newMethodArray
       
  2495 !
  2048 !
  2496 
  2049 
  2497 primAddSelector:newSelector withMethod:newMethod
  2050 primAddSelector:newSelector withMethod:newMethod
  2498     "add the method given by 2nd argument under the selector given by
  2051     "add the method given by 2nd argument under the selector given by
  2499      the 1st argument to the methodDictionary. 
  2052      the 1st argument to the methodDictionary. 
  2532 	methodArray := newMethodArray
  2085 	methodArray := newMethodArray
  2533     ] ifFalse:[
  2086     ] ifFalse:[
  2534 	methodArray at:index put:newMethod
  2087 	methodArray at:index put:newMethod
  2535     ].
  2088     ].
  2536     ^ true
  2089     ^ true
       
  2090 !
       
  2091 
       
  2092 setMethodArray:anArray
       
  2093     "set the method array of the receiver.
       
  2094      this method is for special uses only - there will be no recompilation
       
  2095      and no change record written here.
       
  2096      NOT for general use."
       
  2097 
       
  2098     methodArray := anArray
       
  2099 !
       
  2100 
       
  2101 setMethodDictionary:aDictionary
       
  2102     "set the receivers method dictionary. 
       
  2103      Since no dictionary is actually used, decompose into selector- and
       
  2104      method arrays and set those. For ST-80 compatibility.
       
  2105      NOT for general use."
       
  2106 
       
  2107     |n newSelectorArray newMethodArray idx|
       
  2108 
       
  2109     n := aDictionary size.
       
  2110     newSelectorArray := Array basicNew:n.
       
  2111     newMethodArray := Array basicNew:n.
       
  2112     idx := 1.
       
  2113     aDictionary keysAndValuesDo:[:sel :method |
       
  2114 	newSelectorArray at:idx put:sel.
       
  2115 	newMethodArray at:idx put:method.
       
  2116 	idx := idx + 1
       
  2117     ].
       
  2118     selectorArray := newSelectorArray.
       
  2119     methodArray := newMethodArray
       
  2120 !
       
  2121 
       
  2122 setOtherSuperclasses:anArrayOfClasses
       
  2123     "EXPERIMENTAL: set the other superclasses of the receiver.
       
  2124      this method is for special uses only - there will be no recompilation
       
  2125      and no change record written here; 
       
  2126      Do NOT use it."
       
  2127 
       
  2128     SubclassInfo := nil.
       
  2129     otherSuperclasses := anArrayOfClasses
       
  2130 !
       
  2131 
       
  2132 setSelectorArray:anArray
       
  2133     "set the selector array of the receiver.
       
  2134      this method is for special uses only - there will be no recompilation
       
  2135      and no change record written here.
       
  2136      NOT for general use."
       
  2137 
       
  2138     selectorArray := anArray
       
  2139 !
       
  2140 
       
  2141 setSelectors:sels methods:m
       
  2142     "set some inst vars. 
       
  2143      this method is for special uses only - there will be no recompilation
       
  2144      and no change record written here; 
       
  2145      Do NOT use it."
       
  2146 
       
  2147     selectorArray := sels.
       
  2148     methodArray := m.
       
  2149 !
       
  2150 
       
  2151 setSuperclass:aClass
       
  2152     "set the superclass of the receiver.
       
  2153      this method is for special uses only - there will be no recompilation
       
  2154      and no change record written here. Also, if the receiver class has
       
  2155      already been in use, future operation of the system is not guaranteed to
       
  2156      be correct, since no caches are flushed.
       
  2157      Therefore: do NOT use it; use Behavior>>superclass: (or flush the caches, at least)"
       
  2158 
       
  2159     SubclassInfo := nil.
       
  2160     superclass := aClass
       
  2161 !
       
  2162 
       
  2163 setSuperclass:sup selectors:sels methods:m instSize:i flags:f
       
  2164     "set some inst vars. 
       
  2165      this method is for special uses only - there will be no recompilation
       
  2166      and no change record is written here. Also, if the receiver class has 
       
  2167      already been in use, future operation of the system is not guaranteed to
       
  2168      be correct, since no caches are flushed.
       
  2169      Therefore: do NOT use it; use Behavior>>superclass: (or flush the caches, at least)"
       
  2170 
       
  2171     SubclassInfo := nil.
       
  2172     superclass := sup.
       
  2173     selectorArray := sels.
       
  2174     methodArray := m.
       
  2175     instSize := i.
       
  2176     flags := f
  2537 ! !
  2177 ! !
  2538 
  2178 
  2539 !Behavior methodsFor:'compiler interface'!
  2179 !Behavior methodsFor:'queries'!
  2540 
  2180 
  2541 compiler
  2181 allClassVarNames
  2542     "return the compiler to use for this class.
  2182     "return a collection of all the class variable name-strings
  2543      OBSOLETE: This is the old ST/X interface, kept for migration. 
  2183      this includes all superclass-class variables.
  2544 	       Dont use it - it will vanish."
  2184      Since Behavior has no idea of classvar-names, return an empty collection
  2545 
  2185      here. Redefined in ClassDescription."
  2546     ^ self compilerClass
  2186 
  2547 !
  2187     ^ #()
  2548 
  2188 !
  2549 compilerClass
  2189 
  2550     "return the compiler to use for this class - 
  2190 allDerivedInstances
  2551      this can be redefined in special classes, to get classes with
  2191     "return a collection of all instances of myself and 
  2552      Lisp, Prolog, ASN1, Basic :-) or whatever syntax."
  2192      instances of all subclasses of myself.
  2553 
  2193      This method is going to be removed for protocol compatibility with
  2554     ^ Compiler
  2194      other STs; use allSubInstances"
  2555 !
  2195 
  2556 
  2196     self obsoleteMethodWarning:'please use #allSubInstances'.
  2557 evaluatorClass
  2197     ^ self allSubInstances
  2558     "return the compiler to use for expression evaluation for this class - 
  2198 !
  2559      this can be redefined in special classes, to get classes with
  2199 
  2560      Lisp, Prolog, ASN1, Basic :-) or whatever syntax."
  2200 allInstVarNames
  2561 
  2201     "return a collection of all the instance variable name-strings
  2562     ^ Compiler
  2202      this includes all superclass-instance variables.
  2563 ! !
  2203      Since Behavior has no idea of instvar-names, return an empty collection
  2564 
  2204      here. Redefined in ClassDescription."
  2565 !Behavior methodsFor:'enumerating'!
  2205 
  2566 
  2206     ^ #()
  2567 allInstancesDo:aBlock
  2207 !
  2568     "evaluate aBlock for all of my instances"
  2208 
       
  2209 allInstances
       
  2210     "return a collection of all my instances"
       
  2211 
       
  2212     "Read the documentation on why there seem to be no
       
  2213      instances of SmallInteger and UndefinedObject"
       
  2214 
       
  2215     |coll|
       
  2216 
       
  2217     coll := OrderedCollection new:100.
       
  2218     self allInstancesDo:[:anObject |
       
  2219 	coll add:anObject
       
  2220     ].
       
  2221     ^ coll 
       
  2222 
       
  2223     "
       
  2224      ScrollBar allInstances
       
  2225     "
       
  2226 !
       
  2227 
       
  2228 allSubInstances
       
  2229     "return a collection of all instances of myself and 
       
  2230      instances of all subclasses of myself."
       
  2231 
       
  2232     |coll|
       
  2233 
       
  2234     coll := OrderedCollection new:100.
       
  2235     self allSubInstancesDo:[:anObject |
       
  2236 	(anObject isKindOf:self) ifTrue:[
       
  2237 	    coll add:anObject
       
  2238 	]
       
  2239     ].
       
  2240     ^ coll 
       
  2241 
       
  2242     "
       
  2243      View allSubInstances
       
  2244     "
       
  2245 !
       
  2246 
       
  2247 allSubclasses
       
  2248     "return a collection of all subclasses (direct AND indirect) of
       
  2249      the receiver. There will be no specific order, in which entries
       
  2250      are returned."
       
  2251 
       
  2252     |newColl|
       
  2253 
       
  2254     newColl := OrderedCollection new.
       
  2255     self allSubclassesDo:[:aClass |
       
  2256 	newColl add:aClass
       
  2257     ].
       
  2258     ^ newColl
       
  2259 
       
  2260     "
       
  2261      Collection allSubclasses
       
  2262     "
       
  2263 !
       
  2264 
       
  2265 allSubclassesInOrder
       
  2266     "return a collection of all subclasses (direct AND indirect) of
       
  2267      the receiver. Higher level subclasses will come before lower ones."
       
  2268 
       
  2269     |newColl|
       
  2270 
       
  2271     newColl := OrderedCollection new.
       
  2272     self allSubclassesInOrderDo:[:aClass |
       
  2273 	newColl add:aClass
       
  2274     ].
       
  2275     ^ newColl
       
  2276 
       
  2277     "
       
  2278      Collection allSubclassesInOrder
       
  2279     "
       
  2280 !
       
  2281 
       
  2282 allSuperclasses
       
  2283     "return a collection of the receivers accumulated superclasses"
       
  2284 
       
  2285     |aCollection theSuperClass|
       
  2286 
       
  2287     theSuperClass := superclass.
       
  2288     theSuperClass notNil ifTrue:[
       
  2289 	aCollection := OrderedCollection new.
       
  2290 	[theSuperClass notNil] whileTrue:[
       
  2291 	    aCollection add:theSuperClass.
       
  2292 	    theSuperClass := theSuperClass superclass
       
  2293 	]
       
  2294     ].
       
  2295     ^ aCollection
       
  2296 
       
  2297     "
       
  2298      String allSuperclasses 
       
  2299     "
       
  2300 !
       
  2301 
       
  2302 cachedLookupMethodFor:aSelector
       
  2303     "return the method, which would be executed if aSelector was sent to
       
  2304      an instance of the receiver. I.e. the selector arrays of the receiver
       
  2305      and all of its superclasses are searched for aSelector.
       
  2306      Return the method, or nil if instances do not understand aSelector.
       
  2307      This interface provides exactly the same information as #lookupMethodFor:,
       
  2308      but uses the lookup-cache in the VM for faster search. 
       
  2309      However, keep in mind, that doing a lookup through the cache also adds new
       
  2310      entries and can thus slow down the system by polluting the cache with 
       
  2311      irrelevant entries. (do NOT loop over all objects calling this method).
       
  2312      Does NOT (currently) handle MI"
       
  2313 
       
  2314 %{  /* NOCONTEXT */
       
  2315     extern OBJ __lookup();
       
  2316 
       
  2317     RETURN ( __lookup(self, aSelector, SENDER) );
       
  2318 %}
       
  2319 
       
  2320     "
       
  2321      String cachedLookupMethodFor:#=
       
  2322      String cachedLookupMethodFor:#asOrderedCollection
       
  2323     "
       
  2324 !
       
  2325 
       
  2326 canBeSubclassed
       
  2327     "return true, if its allowed to create subclasses of the receiver.
       
  2328      This method is redefined in SmallInteger and UndefinedObject, since
       
  2329      instances are detected by their pointer-fields, i.e. they do not have
       
  2330      a class entry (you dont have to understand this :-)"
       
  2331 
       
  2332     ^ true
       
  2333 !
       
  2334 
       
  2335 canUnderstand:aSelector
       
  2336     "return true, if the receiver or one of its superclasses implements aSelector.
       
  2337      (i.e. true if my instances understand aSelector)"
       
  2338 
       
  2339     ^ (self lookupMethodFor:aSelector) notNil
       
  2340 
       
  2341     "
       
  2342      True canUnderstand:#ifTrue:
       
  2343      True canUnderstand:#==
       
  2344      True canUnderstand:#do:
       
  2345     "
       
  2346 !
       
  2347 
       
  2348 compiledMethodAt:aSelector
       
  2349     "return the method for given selector aSelector or nil.
       
  2350      Only methods in the receiver - not in the superclass chain are tested."
       
  2351 
       
  2352     |index|
       
  2353 
       
  2354     selectorArray isNil ifTrue:[
       
  2355 	('oops: nil selectorArray in ' , self name) errorPrintNL.
       
  2356 	^ nil
       
  2357     ].
       
  2358 
       
  2359     index := selectorArray identityIndexOf:aSelector startingAt:1.
       
  2360     (index == 0) ifTrue:[^ nil].
       
  2361     ^ methodArray at:index
       
  2362 
       
  2363     "
       
  2364      Object compiledMethodAt:#==
       
  2365      (Object compiledMethodAt:#==) category
       
  2366     "
       
  2367 !
       
  2368 
       
  2369 containsMethod:aMethod
       
  2370     "Return true, if the argument, aMethod is a method of myself"
       
  2371 
       
  2372     methodArray isNil ifTrue:[^ false].  "degenerated class"
       
  2373     ^ (methodArray identityIndexOf:aMethod startingAt:1) ~~ 0
       
  2374 !
       
  2375 
       
  2376 derivedInstanceCount
       
  2377     "return the number of instances of myself and of subclasses"
       
  2378 
       
  2379     |count|
       
  2380 
       
  2381     count := 0.
       
  2382     ObjectMemory allObjectsDo:[:anObject |
       
  2383 	(anObject isKindOf:self) ifTrue:[
       
  2384 	    count := count + 1
       
  2385 	]
       
  2386     ].
       
  2387     ^ count
       
  2388 
       
  2389     "
       
  2390      View derivedInstanceCount
       
  2391      SequenceableCollection derivedInstanceCount
       
  2392     "
       
  2393 !
       
  2394 
       
  2395 hasInstances
       
  2396     "return true, if there are any instances of myself"
       
  2397 
       
  2398     "Read the documentation on why there seem to be no
       
  2399      instances of SmallInteger and UndefinedObject"
  2569 
  2400 
  2570 "/    ObjectMemory allObjectsDo:[:anObject |
  2401 "/    ObjectMemory allObjectsDo:[:anObject |
  2571 "/        (anObject class == self) ifTrue:[
  2402 "/        (anObject class == self) ifTrue:[
  2572 "/            aBlock value:anObject
  2403 "/            ^ true
  2573 "/        ]
  2404 "/        ]
  2574 "/    ]
  2405 "/    ].
  2575 
       
  2576     ObjectMemory allInstancesOf:self do:[:anObject |
  2406     ObjectMemory allInstancesOf:self do:[:anObject |
  2577 	aBlock value:anObject
  2407 	    ^ true
  2578     ]
  2408     ].
  2579 
  2409     ^ false
  2580     "
  2410 
  2581      StandardSystemView allInstancesDo:[:v | Transcript showCr:(v name)]
  2411     "
  2582     "
  2412      Object hasInstances
  2583 !
  2413      SequenceableCollection hasInstances
  2584 
  2414      Float hasInstances
  2585 allDerivedInstancesDo:aBlock
  2415      SmallInteger hasInstances
  2586     "evaluate aBlock for all of my instances and all instances of subclasses.
  2416     "
  2587      This method is going to be removed for protocol compatibility with
  2417 !
  2588      other STs; use allSubInstancesDo:"
  2418 
  2589 
  2419 hasMethods
  2590     self obsoleteMethodWarning:'please use #allSubInstancesDo:'.
  2420     "return true, if there are any (local) methods in this class"
  2591     self allSubInstancesDo:aBlock
  2421 
  2592 
  2422     ^ (methodArray size ~~ 0)
  2593     "
  2423 
  2594      StandardSystemView allDerivedInstancesDo:[:v | Transcript showCr:(v name)]
  2424     "
  2595     "
  2425      True hasMethods
  2596 !
  2426      True class hasMethods
  2597 
  2427     "
  2598 allSubInstancesDo:aBlock
  2428 !
  2599     "evaluate aBlock for all of my instances and all instances of subclasses"
  2429 
  2600 
  2430 hasMultipleSuperclasses
  2601     ObjectMemory allObjectsDo:[:anObject |
  2431     "Return true, if this class inherits from other classes 
  2602 	(anObject isKindOf:self) ifTrue:[
  2432      (beside its primary superclass). 
  2603 	    aBlock value:anObject
  2433      This method is a preparation for a future multiple inheritance extension 
  2604 	]
  2434      - currently it is not supported by the VM"
  2605     ]
  2435 
  2606 
  2436     ^ otherSuperclasses notNil
  2607     "
  2437 !
  2608      StandardSystemView allSubInstancesDo:[:v | Transcript showCr:(v name)]
  2438 
  2609     "
  2439 implements:aSelector
  2610 !
  2440     "return true, if the receiver implements aSelector.
  2611 
  2441      (i.e. implemented in THIS class - NOT in a superclass).
  2612 subclassesDo:aBlock
  2442      Dont use this method to check if someone responds to a message -
  2613     "evaluate the argument, aBlock for all immediate subclasses.
  2443      use #canUnderstand: on the class or #respondsTo: on the instance
  2614      This will only enumerate globally known classes - for anonymous
  2444      to do this."
  2615      behaviors, you have to walk over all instances of Behavior."
  2445 
  2616 
  2446     ^ (selectorArray identityIndexOf:aSelector startingAt:1) ~~ 0
  2617     |coll|
  2447 
  2618 
  2448     "
  2619     SubclassInfo isNil ifTrue:[
  2449      True implements:#ifTrue:
  2620 	Behavior subclassInfo
  2450      True implements:#==
  2621     ].
  2451     "
  2622     SubclassInfo notNil ifTrue:[
  2452 !
  2623 	coll := SubclassInfo at:self ifAbsent:nil.
  2453 
  2624 	coll notNil ifTrue:[
  2454 includesSelector:aSelector
  2625 	    coll do:aBlock.
  2455     "for ST-80 compatibility"
  2626 	].
  2456 
  2627 	^ self
  2457     ^ self implements:aSelector
  2628     ].
  2458 !
  2629 
  2459 
  2630     Smalltalk allBehaviorsDo:[:aClass |
  2460 inheritsFrom:aClass
  2631 	(aClass superclass == self) ifTrue:[
  2461     "return true, if the receiver inherits methods from aClass"
  2632 	    aBlock value:aClass
  2462 
  2633 	]
  2463     ^ self isSubclassOf:aClass
  2634     ]
  2464 
  2635 
  2465     "
  2636     "
  2466      True inheritsFrom:Object
  2637      Collection subclassesDo:[:c | Transcript showCr:(c name)]
  2467      LinkedList inheritsFrom:Array
  2638     "
  2468     "
  2639 !
  2469 !
  2640 
  2470 
  2641 allSubclassesDo:aBlock
  2471 instanceCount
  2642     "evaluate aBlock for all of my subclasses.
  2472     "return the number of instances of myself."
  2643      There is no specific order, in which the entries are enumerated.
  2473 
  2644      This will only enumerate globally known classes - for anonymous
  2474     "Read the documentation on why there seem to be no
  2645      behaviors, you have to walk over all instances of Behavior."
  2475      instances of SmallInteger and UndefinedObject"
  2646 
  2476 
  2647     Smalltalk allBehaviorsDo:[:aClass |
  2477     |count|
  2648 	(aClass isSubclassOf:self) ifTrue:[
  2478 
  2649 	    aBlock value:aClass
  2479     count := 0.
  2650 	]
  2480 "/    ObjectMemory allObjectsDo:[:anObject |
  2651     ]
  2481 "/        (anObject class == self) ifTrue:[
  2652 
  2482 "/            count := count + 1
  2653     "
  2483 "/        ]
  2654      Collection allSubclassesDo:[:c | Transcript showCr:(c name)]
  2484 "/    ].
  2655     "
  2485     ObjectMemory allInstancesOf:self do:[:anObject |
  2656 !
  2486 	count := count + 1
  2657 
  2487     ].
  2658 allSubclassesInOrderDo:aBlock
  2488     ^ count
  2659     "evaluate aBlock for all of my subclasses.
  2489 
  2660      Higher level subclasses will be enumerated before the deeper ones,
  2490     "
  2661      so the order in which aBlock gets called is ok to fileOut classes in
  2491      View instanceCount
  2662      correct order for later fileIn.
  2492      Object instanceCount
  2663      This will only enumerate globally known classes - for anonymous
  2493      Float instanceCount
  2664      behaviors, you have to walk over all instances of Behavior"
  2494      SequenceableCollection instanceCount
  2665 
  2495      SmallInteger instanceCount   .... mhmh - hear, hear
  2666     self subclassesDo:[:aClass |
  2496     "
  2667 	aBlock value:aClass.
  2497 !
  2668 	aClass allSubclassesInOrderDo:aBlock
  2498 
  2669     ]
  2499 isBehavior
  2670 
  2500     "return true, if the receiver is describing another objects behavior,
  2671     "
  2501      i.e. is a class. Defined to avoid the need to use isKindOf:"
  2672      Collection allSubclassesInOrderDo:[:c | Transcript showCr:(c name)]
  2502 
  2673     "
  2503     ^ true
  2674 !
  2504 
  2675 
  2505     "
  2676 allSuperclassesDo:aBlock
  2506      True isBehavior   
  2677     "evaluate aBlock for all of my superclasses"
  2507      true isBehavior
       
  2508     "
       
  2509 !
       
  2510 
       
  2511 isBits
       
  2512     "return true, if instances have indexed byte or short instance variables.
       
  2513      Ignore long, float and double arrays, since ST-80 code using isBits are probably
       
  2514      not prepared to handle them correctly."
       
  2515 
       
  2516 %{  /* NOCONTEXT */
       
  2517 
       
  2518     REGISTER int flags;
       
  2519 
       
  2520     RETURN ( (((flags = (_intVal(_INST(flags)) & ARRAYMASK)) == BYTEARRAY)
       
  2521 	     || (flags == WORDARRAY)) ? true : false ); 
       
  2522 %}
       
  2523 !
       
  2524 
       
  2525 isBytes
       
  2526     "return true, if instances have indexed byte instance variables"
       
  2527 
       
  2528     "this could also be defined as:
       
  2529 	^ (flags bitAnd:(Behavior maskIndexType)) == Behavior flagBytes
       
  2530     "
       
  2531 %{  /* NOCONTEXT */
       
  2532 
       
  2533     RETURN ( ((_intVal(_INST(flags)) & ARRAYMASK) == BYTEARRAY) ? true : false ); 
       
  2534 %}
       
  2535 !
       
  2536 
       
  2537 isDoubles
       
  2538     "return true, if instances have indexed double instance variables"
       
  2539 
       
  2540     "this could also be defined as:
       
  2541 	^ (flags bitAnd:(Behavior maskIndexType)) == Behavior flagDoubles
       
  2542     "
       
  2543 %{  /* NOCONTEXT */
       
  2544 
       
  2545     RETURN ( ((_intVal(_INST(flags)) & ARRAYMASK) == DOUBLEARRAY) ? true : false ); 
       
  2546 %}
       
  2547 !
       
  2548 
       
  2549 isFixed
       
  2550     "return true, if instances do not have indexed instance variables"
       
  2551 
       
  2552     "this could also be defined as:
       
  2553 	^ self isVariable not
       
  2554     "
       
  2555 
       
  2556 %{  /* NOCONTEXT */
       
  2557 
       
  2558     RETURN ( (_intVal(_INST(flags)) & ARRAYMASK) ? false : true ); 
       
  2559 %}
       
  2560 !
       
  2561 
       
  2562 isFloats
       
  2563     "return true, if instances have indexed float instance variables"
       
  2564 
       
  2565     "this could also be defined as:
       
  2566 	^ (flags bitAnd:(Behavior maskIndexType)) == Behavior flagFloats
       
  2567     "
       
  2568 %{  /* NOCONTEXT */
       
  2569 
       
  2570     RETURN ( ((_intVal(_INST(flags)) & ARRAYMASK) == FLOATARRAY) ? true : false ); 
       
  2571 %}
       
  2572 !
       
  2573 
       
  2574 isLongs
       
  2575     "return true, if instances have indexed long instance variables"
       
  2576 
       
  2577     "this could also be defined as:
       
  2578 	^ (flags bitAnd:(Behavior maskIndexType)) == Behavior flagLongs
       
  2579     "
       
  2580 %{  /* NOCONTEXT */
       
  2581 
       
  2582     RETURN ( ((_intVal(_INST(flags)) & ARRAYMASK) == LONGARRAY) ? true : false ); 
       
  2583 %}
       
  2584 !
       
  2585 
       
  2586 isPointers
       
  2587     "return true, if instances have pointer instance variables 
       
  2588      i.e. are either non-indexed or have indexed pointer variables"
       
  2589 
       
  2590     "QUESTION: should we ignore WeakPointers ?"
       
  2591 
       
  2592 %{  /* NOCONTEXT */
       
  2593 
       
  2594     REGISTER int flags;
       
  2595 
       
  2596     flags = _intVal(_INST(flags)) & ARRAYMASK;
       
  2597     switch (flags) {
       
  2598 	default:
       
  2599 	    /* normal objects */
       
  2600 	    RETURN ( true );
       
  2601 
       
  2602 	case BYTEARRAY:
       
  2603 	case WORDARRAY:
       
  2604 	case LONGARRAY:
       
  2605 	case FLOATARRAY:
       
  2606 	case DOUBLEARRAY:
       
  2607 	    RETURN (false );
       
  2608 
       
  2609 	case WKPOINTERARRAY:
       
  2610 	    /* what about those ? */
       
  2611 	    RETURN (true );
       
  2612     }
       
  2613 %}
       
  2614 !
       
  2615 
       
  2616 isSubclassOf:aClass
       
  2617     "return true, if I am a subclass of the argument, aClass"
  2678 
  2618 
  2679     |theClass|
  2619     |theClass|
  2680 
  2620 
  2681     theClass := superclass.
  2621     theClass := superclass.
  2682     [theClass notNil] whileTrue:[
  2622     [theClass notNil] whileTrue:[
  2683 	aBlock value:theClass.
  2623 	(theClass == aClass) ifTrue:[^ true].
  2684 	theClass := theClass superclass
  2624 %{
  2685     ]
  2625 	if (__isBehaviorLike(theClass)) {
  2686 
  2626 	    theClass = __ClassInstPtr(theClass)->c_superclass;
  2687     "
  2627 	} else {
  2688      String allSuperclassesDo:[:c | Transcript showCr:(c name)]
  2628 	    theClass = nil;
       
  2629 	}
       
  2630 %}.
       
  2631 "/        theClass := theClass superclass.
       
  2632     ].
       
  2633     ^ false
       
  2634 
       
  2635     "
       
  2636      String isSubclassOf:Collection  
       
  2637      LinkedList isSubclassOf:Array   
       
  2638      1 isSubclassOf:Number              <- will fail since 1 is no class
       
  2639     "     
       
  2640 !
       
  2641 
       
  2642 isVariable
       
  2643     "return true, if instances have indexed instance variables"
       
  2644 
       
  2645     "this could also be defined as:
       
  2646 	^ (flags bitAnd:(Behavior maskIndexType)) ~~ 0
       
  2647      "
       
  2648 
       
  2649 %{  /* NOCONTEXT */
       
  2650 
       
  2651     RETURN ( (_intVal(_INST(flags)) & ARRAYMASK) ? true : false ); 
       
  2652 %}
       
  2653 !
       
  2654 
       
  2655 isWords
       
  2656     "return true, if instances have indexed short instance variables"
       
  2657 
       
  2658     "this could also be defined as:
       
  2659 	^ (flags bitAnd:(Behavior maskIndexType)) == Behavior flagWords
       
  2660     "
       
  2661 %{  /* NOCONTEXT */
       
  2662 
       
  2663     RETURN ( ((_intVal(_INST(flags)) & ARRAYMASK) == WORDARRAY) ? true : false ); 
       
  2664 %}
       
  2665 !
       
  2666 
       
  2667 lookupMethodFor:aSelector
       
  2668     "return the method, which would be executed if aSelector was sent to
       
  2669      an instance of the receiver. I.e. the selector arrays of the receiver
       
  2670      and all of its superclasses are searched for aSelector.
       
  2671      Return the method, or nil if instances do not understand aSelector.
       
  2672      EXPERIMENTAL: take care of multiple superclasses."
       
  2673 
       
  2674     |m cls|
       
  2675 
       
  2676     cls := self.
       
  2677     [cls notNil] whileTrue:[
       
  2678 	m := cls compiledMethodAt:aSelector.
       
  2679 	m notNil ifTrue:[^ m].
       
  2680 	cls hasMultipleSuperclasses ifTrue:[
       
  2681 	    cls superclasses do:[:aSuperClass |
       
  2682 		m := aSuperClass lookupMethodFor:aSelector.
       
  2683 		m notNil ifTrue:[^ m].
       
  2684 	    ].
       
  2685 	    ^ nil
       
  2686 	] ifFalse:[
       
  2687 	    cls := cls superclass
       
  2688 	]
       
  2689     ].
       
  2690     ^ nil
       
  2691 !
       
  2692 
       
  2693 selectorAtMethod:aMethod
       
  2694     "Return the selector for given method aMethod."
       
  2695 
       
  2696     ^ self selectorAtMethod:aMethod ifAbsent:[nil]
       
  2697 
       
  2698     "
       
  2699      |m|
       
  2700 
       
  2701      m := Object compiledMethodAt:#copy.
       
  2702      Fraction selectorAtMethod:m.
       
  2703     "
       
  2704     "
       
  2705      |m|
       
  2706 
       
  2707      m := Object compiledMethodAt:#copy.
       
  2708      Object selectorAtMethod:m.
       
  2709     "
       
  2710 !
       
  2711 
       
  2712 selectorAtMethod:aMethod ifAbsent:failBlock
       
  2713     "return the selector for given method aMethod
       
  2714      or the value of failBlock, if not found."
       
  2715 
       
  2716     |index|
       
  2717 
       
  2718     index := methodArray identityIndexOf:aMethod startingAt:1.
       
  2719     (index == 0) ifTrue:[^ failBlock value].
       
  2720     ^ selectorArray at:index
       
  2721 
       
  2722     "
       
  2723      |m|
       
  2724 
       
  2725      m := Object compiledMethodAt:#copy.
       
  2726      Object selectorAtMethod:m ifAbsent:['oops'].
       
  2727     "
       
  2728     "
       
  2729      |m|
       
  2730 
       
  2731      m := Object compiledMethodAt:#copy.
       
  2732      Fraction selectorAtMethod:m ifAbsent:['oops'].
       
  2733     "
       
  2734 !
       
  2735 
       
  2736 selectorIndex:aSelector
       
  2737     "return the index in the arrays for given selector aSelector"
       
  2738 
       
  2739     ^ selectorArray identityIndexOf:aSelector startingAt:1
       
  2740 !
       
  2741 
       
  2742 sizeOfInst:n
       
  2743     "return the number of bytes required for an instance of
       
  2744      myself with n indexed instance variables. The argument n 
       
  2745      should be zero for classes without indexed instance variables.
       
  2746      See Behavior>>niceNew: for an application of this."
       
  2747 
       
  2748     |nInstvars|
       
  2749 
       
  2750     nInstvars := self instSize.
       
  2751 %{
       
  2752     int nBytes;
       
  2753 
       
  2754     nBytes = _intVal(nInstvars) * sizeof(OBJ) + OHDR_SIZE; 
       
  2755     if (__isSmallInteger(n)) {
       
  2756 	int nIndex;
       
  2757 
       
  2758 	nIndex = _intVal(n);
       
  2759 	switch (_intVal(_INST(flags)) & ARRAYMASK) {
       
  2760 	    case BYTEARRAY:
       
  2761 		nBytes += nIndex;
       
  2762 		if (nBytes & (ALIGN - 1)) {
       
  2763 		    nBytes = (nBytes & ~(ALIGN - 1)) + ALIGN;
       
  2764 		}
       
  2765 		break;
       
  2766 
       
  2767 	    case WORDARRAY:
       
  2768 		nBytes += nIndex * sizeof(short);
       
  2769 		if (nBytes & (ALIGN - 1)) {
       
  2770 		    nBytes = (nBytes & ~(ALIGN - 1)) + ALIGN;
       
  2771 		}
       
  2772 		break;
       
  2773 
       
  2774 	    case LONGARRAY:
       
  2775 		nBytes += nIndex * sizeof(long);
       
  2776 		break;
       
  2777 
       
  2778 	    case FLOATARRAY:
       
  2779 		nBytes += nIndex * sizeof(float);
       
  2780 		break;
       
  2781 
       
  2782 	    case DOUBLEARRAY:
       
  2783 		nBytes += nIndex * sizeof(double);
       
  2784 		break;
       
  2785 
       
  2786 	    default:
       
  2787 		nBytes += nIndex * sizeof(OBJ);
       
  2788 		break;
       
  2789 	}
       
  2790     }
       
  2791     RETURN (_MKSMALLINT(nBytes));
       
  2792 %}
       
  2793 !
       
  2794 
       
  2795 sourceCodeAt:aSelector
       
  2796     "return the methods source for given selector aSelector or nil.
       
  2797      Only methods in the receiver - not in the superclass chain are tested."
       
  2798 
       
  2799     |method|
       
  2800 
       
  2801     method := self compiledMethodAt:aSelector.
       
  2802     method isNil ifTrue:[^ nil].
       
  2803     ^ method source
       
  2804 
       
  2805     "
       
  2806      True sourceCodeAt:#ifTrue:
       
  2807      Object sourceCodeAt:#==
       
  2808      Behavior sourceCodeAt:#sourceCodeAt:
       
  2809     "
       
  2810 !
       
  2811 
       
  2812 subclasses
       
  2813     "return a collection of the direct subclasses of the receiver"
       
  2814 
       
  2815     |newColl|
       
  2816 
       
  2817     SubclassInfo notNil ifTrue:[
       
  2818 	newColl := SubclassInfo at:self ifAbsent:nil.
       
  2819 	newColl notNil ifTrue:[^ newColl asOrderedCollection]
       
  2820     ].
       
  2821 
       
  2822     newColl := OrderedCollection new.
       
  2823     self subclassesDo:[:aClass |
       
  2824 	newColl add:aClass
       
  2825     ].
       
  2826     ^ newColl
       
  2827 
       
  2828     "
       
  2829      Collection subclasses
       
  2830     "
       
  2831 !
       
  2832 
       
  2833 superclasses
       
  2834     "return a collection of the receivers immediate superclasses.
       
  2835      This method is a preparation for a future multiple inheritance extension 
       
  2836      - currently it is not supported by the VM"
       
  2837 
       
  2838     |a|
       
  2839 
       
  2840     a := Array with:superclass.
       
  2841     otherSuperclasses notNil ifTrue:[
       
  2842 	^ a , otherSuperclasses
       
  2843     ].
       
  2844     ^ a
       
  2845 
       
  2846     "
       
  2847      String superclasses  
       
  2848     "
       
  2849 !
       
  2850 
       
  2851 whichClassImplements:aSelector
       
  2852     "obsolete interface;
       
  2853      use whichClassIncludesSelector: for ST-80 compatibility."
       
  2854 
       
  2855     ^ self whichClassIncludesSelector:aSelector
       
  2856 !
       
  2857 
       
  2858 whichClassIncludesSelector:aSelector
       
  2859     "return the class in the inheritance chain, which implements the method
       
  2860      for aSelector; return nil if none.
       
  2861      EXPERIMENTAL: handle multiple superclasses"
       
  2862 
       
  2863     |cls|
       
  2864 
       
  2865     cls := self.
       
  2866     [cls notNil] whileTrue:[
       
  2867 	(cls implements:aSelector) ifTrue:[^ cls].
       
  2868 	cls hasMultipleSuperclasses ifTrue:[
       
  2869 	    cls superclasses do:[:aSuperClass |
       
  2870 		|implementingClass|
       
  2871 
       
  2872 		implementingClass := aSuperClass whichClassIncludesSelector:aSelector.
       
  2873 		implementingClass notNil ifTrue:[^ implementingClass].
       
  2874 	    ].
       
  2875 	    ^ nil
       
  2876 	] ifFalse:[
       
  2877 	    cls := cls superclass
       
  2878 	]
       
  2879     ].
       
  2880     ^ nil
       
  2881 
       
  2882     "
       
  2883      String whichClassIncludesSelector:#==
       
  2884      String whichClassIncludesSelector:#collect:
       
  2885     "
       
  2886 !
       
  2887 
       
  2888 withAllSubclasses
       
  2889     "return a collection containing the receiver and 
       
  2890      all subclasses (direct AND indirect) of the receiver"
       
  2891 
       
  2892     |newColl|
       
  2893 
       
  2894     newColl := OrderedCollection with:self.
       
  2895     self allSubclassesDo:[:aClass |
       
  2896 	newColl add:aClass
       
  2897     ].
       
  2898     ^ newColl
       
  2899 
       
  2900     "
       
  2901      Collection withAllSubclasses
       
  2902     "
       
  2903 !
       
  2904 
       
  2905 withAllSuperclasses
       
  2906     "return a collection containing the receiver and all
       
  2907      of the receivers accumulated superclasses"
       
  2908 
       
  2909     |aCollection theSuperClass|
       
  2910 
       
  2911     aCollection := OrderedCollection with:self.
       
  2912     theSuperClass := superclass.
       
  2913     [theSuperClass notNil] whileTrue:[
       
  2914 	aCollection add:theSuperClass.
       
  2915 	theSuperClass := theSuperClass superclass
       
  2916     ].
       
  2917     ^ aCollection
       
  2918 
       
  2919     "
       
  2920      String withAllSuperclasses 
  2689     "
  2921     "
  2690 ! !
  2922 ! !
  2691 
  2923 
  2692 !Behavior methodsFor:'binary storage'!
  2924 !Behavior methodsFor:'snapshots'!
  2693 
  2925 
  2694 storeBinaryDefinitionOn: stream manager: manager
  2926 postSnapshot
  2695     "binary store of a classes definition.
  2927     "sent by ObjectMemory, after a snapshot has been written.
  2696      Classes will store the name only and restore by looking for
  2928      Nothing done here."
  2697      that name in the Smalltalk dictionary."
  2929 !
  2698 
  2930 
  2699     | myName |
  2931 preSnapshot
  2700 
  2932     "sent by ObjectMemory, before a snapshot is written.
  2701     myName := self name.
  2933      Nothing done here."
  2702     stream nextNumber:4 put:self signature.
       
  2703     stream nextNumber:2 put:0.
       
  2704     stream nextNumber:2 put:myName size.
       
  2705     myName do:[:c| 
       
  2706 	stream nextPut:c asciiValue
       
  2707     ]
       
  2708 
       
  2709     "
       
  2710      |s|
       
  2711      s := WriteStream on:ByteArray new.
       
  2712      #(1 2 3 4) storeBinaryOn:s.
       
  2713      Object readBinaryFrom:(ReadStream on:s contents)  
       
  2714 
       
  2715      |s|
       
  2716      s := WriteStream on:ByteArray new.
       
  2717      Rectangle storeBinaryOn:s.
       
  2718      Object readBinaryFrom:(ReadStream on:s contents)  
       
  2719     "
       
  2720 !
       
  2721 
       
  2722 readBinaryFrom:aStream
       
  2723     "read an objects binary representation from the argument,
       
  2724      aStream and return it. 
       
  2725      The read object must be a kind of myself, otherwise an error is raised. 
       
  2726      To get any object, use 'Object readBinaryFrom:...',
       
  2727      To get any number, use 'Number readBinaryFrom:...' and so on.
       
  2728      This is the reverse operation to 'storeBinaryOn:'. "
       
  2729 
       
  2730     ^ self readBinaryFrom:aStream onError:[self error:('expected ' , self name)]
       
  2731 
       
  2732     "
       
  2733      |s|
       
  2734      s := WriteStream on:(ByteArray new).
       
  2735      #(1 2 3 4) storeBinaryOn:s.
       
  2736      Object readBinaryFrom:(ReadStream on:s contents)  
       
  2737     "
       
  2738     "
       
  2739      |s|
       
  2740      s := 'testFile' asFilename writeStream binary.
       
  2741      #(1 2 3 4) storeBinaryOn:s.
       
  2742      'hello world' storeBinaryOn:s.
       
  2743      s close.
       
  2744 
       
  2745      s := 'testFile' asFilename readStream binary.
       
  2746      Transcript showCr:(Object readBinaryFrom:s).
       
  2747      Transcript showCr:(Object readBinaryFrom:s).
       
  2748      s close.
       
  2749     "
       
  2750 !
       
  2751 
       
  2752 readBinaryFrom:aStream onError:exceptionBlock
       
  2753     "read an objects binary representation from the argument,
       
  2754      aStream and return it. 
       
  2755      The read object must be a kind of myself, otherwise the value of
       
  2756      the exceptionBlock is returned.
       
  2757      To get any object, use 'Object readBinaryFrom:...',
       
  2758      To get any number, use 'Number readBinaryFrom:...' and so on.
       
  2759      This is the reverse operation to 'storeBinaryOn:'. "
       
  2760 
       
  2761     |newObject|
       
  2762 
       
  2763     newObject := (BinaryInputManager new:1024) readFrom:aStream.
       
  2764     (newObject isKindOf:self) ifFalse:[^ exceptionBlock value].
       
  2765     ^ newObject
       
  2766 
       
  2767     "
       
  2768      |s|
       
  2769      s := WriteStream on:(ByteArray new).
       
  2770      #(1 2 3 4) storeBinaryOn:s.
       
  2771      Object readBinaryFrom:(ReadStream on:s contents) onError:['oops'] 
       
  2772     "
       
  2773     "
       
  2774      |s|
       
  2775      s := WriteStream on:(ByteArray new).
       
  2776      #[1 2 3 4] storeBinaryOn:s.
       
  2777      Array readBinaryFrom:(ReadStream on:s contents)  onError:['oops']  
       
  2778     "
       
  2779 !
       
  2780 
       
  2781 binaryDefinitionFrom:stream manager:manager
       
  2782     "sent during a binary read by the input manager.
       
  2783      Read the definition on an empty instance (of my class) from stream.
       
  2784      All pointer instances are left nil, while all bits are read in here.
       
  2785      return the new object."
       
  2786 
       
  2787     |obj t
       
  2788      basicSize "{ Class: SmallInteger }" |
       
  2789 
       
  2790     self isPointers ifTrue: [
       
  2791 	"/
       
  2792 	"/ inst size not needed - if you uncomment the line below,
       
  2793 	"/ also uncomment the corresponding line in
       
  2794 	"/ Object>>storeBinaryDefinitionOn:manager:
       
  2795 	"/
       
  2796 	"/ stream next. "skip instSize"
       
  2797 	self isVariable ifTrue: [
       
  2798 	    ^ self basicNew:(stream nextNumber:3)
       
  2799 	].
       
  2800 	^ self basicNew
       
  2801     ].
       
  2802 
       
  2803     "
       
  2804      an object with bit-valued instance variables.
       
  2805      These are read here.
       
  2806     "
       
  2807     basicSize := stream nextNumber:4.
       
  2808     obj := self basicNew:basicSize.
       
  2809 
       
  2810     self isBytes ifTrue: [
       
  2811 	stream nextBytes:basicSize into:obj
       
  2812     ] ifFalse: [
       
  2813 	self isWords ifTrue: [
       
  2814 	    1 to:basicSize do:[:i |
       
  2815 		obj basicAt:i put:(stream nextNumber:2)
       
  2816 	    ]
       
  2817 	] ifFalse:[
       
  2818 	    self isLongs ifTrue: [
       
  2819 		1 to:basicSize do:[:i |
       
  2820 		    obj basicAt:i put:(stream nextNumber:4)
       
  2821 		]
       
  2822 	    ] ifFalse:[
       
  2823 		self isFloats ifTrue: [
       
  2824 		    "could do it in one big read on machines which use IEEE floats ..."
       
  2825 		    t := Float basicNew.
       
  2826 		    1 to:basicSize do:[:i |
       
  2827 			Float readBinaryIEEESingleFrom:stream into:t.
       
  2828 			obj basicAt:i put: t
       
  2829 		    ]
       
  2830 		] ifFalse:[
       
  2831 		    self isDoubles ifTrue: [
       
  2832 			"could do it in one big read on machines which use IEEE doubles ..."
       
  2833 			t := Float basicNew.
       
  2834 			1 to:basicSize do:[:i |
       
  2835 			    Float readBinaryIEEEDoubleFrom:stream into:t.
       
  2836 			    obj basicAt:i put: t
       
  2837 			]
       
  2838 		    ]
       
  2839 		]
       
  2840 	    ]
       
  2841 	]
       
  2842     ].
       
  2843     ^obj
       
  2844 !
       
  2845 
       
  2846 canCloneFrom:anObject 
       
  2847     "return true, if this class can clone an obsolete object as retrieved
       
  2848      by a binary load. Subclasses which do not want to have obsolete objects
       
  2849      be converted, should redefine this method to return false.
       
  2850      (However, conversion is never done silently in a binary load; you
       
  2851       have to have a handler for the binaryload errors and for the conversion
       
  2852       request signal.)"
       
  2853 
       
  2854     ^ true
       
  2855 !
       
  2856 
       
  2857 cloneFrom:aPrototype
       
  2858     "return an instance of myself with variables initialized from
       
  2859      a prototype. This is used when instances of obsolete classes are
       
  2860      binary loaded and a conversion is done on the obsolete object. 
       
  2861      UserClasses may redefine this for better conversions."
       
  2862 
       
  2863     |newInst indexed myInfo otherInfo varIndexAssoc|
       
  2864 
       
  2865     indexed := false.
       
  2866     aPrototype class isVariable ifTrue:[
       
  2867 	self isVariable ifTrue:[
       
  2868 	    indexed := true.
       
  2869 	].
       
  2870 	"otherwise, these are lost ..."
       
  2871     ].
       
  2872     indexed ifTrue:[
       
  2873 	newInst := self basicNew:aPrototype basicSize
       
  2874     ] ifFalse:[
       
  2875 	newInst := self basicNew
       
  2876     ].
       
  2877 
       
  2878     myInfo := self instanceVariableOffsets.
       
  2879     otherInfo := aPrototype class instanceVariableOffsets.
       
  2880     myInfo keysAndValuesDo:[:name :index |
       
  2881 	varIndexAssoc := otherInfo at:name ifAbsent:[].
       
  2882 	varIndexAssoc notNil ifTrue:[
       
  2883 	    newInst instVarAt:index put:(aPrototype instVarAt:(varIndexAssoc value))
       
  2884 	]
       
  2885     ].
       
  2886     indexed ifTrue:[
       
  2887 	1 to:aPrototype basicSize do:[:index |
       
  2888 	    newInst basicAt:index put:(aPrototype basicAt:index)
       
  2889 	].
       
  2890     ].
       
  2891     ^ newInst
       
  2892 
       
  2893     "
       
  2894      Class withoutUpdatingChangesDo:[
       
  2895 	 Point subclass:#Point3D
       
  2896 	   instanceVariableNames:'z'
       
  2897 	   classVariableNames:''
       
  2898 	   poolDictionaries:''
       
  2899 	   category:'testing'.
       
  2900 	 (Point3D cloneFrom:1@2) inspect.
       
  2901      ]
       
  2902     "
       
  2903 
       
  2904     "
       
  2905      Class withoutUpdatingChangesDo:[
       
  2906 	 Point variableSubclass:#Point3D
       
  2907 	   instanceVariableNames:'z'
       
  2908 	   classVariableNames:''
       
  2909 	   poolDictionaries:''
       
  2910 	   category:'testing'.
       
  2911 	 (Point3D cloneFrom:#(1 2 3)) inspect.
       
  2912      ]
       
  2913     "
       
  2914 
       
  2915     "
       
  2916      |someObject|
       
  2917 
       
  2918      Class withoutUpdatingChangesDo:[
       
  2919 	 Object subclass:#TestClass1 
       
  2920 	   instanceVariableNames:'foo bar'
       
  2921 	   classVariableNames:''
       
  2922 	   poolDictionaries:''
       
  2923 	   category:'testing'.
       
  2924 	 someObject := TestClass1 new.
       
  2925 	 someObject instVarAt:1 put:'foo'; instVarAt:2 put:'bar'.
       
  2926 	 Object subclass:#TestClass2 
       
  2927 	   instanceVariableNames:'bar foo'
       
  2928 	   classVariableNames:''
       
  2929 	   poolDictionaries:''
       
  2930 	   category:'testing'.
       
  2931 	 (TestClass2 cloneFrom:someObject) inspect.
       
  2932      ]
       
  2933     "
       
  2934 ! !
  2934 ! !
       
  2935