perform:withArguments: and collection

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

perform:withArguments: and collection

Peter Uhnak
Hi,

Apparently sending #perform:withArguments: and using OrderedCollection leads to PrimitiveFailed.

I can recast it, but maybe we can just add

(argArray isArray)
        ifFalse: [ ^ self error: 'Arguments must be instance of Array' ]

to make the error less cryptic.

(or allow OrderedCollection, but since the operation is done in VM it might be needlessly more work.)

Peter

Reply | Threaded
Open this post in threaded view
|

Re: perform:withArguments: and collection

Eliot Miranda-2


On Sun, Mar 12, 2017 at 3:16 PM, Peter Uhnak <[hidden email]> wrote:
Hi,

Apparently sending #perform:withArguments: and using OrderedCollection leads to PrimitiveFailed.

I can recast it, but maybe we can just add

(argArray isArray)
        ifFalse: [ ^ self error: 'Arguments must be instance of Array' ]

+1.  The alternative is having the primitive failure code test for the argument being sequence able and doing it for you:

perform: selector withArguments: argArray inSuperclass: lookupClass
"NOTE:  This is just like perform:withArguments:, except that
the message lookup process begins, not with the receivers's class,
but with the supplied superclass instead.  It will fail if lookupClass
cannot be found among the receiver's superclasses.
Primitive. Essential. See Object documentation whatIsAPrimitive."

<primitive: 100>
argArray isArray ifFalse:
[(argArray isCollection and: [argArray isSequenceable]) ifTrue:
[^self perform: selector withArguments: argArray asArray inSuperclass: lookupClass].
^self error: 'argArray argument must be an Array'].
selector isSymbol ifFalse:
[^self error: 'selector argument must be a Symbol'].
selector numArgs = argArray size ifFalse:
[^self error: 'incorrect number of arguments'].
(self class == lookupClass or: [self class inheritsFrom: lookupClass]) ifFalse:
[^self error: 'lookupClass is not in my inheritance chain'].
(self class lookupMethodFor: selector ifAbsent: nil) ifNotNil:
[:method| | overflowArgs |
(method numArgs = argArray size
 and: [argArray size >= 15]) ifTrue:
[overflowArgs := argArray copyFrom: 1 to: 15.
overflowArgs at: 15 put: (argArray copyFrom: 15 to: overflowArgs size).
^self
perform: selector
withArguments: overflowArgs
inSuperclass: lookupClass]].
self primitiveFailed
 

to make the error less cryptic.

(or allow OrderedCollection, but since the operation is done in VM it might be needlessly more work.)

Right.  IMO, it's a bad idea putting knowledge of OrderedCollection's representation in the VM.


Peter




--
_,,,^..^,,,_
best, Eliot