webidl icon indicating copy to clipboard operation
webidl copied to clipboard

Normative: Match ECMA‑262 function property enumeration order

Open ExE-Boss opened this issue 5 years ago • 18 comments

This makes the order of the "length", "name" and "prototype" properties on WebIDL function objects match web reality (at least Firefox’s behaviour) and ECMA‑262 as of https://github.com/tc39/ecma262/pull/1490 and https://github.com/tc39/ecma262/pull/2116, which also changed CreateBuiltinFunction so that it takes the additional length and name required parameters.


(See WHATWG Working Mode: Changes for more details.)


review?(@annevk, @domenic, @littledan, @ljharb)

Fixes https://github.com/whatwg/webidl/issues/1106


Preview | Diff

ExE-Boss avatar Sep 03 '20 05:09 ExE-Boss

https://github.com/tc39/ecma262/pull/2116 has been merged, so this PR has been updated to pass the length and name parameters to CreateBuiltinFunction directly.

ExE-Boss avatar Feb 19 '21 14:02 ExE-Boss

Great work @ExE-Boss! I'll leave this to others to review, but this looks like a really nice cleanup. Do we have some tests for this as well?

annevk avatar Feb 19 '21 14:02 annevk

Tests are now written in https://github.com/web-platform-tests/wpt/pull/30333.

ExE-Boss avatar Sep 03 '21 14:09 ExE-Boss

Based on https://github.com/web-platform-tests/wpt/pull/30333 it looks like this matches Firefox but mismatches Chrome and Safari (for constructors). So we should make sure at least one of those browsers is interested in changing. @yuki3 @shvaikalesh what do you think?

domenic avatar Sep 03 '21 16:09 domenic

Reflect.ownKeys(Blob):

  • Chrome: ["length", "name", "arguments", "caller", "prototype"]
  • Firefox: [ "length", "name", "prototype", Symbol("Symbol.hasInstance") ]
  • Safari: ["prototype", "name", "length"]

So, Chrome has additional arguments and caller properties, which surprises me. (They appear to be non-functional, at least - (function f(){ new Blob([], { get type(){ console.log(Blob.caller, Blob.arguments) } }) })() prints null twice.)

But Chrome does match the enumeration order for the length and name properties, which I think is the only change actually implied by this PR. In particular, ecma262 specifically refrains from specifying the full enumeration order, including of prototype; it only specifies that length appears before name. (The test262 tests for the corresponding ecma262 PR are much more permissive than the WPT linked above.)

So, possibly the WPT is just over-zealous for the actual change implied by this PR, and could be changed to match the test262 tests. Then both Chrome and Firefox would pass.

bakkot avatar Sep 03 '21 16:09 bakkot

@bakkot to check my understanding, it seems like the correct test would be that name appears right after length, right? So the test262 test is not as fully strict as it could be.

I think Web IDL, being more imperative than the ES spec, actually gives a full ordering between length/name/prototype that matches the tests written. But in terms of ensuring implementer interest for this particular change, I agree we're probably OK.

domenic avatar Sep 03 '21 16:09 domenic

it seems like the correct test would be that name appears right after length, right? So the test262 test is not as fully strict as it could be.

Actually, the test262 test checks exactly that using: nameIndex === lengthIndex + 1

assert(lengthIndex >= 0 && nameIndex === lengthIndex + 1,
	"The `length` property comes before the `name` property on built-in functions");

ExE-Boss avatar Sep 03 '21 16:09 ExE-Boss

Sorry, I totally skimmed the test and misread it. My bad.

domenic avatar Sep 03 '21 16:09 domenic

@bakkot

So, possibly the WPT is just over-zealous for the actual change implied by this PR, and could be changed to match the test262 tests. Then both Chrome and Firefox would pass.

With this PR, the prototype property is the first property that’s added to constructors after the CreateBuiltinFunction call in create an interface object.

ExE-Boss avatar Sep 03 '21 16:09 ExE-Boss

it seems like the correct test would be that name appears right after length, right?

Right.

I think Web IDL, being more imperative than the ES spec, actually gives a full ordering between length/name/prototype that matches the tests written.

Ah, so it does.

bakkot avatar Sep 03 '21 16:09 bakkot

I like this change, both editorial-wise and the way it improves enumeration order consistency. Please use this bug to follow WebKit implementation.

As for caller and arguments, there is a proposal to move them to Function.prototype, which was recently implemented in WebKit to match Firefox.

shvaikalesh avatar Sep 22 '21 04:09 shvaikalesh

Based on web-platform-tests/wpt#30333 it looks like this matches Firefox but mismatches Chrome and Safari (for constructors). So we should make sure at least one of those browsers is interested in changing. @yuki3 @shvaikalesh what do you think?

I'm very sorry that I somehow overlooked the mention. I'm fine with the change to make the order of property enumeration consistent. However, I'm afraid that I cannot help much on this. IIUC, the order of these standard(ish?) properties on function objects is controlled by V8. We'd better ask V8 team to make the change. @verwaest, any thoughts?

yuki3 avatar Sep 22 '21 06:09 yuki3

The proposed changes sound alright. Making this more uniform makes sense.

It seems like we're invalidly adding special accessors for caller/arguments but will always return null for native functions. We can change that too.

As for moving caller/arguments to the prototype chain: Currently v8 returns the caller of the "holder" on which the property is installed. With this I mean that if you put a function with a .caller on the prototype chain of e.g., a sloppy-mode arrow function, we won't return the caller of the arrow function, but the caller of the function on the prototype chain. What are the expected semantics there? (The change itself sounds like an improvement though!)

verwaest avatar Sep 23 '21 10:09 verwaest

@verwaest The proposal sets up Function.prototype.{arguments,caller} as getters (spec), so they can return null or real caller or even throw a TypeError depending on a holder (receiver).

One important bit of the proposal I kinda hope V8 would implement is returning null for (async) generators to match the JSC: we can't return real caller for them and it seems web-compatible.

shvaikalesh avatar Sep 23 '21 14:09 shvaikalesh

I’ve filed bug 1257969 to get this fixed in Chrome as well.

ExE-Boss avatar Oct 08 '21 17:10 ExE-Boss

The “needs tests” label is wrong, as https://github.com/web-platform-tests/wpt/pull/30333 has been merged.

ExE-Boss avatar Apr 22 '23 13:04 ExE-Boss

Argh, apologies for merging the tests ahead of time. Would be good to get this landed anyway, though.

Ms2ger avatar Apr 24 '23 10:04 Ms2ger

That's blocked on one of two things:

  1. @ExE-Boss updates https://github.com/whatwg/participant-data/blob/main/individuals.json with their real name. (See https://github.com/whatwg/sg/issues/93#issuecomment-1120799691 for context.)
  2. Someone else makes this contribution in a new PR.

annevk avatar Apr 24 '23 10:04 annevk