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
�