<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://www.w3.org/Bugs/Public/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4"
          urlbase="https://www.w3.org/Bugs/Public/"
          
          maintainer="sysbot+bugzilla@w3.org"
>

    <bug>
          <bug_id>22808</bug_id>
          <alias>teetee</alias>
          <creation_ts>2013-07-25 22:27:32 +0000</creation_ts>
          <short_desc>Throw if object is constructed without new</short_desc>
          <delta_ts>2016-11-03 21:15:08 +0000</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebAppsWG</product>
          <component>WebIDL</component>
          <version>unspecified</version>
          <rep_platform>PC</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          <see_also>https://bugzilla.mozilla.org/show_bug.cgi?id=916644</see_also>
          <bug_file_loc></bug_file_loc>
          <status_whiteboard>[v1]</status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Anne">annevk</reporter>
          <assigned_to name="Cameron McCormack">cam</assigned_to>
          <cc>adrianba</cc>
    
    <cc>allen</cc>
    
    <cc>brendan</cc>
    
    <cc>bzbarsky</cc>
    
    <cc>d</cc>
    
    <cc>erik.arvidsson</cc>
    
    <cc>jonas</cc>
    
    <cc>jsbell</cc>
    
    <cc>mike</cc>
    
    <cc>Ms2ger</cc>
    
    <cc>public-script-coord</cc>
    
    <cc>tobie.langel</cc>
    
    <cc>tonyaestill</cc>
    
    <cc>travil</cc>
          
          <qa_contact>public-webapps-bugzilla</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>91290</commentid>
    <comment_count>0</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2013-07-25 22:27:32 +0000</bug_when>
    <thetext>That way we can use [[Call]] for subclassing. It&apos;s the ES6 way.

We can hopefully still do this as Chrome/WebKit throw, whereas Gecko/Trident do not.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>91355</commentid>
    <comment_count>1</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2013-07-28 18:11:26 +0000</bug_when>
    <thetext>Hmm.  We can try this; I&apos;m a bit worried about compat impact.  :(</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>91361</commentid>
    <comment_count>2</comment_count>
    <who name="Jonas Sicking (Not reading bugmail)">jonas</who>
    <bug_when>2013-07-28 22:47:34 +0000</bug_when>
    <thetext>Same here. I&apos;d add telemetry to Gecko before actually switching behavior.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>92840</commentid>
    <comment_count>3</comment_count>
    <who name="Ms2ger">Ms2ger</who>
    <bug_when>2013-09-03 07:25:49 +0000</bug_when>
    <thetext>Seems pretty pointless to break something that works.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>92888</commentid>
    <comment_count>4</comment_count>
    <who name="Erik Arvidsson">erik.arvidsson</who>
    <bug_when>2013-09-03 16:53:15 +0000</bug_when>
    <thetext>(In reply to comment #3)
&gt; Seems pretty pointless to break something that works.

It doesn&apos;t work everywhere and it is future hostile.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>93255</commentid>
    <comment_count>5</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2013-09-11 16:30:16 +0000</bug_when>
    <thetext>Also, at least for new objects we should no longer do this. So if we need this I suggest we call it out. E.g. by requiring LegacyConstructor or some such for those objects.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>93408</commentid>
    <comment_count>6</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2013-09-16 06:40:50 +0000</bug_when>
    <thetext>Gecko: https://bugzilla.mozilla.org/show_bug.cgi?id=916644

Travis, Adrian, is this on your radar?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>93431</commentid>
    <comment_count>7</comment_count>
    <who name="Travis Leithead [MSFT]">travil</who>
    <bug_when>2013-09-16 17:15:54 +0000</bug_when>
    <thetext>I&apos;m pretty hesitant to make this change without a web-compat analysis. I can very easily imagine lots and lots of sites that just blindly do:

var x = XMLHttpRequest();
x....

In the past, IE has run a lot of custom code on the web intended just for it. With IE11, we&apos;re starting to run much more of the Firefox/Chrome code, but in this case, not throwing is more compatible. Switching to a throwing behavior has generally made compat worse.

If you want to take on the burden of proof, that&apos;d be great. I&apos;m just saying that I don&apos;t think I&apos;d want to be the one to guinea-pig this change.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>93432</commentid>
    <comment_count>8</comment_count>
    <who name="Erik Arvidsson">erik.arvidsson</who>
    <bug_when>2013-09-16 17:20:23 +0000</bug_when>
    <thetext>(In reply to Travis Leithead [MSFT] from comment #7)
&gt; I&apos;m pretty hesitant to make this change without a web-compat analysis. I can
&gt; very easily imagine lots and lots of sites that just blindly do:
&gt; 
&gt; var x = XMLHttpRequest();
&gt; x....

Remember that that throws in Safari and Chrome so it is unlikely that code on the open web would do that.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>93433</commentid>
    <comment_count>9</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2013-09-16 17:32:44 +0000</bug_when>
    <thetext>Once I get Gecko to the point where our own code is not triggering this situation, I&apos;ll put in some telemetry to see how often this is hit in practice on the web for us....

&gt; so it is unlikely that code on the open web would do that.

Methinks you underestimate the amount of UA-sniffing that happens &quot;on the open web&quot;....  I think it _very_ likely that code would do that; the only question is how common it is for users to run across that code in practice.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>116374</commentid>
    <comment_count>10</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2014-12-16 12:56:12 +0000</bug_when>
    <thetext>https://bugzilla.mozilla.org/show_bug.cgi?id=916644 was fixed. Let&apos;s change IDL.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>117059</commentid>
    <comment_count>11</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2015-01-13 03:42:16 +0000</bug_when>
    <thetext>I just looked at ES6 again, and I&apos;d like to see the edits Allen is making to the whole [[Call]]/[[Construct]]/@@create setup right now land before we change things in IDL here.  Because we&apos;re going to need to override [[Construct]] to not invoke [[Call]] and whatnot, but the exact interaction will depend on exactly what ES looks like.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>117767</commentid>
    <comment_count>12</comment_count>
    <who name="Erik Arvidsson">erik.arvidsson</who>
    <bug_when>2015-02-09 17:04:25 +0000</bug_when>
    <thetext>(In reply to Boris Zbarsky from comment #11)
&gt; I just looked at ES6 again, and I&apos;d like to see the edits Allen is making to
&gt; the whole [[Call]]/[[Construct]]/@@create setup right now land before we
&gt; change things in IDL here.  Because we&apos;re going to need to override
&gt; [[Construct]] to not invoke [[Call]] and whatnot, but the exact interaction
&gt; will depend on exactly what ES looks like.

In ES6, constructor functions created using the class syntax gets marked with &quot;classConstructor&quot; and in the [[Call]] behavior,

http://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects-call-thisargument-argumentslist

we have

2. If F’s [[FunctionKind]] internal slot is &quot;classConstructor&quot;, throw a TypeError exception.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>117769</commentid>
    <comment_count>13</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2015-02-09 17:10:07 +0000</bug_when>
    <thetext>OK.  So it sounds like for Web IDL constructors we should make the following changes:

1)  [[Construct]] does what [[Call] does right now in the Web IDL spec.
2)  [[Call]] just throws a typeerror.

Or we could use the default [[Call]] and set the [[FunctionKind]] thing, but it seems simpler to just do the above, I think.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>117770</commentid>
    <comment_count>14</comment_count>
    <who name="Domenic Denicola">d</who>
    <bug_when>2015-02-09 17:12:26 +0000</bug_when>
    <thetext>I&apos;d rather do the default [[Call]] and set functionKind. functionKind might be used for other things (maybe it already is?) and in general uniformity with ES6 seems better.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>117771</commentid>
    <comment_count>15</comment_count>
    <who name="Allen Wirfs-Brock">allen</who>
    <bug_when>2015-02-09 17:20:26 +0000</bug_when>
    <thetext>(In reply to Domenic Denicola from comment #14)
&gt; I&apos;d rather do the default [[Call]] and set functionKind. functionKind might
&gt; be used for other things (maybe it already is?) and in general uniformity
&gt; with ES6 seems better.

the &quot;default call&quot; and the [[FunctionKind]] slots are specific to &quot;ECMASCript Language functions&quot;.  In other words, functions whose body are implemented using ECMAScript code. 

You want to enable WebIDL methods to be implemented as ECMAScript functions but you don&apos;t want to require it.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>117772</commentid>
    <comment_count>16</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2015-02-09 17:49:58 +0000</bug_when>
    <thetext>So I just looked through the ES6 spec.  The only other use of [[FunctionKind]] is to prevent subclassing a generator function.  This use assumes that anything without a [[FunctionKind]] slot is not a generator, so works fine with Web IDL.

What we _could_ consider is giving a [[FunctionKind]] slot to what the spec calls &quot;Built-in Function objects&quot; and checking it in http://people.mozilla.org/~jorendorff/es6-draft.html#sec-built-in-function-objects-call-thisargument-argumentslist (and modifying http://people.mozilla.org/~jorendorff/es6-draft.html#sec-built-in-function-objects-construct-argumentslist-newtarget to not check it, I guess).  That&apos;s assuming we don&apos;t want the existence of a [[FunctionKind]] slot to imply the function is an &quot;ECMASCript Language function&quot;.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>117773</commentid>
    <comment_count>17</comment_count>
    <who name="Allen Wirfs-Brock">allen</who>
    <bug_when>2015-02-09 18:34:54 +0000</bug_when>
    <thetext>(In reply to Boris Zbarsky from comment #16)

The problem is that many of the ECMAScript library constructors, which are allspecified to be &quot;Built-In Function objects&quot;, do support being &quot;called as a function&quot;. So if we added [[FunctionKind]] to Built-in Function I would also have to specify it&apos;s setting for each ES built-in.  I might consider doing that if I wasn&apos;t within about a week of having to freeze the final ES6 draft.

As an alternative approach consider treating this similarly to what you do for parameter type checking. You can determine whether you are called by as function rather than via [[Construct]] by checking the value of NewTarget.  It has the value undefined if the function is being invoked via [[Call]]. 

So, in your WebIDL parameter checking also check NewTarget (for constructors).

This is essentially what the ES6 spec. does,  individually for each built-in constructor that is not callable.  For example see: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-map-iterable</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>117774</commentid>
    <comment_count>18</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2015-02-09 18:38:01 +0000</bug_when>
    <thetext>Ah, yes, that would work quite nicely.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>125840</commentid>
    <comment_count>19</comment_count>
    <who name="Ms2ger">Ms2ger</who>
    <bug_when>2016-04-13 16:06:31 +0000</bug_when>
    <thetext>Talked to bz on IRC; I believe he agrees that checking NewTarget is the best approach. This depends on &lt;https://github.com/heycam/webidl/issues/106&gt;.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>127921</commentid>
    <comment_count>20</comment_count>
    <who name="Domenic Denicola">d</who>
    <bug_when>2016-10-22 16:05:40 +0000</bug_when>
    <thetext>https://github.com/heycam/webidl/issues/62</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>128042</commentid>
    <comment_count>21</comment_count>
    <who name="Tobie Langel">tobie.langel</who>
    <bug_when>2016-11-03 21:14:46 +0000</bug_when>
    <thetext>Fixed in https://github.com/heycam/webidl/commit/001ba520eb80c23133e65bc721f1f9910732316c</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>