>> > Um, I'm not upto optimization tricks yet, so no. :)
>>
>> This has nothing to do with *your* optimization tricks. These are
>> optimization tricks that the VM and the compiler play on you. Below a
>> list of potentially dangerous selectors that might not cause the GOODS
>> proxy objects to load the object. You need to be aware of these
>> details to be able to write code that works with proxy objects:
>>
>> ifTrue: ifFalse: ifTrue:ifFalse: ifFalse:ifTrue: and: or: whileFalse:
>> whileTrue: whileFalse whileTrue to:do: to:by:do: caseOf:
>> caseOf:otherwise: ifNil: ifNotNil: �ifNil:ifNotNil: ifNotNil:ifNil:
>> repeat + - < > <= >= = ~= * / \\ @ bitShift: // bitAnd: bitOr: at:
>> at:put: size next nextPut: atEnd == class blockCopy: value value: do:
>> new new: x y yourself
>
>
> Just a small comment: not ALL those methods will be *never* executed.
That's why I used the word "might" ;-)
Lukas
>
> All those that are optimized by the compiler:� MessageNode >> #initialize�� (instVar MacroSelectors)
> ��� ifTrue: ifFalse: ifTrue:ifFalse: ifFalse:ifTrue:
> ��� ��� ��� and: or:
> ��� ��� ��� whileFalse: whileTrue: whileFalse whileTrue
> ��� ��� ��� to:do: to:by:do:
> ��� ��� ��� caseOf: caseOf:otherwise:
> ��� ��� ��� ifNil: ifNotNil:� ifNil:ifNotNil: ifNotNil:ifNil:
> ��� ��� ��� repeat
>
>
> Those are never executed, hence you cannot intercept them.
>
> Now, those special selectors that have associated bytecodes:� Smalltalk specialSelectors
> -> #(#+ 1 #- 1 #< 1 #> 1 #'<=' 1 #'>=' 1 #= 1 #'~=' 1 #* 1 #/ 1 #'\\' 1 #@ 1 #bitShift: 1 #'//' 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #'==' 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0)
>
> SOME of them are not executed.
>
> 1) Some are ALWAYS executed
> For example, the bytecode for #atEnd� does nothing more than a small optimization, but it is always executed at the end:
> StackInterpreter >> bytecodePrimAtEnd
> ��� messageSelector := self specialSelector: 21.
> ��� argumentCount := 0.
> ��� self normalSend.
>
> 2) Some are SOMETIMES executed.
> Example, #+, #>=, etc.� All those math bytecode usually work if the receiver and argument are numbers. But if they are not, like in the case of a proxy, then the bytecode fails and hence, the method is executed. Example:
> StackInterpreter >> bytecodePrimAdd
> ��� | rcvr arg result |
> ��� rcvr := self internalStackValue: 1.
> ��� arg := self internalStackValue: 0.
> ��� (self areIntegers: rcvr and: arg)
> ��� ��� ifTrue: [result := (objectMemory integerValueOf: rcvr) + (objectMemory integerValueOf: arg).
> ��� ��� ��� ��� (objectMemory isIntegerValue: result) ifTrue:
> ��� ��� ��� ��� ��� [self internalPop: 2 thenPush: (objectMemory integerObjectOf: result).
> ��� ��� ��� ��� ��� ^ self fetchNextBytecode "success"]]
> ��� ��� ifFalse: [self initPrimCall.
> ��� ��� ��� ��� self externalizeIPandSP.
> ��� ��� ��� ��� self primitiveFloatAdd: rcvr toArg: arg.
> ��� ��� ��� ��� self internalizeIPandSP.
> ��� ��� ��� ��� self successful ifTrue: [^ self fetchNextBytecode "success"]].
>
> ��� messageSelector := self specialSelector: 0.
> ��� argumentCount := 1.
> ��� self normalSend
>
> 3) Some are NEVER executed. For example, #class and #==.
> StackInterpreter >> bytecodePrimEquivalent
>
> ��� | rcvr arg |
> ��� rcvr := self internalStackValue: 1.
> ��� arg := self internalStackValue: 0.
> ��� self booleanCheat: rcvr = arg.
>
>
> So, for a proxy I think the only problem is (apart from the already mentioned compiler inlining) point 3), that is #== and #class
>
> Anyway, I have wirtten a paper about writting proxies in Smalltalk which you may find interesting.
> http://rmod.lille.inria.fr/web/pier/software/Marea/GhostProxies
> You can get the paper from there.
>
> Cheers
>
>
> �
>>
>> Lukas
>>
>> --
>> Lukas Renggli
>> www.lukas-renggli.ch
>>
>
>
>
> --
> Mariano
> http://marianopeck.wordpress.com
>
>
--
Lukas Renggli
www.lukas-renggli.ch