[Vm-dev] Method executing but not sent to the receiver

Mariano Martinez Peck marianopeck at gmail.com
Wed Apr 20 14:14:15 UTC 2011


On Wed, Apr 20, 2011 at 4:08 PM, Henrik Sperre Johansen <
henrik.s.johansen at veloxit.no> wrote:

>
>  On 20.04.2011 15:52, Mariano Martinez Peck wrote:
>
>
>
> I cannot believe it but it seems to work. I would really appreaciate if
> someone can take a look, and consider to integrate it.
> Having no way to execute a method on a receveir WITHOUT sending a message
> to the object, is really a problem. I am implementing proxies, which
> understand NOTHING (their class has method dictionary in nil and I use the
> cannotInterpret trick) and so I CANNOT send a message because I will be in
> loop. I have a similar problem with primitiveChangeClassTo:  but
> fortunately, Eliot did #adoptInstance: which receiver is the class and not
> the object.
>
> Anyway, this is the method
>
> CompiledMethod >> executeWithReceiver: aReceiver arguments: anArray
>  "Execute the compiledMethod against the aReceiver and args in argArray."
>
> <primitive: 190>
>    self primitiveFailed
>
>
> And this is the primitive.
>
>
> StackInterpreterPrimitives >> primitiveExecuteWithReceiverArguments
>     "method, recevier, and the array of arguments are on top of stack.
> Execute method against receiver and args.
>      Set primitiveFunctionPointer because no cache lookup has been done for
> the method, and
>      hence primitiveFunctionPointer is stale."
>     | receiverMethod argCnt argumentArray primitiveIndex receiverObject |
>     receiverMethod := self stackValue: 2.
>     receiverObject := self stackValue: 1.
>     argumentArray := self stackTop.
>     ((objectMemory isOopCompiledMethod: receiverMethod)
>      and: [objectMemory isArray: argumentArray]) ifFalse:
>         [^self primitiveFailFor: PrimErrBadArgument].
>     argCnt := self argumentCountOf: receiverMethod.
>     argCnt = (objectMemory fetchWordLengthOf: argumentArray) ifFalse:
>         [^self primitiveFailFor: PrimErrBadNumArgs].
>     self pop: 3.
>     self push: receiverObject.
>     0 to: argCnt - 1 do:
>         [:i|
>         self push: (objectMemory fetchPointer: i ofObject: argumentArray)].
>     newMethod := receiverMethod.
>     primitiveIndex := self primitiveIndexOf: newMethod.
>     primitiveFunctionPointer := self functionPointerFor: primitiveIndex
> inClass: nil.
>     argumentCount := argCnt.
>     "We set the messageSelector for executeMethod below since things
>      like the at cache read messageSelector and so it cannot be left
> stale."
>     messageSelector := objectMemory nilObject.
>     self executeNewMethod.
>     "Recursive xeq affects primErrorCode"
>     self initPrimCall
>
>
> Thanks for taking a look and hopefully integrate this or something better,
>
> Mariano
>
> Wouldn't you want to do a class check on the object vs installed class of
> the CompiledMethod as part of PrimErrBadArgument checks?
> Otherwise you'd probably end up insilly situations with CompiledMethods
> which accesses/stores to instvars :)
>
>
Sorry Henry, I couldn't follow you :(
I based such implementation in this one: primitiveExecuteMethodArgsArray

primitiveExecuteMethodArgsArray
    "receiver, argsArray, then method are on top of stack.  Execute method
against receiver and args.
     Set primitiveFunctionPointer because no cache lookup has been done for
the method, and
     hence primitiveFunctionPointer is stale."
    | methodArgument argCnt argumentArray primitiveIndex |
    methodArgument := self stackTop.
    argumentArray := self stackValue: 1.
    ((objectMemory isOopCompiledMethod: methodArgument)
     and: [objectMemory isArray: argumentArray]) ifFalse:
        [^self primitiveFailFor: PrimErrBadArgument].
    argCnt := self argumentCountOf: methodArgument.
    argCnt = (objectMemory fetchWordLengthOf: argumentArray) ifFalse:
        [^self primitiveFailFor: PrimErrBadNumArgs].
    self pop: 2.
    0 to: argCnt - 1 do:
        [:i|
        self push: (objectMemory fetchPointer: i ofObject: argumentArray)].
    newMethod := methodArgument.
    primitiveIndex := self primitiveIndexOf: newMethod.
    primitiveFunctionPointer := self functionPointerFor: primitiveIndex
inClass: nil.
    argumentCount := argCnt.
    "We set the messageSelector for executeMethod below since things
     like the at cache read messageSelector and so it cannot be left stale."
    messageSelector := objectMemory nilObject.
    self executeNewMethod.
    "Recursive xeq affects primErrorCode"
    self initPrimCall


Thanks!



> Cheers,
> Henry
>
>


-- 
Mariano
http://marianopeck.wordpress.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20110420/31bb3fc3/attachment.htm


More information about the Vm-dev mailing list