<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
On 20.04.2011 15:52, Mariano Martinez Peck wrote:
<blockquote
cite="mid:BANLkTi=LJacoaQzM0EPNk4C2rTNBaMM59g@mail.gmail.com"
type="cite">
<pre wrap=""> </pre>
<br>
<fieldset class="mimeAttachmentHeader"></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>
Cheers,<br>
Henry<br>
</body>
</html>