<html>
    <head>
      <base href="https://bugs.webkit.org/" />
    </head>
    <body>
      <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#c18">Comment # 18</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:gskachkov&#64;gmail.com" title="GSkachkov &lt;gskachkov&#64;gmail.com&gt;"> <span class="fn">GSkachkov</span></a>
</span></b>
        <pre>Comment on <span class=""><a href="attachment.cgi?id=262540&amp;action=diff" name="attach_262540" title="Patch">attachment 262540</a> <a href="attachment.cgi?id=262540&amp;action=edit" title="Patch">[details]</a></span>
Patch

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

Thanks for the review!
Now I'm running the tests in debug mode. 
After success I'll upload the patch. I hope that it will be happened today :-)

<span class="quote">&gt;&gt; Source/JavaScriptCore/bytecode/CodeBlock.cpp:1663
&gt;&gt; +    , m_needsActivation(unlinkedCodeBlock-&gt;hasActivationRegister() &amp;&amp; (unlinkedCodeBlock-&gt;codeType() == FunctionCode || unlinkedCodeBlock-&gt;codeType() == GlobalCode || unlinkedCodeBlock-&gt;codeType() == EvalCode) )
&gt; 
&gt; Why is this needed?</span >

It allow to avoid  ASSERT error in method needsActivation for Eval and Program case. As I understand we create lexical scope for them so we need activate it. 
See assert ASSERT(m_lexicalEnvironmentRegister.isValid() == m_needsActivation);

<span class="quote">&gt;&gt; Source/JavaScriptCore/bytecode/CodeBlock.h:350
&gt;&gt; +    void setNeedActivation(bool value)
&gt; 
&gt; this is unused.</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:170
&gt;&gt; +    if (programNode-&gt;usesArrowFunction())
&gt; 
&gt; Should this be &quot;if (programNode-&gt;usesArrowFunction() || usesEval())&quot;?</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:485
&gt;&gt; +        if (functionNode-&gt;usesThis() || codeBlock-&gt;usesEval() || functionNode-&gt;usesArrowFunction()) {
&gt; 
&gt; I think we need to emitResolveScoe then emitGetFromScope for every &quot;this&quot; node, right?
&gt; Just doing it once I think is not sufficient. Consider:
&gt; class C {
&gt;     constructor() {
&gt;          let f = (c) =&gt; c ? this : {};
&gt;          f(false);
&gt;          super();
&gt;          f(true);
&gt;     }
&gt; }</span >

Hmm, it seems that I don't understand clearly what does this methods. Your examples very close to scripts that I use to test TDZ in 'super()', see tests with name arrowfunction-tdz-1.js.
How I understand this code. Each time when arrow function is invoked, before run body of function it loads 'this' value to thisRegister. So if I this value is changed by parent function by 'super()', we get from scope of arrow function new 'this' value, because 'this' in lexical_scope will be updated by emitUpdateScopeIfNeed method that we call just after calling 'super()' see change in Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp line 730.

<span class="quote">&gt;&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:490
&gt;&gt;      }
&gt; 
&gt; I think you should add a line of code here that calls &quot;emitUpdateScopeIfNeeded()&quot;
&gt; Currently, you emit code for &quot;emitUpdateScopeIfNeeded()&quot; on each arrow function that's emitted.
&gt; This is excessive. If you simply call &quot;emitUpdateScopeIfNeeded()&quot; here and anytime you call super(),
&gt; we should always have the latest &quot;this&quot; value.
&gt; 
&gt; Also, I think you probably need to call &quot;initializeEmptyVarLexicalEnvironment()&quot; somewhere
&gt; inside this function to be consistent with ProgramNode/EvalNode.</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:541
&gt;&gt; +    else
&gt; 
&gt; This shouldn't be in an else clause. It should happen regardless of the above condition.</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:788
&gt;&gt; +void BytecodeGenerator::initializeEmptyVarLexicalEnvironment(VM&amp; vm)
&gt; 
&gt; I think we can do this in a better way. We can write this purely in terms of pushLexicalScopeInternal().
&gt; The reason is that pushLexicalScopeInternal does necessary bookkeeping for handling
&gt; scopes, etc (especially important within try/catch).
&gt; 
&gt; If you look at initializeDefaultParameterValuesAndSetupFunctionScopeStack() it interfaces with this function.
&gt; I think something like this would work:
&gt; 
&gt; ```
&gt;         VariableEnvironment environment;
&gt;         auto addResult = environment.add(thisIdentifier);
&gt;         addResult.iterator-&gt;value.setIsCaptured();
&gt;         pushLexicalScopeInternal(environment, false, nullptr, TDZRequirement::(Whatever it doesn't matter), ScopeType::LetConstScope, ScopeRegisterType::Block);
&gt; ```
&gt; Note that this works because the ::variable() function explicitly looks for the &quot;this&quot; identifier and
&gt; therefore we won't ever search the scope stack for &quot;this&quot;.</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:2937
&gt;&gt; +void BytecodeGenerator::emitUpdateScopeIfNeed()
&gt; 
&gt; Lets call this &quot;emitPutThisToScopeIfNeeded&quot; or something along those lines.</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:2942
&gt;&gt; +        emitPutToScope(scopeRegister(), thisVar, thisRegister(), DoNotThrowIfNotFoundAndReturnEmpty, NotInitialization);
&gt; 
&gt; I don't like the idea of adding new resolve modes like &quot;DoNotThrowIfNotFoundAndReturnEmpty&quot;.
&gt; Why would we ever not find &quot;this&quot;?
&gt; We should always find it.
&gt; We should make this guarantee by making sure every function places &quot;this&quot; into the lexical environment if needed.</span >

In case if we put 'this' inside of the constructor before 'super()' without flag we will receive ASSERT error. If we will try to get 'this' inside of arrow function that invokes before 'super()'  we will receive undefined and miss the TDZ error.
So that why  I made changes in  JITOperation.cpp operationGetFromScope/operationPutToScope</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>