Hi all,
Monticello has a problem with this class construction:
ProtoObject subclass: #MyClass instanceVariableNames: 'object' classVariableNames: '' poolDictionaries: '' category: 'MyClasses. MyClass superclass: nil
It forgets the last line with superclass specification.
I'm using it for proxy objects. Instances of MyClass have one variable to store a real receiver of messages. MyClass resends messages using doesNotUnderstand mechanism.
doesNotUnderstand: aMessage
^ aMessage sendTo: object.
It works well but there is one problem - Squeak uses optimalization of some message calls. For example, message #class is never called, because Squeak uses special bytecode 199 (bytecodePrimClass). Real class of proxy object is returned instead of receiver class.
Message #isVariable returns wrong value for arrays, large integers etc. So I have made a variable subclass of MyClass and I use it for proxy object of variable receivers. It works well too.
I used this proxy objects for a dictionary and its instance variables including tally. This variable stores a size of dictionary. When Squeak makes a copy of dictionary array, he sends tally like a parameter in constructor of new array, but primitive method fails. VM wants an integer instance strictly.
Any ideas?
Pavel
On Jun 30, 2004, at 12:34 AM, Pavel Křivánek wrote:
Hi all,
Monticello has a problem with this class construction:
ProtoObject subclass: #MyClass instanceVariableNames: 'object' classVariableNames: '' poolDictionaries: '' category: 'MyClasses. MyClass superclass: nil
It forgets the last line with superclass specification.
I'm using it for proxy objects. Instances of MyClass have one variable to store a real receiver of messages. MyClass resends messages using doesNotUnderstand mechanism.
doesNotUnderstand: aMessage
^ aMessage sendTo: object.
It works well but there is one problem - Squeak uses optimalization of some message calls. For example, message #class is never called, because Squeak uses special bytecode 199 (bytecodePrimClass). Real class of proxy object is returned instead of receiver class.
I don't understand in what way this last part is related to Monticello. I can see that Monticello might have trouble saving/loading a class with nil superclass - is that the problem? I always use subclasses of ProtoObject for proxies, which usually works well enough. But if you really need a nil superclass, then yes, we can try to support that. Can you give more info about the errors you are getting when you try?
Avi
The second part of my mail isn't related to Monticello, sorry.
When I save new snapsot, Snapsoo Brower shows:
nil subclass: #MyClass instanceVariableNames: 'object' classVariableNames: '' poolDictionaries: '' category: 'MyClasses'
During loading of snapshot Monticello opens this warning window:
This package depends on the following classes: nil You must resolve these dependencies before you will be able to load these definitions: MyClass etc...
Pavel
----- Original Message ----- From: "Avi Bryant" avi@beta4.com To: "The general-purpose Squeak developers list" squeak-dev@lists.squeakfoundation.org Sent: Wednesday, June 30, 2004 9:41 AM Subject: Re: Monticello bug; #class and #== optimalizations
On Jun 30, 2004, at 12:34 AM, Pavel Křivánek wrote:
Hi all,
Monticello has a problem with this class construction:
ProtoObject subclass: #MyClass instanceVariableNames: 'object' classVariableNames: '' poolDictionaries: '' category: 'MyClasses. MyClass superclass: nil
It forgets the last line with superclass specification.
I'm using it for proxy objects. Instances of MyClass have one variable to store a real receiver of messages. MyClass resends messages using doesNotUnderstand mechanism.
doesNotUnderstand: aMessage
^ aMessage sendTo: object.
It works well but there is one problem - Squeak uses optimalization of some message calls. For example, message #class is never called, because Squeak uses special bytecode 199 (bytecodePrimClass). Real class of proxy object is returned instead of receiver class.
I don't understand in what way this last part is related to Monticello. I can see that Monticello might have trouble saving/loading a class with nil superclass - is that the problem? I always use subclasses of ProtoObject for proxies, which usually works well enough. But if you really need a nil superclass, then yes, we can try to support that. Can you give more info about the errors you are getting when you try?
Avi
hi Pavel,
I also needed to intercept these two messages with my use of proxies in SqueakElib. I have a vm patch that pass through those bytecodes here: http://kilana.unibe.ch:8888/squeakelib/SqueakElibVM-rww.1.mcz
That blocks the bytecodes but there are still three methods you need. I have attached that file. Note that I hand edited the order of methods to put #basicEquivalence: before #==.
One other class of methods that need consideration are those of the #ifTrue:ifFalse: varients. If the receiver isn't a boolean, you get a MustBeBoolean (or whatever it is) error. Tim mentioned this to me and said that changing these could have a noticable impact on the system. :-( Maybe we could change the MustBeBoolean to a msg send, like #cannotInterpret or doesNotUnderstand:. Then we could catch it. I haven't attempted any solution for this case.
Rob
On Wednesday, June 30, 2004, at 12:34 AM, Pavel Křivánek wrote:
Hi all,
Monticello has a problem with this class construction:
ProtoObject subclass: #MyClass instanceVariableNames: 'object' classVariableNames: '' poolDictionaries: '' category: 'MyClasses. MyClass superclass: nil
It forgets the last line with superclass specification.
I'm using it for proxy objects. Instances of MyClass have one variable to store a real receiver of messages. MyClass resends messages using doesNotUnderstand mechanism.
doesNotUnderstand: aMessage
^ aMessage sendTo: object.
It works well but there is one problem - Squeak uses optimalization of some message calls. For example, message #class is never called, because Squeak uses special bytecode 199 (bytecodePrimClass). Real class of proxy object is returned instead of receiver class.
Message #isVariable returns wrong value for arrays, large integers etc. So I have made a variable subclass of MyClass and I use it for proxy object of variable receivers. It works well too.
I used this proxy objects for a dictionary and its instance variables including tally. This variable stores a size of dictionary. When Squeak makes a copy of dictionary array, he sends tally like a parameter in constructor of new array, but primitive method fails. VM wants an integer instance strictly.
Any ideas?
Pavel
Hi Rob,
I think that the clearest solution is to modify the compiler. Remove all optimalizations including jumps in bytecodes for ifTrue:ifFalse:, caseOf: etc. Then recompile whole image. But this step will produce much slower code :-(
The other possible solution is to make special bytecode executor. It should remove optimalizations on the fly. Processes which need to use proxies will run in special simulated mode. It would be slow, but more general solution.
Pavel
hi Pavel,
I also needed to intercept these two messages with my use of proxies in SqueakElib. I have a vm patch that pass through those bytecodes here: http://kilana.unibe.ch:8888/squeakelib/SqueakElibVM-rww.1.mcz
That blocks the bytecodes but there are still three methods you need. I have attached that file. Note that I hand edited the order of methods to put #basicEquivalence: before #==.
One other class of methods that need consideration are those of the #ifTrue:ifFalse: varients. If the receiver isn't a boolean, you get a MustBeBoolean (or whatever it is) error. Tim mentioned this to me and said that changing these could have a noticable impact on the system. :-( Maybe we could change the MustBeBoolean to a msg send, like #cannotInterpret or doesNotUnderstand:. Then we could catch it. I haven't attempted any solution for this case.
Rob
---------------------------------------------------------------------------- ----
On Wednesday, June 30, 2004, at 12:34 AM, Pavel Køivánek wrote:
Hi all,
Monticello has a problem with this class construction:
ProtoObject subclass: #MyClass instanceVariableNames: 'object' classVariableNames: '' poolDictionaries: '' category: 'MyClasses. MyClass superclass: nil
It forgets the last line with superclass specification.
I'm using it for proxy objects. Instances of MyClass have one variable to store a real receiver of messages. MyClass resends messages using doesNotUnderstand mechanism.
doesNotUnderstand: aMessage
^ aMessage sendTo: object.
It works well but there is one problem - Squeak uses optimalization of some message calls. For example, message #class is never called, because Squeak uses special bytecode 199 (bytecodePrimClass). Real class of proxy object is returned instead of receiver class.
Message #isVariable returns wrong value for arrays, large integers etc. So I have made a variable subclass of MyClass and I use it for proxy object of variable receivers. It works well too.
I used this proxy objects for a dictionary and its instance variables including tally. This variable stores a size of dictionary. When Squeak makes a copy of dictionary array, he sends tally like a parameter in constructor of new array, but primitive method fails. VM wants an integer instance strictly.
Any ideas?
Pavel
---------------------------------------------------------------------------- ----
Hi Pavel--
Rather than use doesNotUnderstand:, I think it makes more sense to modify method lookup in the virtual machine, and a few of the bytecode implementations. This has the additional benefit that it doesn't matter what the superclass of the proxy class is. An example set of VM changes is at http://www.netjam.org/squat/releases/current/bits/vmChanges.zip . The Squat snapshots have corresponding object memory changes.
-C
-- Craig Latta improvisational musical informaticist craig@netjam.org www.netjam.org [|] Proceed for Truth!
The trouble is that when you do this you need new VMs for pretty much every proxy implementation. To me it makes much more sense to use DNU: instead of VM lookup changes.
Cheers, - Andreas
----- Original Message ----- From: "Craig Latta" craig@netjam.org To: squeak-dev@lists.squeakfoundation.org Sent: Wednesday, June 30, 2004 10:36 AM Subject: re: #class and #== optimalizations
Hi Pavel--
Rather than use doesNotUnderstand:, I think it makes more sense to modify method lookup in the virtual machine, and a few of the bytecode implementations. This has the additional benefit that it doesn't matter what the superclass of the proxy class is. An example set of VM changes is at http://www.netjam.org/squat/releases/current/bits/vmChanges.zip . The Squat snapshots have corresponding object memory changes.
-C
-- Craig Latta improvisational musical informaticist craig@netjam.org www.netjam.org [|] Proceed for Truth!
The trouble is that when you do this you need new VMs for pretty much every proxy implementation. To me it makes much more sense to use DNU: instead of VM lookup changes.
The trouble with that is that it doesn't work. :)
-C
-- Craig Latta improvisational musical informaticist craig@netjam.org www.netjam.org [|] Proceed for Truth!
The trouble is that when you do this you need new VMs for pretty much
every
proxy implementation. To me it makes much more sense to use DNU: instead
of
VM lookup changes.
The trouble with that is that it doesn't work. :)
Why not? There's no need to generate the byte codes...
Cheers, - Andreas
On Wednesday, June 30, 2004, at 04:55 PM, Andreas Raab wrote:
The trouble is that when you do this you need new VMs for pretty much
every
proxy implementation. To me it makes much more sense to use DNU: instead
of
VM lookup changes.
The trouble with that is that it doesn't work. :)
Why not? There's no need to generate the byte codes...
delegation?
On Wednesday, June 30, 2004, at 03:33 AM, Pavel Krivánek wrote:
I think that the clearest solution is to modify the compiler. Remove all optimalizations including jumps in bytecodes for ifTrue:ifFalse:, caseOf: etc. Then recompile whole image. But this step will produce much slower code :-(
Of course, the translator will counter that to some (unknown to me) degree.
Generally speaking, why aren't those bytecode handlers resending the message if the receiver isn't of the appropriate class? Let the Object level implementations throw the error. Sure, it's the same as the #mustBeBoolean solution, but the semantic would continue to be the original msg selector. That makes a big difference.
The other possible solution is to make special bytecode executor. It should remove optimalizations on the fly. Processes which need to use proxies will run in special simulated mode. It would be slow, but more general solution.
I have seen the term executor used in VW somewhere, but I have never know what it is, and more importantly how it is used/implemented. Does each process hold it's own executor, which dispatches the bytecode stream appropriately to that executor impl? Perhaps each receiver could have an executor to customize bytecode dispatch per class. This sounds interesting, especially if it can more efficiently and transparently handle proxies.
Rob
Class ContextPart can simulate a block of code and it uses actual message calls for bytecodes of type 12 (#class, #== sends etc.).
ContextPart runSimulated: [ 1 class ]
Of course it doesn't solve ifTrue:-like messages and it's much slower than normal code.
Pavel
On Wednesday 30 June 2004 2:38 am, Rob Withers wrote:
One other class of methods that need consideration are those of the #ifTrue:ifFalse: varients. If the receiver isn't a boolean, you get a MustBeBoolean (or whatever it is) error. Tim mentioned this to me and said that changing these could have a noticable impact on the system. :-(
Maybe we could change the MustBeBoolean to a msg send, like #cannotInterpret or doesNotUnderstand:. Then we could catch it. I haven't attempted any solution for this case.
Do you mean like Object>>mustBeBoolean ?
On Wednesday, June 30, 2004, at 02:03 PM, Ned Konz wrote:
On Wednesday 30 June 2004 2:38 am, Rob Withers wrote:
One other class of methods that need consideration are those of the #ifTrue:ifFalse: varients. If the receiver isn't a boolean, you get a MustBeBoolean (or whatever it is) error. Tim mentioned this to me and said that changing these could have a noticable impact on the system. :-(
Maybe we could change the MustBeBoolean to a msg send, like #cannotInterpret or doesNotUnderstand:. Then we could catch it. I haven't attempted any solution for this case.
Do you mean like Object>>mustBeBoolean ?
Ned, if we had something like Object>>mustBeBoolean, then that would be perfect. ;-)
squeak-dev@lists.squeakfoundation.org