>
> 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.

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