On 3 March 2013 18:33, Stéphane Ducasse <[email protected]> wrote:
> Hi
>
> I'm rethinking about my objvlisp lecture. In this lecture I'm talking about 
> building the objVlisp kernel in Smalltalk.
> Now everything is working well except the error handling when a method is not 
> found with different arguments
> than the original. Methods are represented with blocks having different 
> number of arguments.
>
> I have several send messages (I should simplify this in the future)
> ------------------------------------------
> binarySend: selector with: argument
>         "send the message whose selector is <selector> to the receiver. The 
> arguments of the messages
>         are an  <argument>. The method is lookep up in the class of the 
> receiver.
>         self is an objObject or a objClass."
>
>         | ans |
>         ans := (self objClass lookup: selector for: self) value: self value: 
> argument.
>         ^ ans
>
> send: selector withArguments: arguments
>         "send the message whose selector is <selector> to the receiver. The 
> arguments of the messages
>         are an array <arguments>. The method is lookep up in the class of the 
> receiver.
>         self is an objObject or a objClass."
>
>         | ans |
>         ans := (self objClass lookup: selector for: self)
>                                 valueWithArguments: (Array with: self) , 
> arguments.
>         ^ ans
>
> lookup is as simple as
> ------------------------------
>
> lookup: selector for: anObjObject
>         "look for the method named <selector> starting in the receiver.
>         The lookup is done for a message sent to <anObjObject>. self is an 
> objClass"
>
>         ^(self doesUnderstand: selector)
>                 ifTrue:  [ self bodyOfMethod: selector]
>                 ifFalse:  [self objName = #ObjObject
>                                         ifFalse:  [ (Obj giveClassNamed: self 
> objSuperclassId) lookup: selector for: anObjObject.]
>                                 ifTrue: [ anObjObject objClass lookup: #error 
> for: anObjObject]]
>
> Now the problem is that error redefinition only works if the same number of 
> arguments are used and this is not nice.
>
> For example error redefinition works:
> ---------------------------------------------------
> testErrorRedefinition
>         "(self  run: #testErrorRedefinition)"
>
>         self should: [aPoint unarySend: #zork] raise: Error.
>
>         (pointClass at: pointClass offsetForMethodDict) at: #error
>                 put: ([ :superClassOfClassDefiningTheMethod | [:objself  | 
> 33]] value: objectClass).
>
>         self assert: (aPoint unarySend: #zork) = 33.
>
>
> I could use cull: or something like that to be able to execute the block 
> representing the error message
> But I have the impression that I need a way to say that the lookup failed and 
> that the arguments should be packed in a message object.
>
> I looked in the StackVM to see how the arguments were handled: how do we go 
> some
>
>
> lookupMethodInClass: class
>         | currentClass dictionary found |
>         ...
>         currentClass := class.
>         [currentClass ~= objectMemory nilObject]
>                 whileTrue:
>                 [dictionary := objectMemory fetchPointer: 
> MethodDictionaryIndex ofObject: currentClass.
>                 ...
>                 found := self lookupMethodInDictionary: dictionary.
>                 found ifTrue: [^currentClass].
>                 currentClass := self superclassOf: currentClass].
>         ...
>
>         "Cound not find a normal message -- raise exception 
> #doesNotUnderstand:"
>         self createActualMessageTo: class.
>         messageSelector := objectMemory splObj: SelectorDoesNotUnderstand.
>         ^self lookupMethodInClass: class
>
>
>
> Am I correct to believe that createActualMessageTo: eats up the call args and 
> does basically what I would like to do

yes. On DNU, an original message is replaced with #doesNotUnderstand:
as selector and Message instance, which contains original message (the
receiver is unchanged).
Next, VM again does a lookup for #doesNotUnderstand:
and here is caveat: if object does not understands #doesNotUnderstand:
there is no way how you can proceed, so execution should fail with some error.

>
> Stef



-- 
Best regards,
Igor Stasenko.

Reply via email to