<br><br><div class="gmail_quote">On Wed, Apr 20, 2011 at 4:08 PM, Henrik Sperre Johansen <span dir="ltr"><<a href="mailto:henrik.s.johansen@veloxit.no">henrik.s.johansen@veloxit.no</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
<div bgcolor="#ffffff" text="#000000">
On 20.04.2011 15:52, Mariano Martinez Peck wrote:
<blockquote type="cite">
<pre> </pre>
<br>
<fieldset></fieldset>
<br>
I cannot believe it but it seems to work. I would really
appreaciate if someone can take a look, and consider to integrate
it. <br>
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. <br>
<br>
Anyway, this is the method <br>
<br>
CompiledMethod >> executeWithReceiver: aReceiver arguments:
anArray <br>
"Execute the compiledMethod against the aReceiver and args in
argArray."<br>
<br>
<primitive: 190><br>
self primitiveFailed<br>
<br>
<br>
And this is the primitive. <br>
<br>
<br>
StackInterpreterPrimitives >>
primitiveExecuteWithReceiverArguments<br>
"method, recevier, and the array of arguments are on top of
stack. Execute method against receiver and args.<br>
Set primitiveFunctionPointer because no cache lookup has been
done for the method, and<br>
hence primitiveFunctionPointer is stale."<br>
| receiverMethod argCnt argumentArray primitiveIndex
receiverObject |<br>
receiverMethod := self stackValue: 2.<br>
receiverObject := self stackValue: 1.<br>
argumentArray := self stackTop.<br>
((objectMemory isOopCompiledMethod: receiverMethod)<br>
and: [objectMemory isArray: argumentArray]) ifFalse:<br>
[^self primitiveFailFor: PrimErrBadArgument].<br>
argCnt := self argumentCountOf: receiverMethod.<br>
argCnt = (objectMemory fetchWordLengthOf: argumentArray)
ifFalse:<br>
[^self primitiveFailFor: PrimErrBadNumArgs].<br>
self pop: 3.<br>
self push: receiverObject.<br>
0 to: argCnt - 1 do:<br>
[:i|<br>
self push: (objectMemory fetchPointer: i ofObject:
argumentArray)].<br>
newMethod := receiverMethod.<br>
primitiveIndex := self primitiveIndexOf: newMethod.<br>
primitiveFunctionPointer := self functionPointerFor:
primitiveIndex inClass: nil.<br>
argumentCount := argCnt.<br>
"We set the messageSelector for executeMethod below since
things<br>
like the at cache read messageSelector and so it cannot be
left stale."<br>
messageSelector := objectMemory nilObject.<br>
self executeNewMethod.<br>
"Recursive xeq affects primErrorCode"<br>
self initPrimCall<br>
<br>
<br>
Thanks for taking a look and hopefully integrate this or something
better,<br>
<br>
Mariano<br>
</blockquote>
Wouldn't you want to do a class check on the object vs installed
class of the CompiledMethod as part of PrimErrBadArgument checks?<br>
Otherwise you'd probably end up insilly situations with
CompiledMethods which accesses/stores to instvars :)<br>
<br></div></blockquote><div><br>Sorry Henry, I couldn't follow you :(<br>I based such implementation in this one: primitiveExecuteMethodArgsArray<br><br>primitiveExecuteMethodArgsArray<br> "receiver, argsArray, then method are on top of stack. Execute method against receiver and args.<br>
Set primitiveFunctionPointer because no cache lookup has been done for the method, and<br> hence primitiveFunctionPointer is stale."<br> | methodArgument argCnt argumentArray primitiveIndex |<br> methodArgument := self stackTop.<br>
argumentArray := self stackValue: 1.<br> ((objectMemory isOopCompiledMethod: methodArgument)<br> and: [objectMemory isArray: argumentArray]) ifFalse:<br> [^self primitiveFailFor: PrimErrBadArgument].<br>
argCnt := self argumentCountOf: methodArgument.<br> argCnt = (objectMemory fetchWordLengthOf: argumentArray) ifFalse:<br> [^self primitiveFailFor: PrimErrBadNumArgs].<br> self pop: 2.<br> 0 to: argCnt - 1 do:<br>
[:i|<br> self push: (objectMemory fetchPointer: i ofObject: argumentArray)].<br> newMethod := methodArgument.<br> primitiveIndex := self primitiveIndexOf: newMethod.<br> primitiveFunctionPointer := self functionPointerFor: primitiveIndex inClass: nil.<br>
argumentCount := argCnt.<br> "We set the messageSelector for executeMethod below since things<br> like the at cache read messageSelector and so it cannot be left stale."<br> messageSelector := objectMemory nilObject.<br>
self executeNewMethod.<br> "Recursive xeq affects primErrorCode"<br> self initPrimCall<br><br><br>Thanks!<br><br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div bgcolor="#ffffff" text="#000000">
Cheers,<br>
Henry<br>
</div>
<br></blockquote></div><br><br clear="all"><br>-- <br>Mariano<br><a href="http://marianopeck.wordpress.com" target="_blank">http://marianopeck.wordpress.com</a><br><br>