Function apply and call (was RE: Bait taken: Arguments about arguments)
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.
On Jan 15, 2009, at 5:42 PM, David-Sarah Hopwood wrote:
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]].
This is a fix indeed.
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.
SpiderMonkey functions may have at most 65535 parameters. This is not
"rather small" so I'm curious what typical implementations you mean.
Size of numbers is not implementation-defined; it's precisely
specified.
The bound on integer fitting in IEEE-754 double is insanely high
compared to any reasonable bound on maximum number of parameters.
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.
Open a ticket and list your minimum set of allowable limits?
On Jan 15, 2009, at 6:49 PM, Brendan Eich wrote:
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.
SpiderMonkey functions may have at most 65535 parameters.
The 64K-1 limit applies to direct calls. Calling via
Function.prototype.apply has a larger limit for sanity (accidental or
trivial-malicious DOS input): 16777215 or 16M-1.
Brendan Eich wrote:
On Jan 15, 2009, at 5:42 PM, David-Sarah Hopwood wrote:
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]].
This is a fix indeed.
OK, we seem to have a rough concensus. I will open a ticket on this...
Open a ticket and list your minimum set of allowable limits?
... and this.
See below
-----Original Message----- From: es3.x-discuss-bounces at mozilla.org [mailto:es3.x-discuss- bounces at mozilla.org] On Behalf Of David-Sarah Hopwood [snip] 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.)
Array instances needs to have its own version of [[DefineOwnProperty]] to go along with its [[ThrowingPut]].
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.
Well, not quite every use of [[Call]] but a lot of them...that why I said "strictly speaking". I'd classify this as a cosmetic bug.
On Thu, Jan 15, 2009 at 7:35 PM, David-Sarah Hopwood < david.hopwood at industrial-designers.co.uk> wrote:
Brendan Eich wrote:
On Jan 15, 2009, at 5:42 PM, David-Sarah Hopwood wrote:
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]].
This is a fix indeed.
OK, we seem to have a rough concensus. I will open a ticket on this...
Wonderful! And Brendan, you said earlier you were open to freezing strict arguments, and that the joining of arguments should be severed by freezing.
With these two changes, virtual-ES-strict-in-ES-strict emulations such as future Valija will be able to easily emulate strict arguments. An emulated strict arguments need only be a normal frozen non-array object inheriting from Array.prototype with appropriate length, caller, callee, and constructor properties. Otherwise, self-virtualizations would have needed to create a genuine arguments object, since the difference would have been observable. I should have mentioned this earlier as another motivation.
On Jan 15, 2009, at 10:18 PM, Mark S. Miller wrote:
Wonderful! And Brendan, you said earlier you were open to freezing
strict arguments, and that the joining of arguments should be
severed by freezing.
Yes. This is easy to implement with a few strict mode checks in
existing arguments implementations I know of. Other implementors
should give their thoughts, of course.
With these two changes, virtual-ES-strict-in-ES-strict emulations
such as future Valija will be able to easily emulate strict
arguments. An emulated strict arguments need only be a normal frozen
non-array object inheriting from Array.prototype with appropriate
length, caller, callee, and constructor properties. Otherwise, self- virtualizations would have needed to create a genuine arguments
object, since the difference would have been observable. I should
have mentioned this earlier as another motivation.
That's a good point. Emulating arguments with its magic data
properties that a mysterious agent (as Allen put it) keeps in sync
with parameters is Hard(tm).
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.
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].
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.
What does ToArrayLength do? Ensure a numeric value? It isn't in the current spec. draft.
[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]
Strictly speaking step 7 needs to compose the array elements into a List as that is what [[Call]] takes as an argument