Title: [214753] releases/WebKitGTK/webkit-2.16
Revision
214753
Author
carlo...@webkit.org
Date
2017-04-03 02:59:33 -0700 (Mon, 03 Apr 2017)

Log Message

Merge r214029 - [JSC] Default parameter part should be retrieved by op_get_argument opcode instead of changing arity
https://bugs.webkit.org/show_bug.cgi?id=164582

Reviewed by Saam Barati.

JSTests:

* stress/function-with-defaults-inlining.js: Added.
(shouldBe):
(ok):
(a):
* stress/function-with-defaults-non-inlining.js: Added.
(shouldBe):
(ok):
(a):

Source/_javascript_Core:

Previously we implement the default parameters as follows.

    1. We count the default parameters as the usual parameters.
    2. We just get the argument register.
    3. Check it with op_is_undefined.
    4. And fill the binding with either the argument register or default value.

The above is simple. However, it has the side effect that it always increase the arity of the function.
While `function.length` does not increase, internally, the number of parameters of CodeBlock increases.
This effectively prevent our DFG / FTL to perform inlining: currently we only allows DFG to inline
the function with the arity less than or equal the number of passing arguments. It is OK. But when using
default parameters, we frequently do not pass the argument for the parameter with the default value.
Thus, in our current implementation, we frequently need to fixup the arity. And we frequently fail
to inline the function.

This patch fixes the above problem by not increasing the arity of the function. When we encounter the
parameter with the default value, we use `op_argument` to get the argument instead of using the argument
registers.

This improves six-speed defaults.es6 performance by 4.45x.

    defaults.es6        968.4126+-101.2350   ^    217.6602+-14.8831       ^ definitely 4.4492x faster

* bytecode/UnlinkedFunctionExecutable.cpp:
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
* bytecode/UnlinkedFunctionExecutable.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeStack):
(JSC::BytecodeGenerator::initializeNextParameter):
(JSC::BytecodeGenerator::initializeParameters):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::FunctionNode::emitBytecode):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::inliningCost):
* parser/ASTBuilder.h:
(JSC::ASTBuilder::createFunctionMetadata):
* parser/Nodes.cpp:
(JSC::FunctionMetadataNode::FunctionMetadataNode):
* parser/Nodes.h:
(JSC::FunctionParameters::size):
(JSC::FunctionParameters::at):
(JSC::FunctionParameters::append):
(JSC::FunctionParameters::isSimpleParameterList):
* parser/Parser.cpp:
(JSC::Parser<LexerType>::isArrowFunctionParameters):
(JSC::Parser<LexerType>::parseGeneratorFunctionSourceElements):
(JSC::Parser<LexerType>::parseAsyncFunctionSourceElements):
(JSC::Parser<LexerType>::parseFormalParameters):
(JSC::Parser<LexerType>::parseFunctionBody):
(JSC::Parser<LexerType>::parseFunctionParameters):
(JSC::Parser<LexerType>::parseFunctionInfo):
* parser/Parser.h:
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createFunctionMetadata):
* runtime/FunctionExecutable.h:
* runtime/JSFunction.cpp:
(JSC::JSFunction::createBuiltinFunction):
(JSC::JSFunction::reifyLength):

Modified Paths

Added Paths

Diff

Modified: releases/WebKitGTK/webkit-2.16/JSTests/ChangeLog (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/JSTests/ChangeLog	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/JSTests/ChangeLog	2017-04-03 09:59:33 UTC (rev 214753)
@@ -1,5 +1,21 @@
 2017-03-15  Yusuke Suzuki  <utatane....@gmail.com>
 
+        [JSC] Default parameter part should be retrieved by op_get_argument opcode instead of changing arity
+        https://bugs.webkit.org/show_bug.cgi?id=164582
+
+        Reviewed by Saam Barati.
+
+        * stress/function-with-defaults-inlining.js: Added.
+        (shouldBe):
+        (ok):
+        (a):
+        * stress/function-with-defaults-non-inlining.js: Added.
+        (shouldBe):
+        (ok):
+        (a):
+
+2017-03-15  Yusuke Suzuki  <utatane....@gmail.com>
+
         [DFG] ToString operation should have fixup for primitives to say this node does not have side effects
         https://bugs.webkit.org/show_bug.cgi?id=169544
 

Added: releases/WebKitGTK/webkit-2.16/JSTests/stress/function-with-defaults-inlining.js (0 => 214753)


--- releases/WebKitGTK/webkit-2.16/JSTests/stress/function-with-defaults-inlining.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/stress/function-with-defaults-inlining.js	2017-04-03 09:59:33 UTC (rev 214753)
@@ -0,0 +1,24 @@
+(function () {
+'use strict';
+
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function ok(value)
+{
+    return value;
+}
+
+function a(b = 42, c = 43, d)
+{
+    return c + ok(b);
+}
+
+for (var i = 0; i < 1e4; ++i) {
+    shouldBe(a(), 85);
+    shouldBe(a(33), 76);
+    shouldBe(a(33, 22), 55);
+}
+}());

Added: releases/WebKitGTK/webkit-2.16/JSTests/stress/function-with-defaults-non-inlining.js (0 => 214753)


--- releases/WebKitGTK/webkit-2.16/JSTests/stress/function-with-defaults-non-inlining.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/stress/function-with-defaults-non-inlining.js	2017-04-03 09:59:33 UTC (rev 214753)
@@ -0,0 +1,25 @@
+(function () {
+'use strict';
+
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function ok(value)
+{
+    return value;
+}
+
+function a(b = 42, c = 43, d)
+{
+    return c + ok(b);
+}
+noInline(a);
+
+for (var i = 0; i < 1e4; ++i) {
+    shouldBe(a(), 85);
+    shouldBe(a(33), 76);
+    shouldBe(a(33, 22), 55);
+}
+}());

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog	2017-04-03 09:59:33 UTC (rev 214753)
@@ -1,5 +1,73 @@
 2017-03-15  Yusuke Suzuki  <utatane....@gmail.com>
 
+        [JSC] Default parameter part should be retrieved by op_get_argument opcode instead of changing arity
+        https://bugs.webkit.org/show_bug.cgi?id=164582
+
+        Reviewed by Saam Barati.
+
+        Previously we implement the default parameters as follows.
+
+            1. We count the default parameters as the usual parameters.
+            2. We just get the argument register.
+            3. Check it with op_is_undefined.
+            4. And fill the binding with either the argument register or default value.
+
+        The above is simple. However, it has the side effect that it always increase the arity of the function.
+        While `function.length` does not increase, internally, the number of parameters of CodeBlock increases.
+        This effectively prevent our DFG / FTL to perform inlining: currently we only allows DFG to inline
+        the function with the arity less than or equal the number of passing arguments. It is OK. But when using
+        default parameters, we frequently do not pass the argument for the parameter with the default value.
+        Thus, in our current implementation, we frequently need to fixup the arity. And we frequently fail
+        to inline the function.
+
+        This patch fixes the above problem by not increasing the arity of the function. When we encounter the
+        parameter with the default value, we use `op_argument` to get the argument instead of using the argument
+        registers.
+
+        This improves six-speed defaults.es6 performance by 4.45x.
+
+            defaults.es6        968.4126+-101.2350   ^    217.6602+-14.8831       ^ definitely 4.4492x faster
+
+        * bytecode/UnlinkedFunctionExecutable.cpp:
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        * bytecode/UnlinkedFunctionExecutable.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeStack):
+        (JSC::BytecodeGenerator::initializeNextParameter):
+        (JSC::BytecodeGenerator::initializeParameters):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::FunctionNode::emitBytecode):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::inliningCost):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createFunctionMetadata):
+        * parser/Nodes.cpp:
+        (JSC::FunctionMetadataNode::FunctionMetadataNode):
+        * parser/Nodes.h:
+        (JSC::FunctionParameters::size):
+        (JSC::FunctionParameters::at):
+        (JSC::FunctionParameters::append):
+        (JSC::FunctionParameters::isSimpleParameterList):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::isArrowFunctionParameters):
+        (JSC::Parser<LexerType>::parseGeneratorFunctionSourceElements):
+        (JSC::Parser<LexerType>::parseAsyncFunctionSourceElements):
+        (JSC::Parser<LexerType>::parseFormalParameters):
+        (JSC::Parser<LexerType>::parseFunctionBody):
+        (JSC::Parser<LexerType>::parseFunctionParameters):
+        (JSC::Parser<LexerType>::parseFunctionInfo):
+        * parser/Parser.h:
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createFunctionMetadata):
+        * runtime/FunctionExecutable.h:
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::createBuiltinFunction):
+        (JSC::JSFunction::reifyLength):
+
+2017-03-15  Yusuke Suzuki  <utatane....@gmail.com>
+
         [DFG] ToString operation should have fixup for primitives to say this node does not have side effects
         https://bugs.webkit.org/show_bug.cgi?id=169544
 

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.cpp (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.cpp	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.cpp	2017-04-03 09:59:33 UTC (rev 214753)
@@ -88,7 +88,6 @@
     , m_typeProfilingStartOffset(node->functionKeywordStart())
     , m_typeProfilingEndOffset(node->startStartOffset() + node->source().length() - 1)
     , m_parameterCount(node->parameterCount())
-    , m_functionLength(node->functionLength())
     , m_features(0)
     , m_sourceParseMode(node->parseMode())
     , m_isInStrictContext(node->isInStrictContext())

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h	2017-04-03 09:59:33 UTC (rev 214753)
@@ -77,7 +77,6 @@
     void setEcmaName(const Identifier& name) { m_ecmaName = name; }
     const Identifier& inferredName() const { return m_inferredName; }
     unsigned parameterCount() const { return m_parameterCount; }; // Excluding 'this'!
-    unsigned functionLength() const { return m_functionLength; }
     SourceParseMode parseMode() const { return static_cast<SourceParseMode>(m_sourceParseMode); };
 
     const SourceCode& classSource() const { return m_classSource; };
@@ -159,7 +158,6 @@
     unsigned m_typeProfilingStartOffset;
     unsigned m_typeProfilingEndOffset;
     unsigned m_parameterCount;
-    unsigned m_functionLength;
     CodeFeatures m_features;
     SourceParseMode m_sourceParseMode;
     unsigned m_isInStrictContext : 1;

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2017-04-03 09:59:33 UTC (rev 214753)
@@ -254,15 +254,8 @@
     // If IsSimpleParameterList is false, we will create a strict-mode like arguments object.
     // IsSimpleParameterList is false if the argument list contains any default parameter values,
     // a rest parameter, or any destructuring patterns.
-    bool isSimpleParameterList = true;
     // If we do have default parameters, destructuring parameters, or a rest parameter, our parameters will be allocated in a different scope.
-    for (size_t i = 0; i < parameters.size(); i++) {
-        std::pair<DestructuringPatternNode*, ExpressionNode*> parameter = parameters.at(i);
-        bool hasDefaultParameterValue = !!parameter.second;
-        auto pattern = parameter.first;
-        bool isSimpleParameter = !hasDefaultParameterValue && pattern->isBindingNode();
-        isSimpleParameterList &= isSimpleParameter;
-    }
+    bool isSimpleParameterList = parameters.isSimpleParameterList();
 
     SourceParseMode parseMode = codeBlock->parseMode();
 
@@ -983,10 +976,12 @@
             std::pair<DestructuringPatternNode*, ExpressionNode*> parameter = parameters.at(i);
             if (parameter.first->isRestParameter())
                 continue;
-            RefPtr<RegisterID> parameterValue = &registerFor(virtualRegisterForArgument(1 + i));
-            emitMove(temp.get(), parameterValue.get());
+            if ((i + 1) < m_parameters.size())
+                emitMove(temp.get(), &m_parameters[i + 1]);
+            else
+                emitGetArgument(temp.get(), i);
             if (parameter.second) {
-                RefPtr<RegisterID> condition = emitIsUndefined(newTemporary(), parameterValue.get());
+                RefPtr<RegisterID> condition = emitIsUndefined(newTemporary(), temp.get());
                 Ref<Label> skipDefaultParameterBecauseNotUndefined = newLabel();
                 emitJumpIfFalse(condition.get(), skipDefaultParameterBecauseNotUndefined.get());
                 emitNode(temp.get(), parameter.second);
@@ -1103,7 +1098,8 @@
 RegisterID* BytecodeGenerator::initializeNextParameter()
 {
     VirtualRegister reg = virtualRegisterForArgument(m_codeBlock->numParameters());
-    RegisterID& parameter = registerFor(reg);
+    m_parameters.grow(m_parameters.size() + 1);
+    auto& parameter = registerFor(reg);
     parameter.setIndex(reg.offset());
     m_codeBlock->addParameter();
     return &parameter;
@@ -1113,14 +1109,23 @@
 {
     // Make sure the code block knows about all of our parameters, and make sure that parameters
     // needing destructuring are noted.
-    m_parameters.grow(parameters.size() + 1); // reserve space for "this"
     m_thisRegister.setIndex(initializeNextParameter()->index()); // this
+
+    bool nonSimpleArguments = false;
     for (unsigned i = 0; i < parameters.size(); ++i) {
-        auto pattern = parameters.at(i).first;
+        auto parameter = parameters.at(i);
+        auto pattern = parameter.first;
         if (pattern->isRestParameter()) {
             RELEASE_ASSERT(!m_restParameter);
             m_restParameter = static_cast<RestParameterNode*>(pattern);
-        } else
+            nonSimpleArguments = true;
+            continue;
+        }
+        if (parameter.second) {
+            nonSimpleArguments = true;
+            continue;
+        }
+        if (!nonSimpleArguments)
             initializeNextParameter();
     }
 }

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2017-04-03 09:59:33 UTC (rev 214753)
@@ -639,7 +639,6 @@
         RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&);
         RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
         RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* thisValue, RegisterID* property);
-        RegisterID* emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
         RegisterID* emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
         RegisterID* emitPutByVal(RegisterID* base, RegisterID* thisValue, RegisterID* property, RegisterID* value);
         RegisterID* emitDirectPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2017-04-03 09:59:33 UTC (rev 214753)
@@ -3463,13 +3463,13 @@
 void FunctionNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
 {
     if (generator.vm()->typeProfiler()) {
-        for (size_t i = 0; i < m_parameters->size(); i++) {
-            // Destructuring parameters are handled in destructuring nodes.
-            if (!m_parameters->at(i).first->isBindingNode())
-                continue;
-            BindingNode* parameter = static_cast<BindingNode*>(m_parameters->at(i).first);
-            RegisterID reg(CallFrame::argumentOffset(i));
-            generator.emitProfileType(&reg, ProfileTypeBytecodeFunctionArgument, parameter->divotStart(), parameter->divotEnd());
+        // If the parameter list is non simple one, it is handled in bindValue's code.
+        if (m_parameters->isSimpleParameterList()) {
+            for (size_t i = 0; i < m_parameters->size(); i++) {
+                BindingNode* bindingNode = static_cast<BindingNode*>(m_parameters->at(i).first);
+                RegisterID reg(CallFrame::argumentOffset(i));
+                generator.emitProfileType(&reg, ProfileTypeBytecodeFunctionArgument, bindingNode->divotStart(), bindingNode->divotEnd());
+            }
         }
     }
 

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2017-04-03 09:59:33 UTC (rev 214753)
@@ -1424,15 +1424,6 @@
         return UINT_MAX;
     }
     
-    // Does the number of arguments we're passing match the arity of the target? We currently
-    // inline only if the number of arguments passed is greater than or equal to the number
-    // arguments expected.
-    if (static_cast<int>(executable->parameterCount()) + 1 > argumentCountIncludingThis) {
-        if (verbose)
-            dataLog("    Failing because of arity mismatch.\n");
-        return UINT_MAX;
-    }
-    
     // Do we have a code block, and does the code block's size match the heuristics/requirements for
     // being an inline candidate? We might not have a code block (1) if code was thrown away,
     // (2) if we simply hadn't actually made this call yet or (3) code is a builtin function and
@@ -1446,6 +1437,16 @@
             dataLog("    Failing because no code block available.\n");
         return UINT_MAX;
     }
+
+    // Does the number of arguments we're passing match the arity of the target? We currently
+    // inline only if the number of arguments passed is greater than or equal to the number
+    // arguments expected.
+    if (codeBlock->numParameters() > argumentCountIncludingThis) {
+        if (verbose)
+            dataLog("    Failing because of arity mismatch.\n");
+        return UINT_MAX;
+    }
+
     CapabilityLevel capabilityLevel = inlineFunctionForCapabilityLevel(
         codeBlock, kind, callee.isClosureCall());
     if (verbose) {

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/ASTBuilder.h (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/ASTBuilder.h	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/ASTBuilder.h	2017-04-03 09:59:33 UTC (rev 214753)
@@ -427,7 +427,7 @@
         unsigned startColumn, unsigned endColumn, int functionKeywordStart, 
         int functionNameStart, int parametersStart, bool inStrictContext, 
         ConstructorKind constructorKind, SuperBinding superBinding,
-        unsigned parameterCount, unsigned functionLength,
+        unsigned parameterCount,
         SourceParseMode mode, bool isArrowFunctionBodyExpression)
     {
         return new (m_parserArena) FunctionMetadataNode(
@@ -434,7 +434,7 @@
             m_parserArena, startLocation, endLocation, startColumn, endColumn, 
             functionKeywordStart, functionNameStart, parametersStart, 
             inStrictContext, constructorKind, superBinding,
-            parameterCount, functionLength, mode, isArrowFunctionBodyExpression);
+            parameterCount, mode, isArrowFunctionBodyExpression);
     }
 
     ExpressionNode* createArrowFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo)

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/Nodes.cpp (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/Nodes.cpp	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/Nodes.cpp	2017-04-03 09:59:33 UTC (rev 214753)
@@ -135,7 +135,7 @@
     ParserArena&, const JSTokenLocation& startLocation, 
     const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, 
     int functionKeywordStart, int functionNameStart, int parametersStart, bool isInStrictContext, 
-    ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, unsigned functionLength, SourceParseMode mode, bool isArrowFunctionBodyExpression)
+    ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression)
         : Node(endLocation)
         , m_startColumn(startColumn)
         , m_endColumn(endColumn)
@@ -144,7 +144,6 @@
         , m_parametersStart(parametersStart)
         , m_startStartOffset(startLocation.startOffset)
         , m_parameterCount(parameterCount)
-        , m_functionLength(functionLength)
         , m_parseMode(mode)
         , m_isInStrictContext(isInStrictContext)
         , m_superBinding(static_cast<unsigned>(superBinding))

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/Nodes.h (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/Nodes.h	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/Nodes.h	2017-04-03 09:59:33 UTC (rev 214753)
@@ -1867,22 +1867,6 @@
         ModuleNameNode* m_moduleName { nullptr };
     };
 
-    class FunctionParameters : public ParserArenaDeletable {
-    public:
-        FunctionParameters();
-        ALWAYS_INLINE unsigned size() const { return m_patterns.size(); }
-        ALWAYS_INLINE std::pair<DestructuringPatternNode*, ExpressionNode*> at(unsigned index) { return m_patterns[index]; }
-        ALWAYS_INLINE void append(DestructuringPatternNode* pattern, ExpressionNode* defaultValue) 
-        { 
-            ASSERT(pattern); 
-            m_patterns.append(std::make_pair(pattern, defaultValue));
-        }
-
-    private:
-
-        Vector<std::pair<DestructuringPatternNode*, ExpressionNode*>, 3> m_patterns;
-    };
-
     class FunctionMetadataNode final : public Node, public ParserArenaDeletable {
     public:
         using ParserArenaDeletable::operator new;
@@ -1891,7 +1875,7 @@
             ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, 
             unsigned startColumn, unsigned endColumn, int functionKeywordStart, 
             int functionNameStart, int parametersStart, bool isInStrictContext, 
-            ConstructorKind, SuperBinding, unsigned parameterCount, unsigned functionLength,
+            ConstructorKind, SuperBinding, unsigned parameterCount,
             SourceParseMode, bool isArrowFunctionBodyExpression);
 
         void finishParsing(const SourceCode&, const Identifier&, FunctionMode);
@@ -1911,7 +1895,6 @@
         unsigned startColumn() const { return m_startColumn; }
         unsigned endColumn() const { return m_endColumn; }
         unsigned parameterCount() const { return m_parameterCount; }
-        unsigned functionLength() const { return m_functionLength; }
         SourceParseMode parseMode() const { return m_parseMode; }
 
         void setEndPosition(JSTextPosition);
@@ -1948,7 +1931,6 @@
         SourceCode m_classSource;
         int m_startStartOffset;
         unsigned m_parameterCount;
-        unsigned m_functionLength;
         int m_lastLine;
         SourceParseMode m_parseMode;
         unsigned m_isInStrictContext : 1;
@@ -2228,6 +2210,36 @@
         ExpressionNode* m_initializer;
     };
 
+    class FunctionParameters : public ParserArenaDeletable {
+    public:
+        FunctionParameters();
+        ALWAYS_INLINE unsigned size() const { return m_patterns.size(); }
+        ALWAYS_INLINE std::pair<DestructuringPatternNode*, ExpressionNode*> at(unsigned index) { return m_patterns[index]; }
+        ALWAYS_INLINE void append(DestructuringPatternNode* pattern, ExpressionNode* defaultValue)
+        {
+            ASSERT(pattern);
+
+            // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-functiondeclarationinstantiation
+            // This implements IsSimpleParameterList in the Ecma 2015 spec.
+            // If IsSimpleParameterList is false, we will create a strict-mode like arguments object.
+            // IsSimpleParameterList is false if the argument list contains any default parameter values,
+            // a rest parameter, or any destructuring patterns.
+            // If we do have default parameters, destructuring parameters, or a rest parameter, our parameters will be allocated in a different scope.
+
+            bool hasDefaultParameterValue = defaultValue;
+            bool isSimpleParameter = !hasDefaultParameterValue && pattern->isBindingNode();
+            m_isSimpleParameterList &= isSimpleParameter;
+
+            m_patterns.append(std::make_pair(pattern, defaultValue));
+        }
+        ALWAYS_INLINE bool isSimpleParameterList() const { return m_isSimpleParameterList; }
+
+    private:
+
+        Vector<std::pair<DestructuringPatternNode*, ExpressionNode*>, 3> m_patterns;
+        bool m_isSimpleParameterList { true };
+    };
+
     class FuncDeclNode : public StatementNode {
     public:
         FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&);

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/Parser.cpp (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/Parser.cpp	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/Parser.cpp	2017-04-03 09:59:33 UTC (rev 214753)
@@ -286,9 +286,8 @@
             fakeScope->setSourceParseMode(SourceParseMode::ArrowFunctionMode);
 
             unsigned parametersCount = 0;
-            unsigned functionLength = 0;
             bool isArrowFunctionParameterList = true;
-            isArrowFunction = parseFormalParameters(syntaxChecker, syntaxChecker.createFormalParameterList(), isArrowFunctionParameterList, parametersCount, functionLength) && consume(CLOSEPAREN) && match(ARROWFUNCTION);
+            isArrowFunction = parseFormalParameters(syntaxChecker, syntaxChecker.createFormalParameterList(), isArrowFunctionParameterList, parametersCount) && consume(CLOSEPAREN) && match(ARROWFUNCTION);
             propagateError();
             popScope(fakeScope, syntaxChecker.NeedsFreeVariableInfo);
         }
@@ -465,7 +464,7 @@
         failIfFalse(parseSourceElements(generatorFunctionContext, mode), "Cannot parse the body of a generator");
         popScope(generatorBodyScope, TreeBuilder::NeedsFreeVariableInfo);
     }
-    info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, info.functionLength, SourceParseMode::GeneratorBodyMode, false);
+    info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, SourceParseMode::GeneratorBodyMode, false);
 
     info.endLine = tokenLine();
     info.endOffset = m_token.m_data.offset;
@@ -516,7 +515,7 @@
         }
         popScope(asyncFunctionBodyScope, TreeBuilder::NeedsFreeVariableInfo);
     }
-    info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, info.functionLength, innerParseMode, isArrowFunctionBodyExpression);
+    info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, innerParseMode, isArrowFunctionBodyExpression);
 
     info.endLine = tokenLine();
     info.endOffset = isArrowFunctionBodyExpression ? tokenLocation().endOffset : m_token.m_data.offset;
@@ -1825,7 +1824,7 @@
 }
 
 template <typename LexerType>
-template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeBuilder& context, TreeFormalParameterList list, bool isArrowFunction, unsigned& parameterCount, unsigned& functionLength)
+template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeBuilder& context, TreeFormalParameterList list, bool isArrowFunction, unsigned& parameterCount)
 {
 #define failIfDuplicateIfViolation() \
     if (duplicateParameter) {\
@@ -1839,6 +1838,7 @@
     bool hasDestructuringPattern = false;
     bool isRestParameter = false;
     const Identifier* duplicateParameter = nullptr;
+    unsigned restParameterStart = 0;
     do {
         TreeDestructuringPattern parameter = 0;
         TreeExpression defaultValue = 0;
@@ -1851,7 +1851,7 @@
             semanticFailIfTrue(!m_parserState.allowAwait && match(AWAIT), "Can't use 'await' as a parameter name in an async function");
             TreeDestructuringPattern destructuringPattern = parseDestructuringPattern(context, DestructuringKind::DestructureToParameters, ExportType::NotExported, &duplicateParameter, &hasDestructuringPattern);
             propagateError();
-            parameter = context.createRestParameter(destructuringPattern, parameterCount);
+            parameter = context.createRestParameter(destructuringPattern, restParameterStart);
             failIfTrue(match(COMMA), "Rest parameter should be the last parameter in a function declaration"); // Let's have a good error message for this common case.
             isRestParameter = true;
         } else
@@ -1868,9 +1868,9 @@
             currentScope()->setHasNonSimpleParameterList();
         context.appendParameter(list, parameter, defaultValue);
         if (!isRestParameter) {
-            parameterCount++;
+            restParameterStart++;
             if (!hasDefaultParameterValues)
-                functionLength++;
+                parameterCount++;
         }
     } while (!isRestParameter && consume(COMMA));
 
@@ -1881,7 +1881,7 @@
 template <typename LexerType>
 template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody(
     TreeBuilder& context, SyntaxChecker& syntaxChecker, const JSTokenLocation& startLocation, int startColumn, int functionKeywordStart, int functionNameStart, int parametersStart,
-    ConstructorKind constructorKind, SuperBinding superBinding, FunctionBodyType bodyType, unsigned parameterCount, unsigned functionLength, SourceParseMode parseMode)
+    ConstructorKind constructorKind, SuperBinding superBinding, FunctionBodyType bodyType, unsigned parameterCount, SourceParseMode parseMode)
 {
     bool isArrowFunctionBodyExpression = bodyType == ArrowFunctionBodyExpression;
     if (!isArrowFunctionBodyExpression) {
@@ -1889,7 +1889,7 @@
         if (match(CLOSEBRACE)) {
             unsigned endColumn = tokenColumn();
             SuperBinding functionSuperBinding = adjustSuperBindingForBaseConstructor(constructorKind, superBinding, currentScope());
-            return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, functionSuperBinding, parameterCount, functionLength, parseMode, isArrowFunctionBodyExpression);
+            return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, functionSuperBinding, parameterCount, parseMode, isArrowFunctionBodyExpression);
         }
     }
 
@@ -1908,7 +1908,7 @@
     }
     unsigned endColumn = tokenColumn();
     SuperBinding functionSuperBinding = adjustSuperBindingForBaseConstructor(constructorKind, superBinding, currentScope());
-    return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, functionSuperBinding, parameterCount, functionLength, parseMode, isArrowFunctionBodyExpression);
+    return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, functionSuperBinding, parameterCount, parseMode, isArrowFunctionBodyExpression);
 }
 
 static const char* stringForFunctionMode(SourceParseMode mode)
@@ -1962,16 +1962,14 @@
                 
                 if (match(CLOSEPAREN)) {
                     functionInfo.parameterCount = 0;
-                    functionInfo.functionLength = 0;
                 } else {
                     bool isArrowFunction = true;
-                    failIfFalse(parseFormalParameters(context, parameterList, isArrowFunction, functionInfo.parameterCount, functionInfo.functionLength), "Cannot parse parameters for this ", stringForFunctionMode(mode));
+                    failIfFalse(parseFormalParameters(context, parameterList, isArrowFunction, functionInfo.parameterCount), "Cannot parse parameters for this ", stringForFunctionMode(mode));
                 }
                 
                 consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
             } else {
                 functionInfo.parameterCount = 1;
-                functionInfo.functionLength = 1;
                 auto parameter = parseDestructuringPattern(context, DestructuringKind::DestructureToParameters, ExportType::NotExported);
                 failIfFalse(parameter, "Cannot parse parameter pattern");
                 context.appendParameter(parameterList, parameter, 0);
@@ -1989,7 +1987,6 @@
     if (mode == SourceParseMode::GetterMode) {
         consumeOrFail(CLOSEPAREN, "getter functions must have no parameters");
         functionInfo.parameterCount = 0;
-        functionInfo.functionLength = 0;
     } else if (mode == SourceParseMode::SetterMode) {
         failIfTrue(match(CLOSEPAREN), "setter functions must have one parameter");
         const Identifier* duplicateParameter = nullptr;
@@ -2003,17 +2000,15 @@
             currentScope()->setHasNonSimpleParameterList();
         }
         context.appendParameter(parameterList, parameter, defaultValue);
-        functionInfo.parameterCount = 1;
-        functionInfo.functionLength = defaultValue ? 0 : 1;
+        functionInfo.parameterCount = defaultValue ? 0 : 1;
         failIfTrue(match(COMMA), "setter functions must have one parameter");
         consumeOrFail(CLOSEPAREN, "Expected a ')' after a parameter declaration");
     } else {
         if (match(CLOSEPAREN)) {
             functionInfo.parameterCount = 0;
-            functionInfo.functionLength = 0;
         } else {
             bool isArrowFunction = false;
-            failIfFalse(parseFormalParameters(context, parameterList, isArrowFunction, functionInfo.parameterCount, functionInfo.functionLength), "Cannot parse parameters for this ", stringForFunctionMode(mode));
+            failIfFalse(parseFormalParameters(context, parameterList, isArrowFunction, functionInfo.parameterCount), "Cannot parse parameters for this ", stringForFunctionMode(mode));
         }
         consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
     }
@@ -2115,11 +2110,10 @@
                 startLocation, endLocation, startColumn, bodyEndColumn, 
                 functionKeywordStart, functionNameStart, parametersStart, 
                 cachedInfo->strictMode, constructorKind, functionSuperBinding,
-                cachedInfo->parameterCount, cachedInfo->functionLength,
+                cachedInfo->parameterCount,
                 mode, functionBodyType == ArrowFunctionBodyExpression);
             functionInfo.endOffset = cachedInfo->endFunctionOffset;
             functionInfo.parameterCount = cachedInfo->parameterCount;
-            functionInfo.functionLength = cachedInfo->functionLength;
 
             functionScope->restoreFromSourceProviderCache(cachedInfo);
             popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo);
@@ -2287,7 +2281,7 @@
     });
 
     auto performParsingFunctionBody = [&] {
-        return parseFunctionBody(context, syntaxChecker, startLocation, startColumn, functionKeywordStart, functionNameStart, parametersStart, constructorKind, expectedSuperBinding, functionBodyType, functionInfo.parameterCount, functionInfo.functionLength, mode);
+        return parseFunctionBody(context, syntaxChecker, startLocation, startColumn, functionKeywordStart, functionNameStart, parametersStart, constructorKind, expectedSuperBinding, functionBodyType, functionInfo.parameterCount, mode);
     };
 
     if (isGeneratorOrAsyncFunctionWrapperParseMode(mode)) {
@@ -2342,10 +2336,10 @@
     // Any future reparsing can then skip the function.
     // For arrow function is 8 = x=>x + 4 symbols;
     // For ordinary function is 16  = function(){} + 4 symbols
-    const int minimumFunctionLengthToCache = functionBodyType == StandardFunctionBodyBlock ? 16 : 8;
+    const int minimumSourceLengthToCache = functionBodyType == StandardFunctionBodyBlock ? 16 : 8;
     std::unique_ptr<SourceProviderCacheItem> newInfo;
-    int functionLength = functionInfo.endOffset - functionInfo.startOffset;
-    if (TreeBuilder::CanUseFunctionCache && m_functionCache && functionLength > minimumFunctionLengthToCache) {
+    int sourceLength = functionInfo.endOffset - functionInfo.startOffset;
+    if (TreeBuilder::CanUseFunctionCache && m_functionCache && sourceLength > minimumSourceLengthToCache) {
         SourceProviderCacheItemCreationParameters parameters;
         parameters.endFunctionOffset = functionInfo.endOffset;
         parameters.functionNameStart = functionNameStart;
@@ -2354,7 +2348,6 @@
         parameters.lastTokenEndOffset = location.endOffset;
         parameters.lastTokenLineStartOffset = location.lineStartOffset;
         parameters.parameterCount = functionInfo.parameterCount;
-        parameters.functionLength = functionInfo.functionLength;
         parameters.constructorKind = constructorKind;
         parameters.expectedSuperBinding = expectedSuperBinding;
         if (functionBodyType == ArrowFunctionBodyExpression) {

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/Parser.h (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/Parser.h	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/Parser.h	2017-04-03 09:59:33 UTC (rev 214753)
@@ -1532,8 +1532,8 @@
     template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict);
     template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator, bool isAsyncMethod);
     template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind, bool isClassProperty);
-    template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, SyntaxChecker&, const JSTokenLocation&, int, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, SuperBinding, FunctionBodyType, unsigned, unsigned, SourceParseMode);
-    template <class TreeBuilder> ALWAYS_INLINE bool parseFormalParameters(TreeBuilder&, TreeFormalParameterList, bool isArrowFunction, unsigned&, unsigned&);
+    template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, SyntaxChecker&, const JSTokenLocation&, int, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, SuperBinding, FunctionBodyType, unsigned, SourceParseMode);
+    template <class TreeBuilder> ALWAYS_INLINE bool parseFormalParameters(TreeBuilder&, TreeFormalParameterList, bool isArrowFunction, unsigned&);
     enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext };
     template <class TreeBuilder> TreeExpression parseVariableDeclarationList(TreeBuilder&, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext, DeclarationType, ExportType, bool& forLoopConstDoesNotHaveInitializer);
     template <class TreeBuilder> TreeSourceElements parseArrowFunctionSingleExpressionBodySourceElements(TreeBuilder&);

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/SyntaxChecker.h (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/SyntaxChecker.h	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/parser/SyntaxChecker.h	2017-04-03 09:59:33 UTC (rev 214753)
@@ -187,7 +187,7 @@
     ExpressionType createFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
     ExpressionType createGeneratorFunctionBody(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&, const Identifier&) { return FunctionExpr; }
     ExpressionType createAsyncFunctionBody(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
-    int createFunctionMetadata(const JSTokenLocation&, const JSTokenLocation&, int, int, bool, int, int, int, ConstructorKind, SuperBinding, unsigned, int, SourceParseMode, bool, InnerArrowFunctionCodeFeatures = NoInnerArrowFunctionFeatures) { return FunctionBodyResult; }
+    int createFunctionMetadata(const JSTokenLocation&, const JSTokenLocation&, int, int, bool, int, int, int, ConstructorKind, SuperBinding, unsigned, SourceParseMode, bool, InnerArrowFunctionCodeFeatures = NoInnerArrowFunctionFeatures) { return FunctionBodyResult; }
     ExpressionType createArrowFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
     ExpressionType createMethodDefinition(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
     void setFunctionNameStart(int, int) { }

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/FunctionExecutable.h (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/FunctionExecutable.h	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/FunctionExecutable.h	2017-04-03 09:59:33 UTC (rev 214753)
@@ -145,7 +145,6 @@
     const Identifier& ecmaName() { return m_unlinkedExecutable->ecmaName(); }
     const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }
     unsigned parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'!
-    unsigned functionLength() const { return m_unlinkedExecutable->functionLength(); }
     SourceParseMode parseMode() const { return m_unlinkedExecutable->parseMode(); }
     JSParserScriptMode scriptMode() const { return m_unlinkedExecutable->scriptMode(); }
     const SourceCode& classSource() const { return m_unlinkedExecutable->classSource(); }

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/JSFunction.cpp (214752 => 214753)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/JSFunction.cpp	2017-04-03 08:15:27 UTC (rev 214752)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/JSFunction.cpp	2017-04-03 09:59:33 UTC (rev 214753)
@@ -104,7 +104,7 @@
 {
     JSFunction* function = create(vm, executable, globalObject);
     function->putDirect(vm, vm.propertyNames->name, jsString(&vm, executable->name().string()), ReadOnly | DontEnum);
-    function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->functionLength()), ReadOnly | DontEnum);
+    function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->parameterCount()), ReadOnly | DontEnum);
     return function;
 }
 
@@ -112,7 +112,7 @@
 {
     JSFunction* function = create(vm, executable, globalObject);
     function->putDirect(vm, vm.propertyNames->name, jsString(&vm, name), ReadOnly | DontEnum);
-    function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->functionLength()), ReadOnly | DontEnum);
+    function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->parameterCount()), ReadOnly | DontEnum);
     return function;
 }
 
@@ -623,7 +623,7 @@
 
     ASSERT(!hasReifiedLength());
     ASSERT(!isHostFunction());
-    JSValue initialValue = jsNumber(jsExecutable()->functionLength());
+    JSValue initialValue = jsNumber(jsExecutable()->parameterCount());
     unsigned initialAttributes = DontEnum | ReadOnly;
     const Identifier& identifier = vm.propertyNames->length;
     putDirect(vm, identifier, initialValue, initialAttributes);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to