Function apply and call (was RE: Bait taken: Arguments about arguments)

David-Sarah Hopwood david.hopwood at industrial-designers.co.uk
Thu Jan 15 17:42:37 PST 2009


Allen Wirfs-Brock wrote:
> I generally agree that it would be a good idea to specify apply (and call)
> pretty much as proposed below by David-Sarah. The major reason that it
> makes it explicit what happens for most currently unspecified edge cases
> such as a sparse argArray or argArray properties that are accessors.

Exactly: even if the second argument to 'apply' were restricted to Array
and arguments objects, the properties can (and would in the case of an
arguments object specified as in the current draft) have getters.
So an implementation *must* read the properties in a way that has the
full generality of [[Get]], and might as well be specified using [[Get]].

> It would also eliminate the need to explicitly require that argArray be
> an array or arguments object [but as a possible downside, I can imagine
> an implementation reasonably using the current " must be an array"
> restriction to implement apply in a manner that only works with objects
> that have some special internal array representation].

An implementation can optimize special-case representations of non-sparse
arrays without getters, but as explained above, it cannot *restrict* the
second argument to 'apply' such a representation; that is not a valid
optimization even according to the current draft (and is not reasonable
even in ES3 plus getter/setter extensions).

> It is clearly a (pretty obvious and hence not very significant) bug that
> the Es3 specification doesn't say that apply and call return the result of
> [[Call]].  At the very least that should be fixed in the ES3.1 spec.
> 
> I think putting in the argument number limit check is starting down
> a slippery slope. There are many things in the spec. (number of locals,
> size of numbers, size of methods, etc.) that might plausibly have an
> implementation limit. I don't think we can reasonably identify all of
> them and I don't think this one is special enough to make it an exception.

The issue here is that typical implementations do have a rather small
limit on number of arguments. If the spec doesn't acknowledge this,
then those implementations are clearly violating the spec.

Size of numbers is not implementation-defined; it's precisely specified.

I think there are fewer reasonably allowable implementation limits (that
should not be treated as implementation bugs) than you suggest. They can
and should all be explicitly pointed out by the spec -- but I'm quite happy
for that to be treated as a separate issue.

> What does ToArrayLength do? Ensure a numeric value? It isn't in the
> current spec. draft.

Sorry, that was a change I originally proposed at the same time as
writing this wording, that is no longer relevant. It should be ToUint32.

> [this leads me to think that there is a problem that as currently specified,
> Object.defineProperty(anArray,"length",{value: "xyz"}) will violate the
> array length invariant...another ES3.1 bug]

Yes, I think you're right here. Also,
 - defining an array index property past the current length would
   violate the invariant.
 - host objects might have similar invariants that are supposed to
   be enforced by overriding [[Get]] or [[ThrowingPut]], and that
   Object.defineProperty would bypass.

(The bug seems to be in [[DefineOwnProperty]]. I'm not sure how to fix it.)

> Strictly speaking step 7 needs to compose the array elements into a
> List as that is what [[Call]] takes as an argument

If this is wrong then so is every other use of [[Call]] in the spec,
since none of them *explicitly* say that they construct a List.

-- 
David-Sarah Hopwood


More information about the Es-discuss mailing list