<html>
    <head>
      <base href="https://bugs.webkit.org/" />
    </head>
    <body><span class="vcard"><a class="email" href="mailto:sbarati&#64;apple.com" title="Saam Barati &lt;sbarati&#64;apple.com&gt;"> <span class="fn">Saam Barati</span></a>
</span> changed
              <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [ES6] Arrow function created before super() causes TDZ, should it?"
   href="https://bugs.webkit.org/show_bug.cgi?id=149338">bug 149338</a>
        <br>
             <table border="1" cellspacing="0" cellpadding="8">
          <tr>
            <th>What</th>
            <th>Removed</th>
            <th>Added</th>
          </tr>

         <tr>
           <td style="text-align:right;">Attachment #265001 Flags</td>
           <td>review?
           </td>
           <td>review-
           </td>
         </tr></table>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [ES6] Arrow function created before super() causes TDZ, should it?"
   href="https://bugs.webkit.org/show_bug.cgi?id=149338#c72">Comment # 72</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [ES6] Arrow function created before super() causes TDZ, should it?"
   href="https://bugs.webkit.org/show_bug.cgi?id=149338">bug 149338</a>
              from <span class="vcard"><a class="email" href="mailto:sbarati&#64;apple.com" title="Saam Barati &lt;sbarati&#64;apple.com&gt;"> <span class="fn">Saam Barati</span></a>
</span></b>
        <pre>Comment on <span class=""><a href="attachment.cgi?id=265001&amp;action=diff" name="attach_265001" title="Patch">attachment 265001</a> <a href="attachment.cgi?id=265001&amp;action=edit" title="Patch">[details]</a></span>
Patch

View in context: <a href="https://bugs.webkit.org/attachment.cgi?id=265001&amp;action=review">https://bugs.webkit.org/attachment.cgi?id=265001&amp;action=review</a>

This patch is just about done. It's in really good shape. I just have a few final comments and then I think it's ready to land.

<span class="quote">&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:833
&gt; +    addResult.iterator-&gt;value.setIsConst();</span >

Why is &quot;this&quot; modeled as a &quot;const&quot; variable?
I think it's better to just model them as normal variables because
we write to them more than once. Modeling them as
&quot;const&quot; will probably make the put_to_scope code fail when
it goes down the slow path. Unless we always make sure the put_to_scope
passes in the Initialize flag.

It's worth having tests to ensure the code works going
down the slow path. One way to write such a test is to
make the eval var injection watchpoint fire. I think something like this should make
the &quot;this&quot;/&quot;new.target&quot; go down the slow path (you should verify):
```
class C {
    constructor() {
        eval(&quot;var x = 20&quot;);
        super();
        let f = () =&gt; this;
    }
}
```

<span class="quote">&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:3863
&gt; +</span >

nit: only one newline is needed.

<span class="quote">&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:3876
&gt; +    emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, newTargetVar, newTarget(), DoNotThrowIfNotFound, NotInitialization);</span >

This should be &quot;Initialization&quot;. As I commented above, I think this code would fail if it went down the slow path. We should ensure it works going down the slow path of put_to_scope.

<span class="quote">&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:3885
&gt; +        emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, protoScope, &amp;m_calleeRegister, DoNotThrowIfNotFound, NotInitialization);</span >

Ditto: should be &quot;Initialization&quot;.
Also, I was totally wrong about naming this &quot;super...&quot;, this is really the derived constructor that we're storing in the environemnt
and then later loading __proto__ on. We should name it like &quot;derivedConstructorPrivateName&quot; or &quot;derivedClassPrivateName&quot;. Sorry about that.
I had thought we were eagerly storing the __proto__ of the derived constructor.

<span class="quote">&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:3894
&gt; +    emitPutToScope(isDerivedConstructorContext() ? emitResolveScope(nullptr, thisVar) : m_arrowFunctionContextLexicalEnvironmentRegister, thisVar, thisRegister(), DoNotThrowIfNotFound, NotInitialization);</span >

I think it's arguable whether or not this should be &quot;Initialization&quot; or &quot;NotInitialization&quot;. I'd say it should be &quot;Initialization&quot; even though it may execute more than once.
Either way, I think the &quot;this&quot; variable probably shouldn't be marked as being like &quot;const&quot;.

Also, we don't want to have more than one op_resolve_scope here because it will always resolve to the same thing. I'm not sure if this code
will run more than once unless we call &quot;super()&quot; more than once in a constructor. This seems really unlikely in real code (but I think it's legal in ES6 to do so),
so it's cleaner to ensure we never emit op_resolve_scope unnecessarily by doing something like this:

if (isDerivedConstructorContext())
    emitLoadArrowFunctionLexicalEnvironment()
emitPutToScope(isDerivedConstructorContext() ? m_resolvedArrowFunctionScopeContextRegister.get() : m_arrowFunctionContextLexicalEnvironmentRegister, thisVar, thisRegister(), DoNotThrowIfNotFound, Initialization);

<span class="quote">&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:830
&gt; +        RefPtr&lt;RegisterID&gt; m_resolvedArrowFunctionScopeContextRegister { nullptr };</span >

you don't need the nullptr initializer here, RefPtrs are by default initialized to null.

<span class="quote">&gt; Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:3003
&gt; +        bool usesArrowOrEval = generator.usesArrowFunction() || generator.usesEval();</span >

There are a lot of places where you do usesArrow() || usesEval(), I wonder if it's worth giving this
condition a more descriptive name in the various bytecodegenerator constructors.
Maybe like &quot;m_needsToUpdateArrowFunctionContext(generator.usesArrowFunction() || generator.usesEval())&quot;
Just a thought, I'm also okay with having this condition tested at all the interesting places.

<span class="quote">&gt; Source/JavaScriptCore/runtime/Executable.h:348
&gt; +    bool isArrowFunctionContext() const { return m_isArrowFunctionContext; }</span >

Could we get rid of these properties (not these methods) and just ask the unlinked code block for this data or get at it through CodeFeatures?

<span class="quote">&gt; Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-newtarget.js:1
&gt; +var testCase = function (actual, expected, message) {</span >

style: Let's make this file 4-space indented throughout

<span class="quote">&gt; Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-newtarget.js:13
&gt; +for (var i=0; i&lt;10000; i++) {</span >

I think we can get away w/ 1000 iterations for all the loops in this test.
10000 seems overkill.

<span class="quote">&gt; Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-newtarget.js:27
&gt; +        passed = new.target === B;</span >

Shouldn't this be '&amp;=' and the below just be &quot;=&quot; since below &quot;passed &amp;= new.target === B&quot; is executed first?

<span class="quote">&gt; Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-newtarget.js:50
&gt; +      passed &amp;= new.target === B;</span >

Why would this be &quot;B&quot;?

<span class="quote">&gt; Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-newtarget.js:75
&gt; +</span >

I take my previous comment back, I don't think we really need a test for this, it's just confusing.

<span class="quote">&gt; Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-1.js:1
&gt; +var testCase = function (actual, expected, message) {</span >

style: You should make all your test files have a consistent 4-space indent.

<span class="quote">&gt; Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-1.js:16
&gt; +  constructor (inArrowFuction, inConstructor, repeatInArrowFunction) {</span >

&quot;repeatInArrowFunction&quot; is unused, maybe remove it or were you planning on calling super() twice?

<span class="quote">&gt; Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-1.js:35
&gt; +for (var i=0; i &lt; 10000; i++) {</span >

I think 1000 iterations is also good for tests in this file.

<span class="quote">&gt; Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-2.js:17
&gt; +    var arrow = () =&gt; () =&gt; () =&gt; {</span >

👍

<span class="quote">&gt; Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-2.js:34
&gt; +for (var i=0; i &lt; 10000; i++) {</span >

1000 iterations is probably good for this file too.

<span class="quote">&gt; Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-2.js:39
&gt; +var testException = function (value1, value2, value3, index) {</span >

value3 is unused.
I would make this function take only the index parameter
because value1 and value2 are always false. It's easier
to just pass in &quot;false&quot; yourself

<span class="quote">&gt; Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-2.js:95
&gt; +        E.__proto__ = function () {};</span >

Might be worth having a test that sets __proto__ to &quot;null&quot; and make sure that we throw an error.

<span class="quote">&gt; Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-3.js:31
&gt; +for (var i=0; i &lt; 10000; i++) {</span >

I think all your tests can just be 1000 iterations.

<span class="quote">&gt; Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-supercall-3.js:35
&gt; +// Fixme: Failed test with 'Segmentation fault: 11' error in release mode in 6 cases from 14. List of failed case:</span >

Is this fixed?</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>