[Vm-dev] Method executing but not sent to the receiver
Henrik Sperre Johansen
henrik.s.johansen at veloxit.no
Wed Apr 20 14:08:26 UTC 2011
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:
> self push: (objectMemory fetchPointer: i ofObject:
> 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
> messageSelector := objectMemory nilObject.
> self executeNewMethod.
> "Recursive xeq affects primErrorCode"
> self initPrimCall
> Thanks for taking a look and hopefully integrate this or something better,
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 :)
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Vm-dev