Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

does [Constructor] invocation require 'new' or not (generally)? #62

Closed
travisleithead opened this issue Oct 7, 2015 · 10 comments
Closed
Labels
☕☕ difficulty:medium Hard to fix ⌛⌛ duration:medium Shouldn't be too long to fix

Comments

@travisleithead
Copy link
Member

Related to issue #55, where in WebIDL does it say (or not say) that invoking constructable interfaces (those interfaces with [NamedConstructor] or one or more [Constructor] extended attributes) should throw when not used with new?

As far as I can tell, in section 4.5.1.1, this is all we get:

 The internal [[Call]] method of the interface object behaves as follows, assuming arg0..n−1 is the list of argument values passed to the constructor, and I is the interface:

1. If I was not declared with a [Constructor] extended attribute, then throw a TypeError.
2. Let id be the identifier of interface I.
3. Initialize S to the effective overload set for constructors with identifier id on interface I and with argument count n.
4. Let <constructor, values> be the result of passing S and arg0..n−1 to the overload resolution algorithm.
5. Let R be the result of performing the actions listed in the description of constructor with values as the argument values.
6. Return the result of converting R to an ECMAScript interface type value I.

Seems like what I'm looking for is wrapped up in step 5, but in my reading this step is deferring to prose for each individual constructor. Would this include requiring the use of new?

In Gecko and Blink, it looks constructable interfaces require new (at least for those I tested, e.g., Image(), XMLHttpRequest(), and in Gecko only ATM: DOMException()).

@domenic
Copy link
Member

domenic commented Oct 7, 2015

You are starting to encounter the fact that Web IDL is not updated to ES2015 very much :(

I believe the intention has been for a while to require new. (There are probably some old bugs explaining how we got there in Bugzilla.)

Maybe there is something buried in the spec that requires that, or maybe the spec is just not updated yet.

@bzbarsky
Copy link
Collaborator

bzbarsky commented Oct 8, 2015

The current IDL spec is defined purely in terms of [[Call]] and does not in fact say to throw on calls without new. @travisleithead's reading in #62 (comment) is correct as far as the current spec goes; step 5 is precisely "do the prose here".

There's a very longstanding spec issue to fix this: https://www.w3.org/Bugs/Public/show_bug.cgi?id=22808. It hasn't happened yet because for a while it wasn't quite clear what the fixed spec should say exactly to produce the desired effect, and then there was a lack of editing bandwidth. I'm sorry the spec here doesn't say the right thing, but I believe the right thing is in fact to throw when called without new.

@tobie tobie added editorial Changes that do not affect how the standard is understood. ⌛⌛ duration:medium Shouldn't be too long to fix ☕☕ difficulty:medium Hard to fix labels Jun 19, 2016
@ylafon ylafon removed the editorial Changes that do not affect how the standard is understood. label Jun 22, 2016
@domenic
Copy link
Member

domenic commented Oct 22, 2016

So, concretely, fixing this should not require much more than adding a NewTarget check after or before step 1 of https://heycam.github.io/webidl/#es-interface-call, I believe. The same check as e.g. https://tc39.github.io/ecma262/#sec-set-iterable

@bzbarsky
Copy link
Collaborator

Yes, I think so.

Adding if after step 1 is better, imo, because it provides a more relevant error message in practice. We'd need to ensure that [[Construct]] is set to https://tc39.github.io/ecma262/#sec-built-in-function-objects-construct-argumentslist-newtarget (I guess by saying somewhere that it's "a constructor" and linking to ... nothing, I guess, because the relevant concept in ES is not linkable; maybe just to https://tc39.github.io/ecma262/#sec-built-in-function-objects or something).

@tobie
Copy link
Collaborator

tobie commented Oct 25, 2016

My understanding from reading the ES spec is that [[Call]] refers to: fn() while [[Construct]] refers to new fn(). Is that correct?

In that case, wouldn't it make sense to define the [[Call]] method of Interfaces as:

1. throw a TypeError

...and move the current definition of [[Call]] to [[Construct]]?

I'm probably missing something. If so, please enlighten me. Thanks. :)

@bzbarsky
Copy link
Collaborator

@tobie See previous discussion in https://www.w3.org/Bugs/Public/show_bug.cgi?id=22808 but there was also some discussion somewhere that I can't find right now....

What we really want to do is to neither define [[Call]] nor [[Construct]] but simply define the behavior of "evaluating F in an implementation defined manner that conforms to the specification of F" as invoked from https://tc39.github.io/ecma262/#sec-built-in-function-objects-call-thisargument-argumentslist step 10. Otherwise we have to duplicate all the other bookeeping that https://tc39.github.io/ecma262/#sec-built-in-function-objects-call-thisargument-argumentslist does, and we would really rather avoid that.

And within "evaluating F in an implementation defined manner that conforms to the specification of F" the only way to do the new thing we want is to check NewTarget.

@tobie
Copy link
Collaborator

tobie commented Oct 25, 2016

What we really want to do is to neither define [[Call]] nor [[Construct]] but simply define the behavior of "evaluating F in an implementation defined manner that conforms to the specification of F"

OK that makes perfect sense now. Thanks.

@tobie
Copy link
Collaborator

tobie commented Oct 25, 2016

Should the algorithm throw or return completion records?

@bzbarsky
Copy link
Collaborator

The ES spec expects it to return a completion record, I think.

@tobie
Copy link
Collaborator

tobie commented Oct 25, 2016

Seems the ES specs has hooks that make the creation of a completion implicit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
☕☕ difficulty:medium Hard to fix ⌛⌛ duration:medium Shouldn't be too long to fix
Development

No branches or pull requests

5 participants