ghost
DESCRIPTION
ESUG 2011, EdinburghTRANSCRIPT
What is a proxy?
2
A proxy object is a surrogate or placeholder that controls access to
another target object.
Monday, August 22, 2011
Glossary
Target: object to proxify.
Client: user of the proxy.
Interceptor: object that intercepts message sending.
Handler: object that performs a desired action as a consequence of an interception.
3
Monday, August 22, 2011
Forwarder and Logging example
4
Monday, August 22, 2011
With or without Object replacement?
In proxies with object replacement (#become:), the target object is replaced by a proxy.
Proxies without object replacement are a kind of factory.
5
Monday, August 22, 2011
With or without Object replacement?
In proxies with object replacement (#become:), the target object is replaced by a proxy.
Proxies without object replacement are a kind of factory.
5
Monday, August 22, 2011
Traditional proxy implementations
6
Usage of a minimal object together with an implementation of a custom #doesNotUnderstand
doesNotUnderstand:executeBeforeHandlingexecuteAfterHandling
targetProxy
identityHashpointersTonextObject...
ProtoObject
Monday, August 22, 2011
7
We are going to play a little game...
Monday, August 22, 2011
8
Are both prints in Transcript the same or not?
Monday, August 22, 2011
8
Are both prints in Transcript the same or not?
Conclusion: methods understood are NOT intercepted.Is that bad?
Monday, August 22, 2011
8
Are both prints in Transcript the same or not?
Conclusion: methods understood are NOT intercepted.Is that bad?
Different execution paths Errors difficult to findMonday, August 22, 2011
9
Do we want the regular #doesNotUnderstand or to intercept the message?
Monday, August 22, 2011
10
Do we want the regular #doesNotUnderstand or to intercept the message?
Monday, August 22, 2011
11
I wanted the normal #doesNotUnderstand!!!
Monday, August 22, 2011
12
I wanted the normal #doesNotUnderstand!!!
Monday, August 22, 2011
Problems #doesNotUnderstand: cannot be trapped like a regular message.
Mix of handling procedure and proxy interception.
Only methods that are not understood are intercepted.
No separation between proxies and handlers
13
This approach is not stratified
Monday, August 22, 2011
14
Subclassing from nil does not solve the problem.
Monday, August 22, 2011
15
VM CRASH
This solution is not uniform
Monday, August 22, 2011
16
A Uniform, Light-weight and Stratified Proxy Model and Implementation.
Monday, August 22, 2011
Used hooks
Object replacement (#become:)
Change an object’s class (#adoptInstance:)
Objects as methods (#run:with:in:)
Classes with no method dictionary (#cannotInterpret:)
17
Monday, August 22, 2011
Object replacement
18
AB
CD
AB
CD
c become: d
Monday, August 22, 2011
Objects as methods
19
The VM sends #run: aSelector with: anArray in: aReceiver
Monday, August 22, 2011
Objects as methods
19
The VM sends #run: aSelector with: anArray in: aReceiver
So.....We can implement in Proxy:
Monday, August 22, 2011
CLasses with no method dictionary
20
aProxy
aProxy username
1: #username send
methodDict := nilProxyTrap
cannotInterpret: aMessageProxy
Object
2: #aProxy lookup
3: Since the method dictionary was nil, the VM sends #cannotInterpret to
the receiver but starting the lookup in the superclass
4: #cannotInterpret: lookup
Referencesinstance ofmessage sendlookupsubclass
Monday, August 22, 2011
Ghost model
21
cannotInterpret:proxyFor:
handlertarget
Proxy
initializenilMethodDict
ProxyTrap
Object
handleInterception: anInterceptionProxyHandler
handleInterception: anInterceptionSimpleForwarderHandler
messageproxyproxyState
Interception
Monday, August 22, 2011
How it works?
22
cannotInterpret:proxyFor:
handlertarget
Proxy
initializenilMethodDict
ProxyTrap
Object
Monday, August 22, 2011
How it works?
22
cannotInterpret:proxyFor:
handlertarget
Proxy
initializenilMethodDict
ProxyTrap
Object
Proxy class >>
Monday, August 22, 2011
How it works?
22
cannotInterpret:proxyFor:
handlertarget
Proxy
initializenilMethodDict
ProxyTrap
Object
aProxy
‘Mariano’aHandler
instanceOf
Proxy class >>
Monday, August 22, 2011
How it works?
22
cannotInterpret:proxyFor:
handlertarget
Proxy
initializenilMethodDict
ProxyTrap
Object
aProxy
‘Mariano’aHandler
instanceOf
Proxy class >>
ProxyTrap class >>
Monday, August 22, 2011
How it works?
22
cannotInterpret:proxyFor:
handlertarget
Proxy
initializenilMethodDict
ProxyTrap
Object
aProxy
‘Mariano’aHandler
instanceOf
Proxy class >>
ProxyTrap class >>
Monday, August 22, 2011
How it works?
22
cannotInterpret:proxyFor:
handlertarget
Proxy
initializenilMethodDict
ProxyTrap
Object
aProxy
‘Mariano’aHandler
instanceOf
Proxy class >>
Monday, August 22, 2011
aProxy
aProxy username
1: #username send
methodDict := nilProxyTrap
cannotInterpret: aMessageProxy
Object
2: #aProxy lookup
3: Since the method dictionary was nil, the VM sends #cannotInterpret to
the receiver but starting the lookup in the superclass
4: #cannotInterpret: lookup
Referencesinstance ofmessage sendlookupsubclass
How it works?
23
Monday, August 22, 2011
aProxy
aProxy username
1: #username send
methodDict := nilProxyTrap
cannotInterpret: aMessageProxy
Object
2: #aProxy lookup
3: Since the method dictionary was nil, the VM sends #cannotInterpret to
the receiver but starting the lookup in the superclass
4: #cannotInterpret: lookup
Referencesinstance ofmessage sendlookupsubclass
How it works?
23
Monday, August 22, 2011
aProxy
aProxy username
1: #username send
methodDict := nilProxyTrap
cannotInterpret: aMessageProxy
Object
2: #aProxy lookup
3: Since the method dictionary was nil, the VM sends #cannotInterpret to
the receiver but starting the lookup in the superclass
4: #cannotInterpret: lookup
Referencesinstance ofmessage sendlookupsubclass
How it works?
23
Monday, August 22, 2011
aProxy
aProxy username
1: #username send
methodDict := nilProxyTrap
cannotInterpret: aMessageProxy
Object
2: #aProxy lookup
3: Since the method dictionary was nil, the VM sends #cannotInterpret to
the receiver but starting the lookup in the superclass
4: #cannotInterpret: lookup
Referencesinstance ofmessage sendlookupsubclass
How it works?
23
Monday, August 22, 2011
aProxy
aProxy username
1: #username send
methodDict := nilProxyTrap
cannotInterpret: aMessageProxy
Object
2: #aProxy lookup
3: Since the method dictionary was nil, the VM sends #cannotInterpret to
the receiver but starting the lookup in the superclass
4: #cannotInterpret: lookup
Referencesinstance ofmessage sendlookupsubclass
How it works?
23
Monday, August 22, 2011
aProxy
aProxy username
1: #username send
methodDict := nilProxyTrap
cannotInterpret: aMessageProxy
Object
2: #aProxy lookup
3: Since the method dictionary was nil, the VM sends #cannotInterpret to
the receiver but starting the lookup in the superclass
4: #cannotInterpret: lookup
Referencesinstance ofmessage sendlookupsubclass
How it works?
23
Proxy >>
Monday, August 22, 2011
aProxy
aProxy username
1: #username send
methodDict := nilProxyTrap
cannotInterpret: aMessageProxy
Object
2: #aProxy lookup
3: Since the method dictionary was nil, the VM sends #cannotInterpret to
the receiver but starting the lookup in the superclass
4: #cannotInterpret: lookup
Referencesinstance ofmessage sendlookupsubclass
How it works?
23
Proxy >>
SimpleForwarderHandler >>
Monday, August 22, 2011
24
Traditional Ghost
#doesNotUnderstand: cannot be trapped like a regular message.
#cannotInterpret: is trapped like a regular message.
Mix of handling procedure and proxy interception.
No mix of handling procedure and proxy interception.
Only methods that are not understood are intercepted.
“All” methods are intercepted.
No separation between proxies and handlers.
Clear separation between proxies and handlers.
Monday, August 22, 2011
25
is stratified
Monday, August 22, 2011
Methods not intercepted
26
1) Optimizations done by the Compiler
2) Special shortcut bytecodes between Compiler and VM
2.1) Methods NEVER sent: #== and #class2.2) Methods that may or may not be executed depending
on the receiver and arguments: e.g. in ‘1+1’ #+ is not executed. But with ‘1+$C’ #+ is executed.
2.3)Always executed, they are just little optimizations. Examples #new, #next, #nextPut:, #size, etc.
Monday, August 22, 2011
Methods not intercepted
26
1) Optimizations done by the Compiler
2) Special shortcut bytecodes between Compiler and VM
2.1) Methods NEVER sent: #== and #class2.2) Methods that may or may not be executed depending
on the receiver and arguments: e.g. in ‘1+1’ #+ is not executed. But with ‘1+$C’ #+ is executed.
2.3)Always executed, they are just little optimizations. Examples #new, #next, #nextPut:, #size, etc.
Monday, August 22, 2011
Methods not intercepted
26
1) Optimizations done by the Compiler
2) Special shortcut bytecodes between Compiler and VM
2.1) Methods NEVER sent: #== and #class2.2) Methods that may or may not be executed depending
on the receiver and arguments: e.g. in ‘1+1’ #+ is not executed. But with ‘1+$C’ #+ is executed.
2.3)Always executed, they are just little optimizations. Examples #new, #next, #nextPut:, #size, etc.
Monday, August 22, 2011
Proxy for classes
27
cannotInterpret:proxyFor:
handlertarget
Proxy
initializenilMethodDict
ProxyTrap
Object
cannotInterpret:proxyFor:
superclass methodDictformathandlertarget
ClassProxy
initializenilMethodDict
ClassProxyTrap
logIn:validate:
usernameage
User
Monday, August 22, 2011
Proxy for classes
27
cannotInterpret:proxyFor:
handlertarget
Proxy
initializenilMethodDict
ProxyTrap
Object
cannotInterpret:proxyFor:
superclass methodDictformathandlertarget
ClassProxy
initializenilMethodDict
ClassProxyTrap
logIn:validate:
usernameage
User
Monday, August 22, 2011
Proxy for classes
27
cannotInterpret:proxyFor:
handlertarget
Proxy
initializenilMethodDict
ProxyTrap
Object
cannotInterpret:proxyFor:
superclass methodDictformathandlertarget
ClassProxy
initializenilMethodDict
ClassProxyTrap
logIn:validate:
usernameage
User
Monday, August 22, 2011
Proxy for classes
27
cannotInterpret:proxyFor:
handlertarget
Proxy
initializenilMethodDict
ProxyTrap
Object
cannotInterpret:proxyFor:
superclass methodDictformathandlertarget
ClassProxy
initializenilMethodDict
ClassProxyTrap
logIn:validate:
usernameage
User
Monday, August 22, 2011
Proxy for classes
27
cannotInterpret:proxyFor:
handlertarget
Proxy
initializenilMethodDict
ProxyTrap
Object
cannotInterpret:proxyFor:
superclass methodDictformathandlertarget
ClassProxy
initializenilMethodDict
ClassProxyTrap
aUseraClassProxy
methodDict = nilsuperclass = ClassProxy
logIn:validate:
usernameage
User
instance of
Monday, August 22, 2011
Proxy for classes
27
cannotInterpret:proxyFor:
handlertarget
Proxy
initializenilMethodDict
ProxyTrap
Object
cannotInterpret:proxyFor:
superclass methodDictformathandlertarget
ClassProxy
initializenilMethodDict
ClassProxyTrap
aUseraClassProxy
methodDict = nilsuperclass = ClassProxy
logIn:validate:
usernameage
User
instance of
User nameMonday, August 22, 2011
Proxy for classes
27
cannotInterpret:proxyFor:
handlertarget
Proxy
initializenilMethodDict
ProxyTrap
Object
cannotInterpret:proxyFor:
superclass methodDictformathandlertarget
ClassProxy
initializenilMethodDict
ClassProxyTrap
aUseraClassProxy
methodDict = nilsuperclass = ClassProxy
logIn:validate:
usernameage
User
instance of
aUser username
User nameMonday, August 22, 2011
Proxy for methods
28
Monday, August 22, 2011
Proxy for methods
28
Regular message
Monday, August 22, 2011
Proxy for methods
28
Regular messageMethod execution
Monday, August 22, 2011
Proxy for methods
28
Just handling #run:with:in correctly is enough to also intercept method execution.
Regular messageMethod execution
Monday, August 22, 2011
is
29
Uniform
Monday, August 22, 2011
is
29
moreUniform
Monday, August 22, 2011
More features
Low memory footprint.
Compact classes.
Store the minimal needed state.
Easy debugging.
Custom list of messages.
30
Monday, August 22, 2011
Conclusion
31
With a little bit of special support from the VM (#cannotInterpret hook), we can have an image-side proxy solution
much better than the classic #doesNotUnderstand:
Monday, August 22, 2011
Future work
Experiment with immediate proxies (memory address tag) in VM side.
Think how to correctly intercept non-executed methods.
32
Monday, August 22, 2011
Links
http://rmod.lille.inria.fr/web/pier/software/Marea/GhostProxies
http://www.squeaksource.com/Marea.html
33
Monday, August 22, 2011
Mariano Martinez [email protected]
http://marianopeck.wordpress.com/
RMod
A Uniform, Light-weight and Stratified Proxy Model and Implementation
Monday, August 22, 2011