+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
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 */,
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;
}
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(); }
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;
}
}
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();
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");
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;
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;
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;
// 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;
}
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 {
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;
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;
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);
#include "Nodes.h"
#include "ParserArena.h"
#include "ParserError.h"
+#include "ParserFunctionInfo.h"
#include "ParserTokens.h"
#include "SourceProvider.h"
#include "SourceProviderCache.h"
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();
--- /dev/null
+/*
+ * 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
#define SyntaxChecker_h
#include "Lexer.h"
+#include "ParserFunctionInfo.h"
#include "YarrSyntaxChecker.h"
namespace JSC {
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; }
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; }
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);