Title: [167964] trunk
Revision
167964
Author
oli...@apple.com
Date
2014-04-29 15:23:17 -0700 (Tue, 29 Apr 2014)

Log Message

Source/_javascript_Core: Don't hold on to parameterBindingNodes forever
https://bugs.webkit.org/show_bug.cgi?id=132360

Reviewed by Geoffrey Garen.

Don't keep the parameter nodes anymore. Instead we store the
original parameter string and reparse whenever we actually
need them. Because we only actually need them for compilation
this only results in a single extra parse.

* bytecode/UnlinkedCodeBlock.cpp:
(JSC::generateFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
(JSC::UnlinkedFunctionExecutable::visitChildren):
(JSC::UnlinkedFunctionExecutable::finishCreation):
(JSC::UnlinkedFunctionExecutable::paramString):
(JSC::UnlinkedFunctionExecutable::parameters):
(JSC::UnlinkedFunctionExecutable::parameterCount): Deleted.
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedFunctionExecutable::create):
(JSC::UnlinkedFunctionExecutable::parameterCount):
(JSC::UnlinkedFunctionExecutable::parameters): Deleted.
(JSC::UnlinkedFunctionExecutable::finishCreation): Deleted.
* parser/ASTBuilder.h:
(JSC::ASTBuilder::ASTBuilder):
(JSC::ASTBuilder::setFunctionBodyParameters):
* parser/Nodes.h:
(JSC::FunctionBodyNode::parametersStartOffset):
(JSC::FunctionBodyNode::parametersEndOffset):
(JSC::FunctionBodyNode::setParameterLocation):
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseFunctionInfo):
(JSC::parseParameters):
* parser/Parser.h:
(JSC::parse):
* parser/SourceCode.h:
(JSC::SourceCode::subExpression):
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::setFunctionBodyParameters):

LayoutTests: Don't hold on to parameter BindingNodes forever
https://bugs.webkit.org/show_bug.cgi?id=132360

Reviewed by Geoffrey Garen.

We don't regenerate the parameter string anymore, so these tests now
match the original input.

* js/destructuring-assignment-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (167963 => 167964)


--- trunk/LayoutTests/ChangeLog	2014-04-29 22:21:04 UTC (rev 167963)
+++ trunk/LayoutTests/ChangeLog	2014-04-29 22:23:17 UTC (rev 167964)
@@ -1,3 +1,15 @@
+2014-04-29  Oliver Hunt  <oli...@apple.com>
+
+        Don't hold on to parameter BindingNodes forever
+        https://bugs.webkit.org/show_bug.cgi?id=132360
+
+        Reviewed by Geoffrey Garen.
+
+        We don't regenerate the parameter string anymore, so these tests now
+        match the original input.
+
+        * js/destructuring-assignment-expected.txt:
+
 2014-04-28  Roger Fong  <roger_f...@apple.com>
 
         Plugins hidden by images should autoplay.

Modified: trunk/LayoutTests/js/destructuring-assignment-expected.txt (167963 => 167964)


--- trunk/LayoutTests/js/destructuring-assignment-expected.txt	2014-04-29 22:21:04 UTC (rev 167963)
+++ trunk/LayoutTests/js/destructuring-assignment-expected.txt	2014-04-29 22:23:17 UTC (rev 167964)
@@ -12,7 +12,7 @@
 PASS var {a,b}={a:'1',b:'2'}; var r=a+b; r is '12'
 Function as String: (function({a,b}) { return a+b;})
 PASS (function({a,b}) { return a+b;})({a:'1',b:'2'}) is '12'
-PASS (function ({a:a,b:b}) { return a+b;})({a:'1',b:'2'}) is '12'
+PASS (function ({a,b}) { return a+b;})({a:'1',b:'2'}) is '12'
 PASS ({a,b}={a:'1',b:'2'}); var r=a+b; r is '12'
 PASS var {c:a,d:b}={c:'1',d:'2'}; var r=a+b; r is '12'
 Function as String: (function({c:a,d:b}) { return a+b;})
@@ -27,7 +27,7 @@
 PASS var {true:a,false:b,undefined:c,null:d,in:e,for:f,1.5:g,'foo bar':h}={true:'a',false:'b',undefined:'c',null:'d',in:'e',for:'f',1.5:'g','foo bar':'h'}; var r=a+b+c+d+e+f+g+h; r is 'abcdefgh'
 Function as String: (function({true:a,false:b,undefined:c,null:d,in:e,for:f,1.5:g,'foo bar':h}) { return a+b+c+d+e+f+g+h;})
 PASS (function({true:a,false:b,undefined:c,null:d,in:e,for:f,1.5:g,'foo bar':h}) { return a+b+c+d+e+f+g+h;})({true:'a',false:'b',undefined:'c',null:'d',in:'e',for:'f',1.5:'g','foo bar':'h'}) is 'abcdefgh'
-PASS (function ({true:a,false:b,undefined:c,null:d,in:e,for:f,1.5:g,"foo bar":h}) { return a+b+c+d+e+f+g+h;})({true:'a',false:'b',undefined:'c',null:'d',in:'e',for:'f',1.5:'g','foo bar':'h'}) is 'abcdefgh'
+PASS (function ({true:a,false:b,undefined:c,null:d,in:e,for:f,1.5:g,'foo bar':h}) { return a+b+c+d+e+f+g+h;})({true:'a',false:'b',undefined:'c',null:'d',in:'e',for:'f',1.5:'g','foo bar':'h'}) is 'abcdefgh'
 PASS ({true:a,false:b,undefined:c,null:d,in:e,for:f,1.5:g,'foo bar':h}={true:'a',false:'b',undefined:'c',null:'d',in:'e',for:'f',1.5:'g','foo bar':'h'}); var r=a+b+c+d+e+f+g+h; r is 'abcdefgh'
 PASS var [{c:a,d:b}]=[{c:'1',d:'2'}]; var r=a+b; r is '12'
 Function as String: (function([{c:a,d:b}]) { return a+b;})
@@ -49,7 +49,7 @@
 PASS var {a,b}=anArray; var r=a+b; r is '34'
 Function as String: (function({a,b}) { return a+b;})
 PASS (function({a,b}) { return a+b;})(anArray) is '34'
-PASS (function ({a:a,b:b}) { return a+b;})(anArray) is '34'
+PASS (function ({a,b}) { return a+b;})(anArray) is '34'
 PASS ({a,b}=anArray); var r=a+b; r is '34'
 PASS var {a:a,b:b}=anArray; var r=a+b; r is '34'
 Function as String: (function({a:a,b:b}) { return a+b;})
@@ -59,7 +59,7 @@
 PASS var {a,b}=anObject; var r=a+b; r is '12'
 Function as String: (function({a,b}) { return a+b;})
 PASS (function({a,b}) { return a+b;})(anObject) is '12'
-PASS (function ({a:a,b:b}) { return a+b;})(anObject) is '12'
+PASS (function ({a,b}) { return a+b;})(anObject) is '12'
 PASS ({a,b}=anObject); var r=a+b; r is '12'
 PASS var {a:a,b:b}=anObject; var r=a+b; r is '12'
 Function as String: (function({a:a,b:b}) { return a+b;})
@@ -74,7 +74,7 @@
 PASS var {'a':a,'b':b}=anObject; var r=a+b; r is '12'
 Function as String: (function({'a':a,'b':b}) { return a+b;})
 PASS (function({'a':a,'b':b}) { return a+b;})(anObject) is '12'
-PASS (function ({"a":a,"b":b}) { return a+b;})(anObject) is '12'
+PASS (function ({'a':a,'b':b}) { return a+b;})(anObject) is '12'
 PASS ({'a':a,'b':b}=anObject); var r=a+b; r is '12'
 PASS a+b is '1122'
 PASS a+b is '2211'

Modified: trunk/Source/_javascript_Core/ChangeLog (167963 => 167964)


--- trunk/Source/_javascript_Core/ChangeLog	2014-04-29 22:21:04 UTC (rev 167963)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-04-29 22:23:17 UTC (rev 167964)
@@ -1,3 +1,45 @@
+2014-04-29  Oliver Hunt  <oli...@apple.com>
+
+        Don't hold on to parameterBindingNodes forever
+        https://bugs.webkit.org/show_bug.cgi?id=132360
+
+        Reviewed by Geoffrey Garen.
+
+        Don't keep the parameter nodes anymore. Instead we store the
+        original parameter string and reparse whenever we actually
+        need them. Because we only actually need them for compilation
+        this only results in a single extra parse.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock):
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        (JSC::UnlinkedFunctionExecutable::visitChildren):
+        (JSC::UnlinkedFunctionExecutable::finishCreation):
+        (JSC::UnlinkedFunctionExecutable::paramString):
+        (JSC::UnlinkedFunctionExecutable::parameters):
+        (JSC::UnlinkedFunctionExecutable::parameterCount): Deleted.
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedFunctionExecutable::create):
+        (JSC::UnlinkedFunctionExecutable::parameterCount):
+        (JSC::UnlinkedFunctionExecutable::parameters): Deleted.
+        (JSC::UnlinkedFunctionExecutable::finishCreation): Deleted.
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::ASTBuilder):
+        (JSC::ASTBuilder::setFunctionBodyParameters):
+        * parser/Nodes.h:
+        (JSC::FunctionBodyNode::parametersStartOffset):
+        (JSC::FunctionBodyNode::parametersEndOffset):
+        (JSC::FunctionBodyNode::setParameterLocation):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseFunctionInfo):
+        (JSC::parseParameters):
+        * parser/Parser.h:
+        (JSC::parse):
+        * parser/SourceCode.h:
+        (JSC::SourceCode::subExpression):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::setFunctionBodyParameters):
+
 2014-04-29  Mark Hahnenberg  <mhahnenb...@apple.com>
 
         JSProxies should be cacheable

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp (167963 => 167964)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2014-04-29 22:21:04 UTC (rev 167963)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2014-04-29 22:23:17 UTC (rev 167964)
@@ -51,8 +51,15 @@
 
 static UnlinkedFunctionCodeBlock* generateFunctionCodeBlock(VM& vm, UnlinkedFunctionExecutable* executable, const SourceCode& source, CodeSpecializationKind kind, DebuggerMode debuggerMode, ProfilerMode profilerMode, UnlinkedFunctionKind functionKind, ParserError& error)
 {
-    RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(&vm, source, executable->parameters(), executable->name(), executable->toStrictness(), JSParseFunctionCode, error);
+    RefPtr<FunctionParameters> parameters = executable->parameters(&vm);
+    if (!parameters) {
+        error = ParserError(ParserError::StackOverflow);
+        error.m_line = source.firstLine();
+        return 0;
+    }
 
+    RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(&vm, source, parameters.get(), executable->name(), executable->toStrictness(), JSParseFunctionCode, error);
+
     if (!body) {
         ASSERT(error.m_type != ParserError::ErrorNone);
         return 0;
@@ -60,7 +67,7 @@
 
     if (executable->forceUsesArguments())
         body->setUsesArguments();
-    body->finishParsing(executable->parameters(), executable->name(), executable->functionMode());
+    body->finishParsing(parameters.get(), executable->name(), executable->functionMode());
     executable->recordParse(body->features(), body->hasCapturedVariables());
     
     UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, ExecutableInfo(body->needsActivation(), body->usesEval(), body->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction));
@@ -92,7 +99,7 @@
     , m_isBuiltinFunction(kind == UnlinkedBuiltinFunction)
     , m_name(node->ident())
     , m_inferredName(node->inferredName())
-    , m_parameters(node->parameters())
+    , m_parameterCount(node->parameterCount())
     , m_firstLineOffset(node->firstLine() - source.firstLine())
     , m_lineCount(node->lastLine() - node->firstLine())
     , m_unlinkedFunctionNameStart(node->functionNameStart() - source.startOffset())
@@ -105,11 +112,6 @@
 {
 }
 
-size_t UnlinkedFunctionExecutable::parameterCount() const
-{
-    return m_parameters->size();
-}
-
 void UnlinkedFunctionExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     UnlinkedFunctionExecutable* thisObject = jsCast<UnlinkedFunctionExecutable*>(cell);
@@ -122,6 +124,7 @@
     visitor.append(&thisObject->m_nameValue);
     visitor.append(&thisObject->m_symbolTableForCall);
     visitor.append(&thisObject->m_symbolTableForConstruct);
+    visitor.append(&thisObject->m_parameterString);
 }
 
 FunctionExecutable* UnlinkedFunctionExecutable::link(VM& vm, const SourceCode& source, size_t lineOffset)
@@ -184,18 +187,32 @@
     return result;
 }
 
+void UnlinkedFunctionExecutable::finishCreation(VM& vm, const SourceCode& source, FunctionBodyNode* node)
+{
+    Base::finishCreation(vm);
+    m_nameValue.set(vm, this, jsString(&vm, name().string()));
+    // We make an isolated copy of the parameter string as we don't want to keep the
+    // full source string alive.
+    String parameterString = source.provider()->getRange(node->parametersStartOffset(), node->parametersEndOffset()).isolatedCopy();
+    m_parameterString.set(vm, this, jsString(&vm, parameterString));
+}
+
 String UnlinkedFunctionExecutable::paramString() const
 {
-    FunctionParameters& parameters = *m_parameters;
-    StringBuilder builder;
-    for (size_t pos = 0; pos < parameters.size(); ++pos) {
-        if (!builder.isEmpty())
-            builder.appendLiteral(", ");
-        parameters.at(pos)->toString(builder);
-    }
-    return builder.toString();
+    return m_parameterString->tryGetValue();
 }
 
+RefPtr<FunctionParameters> UnlinkedFunctionExecutable::parameters(VM* vm)
+{
+    if (!m_parameterCount)
+        return FunctionParameters::create(nullptr);
+
+    SourceCode parameterSource = makeSource(m_parameterString->tryGetValue());
+    RefPtr<FunctionParameters> parameters = parseParameters(vm, parameterSource, toStrictness());
+    ASSERT(!parameters || parameters->size() == m_parameterCount);
+    return parameters;
+}
+
 UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
     : Base(*vm, structure)
     , m_numVars(0)

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (167963 => 167964)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h	2014-04-29 22:21:04 UTC (rev 167963)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h	2014-04-29 22:23:17 UTC (rev 167964)
@@ -95,7 +95,7 @@
     static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, bool isFromGlobalCode, UnlinkedFunctionKind unlinkedFunctionKind)
     {
         UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node, isFromGlobalCode, unlinkedFunctionKind);
-        instance->finishCreation(*vm);
+        instance->finishCreation(*vm, source, node);
         return instance;
     }
 
@@ -106,7 +106,7 @@
     {
         return (kind == CodeForCall) ? m_symbolTableForCall.get() : m_symbolTableForConstruct.get();
     }
-    size_t parameterCount() const;
+    size_t parameterCount() const { return m_parameterCount; }
     bool isInStrictContext() const { return m_isInStrictContext; }
     FunctionMode functionMode() const { return m_functionMode; }
     JSParserStrictness toStrictness() const
@@ -142,7 +142,7 @@
         m_codeBlockForConstruct.clear();
     }
 
-    FunctionParameters* parameters() { return m_parameters.get(); }
+    RefPtr<FunctionParameters> parameters(VM*);
 
     void recordParse(CodeFeatures features, bool hasCapturedVariables)
     {
@@ -163,6 +163,7 @@
 
 private:
     UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*, bool isFromGlobalCode, UnlinkedFunctionKind);
+
     WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
     WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
 
@@ -176,9 +177,10 @@
     Identifier m_name;
     Identifier m_inferredName;
     WriteBarrier<JSString> m_nameValue;
+    WriteBarrier<JSString> m_parameterString;
     WriteBarrier<SymbolTable> m_symbolTableForCall;
     WriteBarrier<SymbolTable> m_symbolTableForConstruct;
-    RefPtr<FunctionParameters> m_parameters;
+    unsigned m_parameterCount;
     unsigned m_firstLineOffset;
     unsigned m_lineCount;
     unsigned m_unlinkedFunctionNameStart;
@@ -192,11 +194,7 @@
     FunctionMode m_functionMode;
 
 protected:
-    void finishCreation(VM& vm)
-    {
-        Base::finishCreation(vm);
-        m_nameValue.set(vm, this, jsString(&vm, name().string()));
-    }
+    void finishCreation(VM&, const SourceCode&, FunctionBodyNode*);
 
     static void visitChildren(JSCell*, SlotVisitor&);
 

Modified: trunk/Source/_javascript_Core/parser/ASTBuilder.h (167963 => 167964)


--- trunk/Source/_javascript_Core/parser/ASTBuilder.h	2014-04-29 22:21:04 UTC (rev 167963)
+++ trunk/Source/_javascript_Core/parser/ASTBuilder.h	2014-04-29 22:23:17 UTC (rev 167964)
@@ -76,7 +76,7 @@
         Operator m_op;
     };
 public:
-    ASTBuilder(VM* vm, SourceCode* sourceCode)
+    ASTBuilder(VM* vm, const SourceCode* sourceCode)
         : m_vm(vm)
         , m_sourceCode(sourceCode)
         , m_scope(vm)
@@ -289,6 +289,11 @@
         return FunctionBodyNode::create(m_vm, startLocation, endLocation, startColumn, endColumn, inStrictContext);
     }
 
+    void setFunctionBodyParameters(FunctionBodyNode* body, const JSTokenLocation& openParen, const JSTokenLocation& closeParen)
+    {
+        body->setParameterLocation(openParen, closeParen);
+    }
+
     void setFunctionNameStart(FunctionBodyNode* body, int functionNameStart)
     {
         body->setFunctionNameStart(functionNameStart);
@@ -722,7 +727,7 @@
     }
     
     VM* m_vm;
-    SourceCode* m_sourceCode;
+    const SourceCode* m_sourceCode;
     Scope m_scope;
     Vector<BinaryOperand, 10, UnsafeVectorOverflow> m_binaryOperandStack;
     Vector<AssignmentInfo, 10, UnsafeVectorOverflow> m_assignmentInfoStack;

Modified: trunk/Source/_javascript_Core/parser/Nodes.h (167963 => 167964)


--- trunk/Source/_javascript_Core/parser/Nodes.h	2014-04-29 22:21:04 UTC (rev 167963)
+++ trunk/Source/_javascript_Core/parser/Nodes.h	2014-04-29 22:23:17 UTC (rev 167964)
@@ -1535,6 +1535,8 @@
 
         FunctionParameters* parameters() const { return m_parameters.get(); }
         size_t parameterCount() const { return m_parameters->size(); }
+        int parametersStartOffset() const { return m_parametersStart.endOffset; }
+        int parametersEndOffset() const { return m_parametersEnd.startOffset; }
 
         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
@@ -1557,6 +1559,11 @@
 
         static const bool scopeIsFunction = true;
 
+        void setParameterLocation(const JSTokenLocation& openParen, const JSTokenLocation& closeParen)
+        {
+            m_parametersStart = openParen;
+            m_parametersEnd = closeParen;
+        }
     private:
         FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, bool inStrictContext);
         FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
@@ -1565,6 +1572,8 @@
         Identifier m_inferredName;
         FunctionMode m_functionMode;
         RefPtr<FunctionParameters> m_parameters;
+        JSTokenLocation m_parametersStart;
+        JSTokenLocation m_parametersEnd;
         int m_functionNameStart;
         unsigned m_startColumn;
         unsigned m_endColumn;

Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (167963 => 167964)


--- trunk/Source/_javascript_Core/parser/Parser.cpp	2014-04-29 22:21:04 UTC (rev 167963)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp	2014-04-29 22:23:17 UTC (rev 167964)
@@ -1248,6 +1248,7 @@
         failDueToUnexpectedToken();
         return false;
     }
+    JSTokenLocation openParen = tokenLocation();
     if (!consume(OPENPAREN)) {
         semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
         failWithMessage("Expected an opening '(' before a ", stringForFunctionMode(mode), "'s parameter list");
@@ -1256,6 +1257,7 @@
         parameters = parseFormalParameters(context);
         failIfFalse(parameters, "Cannot parse parameters for this ", stringForFunctionMode(mode));
     }
+    JSTokenLocation endParen = m_token.m_location;
     consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
     matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body");
     
@@ -1281,7 +1283,7 @@
             endLocation.startOffset - endLocation.lineStartOffset;
 
         body = context.createFunctionBody(startLocation, endLocation, bodyStartColumn, bodyEndColumn, cachedInfo->strictMode);
-        
+        context.setFunctionBodyParameters(body, openParen, endParen);
         functionScope->restoreFromSourceProviderCache(cachedInfo);
         failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error");
         
@@ -1301,6 +1303,7 @@
     body = parseFunctionBody(context);
     restoreState(oldState);
     failIfFalse(body, "Cannot parse the body of this ", stringForFunctionMode(mode));
+    context.setFunctionBodyParameters(body, openParen, endParen);
     if (functionScope->strictMode() && name) {
         RELEASE_ASSERT(mode == FunctionMode);
         semanticFailIfTrue(m_vm->propertyNames->arguments == *name, "'", name->impl(), "' is not a valid function name in strict mode");
@@ -2404,6 +2407,25 @@
     out.print("Unexpected token '", getToken(), "'");
 }
 
+PassRefPtr<FunctionParameters> parseParameters(VM* vm, const SourceCode& source, JSParserStrictness strictness)
+{
+    SamplingRegion samplingRegion("Parsing parameters");
+    ParameterNode* parameters = 0;
+    ASSERT(!source.provider()->source().isNull());
+    if (source.provider()->source().is8Bit()) {
+        Parser<Lexer<LChar>> parser(vm, source, 0, Identifier(), strictness, JSParseFunctionCode);
+        ASTBuilder builder(vm, &source);
+        parameters = parser.parseFormalParameters(builder);
+    } else {
+        Parser<Lexer<UChar>> parser(vm, source, 0, Identifier(), strictness, JSParseFunctionCode);
+        ASTBuilder builder(vm, &source);
+        parameters = parser.parseFormalParameters(builder);
+    }
+    if (!parameters)
+        return nullptr;
+    return FunctionParameters::create(parameters);
+}
+
 // Instantiate the two flavors of Parser we need instead of putting most of this file in Parser.h
 template class Parser<Lexer<LChar>>;
 template class Parser<Lexer<UChar>>;

Modified: trunk/Source/_javascript_Core/parser/Parser.h (167963 => 167964)


--- trunk/Source/_javascript_Core/parser/Parser.h	2014-04-29 22:21:04 UTC (rev 167963)
+++ trunk/Source/_javascript_Core/parser/Parser.h	2014-04-29 22:23:17 UTC (rev 167964)
@@ -409,6 +409,7 @@
 class Parser {
     WTF_MAKE_NONCOPYABLE(Parser);
     WTF_MAKE_FAST_ALLOCATED;
+    friend PassRefPtr<FunctionParameters> parseParameters(VM*, const SourceCode&, JSParserStrictness);
 
 public:
     Parser(VM*, const SourceCode&, FunctionParameters*, const Identifier&, JSParserStrictness, JSParserMode);
@@ -972,6 +973,7 @@
         }
         return result.release();
     }
+    RELEASE_ASSERT(strictness != JSParseBuiltin);
     Parser<Lexer<UChar>> parser(vm, source, parameters, name, strictness, parserMode);
     RefPtr<ParsedNode> result = parser.parse<ParsedNode>(error);
     if (positionBeforeLastNewline)
@@ -979,5 +981,7 @@
     return result.release();
 }
 
+PassRefPtr<FunctionParameters> parseParameters(VM*, const SourceCode&, JSParserStrictness);
+
 } // namespace
 #endif

Modified: trunk/Source/_javascript_Core/parser/SourceCode.h (167963 => 167964)


--- trunk/Source/_javascript_Core/parser/SourceCode.h	2014-04-29 22:21:04 UTC (rev 167963)
+++ trunk/Source/_javascript_Core/parser/SourceCode.h	2014-04-29 22:23:17 UTC (rev 167964)
@@ -103,7 +103,7 @@
         int endOffset() const { return m_endChar; }
         int length() const { return m_endChar - m_startChar; }
         
-        SourceCode subExpression(unsigned openBrace, unsigned closeBrace, int firstLine, int startColumn);
+        SourceCode subExpression(unsigned openBrace, unsigned closeBrace, int firstLine, int startColumn) const;
 
     private:
         RefPtr<SourceProvider> m_provider;
@@ -118,7 +118,7 @@
         return SourceCode(StringSourceProvider::create(source, url, startPosition), startPosition.m_line.oneBasedInt(), startPosition.m_column.oneBasedInt());
     }
 
-    inline SourceCode SourceCode::subExpression(unsigned openBrace, unsigned closeBrace, int firstLine, int startColumn)
+    inline SourceCode SourceCode::subExpression(unsigned openBrace, unsigned closeBrace, int firstLine, int startColumn) const
     {
         ASSERT(provider()->source()[openBrace] == '{');
         ASSERT(provider()->source()[closeBrace] == '}');

Modified: trunk/Source/_javascript_Core/parser/SyntaxChecker.h (167963 => 167964)


--- trunk/Source/_javascript_Core/parser/SyntaxChecker.h	2014-04-29 22:21:04 UTC (rev 167963)
+++ trunk/Source/_javascript_Core/parser/SyntaxChecker.h	2014-04-29 22:23:17 UTC (rev 167964)
@@ -160,6 +160,7 @@
     ExpressionType createAssignResolve(const JSTokenLocation&, const Identifier&, ExpressionType, int, int, int) { return AssignmentExpr; }
     ExpressionType createFunctionExpr(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int) { return FunctionExpr; }
     int createFunctionBody(const JSTokenLocation&, const JSTokenLocation&, int, int, bool) { return FunctionBodyResult; }
+    void setFunctionBodyParameters(int, const JSTokenLocation&, const JSTokenLocation&) { }
     void setFunctionNameStart(int, int) { }
     int createArguments() { return ArgumentsResult; }
     int createArguments(int) { return ArgumentsResult; }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to