CompiledMethod>>value:withArguments:
Ian Piumarta
Ian.Piumarta at inria.fr
Tue Dec 28 18:26:59 UTC 1999
> Method wrappers are an extremely useful technique to gather all
> kinds of run-time information, to implement wrappers, ...
[...]
> It seems to me that Squeak is missing in reflective facilities in message
> handling.
Sounds to me like a challenge. ;^)
> For that matter, so are most Smalltalk VM's.
Ahh, but the beauty of Smalltalk is the possibility of reifying and
interceding on all execution state: if it's missing then you just go
implement it, whatever "it" might be. (And if it doesn't run blindingly
fast afterwards then consider it a bug in the VM's runtime. ;-)
> > Don't you think we could solve this by doing something along the lines of:
> > CompiledMethod>>valueWithReceiver: aClass Arguments: argList
> > | aProcess aContext |
> > aContext _ MethodContext
> > sender: thisContext sender
> > receiver: aClass
> > method: self
> > arguments: argList.
> > aProcess _ Process forContext: aContext priority: Processor activePriority.
> > aProcess resume
Process? Isn't this a bit like swatting a fly with a steam roller?
Methinks the problem is a little more subtle. For starters, a minimum of
verification for compatibility between the CompiledMethod and the given
receiver/arguments is required. (We've come a long way since "Processor :=
nil" for cruel and unusual ways in which to crash the VM. ;-). Try the
following instead...
Behavior methodsFor: 'testing method dictionary'
includesMethod: aCompiledMethod
"Answer whether aCompiledMethod is in the method dictionary of
the receiver."
^self methodDict includes: aCompiledMethod
canExecute: method
"Answer whether the receiver implements a message whose method
is the argument. The method can be in the method dictionary of the
receiver or any of its superclasses."
(self includesMethod: method) ifTrue: [^true].
superclass == nil ifTrue: [^false].
^superclass canExecute: method
CompiledMethod methodsFor: 'evaluating'
valueWithReceiver: anObject arguments: argumentArray
"Answer the result of executing the receiver with anObject as
receiver and argumentArray as arguments. Signal an error if the
receiver is not a method suitable for anObject, or if the
argumentArray contains the wrong number of arguments for the
receiver."
(self numArgs == argumentArray size and: [anObject class canExecute: self])
ifTrue:
[thisContext swapSender: (MethodContext
sender: thisContext sender
receiver: anObject
method: self
arguments: argumentArray)]
ifFalse:
[self error: 'receiver and/or arguments not appropriate for this method']
Examples:
(SmallInteger compiledMethodAt: #+) valueWithReceiver: 3 arguments: #(4).
(Number compiledMethodAt: #//) valueWithReceiver: 22 arguments: #(7).
(SmallInteger compiledMethodAt: #+) valueWithReceiver: 3 arguments: #(foo).
(Number compiledMethodAt: #negated) valueWithReceiver: 22 arguments: #().
(Number compiledMethodAt: #negated) valueWithReceiver: 22 arguments: #(7).
(Point compiledMethodAt: #=) valueWithReceiver: 3 at 4 arguments: #(4).
(Point compiledMethodAt: #=) valueWithReceiver: 3 arguments: (Array with: 3 at 4).
And finally (for the incurably skeptical):
(CompiledMethod compiledMethodAt: #valueWithReceiver:arguments:)
valueWithReceiver: (SmallInteger compiledMethodAt: #+)
arguments: #(3 (4))
FWIW: The only part of the above implementation that isn't blindingly fast
is the inclusion test for the method somewhere in or above anObject class.
(The corresponding primitive [twenty lines of code, tops] could do the test
iteratively, and would be about the same speed as #perform:. Left as an
exercise for anybody who still has a mains electricity supply after midnight
on the 31st...)
Happy wrapping!
Ian
PS: > In VW this is a primitive
I suspect that the primitive response in VW is nothing more than a
"hook" that the runtime uses to recompile the send site into something
entirely more intelligent that (ab)uses the inline cache and/or method
prologue for #valWithRcvr:args: to make the response as fast as a normal
message send. (Otherwise the [slower] 100%-Smalltalk implementation is
entirely sufficient.)
More information about the Squeak-dev
mailing list
|