<html>
    <head>
      <base href="https://bugs.webkit.org/" />
    </head>
    <body>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [ES6] Implement ES6 arrow function syntax. Arrow function specific features. Lexical bind of this"
   href="https://bugs.webkit.org/show_bug.cgi?id=144956#c97">Comment # 97</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [ES6] Implement ES6 arrow function syntax. Arrow function specific features. Lexical bind of this"
   href="https://bugs.webkit.org/show_bug.cgi?id=144956">bug 144956</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="bz_obsolete"><a href="attachment.cgi?id=257956&amp;action=diff" name="attach_257956" title="Patch">attachment 257956</a> <a href="attachment.cgi?id=257956&amp;action=edit" title="Patch">[details]</a></span>
Patch

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

<span class="quote">&gt;&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:513
&gt;&gt; +            RefPtr&lt;RegisterID&gt; arrowFunctionBoundThis = emitLoadArrowFunctionThis(addVar());
&gt; 
&gt; this should be a temporary register, not an addVar().</span >

In new patch I've used directly m_thisRegister, without any temp and var, Is it Ok?

<span class="quote">&gt;&gt; Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:2868
&gt;&gt; +    arrowFunctionThis-&gt;ref();
&gt; 
&gt; don't ref this. this is an anti-pattern.</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2962
&gt;&gt; +// ------------------------------ ArrowFuncExprNode ---------------------------------
&gt; 
&gt; Nit: new line after comment to follow style of the file.</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:1744
&gt;&gt; +            if (JSArrowFunction* function = jsDynamicCast&lt;JSArrowFunction*&gt;(base)) {
&gt; 
&gt; Will this every be nullptr when base is truthy?</span >

I hope so, do I need to change to some another condition?

<span class="quote">&gt;&gt; Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:3726
&gt;&gt; +                result = weakJSConstant(function-&gt;boundThis());
&gt; 
&gt; I don't think this needs to be weak. I don't think it will make any difference because the arrow function
&gt; will always keep bound this alive, but it seems more correct to me to not be weak.
&gt; 
&gt; If something is weak, it means that if that cell is GCed, then the resulting DFG code goes away.
&gt; If something is strong, it means the DFG code keeps that cell alive. I think strong makes more sense here.</span >

Done, it is jsConstant now

<span class="quote">&gt;&gt; Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:1273
&gt;&gt; +            m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node-&gt;origin,
&gt; 
&gt; What is this doing?
&gt; Why are we doing this instead of &quot;fixEdge&lt;CellUse&gt;(node-&gt;child2())&quot;?</span >

Fixed

<span class="quote">&gt;&gt; Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp:843
&gt;&gt; +        case NewArrowFunction: {
&gt; 
&gt; I would combine this case with the case below so you don't repeat code.
&gt; You can just do:
&gt; &quot;if (op == NewArrowFunction) write.add(FunctionBoundThisPLoc ...)&quot;</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp:848
&gt;&gt; +            target = &amp;m_heap.newAllocation(node, Allocation::Kind::Function);
&gt; 
&gt; This is wrong. You need to add Allocation::Kind::ArrowFunction and use it here, otherwise you are transforming an arrow function into a regular function when sinking (not eliminating).
&gt; You should have isFunction() return true for Kind::ArrowFunction as well, and define a new isArrowFunction() helper in the Allocation class. Here is a test case for this, if my understanding of arrow functions is correct:
&gt; 
&gt; ````
&gt; function f(p) {
&gt;   var arr = (x) =&gt; this;
&gt;   if (p) return arr;
&gt; }
&gt; 
&gt; for (var i = 0; i &lt; 100000; ++i)
&gt;     f(i % 2);
&gt; 
&gt; if (f(true)() != f)
&gt;     throw new Error(&quot;Bad sinking.&quot;);
&gt; ````</span >

I've add Kind::ArrowFunction enum and isArrowFunction() function, also add following tests:
        *tests/stress/arrowfunction-lexical-this-activation-sink-osrexit.js
        * tests/stress/arrowfunction-lexical-this-activation-sink.js
        * tests/stress/arrowfunction-lexical-this-sinking-no-double-allocate.js
        * tests/stress/arrowfunction-lexical-this-sinking-osrexit.js
        * tests/stress/arrowfunction-lexical-this-sinking-put.js
        * tests/stress/arrowfunction-sinking-no-double-allocate.js
        * tests/stress/arrowfunction-sinking-osrexit.js
        * tests/stress/arrowfunction-sinking-put.js
Could you please take a look if it make sense?

<span class="quote">&gt;&gt; Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp:991
&gt;&gt; +                exactRead = FunctionActivationPLoc;
&gt; 
&gt; This is wrong. Revert.</span >

Done

<span class="quote">&gt;&gt;&gt; Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp:997
&gt;&gt;&gt; +        case LoadArrowFunctionThis:
&gt;&gt; 
&gt;&gt; I don't think we need to worry about LoadArrowFunctionThis in the allocation
&gt;&gt; sinking phase. This will just be loading from callee which should be materialized already at the top of a function.
&gt; 
&gt; We'd need to worry about it if we inlined arrow functions, which this patch does not handle by the look of it. If the plan is to implement inlining of arrow functions later, this should at least be a FIXME. Otherwise, this should check for target-&gt;isArrowFunctionAllocation() instead; cf above.</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp:1998
&gt;&gt; +        case NewArrowFunction: {
&gt; 
&gt; I think we can combine this and the below case and make necessary changes/asserts
&gt; based on if op is NewArrowFunction or NewFunction</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp:3074
&gt;&gt; +    void compileNewFunction(NodeType nodeType)
&gt; 
&gt; We don't need NodeType as a parameter here. m_node should have all the info you need.</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/jit/JIT.h:642
&gt;&gt; +        void emitNewFuncExprCommon(Instruction*, FunctionType);
&gt; 
&gt; If you have Instruction* you don't need FunctionType. You can just look at the opcode to determine if it's an arrow function or not.</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/jit/JITOperations.cpp:969
&gt;&gt; +EncodedJSValue operationNewArrowFunctionCommon(ExecState* exec, JSScope* scope, JSCell* functionExecutable, EncodedJSValue thisValue, bool isInvalidated)
&gt; 
&gt; I don't think you need to declare this in the header. You can just make this a static function in this file.</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:1016
&gt;&gt; +inline JSFunction* getJSFunctionExpr(ExecState* exec, Instruction* pc, VM&amp; vm)
&gt; 
&gt; Let's get rid of this function now that it only has one caller.
&gt; It made more sense before you refactored how the arrow function object layout.</span >

Done

<span class="quote">&gt;&gt; Source/JavaScriptCore/runtime/JSArrowFunction.cpp:51
&gt;&gt; +    executable-&gt;singletonFunction()-&gt;notifyWrite(vm, result, &quot;Allocating a arrow function&quot;);
&gt; 
&gt; nit: &quot;a&quot; =&gt; &quot;an&quot;</span >

Done

<span class="quote">&gt;&gt; LayoutTests/js/script-tests/arrowfunction-lexical-this-1.js:1
&gt;&gt; +description('Tests for ES6 arrow function lexical bind of this');
&gt; 
&gt; I would combine &quot;arrow function-lexical-this-1/2/3&quot; into one file or give them more descriptive names.</span >

Done

<span class="quote">&gt;&gt; LayoutTests/js/script-tests/arrowfunction-lexical-this-2.js:9
&gt;&gt; +shouldBe(&quot;afObjLexBind2Instance.func() === afObjLexBind2Instance&quot;, &quot;true&quot;);
&gt; 
&gt; Can we also try doing stuff like:
&gt; afObjLexBind2.call(V, ...)
&gt; where V might be many different things?
&gt; Basically, we should test &quot;bound&quot; this outside
&gt; a constructor and with different this values.
&gt; (Maybe a separate test).</span >

What kind different |this| should be, number, undefined, string?</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>