Hi. There is something I don't understand about #cannotInterpret and maybe you can help me. Since I am not sure if this is more image side or vm, I did a cross post, sorry for that. Context: I am implementing proxies for classes. Since I want that a proxy loads back the original object when receiving the message #class, I have removed from the compiler the shortcut bytecode for class, with this: (ParseNode classVarNamed: 'StdSelectors') removeKey: #class ifAbsent: []. Now, my testcase is something like this: | inst proxy | "This is the simplest test that does the less assert as possible." inst := ClassWith1Var new. self assert: inst foo = 'foo'. proxy := ClassProxyInstVar new. proxy become: ClassWith1Var. "here I can send any message, it is just to load back the original class" inst basicIdentityHash. self assert: (inst class == ClassWith1Var). self assert: inst foo = 'foo'. ProtoObject subclass: #ClassProxyInstVar instanceVariableNames: 'superclass methodDict format actualClass' classVariableNames: '' poolDictionaries: '' category: 'Proxies' ClassProxyInstVar >> initialize super initialize. superclass := ProxySuperclass. methodDict := nil. actualClass := self So...with this i can use an instance of ClassProxyInstVar like a class. When an instance of the class receives a message, the methodDict will be in nil, and then the VM will send the #cannotInterpret. and there I want to put back the original class. Then I do: ProxySuperclass >> cannotInterpret: aMessage Transcript cr; show: 'cannotInterpret:'; space; show: aMessage selector.. self class restore. ^aMessage sendTo: self Now, this is working, but there is something I DO NOT UNSERSTAND. When I try to do the "inst basicIdentityHash" the VM will send the #cannotInterpret to ProxySuperclass because the methodDict was nil in ClassProxyInstVar. Ok, perfect. What I don't understand is how the method #cannotInterptet can be run perfeclty in this case, since I am doing a "self class restore" there. Remember I removed the shortcut bytecode, so #class is sent like any normal message. So, my question is, when sending "self class", why the VM doesn't call #cannotInterpter again like it did it when I did " inst basicIdentityHash." ? in other words...why the VM isn't entering in a loop ? There is something I am not seeing. Thanks for any help in advance, Mariano |
AFAIK, #cannotInterpret: is sent to super On 16 January 2011 11:50, Mariano Martinez Peck <[hidden email]> wrote: > > Hi. There is something I don't understand about #cannotInterpret and maybe you can help me. Since I am not sure if this is more image side or vm, I did a cross post, sorry for that. > Context: I am implementing proxies for classes. Since I want that a proxy loads back the original object when receiving the message #class, I have removed from the compiler the shortcut bytecode for class, with this: > > (ParseNode classVarNamed: 'StdSelectors') removeKey: #class ifAbsent: []. > > Now, my testcase is something like this: > > | inst proxy | > "This is the simplest test that does the less assert as possible." > inst := ClassWith1Var new. > self assert: inst foo = 'foo'. > proxy := ClassProxyInstVar new. > proxy become: ClassWith1Var. > "here I can send any message, it is just to load back the original class" > inst basicIdentityHash. > self assert: (inst class == ClassWith1Var). > self assert: inst foo = 'foo'. > > > ProtoObject subclass: #ClassProxyInstVar > instanceVariableNames: 'superclass methodDict format actualClass' > classVariableNames: '' > poolDictionaries: '' > category: 'Proxies' > > > ClassProxyInstVar >> initialize > super initialize. > superclass := ProxySuperclass. > methodDict := nil. > actualClass := self > > > So...with this i can use an instance of ClassProxyInstVar like a class. When an instance of the class receives a message, the methodDict will be in nil, and then the VM will send the #cannotInterpret. and there I want to put back the original class. Then I do: > > ProxySuperclass >> cannotInterpret: aMessage > Transcript cr; > show: 'cannotInterpret:'; > space; > show: aMessage selector.. > self class restore. > ^aMessage sendTo: self > > Now, this is working, but there is something I DO NOT UNSERSTAND. When I try to do the "inst basicIdentityHash" the VM will send the #cannotInterpret to ProxySuperclass because the methodDict was nil in ClassProxyInstVar. Ok, perfect. What I don't understand is how the method #cannotInterptet can be run perfeclty in this case, since I am doing a "self class restore" there. Remember I removed the shortcut bytecode, so #class is sent like any normal message. So, my question is, when sending "self class", why the VM doesn't call #cannotInterpter again like it did it when I did " inst basicIdentityHash." ? in other words...why the VM isn't entering in a loop ? There is something I am not seeing. > check the bytecode of method. A special sends, which shortcutted using different bytecode. To avoid self sends, which will lead to infinite loop, you can use the message's lookupClass to send message to class side: aMessage lookupClass restore. > Thanks for any help in advance, > > Mariano > > -- Best regards, Igor Stasenko AKA sig. |
On Sun, Jan 16, 2011 at 1:26 PM, Igor Stasenko <[hidden email]> wrote:
yes, I know, this is why in my case I implemented that in the superclass.
Yes, but I disable them, by evaluating: "(ParseNode classVarNamed: 'StdSelectors') removeKey: #class ifAbsent: []."
This is a good trick!!! This was really helpful Igor. Anyway, now I found which was my problem. I mean, I understood why it was not causing a loop and was working instead. The thing is that I evaluated "(ParseNode classVarNamed: 'StdSelectors') removeKey: #class ifAbsent: []." but then I check the the implemenation of #cannotInterpret and it was still using the shortcut bytecode for #class. Why ? because I forget a Compiler recompileAll!!!! hehehehe :) thanks Mariano
|
Free forum by Nabble | Edit this page |