Consolidate out arguments of parseFunctionInfo into a struct
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 22 Jan 2015 06:39:31 +0000 (06:39 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 22 Jan 2015 06:39:31 +0000 (06:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=140754

Reviewed by Oliver Hunt.

Introduced ParserFunctionInfo for storing out arguments of parseFunctionInfo.

* JavaScriptCore.xcodeproj/project.pbxproj:
* parser/ASTBuilder.h:
(JSC::ASTBuilder::createFunctionExpr):
(JSC::ASTBuilder::createGetterOrSetterProperty): This one takes a property name in addition to
ParserFunctionInfo since the property name and the function name could differ.
(JSC::ASTBuilder::createFuncDeclStatement):
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseFunctionInfo):
(JSC::Parser<LexerType>::parseFunctionDeclaration):
(JSC::Parser<LexerType>::parseProperty):
(JSC::Parser<LexerType>::parseMemberExpression):
* parser/Parser.h:
* parser/ParserFunctionInfo.h: Added.
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createFunctionExpr):
(JSC::SyntaxChecker::createFuncDeclStatement):
(JSC::SyntaxChecker::createClassDeclStatement):
(JSC::SyntaxChecker::createGetterOrSetterProperty):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@178888 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/parser/ASTBuilder.h
Source/JavaScriptCore/parser/Parser.cpp
Source/JavaScriptCore/parser/Parser.h
Source/JavaScriptCore/parser/ParserFunctionInfo.h [new file with mode: 0644]
Source/JavaScriptCore/parser/SyntaxChecker.h

index d56d34e7ef83d05d86430779edbc3b4d8c79217d..e813153c4b57208b037ad6cd6cd42abbca83611a 100644 (file)
@@ -1,3 +1,31 @@
+2015-01-21  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Consolidate out arguments of parseFunctionInfo into a struct
+        https://bugs.webkit.org/show_bug.cgi?id=140754
+
+        Reviewed by Oliver Hunt.
+
+        Introduced ParserFunctionInfo for storing out arguments of parseFunctionInfo.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createFunctionExpr):
+        (JSC::ASTBuilder::createGetterOrSetterProperty): This one takes a property name in addition to
+        ParserFunctionInfo since the property name and the function name could differ.
+        (JSC::ASTBuilder::createFuncDeclStatement):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseFunctionInfo):
+        (JSC::Parser<LexerType>::parseFunctionDeclaration):
+        (JSC::Parser<LexerType>::parseProperty):
+        (JSC::Parser<LexerType>::parseMemberExpression):
+        * parser/Parser.h:
+        * parser/ParserFunctionInfo.h: Added.
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createFunctionExpr):
+        (JSC::SyntaxChecker::createFuncDeclStatement):
+        (JSC::SyntaxChecker::createClassDeclStatement):
+        (JSC::SyntaxChecker::createGetterOrSetterProperty):
+
 2015-01-21  Mark Hahnenberg  <mhahnenb@gmail.com>
 
         Change Heap::m_compiledCode to use a Vector
index e79d7c1e5e85d21306129fa98e6bd9933f4e124e..4ffe6a0f26e26f73de16d47392cf4c383ad542a1 100644 (file)
                99E45A2118A1B2590026D88F /* EncodedValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EncodedValue.h; sourceTree = "<group>"; };
                99E45A2218A1B2590026D88F /* InputCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputCursor.h; sourceTree = "<group>"; };
                99E45A2318A1B2590026D88F /* NondeterministicInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NondeterministicInput.h; sourceTree = "<group>"; };
+               9B4954E81A6640DB002815A6 /* ParserFunctionInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ParserFunctionInfo.h; sourceTree = "<group>"; };
                9E729409190F0306001A91B5 /* BundlePath.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BundlePath.mm; sourceTree = "<group>"; };
                9E72940A190F0514001A91B5 /* BundlePath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BundlePath.h; sourceTree = "<group>"; };
                9EA5C7A0190F05D200508EBE /* InitializeLLVMMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InitializeLLVMMac.cpp; path = llvm/InitializeLLVMMac.cpp; sourceTree = "<group>"; };
                                93052C320FB792190048FDC3 /* ParserArena.cpp */,
                                93052C330FB792190048FDC3 /* ParserArena.h */,
                                0FCCAE4316D0CF6E00D0C65B /* ParserError.h */,
+                               9B4954E81A6640DB002815A6 /* ParserFunctionInfo.h */,
                                A77F18241641925400640A47 /* ParserModes.h */,
                                65303D631447B9E100D3F904 /* ParserTokens.h */,
                                869EBCB60E8C6D4A008722CC /* ResultType.h */,
index 94b3063de57f0bced423a8a65d2c2fb7559c90cc..16573a66a590542c5b7f17d17457569d06f4381b 100644 (file)
@@ -273,11 +273,12 @@ public:
         return node;
     }
 
-    ExpressionNode* createFunctionExpr(const JSTokenLocation& location, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, unsigned openBraceOffset, unsigned closeBraceOffset, int bodyStartLine, int bodyEndLine, unsigned startColumn, unsigned functionKeywordStart)
+    ExpressionNode* createFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& info, unsigned functionKeywordStart)
     {
-        FuncExprNode* result = new (m_parserArena) FuncExprNode(location, *name, body, m_sourceCode->subExpression(openBraceOffset, closeBraceOffset, bodyStartLine, startColumn), parameters);
-        body->setLoc(bodyStartLine, bodyEndLine, location.startOffset, location.lineStartOffset);
-        body->setFunctionKeywordStart(functionKeywordStart);
+        FuncExprNode* result = new (m_parserArena) FuncExprNode(location, *info.name, info.body,
+            m_sourceCode->subExpression(info.openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn), info.parameters);
+        info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset);
+        info.body->setFunctionKeywordStart(functionKeywordStart);
         return result;
     }
 
@@ -291,20 +292,24 @@ public:
         body->setFunctionNameStart(functionNameStart);
     }
     
-    NEVER_INLINE PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type, bool, const Identifier* name, ParameterNode* params, FunctionBodyNode* body, unsigned openBraceOffset, unsigned closeBraceOffset, int bodyStartLine, int bodyEndLine, unsigned bodyStartColumn, unsigned getOrSetStartOffset)
+    NEVER_INLINE PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type, bool,
+        const Identifier* name, const ParserFunctionInfo<ASTBuilder>& info, unsigned getOrSetStartOffset)
     {
         ASSERT(name);
-        body->setLoc(bodyStartLine, bodyEndLine, location.startOffset, location.lineStartOffset);
-        body->setInferredName(*name);
-        body->setFunctionKeywordStart(getOrSetStartOffset);
-        return new (m_parserArena) PropertyNode(*name, new (m_parserArena) FuncExprNode(location, m_vm->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn), params), type);
+        info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset);
+        info.body->setInferredName(*name);
+        info.body->setFunctionKeywordStart(getOrSetStartOffset);
+        return new (m_parserArena) PropertyNode(*name, new (m_parserArena) FuncExprNode(location, m_vm->propertyNames->nullIdentifier,
+            info.body, m_sourceCode->subExpression(info.openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn), info.parameters), type);
     }
     
-    NEVER_INLINE PropertyNode* createGetterOrSetterProperty(VM* vm, ParserArena& parserArena, const JSTokenLocation& location, PropertyNode::Type type, bool, double name, ParameterNode* params, FunctionBodyNode* body, unsigned openBraceOffset, unsigned closeBraceOffset, int bodyStartLine, int bodyEndLine, unsigned bodyStartColumn, unsigned getOrSetStartOffset)
+    NEVER_INLINE PropertyNode* createGetterOrSetterProperty(VM* vm, ParserArena& parserArena, const JSTokenLocation& location, PropertyNode::Type type, bool, double name, const ParserFunctionInfo<ASTBuilder>& info, unsigned getOrSetStartOffset)
     {
-        body->setLoc(bodyStartLine, bodyEndLine, location.startOffset, location.lineStartOffset);
-        body->setFunctionKeywordStart(getOrSetStartOffset);
-        return new (m_parserArena) PropertyNode(parserArena.identifierArena().makeNumericIdentifier(vm, name), new (m_parserArena) FuncExprNode(location, vm->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn), params), type);
+        info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset);
+        info.body->setFunctionKeywordStart(getOrSetStartOffset);
+        const Identifier& ident = parserArena.identifierArena().makeNumericIdentifier(vm, name);
+        return new (m_parserArena) PropertyNode(ident, new (m_parserArena) FuncExprNode(location, vm->propertyNames->nullIdentifier,
+            info.body, m_sourceCode->subExpression(info.openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn), info.parameters), type);
     }
 
     ArgumentsNode* createArguments() { return new (m_parserArena) ArgumentsNode(); }
@@ -336,14 +341,15 @@ public:
     ClauseListNode* createClauseList(CaseClauseNode* clause) { return new (m_parserArena) ClauseListNode(clause); }
     ClauseListNode* createClauseList(ClauseListNode* tail, CaseClauseNode* clause) { return new (m_parserArena) ClauseListNode(tail, clause); }
 
-    StatementNode* createFuncDeclStatement(const JSTokenLocation& location, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, unsigned openBraceOffset, unsigned closeBraceOffset, int bodyStartLine, int bodyEndLine, unsigned bodyStartColumn, unsigned functionKeywordStart)
+    StatementNode* createFuncDeclStatement(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& info, unsigned functionKeywordStart)
     {
-        FuncDeclNode* decl = new (m_parserArena) FuncDeclNode(location, *name, body, m_sourceCode->subExpression(openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn), parameters);
-        if (*name == m_vm->propertyNames->arguments)
+        FuncDeclNode* decl = new (m_parserArena) FuncDeclNode(location, *info.name, info.body,
+            m_sourceCode->subExpression(info.openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn), info.parameters);
+        if (*info.name == m_vm->propertyNames->arguments)
             usesArguments();
         m_scope.m_funcDeclarations.append(decl->body());
-        body->setLoc(bodyStartLine, bodyEndLine, location.startOffset, location.lineStartOffset);
-        body->setFunctionKeywordStart(functionKeywordStart);
+        info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset);
+        info.body->setFunctionKeywordStart(functionKeywordStart);
         return decl;
     }
 
index 46439d5d2840069c80e466752c12a4a30205e5af..cc068fe67561976a29a2c0e27cd63fc92f32bbb7 100644 (file)
@@ -1273,7 +1273,7 @@ static const char* stringForFunctionMode(FunctionParseMode mode)
 }
 
 template <typename LexerType>
-template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, FunctionParseMode mode, bool nameIsInContainingScope, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, unsigned& openBraceOffset, unsigned& closeBraceOffset, int& bodyStartLine, unsigned& bodyStartColumn)
+template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, FunctionParseMode mode, bool nameIsInContainingScope, ParserFunctionInfo<TreeBuilder>& info)
 {
     AutoPopScopeRef functionScope(this, pushScope());
     functionScope->setIsFunction();
@@ -1281,11 +1281,11 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
     const Identifier* lastFunctionName = m_lastFunctionName;
     m_lastFunctionName = nullptr;
     if (match(IDENT)) {
-        name = m_token.m_data.ident;
-        m_lastFunctionName = name;
+        info.name = m_token.m_data.ident;
+        m_lastFunctionName = info.name;
         next();
         if (!nameIsInContainingScope)
-            failIfFalseIfStrict(functionScope->declareVariable(name), "'", name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode");
+            failIfFalseIfStrict(functionScope->declareVariable(info.name), "'", info.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode");
     } else if (requirements == FunctionNeedsName) {
         if (match(OPENPAREN) && mode == FunctionMode)
             semanticFail("Function statements must have a name");
@@ -1298,19 +1298,19 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
         failWithMessage("Expected an opening '(' before a ", stringForFunctionMode(mode), "'s parameter list");
     }
     if (!match(CLOSEPAREN)) {
-        parameters = parseFormalParameters(context);
-        failIfFalse(parameters, "Cannot parse parameters for this ", stringForFunctionMode(mode));
+        info.parameters = parseFormalParameters(context);
+        failIfFalse(info.parameters, "Cannot parse parameters for this ", stringForFunctionMode(mode));
     }
     consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
     matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body");
     
-    openBraceOffset = m_token.m_data.offset;
-    bodyStartLine = tokenLine();
-    bodyStartColumn = m_token.m_data.offset - m_token.m_data.lineStartOffset;
+    info.openBraceOffset = m_token.m_data.offset;
+    info.bodyStartLine = tokenLine();
+    info.bodyStartColumn = m_token.m_data.offset - m_token.m_data.lineStartOffset;
     JSTokenLocation startLocation(tokenLocation());
     
     // If we know about this function already, we can use the cached info and skip the parser to the end of the function.
-    if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(openBraceOffset) : 0) {
+    if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(info.openBraceOffset) : 0) {
         // If we're in a strict context, the cached function info must say it was strict too.
         ASSERT(!strictMode() || cachedInfo->strictMode);
         JSTokenLocation endLocation;
@@ -1319,21 +1319,21 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
         endLocation.startOffset = cachedInfo->closeBraceOffset;
         endLocation.lineStartOffset = cachedInfo->closeBraceLineStartOffset;
 
-        bool endColumnIsOnStartLine = (endLocation.line == bodyStartLine);
+        bool endColumnIsOnStartLine = (endLocation.line == info.bodyStartLine);
         ASSERT(endLocation.startOffset >= endLocation.lineStartOffset);
         unsigned bodyEndColumn = endColumnIsOnStartLine ?
             endLocation.startOffset - m_token.m_data.lineStartOffset :
             endLocation.startOffset - endLocation.lineStartOffset;
         unsigned currentLineStartOffset = m_token.m_location.lineStartOffset;
 
-        body = context.createFunctionBody(startLocation, endLocation, bodyStartColumn, bodyEndColumn, cachedInfo->strictMode);
+        info.body = context.createFunctionBody(startLocation, endLocation, info.bodyStartColumn, bodyEndColumn, cachedInfo->strictMode);
         
         functionScope->restoreFromSourceProviderCache(cachedInfo);
         failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error");
         
-        closeBraceOffset = cachedInfo->closeBraceOffset;
+        info.closeBraceOffset = cachedInfo->closeBraceOffset;
 
-        context.setFunctionNameStart(body, functionNameStart);
+        context.setFunctionNameStart(info.body, functionNameStart);
         m_token = cachedInfo->closeBraceToken();
         if (endColumnIsOnStartLine)
             m_token.m_location.lineStartOffset = currentLineStartOffset;
@@ -1341,23 +1341,24 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
         m_lexer->setOffset(m_token.m_location.endOffset, m_token.m_location.lineStartOffset);
         m_lexer->setLineNumber(m_token.m_location.line);
 
-        context.setEndOffset(body, m_lexer->currentOffset());
+        context.setEndOffset(info.body, m_lexer->currentOffset());
         
         next();
+        info.bodyEndLine = m_lastTokenEndPosition.line;
         return true;
     }
     m_lastFunctionName = lastFunctionName;
     ParserState oldState = saveState();
-    body = parseFunctionBody(context);
+    info.body = parseFunctionBody(context);
     restoreState(oldState);
-    failIfFalse(body, "Cannot parse the body of this ", stringForFunctionMode(mode));
-    context.setEndOffset(body, m_lexer->currentOffset());
-    if (functionScope->strictMode() && name) {
+    failIfFalse(info.body, "Cannot parse the body of this ", stringForFunctionMode(mode));
+    context.setEndOffset(info.body, m_lexer->currentOffset());
+    if (functionScope->strictMode() && info.name) {
         RELEASE_ASSERT(mode == FunctionMode);
-        semanticFailIfTrue(m_vm->propertyNames->arguments == *name, "'", name->impl(), "' is not a valid function name in strict mode");
-        semanticFailIfTrue(m_vm->propertyNames->eval == *name, "'", name->impl(), "' is not a valid function name in strict mode");
+        semanticFailIfTrue(m_vm->propertyNames->arguments == *info.name, "'", info.name->impl(), "' is not a valid function name in strict mode");
+        semanticFailIfTrue(m_vm->propertyNames->eval == *info.name, "'", info.name->impl(), "' is not a valid function name in strict mode");
     }
-    closeBraceOffset = m_token.m_data.offset;
+    info.closeBraceOffset = m_token.m_data.offset;
     unsigned closeBraceLine = m_token.m_data.line;
     unsigned closeBraceLineStartOffset = m_token.m_data.lineStartOffset;
     
@@ -1365,26 +1366,27 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
     // Any future reparsing can then skip the function.
     static const int minimumFunctionLengthToCache = 16;
     std::unique_ptr<SourceProviderCacheItem> newInfo;
-    int functionLength = closeBraceOffset - openBraceOffset;
+    int functionLength = info.closeBraceOffset - info.openBraceOffset;
     if (TreeBuilder::CanUseFunctionCache && m_functionCache && functionLength > minimumFunctionLengthToCache) {
         SourceProviderCacheItemCreationParameters parameters;
         parameters.functionNameStart = functionNameStart;
         parameters.closeBraceLine = closeBraceLine;
-        parameters.closeBraceOffset = closeBraceOffset;
+        parameters.closeBraceOffset = info.closeBraceOffset;
         parameters.closeBraceLineStartOffset = closeBraceLineStartOffset;
         functionScope->fillParametersForSourceProviderCache(parameters);
         newInfo = SourceProviderCacheItem::create(parameters);
 
     }
-    context.setFunctionNameStart(body, functionNameStart);
+    context.setFunctionNameStart(info.body, functionNameStart);
     
     failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error");
     matchOrFail(CLOSEBRACE, "Expected a closing '}' after a ", stringForFunctionMode(mode), " body");
     
     if (newInfo)
-        m_functionCache->add(openBraceOffset, WTF::move(newInfo));
+        m_functionCache->add(info.openBraceOffset, WTF::move(newInfo));
     
     next();
+    info.bodyEndLine = m_lastTokenEndPosition.line;
     return true;
 }
 
@@ -1395,17 +1397,11 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla
     JSTokenLocation location(tokenLocation());
     unsigned functionKeywordStart = tokenStart();
     next();
-    const Identifier* name = 0;
-    TreeFormalParameterList parameters = 0;
-    TreeFunctionBody body = 0;
-    unsigned openBraceOffset = 0;
-    unsigned closeBraceOffset = 0;
-    int bodyStartLine = 0;
-    unsigned bodyStartColumn = 0;
-    failIfFalse((parseFunctionInfo(context, FunctionNeedsName, FunctionMode, true, name, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)), "Cannot parse this function");
-    failIfFalse(name, "Function statements must have a name");
-    failIfFalseIfStrict(declareVariable(name), "Cannot declare a function named '", name->impl(), "' in strict mode");
-    return context.createFuncDeclStatement(location, name, body, parameters, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn, functionKeywordStart);
+    ParserFunctionInfo<TreeBuilder> info;
+    failIfFalse((parseFunctionInfo(context, FunctionNeedsName, FunctionMode, true, info)), "Cannot parse this function");
+    failIfFalse(info.name, "Function statements must have a name");
+    failIfFalseIfStrict(declareVariable(info.name), "Cannot declare a function named '", info.name->impl(), "' in strict mode");
+    return context.createFuncDeclStatement(location, info, functionKeywordStart);
 }
 
 struct LabelInfo {
@@ -1799,13 +1795,6 @@ template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
             return context.createProperty(ident, node, PropertyNode::Constant, complete);
         }
         failIfFalse(wasIdent, "Expected an identifier as property name");
-        const Identifier* accessorName = 0;
-        TreeFormalParameterList parameters = 0;
-        TreeFunctionBody body = 0;
-        unsigned openBraceOffset = 0;
-        unsigned closeBraceOffset = 0;
-        int bodyStartLine = 0;
-        unsigned bodyStartColumn = 0;
         PropertyNode::Type type;
         if (*ident == m_vm->propertyNames->get)
             type = PropertyNode::Getter;
@@ -1823,16 +1812,17 @@ template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
             failDueToUnexpectedToken();
         JSTokenLocation location(tokenLocation());
         next();
+        ParserFunctionInfo<TreeBuilder> info;
         if (type == PropertyNode::Getter) {
             failIfFalse(match(OPENPAREN), "Expected a parameter list for getter definition");
-            failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, GetterMode, false, accessorName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)), "Cannot parse getter definition");
+            failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, GetterMode, false, info)), "Cannot parse getter definition");
         } else {
             failIfFalse(match(OPENPAREN), "Expected a parameter list for setter definition");
-            failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SetterMode, false, accessorName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)), "Cannot parse setter definition");
+            failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SetterMode, false, info)), "Cannot parse setter definition");
         }
         if (stringPropertyName)
-            return context.createGetterOrSetterProperty(location, type, complete, stringPropertyName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn, getterOrSetterStartOffset);
-        return context.createGetterOrSetterProperty(const_cast<VM*>(m_vm), m_parserArena, location, type, complete, numericPropertyName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn, getterOrSetterStartOffset);
+            return context.createGetterOrSetterProperty(location, type, complete, stringPropertyName, info, getterOrSetterStartOffset);
+        return context.createGetterOrSetterProperty(const_cast<VM*>(m_vm), m_parserArena, location, type, complete, numericPropertyName, info, getterOrSetterStartOffset);
     }
     case NUMBER: {
         double propertyName = m_token.m_data.doubleValue;
@@ -2172,20 +2162,15 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
         next();
         newCount++;
     }
-    
+
     if (match(FUNCTION)) {
-        const Identifier* name = &m_vm->propertyNames->nullIdentifier;
-        TreeFormalParameterList parameters = 0;
-        TreeFunctionBody body = 0;
-        unsigned openBraceOffset = 0;
-        unsigned closeBraceOffset = 0;
-        int bodyStartLine = 0;
-        unsigned bodyStartColumn = 0;
         unsigned functionKeywordStart = tokenStart();
         location = tokenLocation();
         next();
-        failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, false, name, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)), "Cannot parse function expression");
-        base = context.createFunctionExpr(location, name, body, parameters, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn, functionKeywordStart);
+        ParserFunctionInfo<TreeBuilder> info;
+        info.name = &m_vm->propertyNames->nullIdentifier;
+        failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, false, info)), "Cannot parse function expression");
+        base = context.createFunctionExpr(location, info, functionKeywordStart);
     } else
         base = parsePrimaryExpression(context);
     
index 764e3d33a91a7fac8acbaf325edbc1ec4f99d2ec..755dc76206bdae11c60b97c7fc46d48c99eeb8f5 100644 (file)
@@ -31,6 +31,7 @@
 #include "Nodes.h"
 #include "ParserArena.h"
 #include "ParserError.h"
+#include "ParserFunctionInfo.h"
 #include "ParserTokens.h"
 #include "SourceProvider.h"
 #include "SourceProviderCache.h"
@@ -733,7 +734,9 @@ private:
     template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern createBindingPattern(TreeBuilder&, DeconstructionKind, const Identifier&, int depth, JSToken);
     template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern parseDeconstructionPattern(TreeBuilder&, DeconstructionKind, int depth = 0);
     template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern tryParseDeconstructionPatternExpression(TreeBuilder&);
-    template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, unsigned& openBraceOffset, unsigned& closeBraceOffset, int& bodyStartLine, unsigned& bodyStartColumn);
+
+    template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, ParserFunctionInfo<TreeBuilder>&);
+
     ALWAYS_INLINE int isBinaryOperator(JSTokenType);
     bool allowAutomaticSemicolon();
     
diff --git a/Source/JavaScriptCore/parser/ParserFunctionInfo.h b/Source/JavaScriptCore/parser/ParserFunctionInfo.h
new file mode 100644 (file)
index 0000000..e208245
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ParserFunctionInfo_h
+#define ParserFunctionInfo_h
+
+namespace JSC {
+
+template <class TreeBuilder>
+struct ParserFunctionInfo {
+    const Identifier* name = 0;
+    typename TreeBuilder::FormalParameterList parameters = 0;
+    typename TreeBuilder::FunctionBody body = 0;
+    unsigned openBraceOffset = 0;
+    unsigned closeBraceOffset = 0;
+    int bodyStartLine = 0;
+    int bodyEndLine = 0;
+    unsigned bodyStartColumn = 0;
+};
+
+}
+
+#endif
index fd14521fd2dac2f8cfc0bfc8ac4b0d753a22196e..eee25651b6db00411cfe62dfb22800f65076e1af 100644 (file)
@@ -27,6 +27,7 @@
 #define SyntaxChecker_h
 
 #include "Lexer.h"
+#include "ParserFunctionInfo.h"
 #include "YarrSyntaxChecker.h"
 
 namespace JSC {
@@ -159,7 +160,7 @@ public:
     ExpressionType createConditionalExpr(const JSTokenLocation&, ExpressionType, ExpressionType, ExpressionType) { return ConditionalExpr; }
     ExpressionType createAssignResolve(const JSTokenLocation&, const Identifier&, ExpressionType, int, int, int) { return AssignmentExpr; }
     ExpressionType createEmptyVarExpression(const JSTokenLocation&, const Identifier&) { return AssignmentExpr; }
-    ExpressionType createFunctionExpr(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int, int) { return FunctionExpr; }
+    ExpressionType createFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&, int) { return FunctionExpr; }
     int createFunctionBody(const JSTokenLocation&, const JSTokenLocation&, int, int, bool) { return FunctionBodyResult; }
     void setFunctionNameStart(int, int) { }
     int createArguments() { return ArgumentsResult; }
@@ -193,7 +194,8 @@ public:
     int createClause(int, int) { return ClauseResult; }
     int createClauseList(int) { return ClauseListResult; }
     int createClauseList(int, int) { return ClauseListResult; }
-    int createFuncDeclStatement(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int, int) { return StatementResult; }
+    int createFuncDeclStatement(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&, int) { return StatementResult; }
+    int createClassDeclStatement(const JSTokenLocation&, const Identifier&, ExpressionType, ExpressionType, PropertyList, PropertyList, int, int) { return StatementResult; }
     int createBlockStatement(const JSTokenLocation&, int, int, int) { return StatementResult; }
     int createExprStatement(const JSTokenLocation&, int, int, int) { return StatementResult; }
     int createIfStatement(const JSTokenLocation&, int, int, int, int) { return StatementResult; }
@@ -218,14 +220,14 @@ public:
     int createDebugger(const JSTokenLocation&, int, int) { return StatementResult; }
     int createConstStatement(const JSTokenLocation&, int, int, int) { return StatementResult; }
     int appendConstDecl(const JSTokenLocation&, int, const Identifier*, int) { return StatementResult; }
-    Property createGetterOrSetterProperty(const JSTokenLocation&, PropertyNode::Type type, bool strict, const Identifier* name, int, int, int, int, int, int, int, int)
+    Property createGetterOrSetterProperty(const JSTokenLocation&, PropertyNode::Type type, bool strict, const Identifier* name, const ParserFunctionInfo<SyntaxChecker>&, unsigned)
     {
         ASSERT(name);
         if (!strict)
             return Property(type);
         return Property(name, type);
     }
-    Property createGetterOrSetterProperty(VM* vm, ParserArena& parserArena, const JSTokenLocation&, PropertyNode::Type type, bool strict, double name, int, int, int, int, int, int, int, int)
+    Property createGetterOrSetterProperty(VM* vm, ParserArena& parserArena, const JSTokenLocation&, PropertyNode::Type type, bool strict, double name, const ParserFunctionInfo<SyntaxChecker>&, unsigned)
     {
         if (!strict)
             return Property(type);