diff options
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore/parser')
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/parser/Grammar.y | 493 | ||||
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/parser/Lexer.cpp | 118 | ||||
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/parser/Lexer.h | 22 | ||||
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/parser/NodeConstructors.h | 58 | ||||
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp | 435 | ||||
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/parser/Nodes.h | 368 | ||||
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/parser/Parser.cpp | 29 | ||||
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/parser/Parser.h | 57 | ||||
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.cpp | 72 | ||||
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.h | 82 | ||||
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/parser/SourceCode.h | 3 |
11 files changed, 808 insertions, 929 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Grammar.y b/src/3rdparty/webkit/JavaScriptCore/parser/Grammar.y index 354c78630..6d953dfed 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Grammar.y +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Grammar.y @@ -25,18 +25,13 @@ #include "config.h" -#include <string.h> -#include <stdlib.h> -#include "JSValue.h" #include "JSObject.h" -#include "NodeConstructors.h" -#include "Lexer.h" #include "JSString.h" -#include "JSGlobalData.h" -#include "CommonIdentifiers.h" +#include "Lexer.h" +#include "NodeConstructors.h" #include "NodeInfo.h" -#include "Parser.h" -#include <wtf/FastMalloc.h> +#include <stdlib.h> +#include <string.h> #include <wtf/MathExtras.h> #define YYMALLOC fastMalloc @@ -45,46 +40,43 @@ #define YYMAXDEPTH 10000 #define YYENABLE_NLS 0 -/* default values for bison */ +// Default values for bison. #define YYDEBUG 0 // Set to 1 to debug a parse error. #define jscyydebug 0 // Set to 1 to debug a parse error. #if !PLATFORM(DARWIN) - // avoid triggering warnings in older bison +// Avoid triggering warnings in older bison by not setting this on the Darwin platform. +// FIXME: Is this still needed? #define YYERROR_VERBOSE #endif -int jscyylex(void* lvalp, void* llocp, void* globalPtr); int jscyyerror(const char*); + static inline bool allowAutomaticSemicolon(JSC::Lexer&, int); #define GLOBAL_DATA static_cast<JSGlobalData*>(globalPtr) -#define LEXER (GLOBAL_DATA->lexer) - -#define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon(*LEXER, yychar)) YYABORT; } while (0) -#define SET_EXCEPTION_LOCATION(node, start, divot, end) node->setExceptionSourceCode((divot), (divot) - (start), (end) - (divot)) -#define DBG(l, s, e) (l)->setLoc((s).first_line, (e).last_line) +#define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon(*GLOBAL_DATA->lexer, yychar)) YYABORT; } while (0) using namespace JSC; using namespace std; -static ExpressionNode* makeAssignNode(void*, ExpressionNode* loc, Operator, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end); -static ExpressionNode* makePrefixNode(void*, ExpressionNode* expr, Operator, int start, int divot, int end); -static ExpressionNode* makePostfixNode(void*, ExpressionNode* expr, Operator, int start, int divot, int end); -static PropertyNode* makeGetterOrSetterPropertyNode(void*, const Identifier &getOrSet, const Identifier& name, ParameterNode*, FunctionBodyNode*, const SourceCode&); -static ExpressionNodeInfo makeFunctionCallNode(void*, ExpressionNodeInfo func, ArgumentsNodeInfo, int start, int divot, int end); -static ExpressionNode* makeTypeOfNode(void*, ExpressionNode*); -static ExpressionNode* makeDeleteNode(void*, ExpressionNode*, int start, int divot, int end); -static ExpressionNode* makeNegateNode(void*, ExpressionNode*); -static NumberNode* makeNumberNode(void*, double); -static ExpressionNode* makeBitwiseNotNode(void*, ExpressionNode*); -static ExpressionNode* makeMultNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeDivNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeAddNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeSubNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeLeftShiftNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static ExpressionNode* makeRightShiftNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments); -static StatementNode* makeVarStatementNode(void*, ExpressionNode*); -static ExpressionNode* combineCommaNodes(void*, ExpressionNode* list, ExpressionNode* init); +static ExpressionNode* makeAssignNode(JSGlobalData*, ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, int start, int divot, int end); +static ExpressionNode* makePrefixNode(JSGlobalData*, ExpressionNode*, Operator, int start, int divot, int end); +static ExpressionNode* makePostfixNode(JSGlobalData*, ExpressionNode*, Operator, int start, int divot, int end); +static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData*, const Identifier& getOrSet, const Identifier& name, ParameterNode*, FunctionBodyNode*, const SourceCode&); +static ExpressionNodeInfo makeFunctionCallNode(JSGlobalData*, ExpressionNodeInfo function, ArgumentsNodeInfo, int start, int divot, int end); +static ExpressionNode* makeTypeOfNode(JSGlobalData*, ExpressionNode*); +static ExpressionNode* makeDeleteNode(JSGlobalData*, ExpressionNode*, int start, int divot, int end); +static ExpressionNode* makeNegateNode(JSGlobalData*, ExpressionNode*); +static NumberNode* makeNumberNode(JSGlobalData*, double); +static ExpressionNode* makeBitwiseNotNode(JSGlobalData*, ExpressionNode*); +static ExpressionNode* makeMultNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeDivNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeAddNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeSubNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeLeftShiftNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static ExpressionNode* makeRightShiftNode(JSGlobalData*, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); +static StatementNode* makeVarStatementNode(JSGlobalData*, ExpressionNode*); +static ExpressionNode* combineCommaNodes(JSGlobalData*, ExpressionNode* list, ExpressionNode* init); #if COMPILER(MSVC) @@ -97,17 +89,17 @@ static ExpressionNode* combineCommaNodes(void*, ExpressionNode* list, Expression #define YYPARSE_PARAM globalPtr #define YYLEX_PARAM globalPtr -template <typename T> NodeDeclarationInfo<T> createNodeDeclarationInfo(T node, ParserArenaData<DeclarationStacks::VarStack>* varDecls, - ParserArenaData<DeclarationStacks::FunctionStack>* funcDecls, - CodeFeatures info, - int numConstants) +template <typename T> inline NodeDeclarationInfo<T> createNodeDeclarationInfo(T node, + ParserArenaData<DeclarationStacks::VarStack>* varDecls, + ParserArenaData<DeclarationStacks::FunctionStack>* funcDecls, + CodeFeatures info, int numConstants) { ASSERT((info & ~AllFeatures) == 0); NodeDeclarationInfo<T> result = { node, varDecls, funcDecls, info, numConstants }; return result; } -template <typename T> NodeInfo<T> createNodeInfo(T node, CodeFeatures info, int numConstants) +template <typename T> inline NodeInfo<T> createNodeInfo(T node, CodeFeatures info, int numConstants) { ASSERT((info & ~AllFeatures) == 0); NodeInfo<T> result = { node, info, numConstants }; @@ -133,21 +125,20 @@ template <typename T> inline T mergeDeclarationLists(T decls1, T decls2) return decls1; } -static void appendToVarDeclarationList(void* globalPtr, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, const Identifier& ident, unsigned attrs) +static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, const Identifier& ident, unsigned attrs) { if (!varDecls) - varDecls = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; - - varDecls->data.append(make_pair(ident, attrs)); + varDecls = new (globalData) ParserArenaData<DeclarationStacks::VarStack>; + varDecls->data.append(make_pair(&ident, attrs)); } -static inline void appendToVarDeclarationList(void* globalPtr, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, ConstDeclNode* decl) +static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, ConstDeclNode* decl) { unsigned attrs = DeclarationStacks::IsConstant; if (decl->hasInitializer()) attrs |= DeclarationStacks::HasInitializer; - appendToVarDeclarationList(globalPtr, varDecls, decl->ident(), attrs); + appendToVarDeclarationList(globalData, varDecls, decl->ident(), attrs); } %} @@ -155,7 +146,7 @@ static inline void appendToVarDeclarationList(void* globalPtr, ParserArenaData<D %union { int intValue; double doubleValue; - Identifier* ident; + const Identifier* ident; // expression subtrees ExpressionNodeInfo expressionNode; @@ -184,6 +175,20 @@ static inline void appendToVarDeclarationList(void* globalPtr, ParserArenaData<D Operator op; } +%{ + +template <typename T> inline void setStatementLocation(StatementNode* statement, const T& start, const T& end) +{ + statement->setLoc(start.first_line, end.last_line); +} + +static inline void setExceptionLocation(ThrowableExpressionData* node, unsigned start, unsigned divot, unsigned end) +{ + node->setExceptionSourceCode(divot, divot - start, end - divot); +} + +%} + %start Program /* literals */ @@ -291,21 +296,25 @@ Literal: | NUMBER { $$ = createNodeInfo<ExpressionNode*>(makeNumberNode(GLOBAL_DATA, $1), 0, 1); } | STRING { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StringNode(GLOBAL_DATA, *$1), 0, 1); } | '/' /* regexp */ { - Lexer& l = *LEXER; - if (!l.scanRegExp()) + Lexer& l = *GLOBAL_DATA->lexer; + const Identifier* pattern; + const Identifier* flags; + if (!l.scanRegExp(pattern, flags)) YYABORT; - RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, l.pattern(), l.flags()); - int size = l.pattern().size() + 2; // + 2 for the two /'s - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.first_column + size, @1.first_column + size); + RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, *pattern, *flags); + int size = pattern->size() + 2; // + 2 for the two /'s + setExceptionLocation(node, @1.first_column, @1.first_column + size, @1.first_column + size); $$ = createNodeInfo<ExpressionNode*>(node, 0, 0); } | DIVEQUAL /* regexp with /= */ { - Lexer& l = *LEXER; - if (!l.scanRegExp()) + Lexer& l = *GLOBAL_DATA->lexer; + const Identifier* pattern; + const Identifier* flags; + if (!l.scanRegExp(pattern, flags, '=')) YYABORT; - RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, "=" + l.pattern(), l.flags()); - int size = l.pattern().size() + 2; // + 2 for the two /'s - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.first_column + size, @1.first_column + size); + RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, *pattern, *flags); + int size = pattern->size() + 2; // + 2 for the two /'s + setExceptionLocation(node, @1.first_column, @1.first_column + size, @1.first_column + size); $$ = createNodeInfo<ExpressionNode*>(node, 0, 0); } ; @@ -313,14 +322,14 @@ Literal: Property: IDENT ':' AssignmentExpr { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, *$1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); } | STRING ':' AssignmentExpr { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, *$1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); } - | NUMBER ':' AssignmentExpr { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, Identifier(GLOBAL_DATA, UString::from($1)), $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); } - | IDENT IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(globalPtr, *$1, *$2, 0, $6, LEXER->sourceCode($5, $7, @5.first_line)), ClosureFeature, 0); DBG($6, @5, @7); if (!$$.m_node) YYABORT; } + | NUMBER ':' AssignmentExpr { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, $1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); } + | IDENT IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(GLOBAL_DATA, *$1, *$2, 0, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line)), ClosureFeature, 0); setStatementLocation($6, @5, @7); if (!$$.m_node) YYABORT; } | IDENT IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE { - $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(globalPtr, *$1, *$2, $4.m_node.head, $7, LEXER->sourceCode($6, $8, @6.first_line)), $4.m_features | ClosureFeature, 0); + $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(GLOBAL_DATA, *$1, *$2, $4.m_node.head, $7, GLOBAL_DATA->lexer->sourceCode($6, $8, @6.first_line)), $4.m_features | ClosureFeature, 0); if ($4.m_features & ArgumentsFeature) $7->setUsesArguments(); - DBG($7, @6, @8); + setStatementLocation($7, @6, @8); if (!$$.m_node) YYABORT; } @@ -385,15 +394,15 @@ MemberExpr: PrimaryExpr | FunctionExpr { $$ = createNodeInfo<ExpressionNode*>($1.m_node, $1.m_features, $1.m_numConstants); } | MemberExpr '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | MemberExpr '.' IDENT { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); } | NEW MemberExpr Arguments { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node, $3.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @2.last_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features | $3.m_features, $2.m_numConstants + $3.m_numConstants); } ; @@ -401,15 +410,15 @@ MemberExpr: MemberExprNoBF: PrimaryExprNoBrace | MemberExprNoBF '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | MemberExprNoBF '.' IDENT { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); } | NEW MemberExpr Arguments { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node, $3.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @2.last_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features | $3.m_features, $2.m_numConstants + $3.m_numConstants); } ; @@ -417,7 +426,7 @@ MemberExprNoBF: NewExpr: MemberExpr | NEW NewExpr { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features, $2.m_numConstants); } ; @@ -425,32 +434,32 @@ NewExpr: NewExprNoBF: MemberExprNoBF | NEW NewExpr { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features, $2.m_numConstants); } ; CallExpr: - MemberExpr Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); } - | CallExpr Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); } + MemberExpr Arguments { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); } + | CallExpr Arguments { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); } | CallExpr '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | CallExpr '.' IDENT { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); } ; CallExprNoBF: - MemberExprNoBF Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); } - | CallExprNoBF Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); } + MemberExprNoBF Arguments { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); } + | CallExprNoBF Arguments { $$ = makeFunctionCallNode(GLOBAL_DATA, $1, $2, @1.first_column, @1.last_column, @2.last_column); } | CallExprNoBF '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | CallExprNoBF '.' IDENT { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); } ; @@ -568,10 +577,10 @@ RelationalExpr: | RelationalExpr LE ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | RelationalExpr GE ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | RelationalExpr INSTANCEOF ShiftExpr { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | RelationalExpr INTOKEN ShiftExpr { InNode* node = new (GLOBAL_DATA) InNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } ; @@ -583,7 +592,7 @@ RelationalExprNoIn: | RelationalExprNoIn GE ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | RelationalExprNoIn INSTANCEOF ShiftExpr { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } ; @@ -595,11 +604,11 @@ RelationalExprNoBF: | RelationalExprNoBF GE ShiftExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | RelationalExprNoBF INSTANCEOF ShiftExpr { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } | RelationalExprNoBF INTOKEN ShiftExpr { InNode* node = new (GLOBAL_DATA) InNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); } ; @@ -810,17 +819,17 @@ Statement: ; Block: - OPENBRACE CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, 0), 0, 0, 0, 0); - DBG($$.m_node, @1, @2); } - | OPENBRACE SourceElements CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - DBG($$.m_node, @1, @3); } + OPENBRACE CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, 0), 0, 0, 0, 0); + setStatementLocation($$.m_node, @1, @2); } + | OPENBRACE SourceElements CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); + setStatementLocation($$.m_node, @1, @3); } ; VariableStatement: VAR VariableDeclarationList ';' { $$ = createNodeDeclarationInfo<StatementNode*>(makeVarStatementNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - DBG($$.m_node, @1, @3); } + setStatementLocation($$.m_node, @1, @3); } | VAR VariableDeclarationList error { $$ = createNodeDeclarationInfo<StatementNode*>(makeVarStatementNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - DBG($$.m_node, @1, @2); + setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } ; @@ -833,7 +842,7 @@ VariableDeclarationList: $$.m_numConstants = 0; } | IDENT Initializer { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.first_column + 1, @2.last_column); + setExceptionLocation(node, @1.first_column, @2.first_column + 1, @2.last_column); $$.m_node = node; $$.m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer); @@ -851,7 +860,7 @@ VariableDeclarationList: } | VariableDeclarationList ',' IDENT Initializer { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @3.first_column, @4.first_column + 1, @4.last_column); + setExceptionLocation(node, @3.first_column, @4.first_column + 1, @4.last_column); $$.m_node = combineCommaNodes(GLOBAL_DATA, $1.m_node, node); $$.m_varDeclarations = $1.m_varDeclarations; appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer); @@ -870,7 +879,7 @@ VariableDeclarationListNoIn: $$.m_numConstants = 0; } | IDENT InitializerNoIn { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.first_column + 1, @2.last_column); + setExceptionLocation(node, @1.first_column, @2.first_column + 1, @2.last_column); $$.m_node = node; $$.m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer); @@ -888,7 +897,7 @@ VariableDeclarationListNoIn: } | VariableDeclarationListNoIn ',' IDENT InitializerNoIn { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_features & AssignFeature); - SET_EXCEPTION_LOCATION(node, @3.first_column, @4.first_column + 1, @4.last_column); + setExceptionLocation(node, @3.first_column, @4.first_column + 1, @4.last_column); $$.m_node = combineCommaNodes(GLOBAL_DATA, $1.m_node, node); $$.m_varDeclarations = $1.m_varDeclarations; appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer); @@ -900,10 +909,10 @@ VariableDeclarationListNoIn: ConstStatement: CONSTTOKEN ConstDeclarationList ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ConstStatementNode(GLOBAL_DATA, $2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - DBG($$.m_node, @1, @3); } + setStatementLocation($$.m_node, @1, @3); } | CONSTTOKEN ConstDeclarationList error { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ConstStatementNode(GLOBAL_DATA, $2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } + setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } ; ConstDeclarationList: @@ -945,36 +954,36 @@ EmptyStatement: ExprStatement: ExprNoBF ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ExprStatementNode(GLOBAL_DATA, $1.m_node), 0, 0, $1.m_features, $1.m_numConstants); - DBG($$.m_node, @1, @2); } + setStatementLocation($$.m_node, @1, @2); } | ExprNoBF error { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ExprStatementNode(GLOBAL_DATA, $1.m_node), 0, 0, $1.m_features, $1.m_numConstants); - DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } + setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } ; IfStatement: IF '(' Expr ')' Statement %prec IF_WITHOUT_ELSE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) IfNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features, $3.m_numConstants + $5.m_numConstants); - DBG($$.m_node, @1, @4); } + setStatementLocation($$.m_node, @1, @4); } | IF '(' Expr ')' Statement ELSE Statement { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) IfElseNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node), mergeDeclarationLists($5.m_varDeclarations, $7.m_varDeclarations), mergeDeclarationLists($5.m_funcDeclarations, $7.m_funcDeclarations), $3.m_features | $5.m_features | $7.m_features, $3.m_numConstants + $5.m_numConstants + $7.m_numConstants); - DBG($$.m_node, @1, @4); } + setStatementLocation($$.m_node, @1, @4); } ; IterationStatement: DO Statement WHILE '(' Expr ')' ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DoWhileNode(GLOBAL_DATA, $2.m_node, $5.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features | $5.m_features, $2.m_numConstants + $5.m_numConstants); - DBG($$.m_node, @1, @3); } + setStatementLocation($$.m_node, @1, @3); } | DO Statement WHILE '(' Expr ')' error { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DoWhileNode(GLOBAL_DATA, $2.m_node, $5.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features | $5.m_features, $2.m_numConstants + $5.m_numConstants); - DBG($$.m_node, @1, @3); } // Always performs automatic semicolon insertion. + setStatementLocation($$.m_node, @1, @3); } // Always performs automatic semicolon insertion. | WHILE '(' Expr ')' Statement { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) WhileNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features, $3.m_numConstants + $5.m_numConstants); - DBG($$.m_node, @1, @4); } + setStatementLocation($$.m_node, @1, @4); } | FOR '(' ExprNoInOpt ';' ExprOpt ';' ExprOpt ')' Statement { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ForNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node, $9.m_node, false), $9.m_varDeclarations, $9.m_funcDeclarations, $3.m_features | $5.m_features | $7.m_features | $9.m_features, $3.m_numConstants + $5.m_numConstants + $7.m_numConstants + $9.m_numConstants); - DBG($$.m_node, @1, @8); + setStatementLocation($$.m_node, @1, @8); } | FOR '(' VAR VariableDeclarationListNoIn ';' ExprOpt ';' ExprOpt ')' Statement { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ForNode(GLOBAL_DATA, $4.m_node, $6.m_node, $8.m_node, $10.m_node, true), @@ -982,30 +991,30 @@ IterationStatement: mergeDeclarationLists($4.m_funcDeclarations, $10.m_funcDeclarations), $4.m_features | $6.m_features | $8.m_features | $10.m_features, $4.m_numConstants + $6.m_numConstants + $8.m_numConstants + $10.m_numConstants); - DBG($$.m_node, @1, @9); } + setStatementLocation($$.m_node, @1, @9); } | FOR '(' LeftHandSideExpr INTOKEN Expr ')' Statement { ForInNode* node = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node); - SET_EXCEPTION_LOCATION(node, @3.first_column, @3.last_column, @5.last_column); + setExceptionLocation(node, @3.first_column, @3.last_column, @5.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, $7.m_varDeclarations, $7.m_funcDeclarations, $3.m_features | $5.m_features | $7.m_features, $3.m_numConstants + $5.m_numConstants + $7.m_numConstants); - DBG($$.m_node, @1, @6); + setStatementLocation($$.m_node, @1, @6); } | FOR '(' VAR IDENT INTOKEN Expr ')' Statement { ForInNode *forIn = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, *$4, 0, $6.m_node, $8.m_node, @5.first_column, @5.first_column - @4.first_column, @6.last_column - @5.first_column); - SET_EXCEPTION_LOCATION(forIn, @4.first_column, @5.first_column + 1, @6.last_column); + setExceptionLocation(forIn, @4.first_column, @5.first_column + 1, @6.last_column); appendToVarDeclarationList(GLOBAL_DATA, $8.m_varDeclarations, *$4, DeclarationStacks::HasInitializer); $$ = createNodeDeclarationInfo<StatementNode*>(forIn, $8.m_varDeclarations, $8.m_funcDeclarations, ((*$4 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $6.m_features | $8.m_features, $6.m_numConstants + $8.m_numConstants); - DBG($$.m_node, @1, @7); } + setStatementLocation($$.m_node, @1, @7); } | FOR '(' VAR IDENT InitializerNoIn INTOKEN Expr ')' Statement { ForInNode *forIn = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, *$4, $5.m_node, $7.m_node, $9.m_node, @5.first_column, @5.first_column - @4.first_column, @5.last_column - @5.first_column); - SET_EXCEPTION_LOCATION(forIn, @4.first_column, @6.first_column + 1, @7.last_column); + setExceptionLocation(forIn, @4.first_column, @6.first_column + 1, @7.last_column); appendToVarDeclarationList(GLOBAL_DATA, $9.m_varDeclarations, *$4, DeclarationStacks::HasInitializer); $$ = createNodeDeclarationInfo<StatementNode*>(forIn, $9.m_varDeclarations, $9.m_funcDeclarations, ((*$4 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $5.m_features | $7.m_features | $9.m_features, $5.m_numConstants + $7.m_numConstants + $9.m_numConstants); - DBG($$.m_node, @1, @8); } + setStatementLocation($$.m_node, @1, @8); } ; ExprOpt: @@ -1020,63 +1029,63 @@ ExprNoInOpt: ContinueStatement: CONTINUE ';' { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - DBG($$.m_node, @1, @2); } + setStatementLocation($$.m_node, @1, @2); } | CONTINUE error { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); + setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } + setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } | CONTINUE IDENT ';' { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *$2); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - DBG($$.m_node, @1, @3); } + setStatementLocation($$.m_node, @1, @3); } | CONTINUE IDENT error { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *$2); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } + setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } ; BreakStatement: BREAK ';' { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG($$.m_node, @1, @2); } + setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @2); } | BREAK error { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA), 0, 0, 0, 0); DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } + setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA), 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } | BREAK IDENT ';' { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG($$.m_node, @1, @3); } + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @3); } | BREAK IDENT error { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2), 0, 0, 0, 0); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2), 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } ; ReturnStatement: RETURN ';' { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG($$.m_node, @1, @2); } + setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @2); } | RETURN error { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0); - SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } + setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } | RETURN Expr ';' { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, $2.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); DBG($$.m_node, @1, @3); } + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); setStatementLocation($$.m_node, @1, @3); } | RETURN Expr error { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, $2.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } ; WithStatement: WITH '(' Expr ')' Statement { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) WithNode(GLOBAL_DATA, $3.m_node, $5.m_node, @3.last_column, @3.last_column - @3.first_column), $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features | WithFeature, $3.m_numConstants + $5.m_numConstants); - DBG($$.m_node, @1, @4); } + setStatementLocation($$.m_node, @1, @4); } ; SwitchStatement: SWITCH '(' Expr ')' CaseBlock { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) SwitchNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features, $3.m_numConstants + $5.m_numConstants); - DBG($$.m_node, @1, @4); } + setStatementLocation($$.m_node, @1, @4); } ; CaseBlock: @@ -1090,7 +1099,7 @@ CaseBlock: ; CaseClausesOpt: -/* nothing */ { $$.m_node.head = 0; $$.m_node.tail = 0; $$.m_varDeclarations = 0; $$.m_funcDeclarations = 0; $$.m_features = 0; $$.m_numConstants = 0; } + /* nothing */ { $$.m_node.head = 0; $$.m_node.tail = 0; $$.m_varDeclarations = 0; $$.m_funcDeclarations = 0; $$.m_features = 0; $$.m_numConstants = 0; } | CaseClauses ; @@ -1122,18 +1131,18 @@ DefaultClause: LabelledStatement: IDENT ':' Statement { LabelNode* node = new (GLOBAL_DATA) LabelNode(GLOBAL_DATA, *$1, $3.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, $3.m_varDeclarations, $3.m_funcDeclarations, $3.m_features, $3.m_numConstants); } ; ThrowStatement: THROW Expr ';' { ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, $2.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); DBG($$.m_node, @1, @2); + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); setStatementLocation($$.m_node, @1, @2); } | THROW Expr error { ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, $2.m_node); - SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; + setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } ; @@ -1143,57 +1152,57 @@ TryStatement: mergeDeclarationLists($2.m_funcDeclarations, $4.m_funcDeclarations), $2.m_features | $4.m_features, $2.m_numConstants + $4.m_numConstants); - DBG($$.m_node, @1, @2); } + setStatementLocation($$.m_node, @1, @2); } | TRY Block CATCH '(' IDENT ')' Block { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, $2.m_node, *$5, ($7.m_features & EvalFeature) != 0, $7.m_node, 0), mergeDeclarationLists($2.m_varDeclarations, $7.m_varDeclarations), mergeDeclarationLists($2.m_funcDeclarations, $7.m_funcDeclarations), $2.m_features | $7.m_features | CatchFeature, $2.m_numConstants + $7.m_numConstants); - DBG($$.m_node, @1, @2); } + setStatementLocation($$.m_node, @1, @2); } | TRY Block CATCH '(' IDENT ')' Block FINALLY Block { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, $2.m_node, *$5, ($7.m_features & EvalFeature) != 0, $7.m_node, $9.m_node), mergeDeclarationLists(mergeDeclarationLists($2.m_varDeclarations, $7.m_varDeclarations), $9.m_varDeclarations), mergeDeclarationLists(mergeDeclarationLists($2.m_funcDeclarations, $7.m_funcDeclarations), $9.m_funcDeclarations), $2.m_features | $7.m_features | $9.m_features | CatchFeature, $2.m_numConstants + $7.m_numConstants + $9.m_numConstants); - DBG($$.m_node, @1, @2); } + setStatementLocation($$.m_node, @1, @2); } ; DebuggerStatement: DEBUGGER ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); - DBG($$.m_node, @1, @2); } + setStatementLocation($$.m_node, @1, @2); } | DEBUGGER error { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); - DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } + setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } ; FunctionDeclaration: - FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new FuncDeclNode(GLOBAL_DATA, *$2, $6, LEXER->sourceCode($5, $7, @5.first_line)), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | ClosureFeature, 0); DBG($6, @5, @7); $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)); } + FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) FuncDeclNode(GLOBAL_DATA, *$2, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line)), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | ClosureFeature, 0); setStatementLocation($6, @5, @7); $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)->body()); } | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE - { - $$ = createNodeDeclarationInfo<StatementNode*>(new FuncDeclNode(GLOBAL_DATA, *$2, $7, LEXER->sourceCode($6, $8, @6.first_line), $4.m_node.head), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $4.m_features | ClosureFeature, 0); + { + $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) FuncDeclNode(GLOBAL_DATA, *$2, $7, GLOBAL_DATA->lexer->sourceCode($6, $8, @6.first_line), $4.m_node.head), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $4.m_features | ClosureFeature, 0); if ($4.m_features & ArgumentsFeature) - $7->setUsesArguments(); - DBG($7, @6, @8); - $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)); + $7->setUsesArguments(); + setStatementLocation($7, @6, @8); + $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)->body()); } ; FunctionExpr: - FUNCTION '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, $5, LEXER->sourceCode($4, $6, @4.first_line)), ClosureFeature, 0); DBG($5, @4, @6); } - | FUNCTION '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE - { - $$ = createNodeInfo(new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, $6, LEXER->sourceCode($5, $7, @5.first_line), $3.m_node.head), $3.m_features | ClosureFeature, 0); - if ($3.m_features & ArgumentsFeature) + FUNCTION '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, $5, GLOBAL_DATA->lexer->sourceCode($4, $6, @4.first_line)), ClosureFeature, 0); setStatementLocation($5, @4, @6); } + | FUNCTION '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE + { + $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line), $3.m_node.head), $3.m_features | ClosureFeature, 0); + if ($3.m_features & ArgumentsFeature) $6->setUsesArguments(); - DBG($6, @5, @7); + setStatementLocation($6, @5, @7); } - | FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new FuncExprNode(GLOBAL_DATA, *$2, $6, LEXER->sourceCode($5, $7, @5.first_line)), ClosureFeature, 0); DBG($6, @5, @7); } - | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE - { - $$ = createNodeInfo(new FuncExprNode(GLOBAL_DATA, *$2, $7, LEXER->sourceCode($6, $8, @6.first_line), $4.m_node.head), $4.m_features | ClosureFeature, 0); + | FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, *$2, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line)), ClosureFeature, 0); setStatementLocation($6, @5, @7); } + | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE + { + $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, *$2, $7, GLOBAL_DATA->lexer->sourceCode($6, $8, @6.first_line), $4.m_node.head), $4.m_features | ClosureFeature, 0); if ($4.m_features & ArgumentsFeature) $7->setUsesArguments(); - DBG($7, @6, @8); + setStatementLocation($7, @6, @8); } ; @@ -1241,8 +1250,8 @@ Literal_NoNode: | FALSETOKEN | NUMBER { } | STRING { } - | '/' /* regexp */ { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; } - | DIVEQUAL /* regexp with /= */ { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; } + | '/' /* regexp */ { if (!GLOBAL_DATA->lexer->skipRegExp()) YYABORT; } + | DIVEQUAL /* regexp with /= */ { if (!GLOBAL_DATA->lexer->skipRegExp()) YYABORT; } ; Property_NoNode: @@ -1824,26 +1833,28 @@ SourceElements_NoNode: %% -static ExpressionNode* makeAssignNode(void* globalPtr, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end) +#undef GLOBAL_DATA + +static ExpressionNode* makeAssignNode(JSGlobalData* globalData, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end) { if (!loc->isLocation()) - return new (GLOBAL_DATA) AssignErrorNode(GLOBAL_DATA, loc, op, expr, divot, divot - start, end - divot); + return new (globalData) AssignErrorNode(globalData, loc, op, expr, divot, divot - start, end - divot); if (loc->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(loc); if (op == OpEqual) { - AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, resolve->identifier(), expr, exprHasAssignments); - SET_EXCEPTION_LOCATION(node, start, divot, end); + AssignResolveNode* node = new (globalData) AssignResolveNode(globalData, resolve->identifier(), expr, exprHasAssignments); + setExceptionLocation(node, start, divot, end); return node; } else - return new (GLOBAL_DATA) ReadModifyResolveNode(GLOBAL_DATA, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); + return new (globalData) ReadModifyResolveNode(globalData, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); } if (loc->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc); if (op == OpEqual) - return new (GLOBAL_DATA) AssignBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot()); + return new (globalData) AssignBracketNode(globalData, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot()); else { - ReadModifyBracketNode* node = new (GLOBAL_DATA) ReadModifyBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot); + ReadModifyBracketNode* node = new (globalData) ReadModifyBracketNode(globalData, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot); node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); return node; } @@ -1851,117 +1862,117 @@ static ExpressionNode* makeAssignNode(void* globalPtr, ExpressionNode* loc, Oper ASSERT(loc->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc); if (op == OpEqual) - return new (GLOBAL_DATA) AssignDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot()); + return new (globalData) AssignDotNode(globalData, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot()); - ReadModifyDotNode* node = new (GLOBAL_DATA) ReadModifyDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); + ReadModifyDotNode* node = new (globalData) ReadModifyDotNode(globalData, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->endOffset()); return node; } -static ExpressionNode* makePrefixNode(void* globalPtr, ExpressionNode* expr, Operator op, int start, int divot, int end) +static ExpressionNode* makePrefixNode(JSGlobalData* globalData, ExpressionNode* expr, Operator op, int start, int divot, int end) { if (!expr->isLocation()) - return new (GLOBAL_DATA) PrefixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot); + return new (globalData) PrefixErrorNode(globalData, expr, op, divot, divot - start, end - divot); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (GLOBAL_DATA) PrefixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot); + return new (globalData) PrefixResolveNode(globalData, resolve->identifier(), op, divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - PrefixBracketNode* node = new (GLOBAL_DATA) PrefixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); + PrefixBracketNode* node = new (globalData) PrefixBracketNode(globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); node->setSubexpressionInfo(bracket->divot(), bracket->startOffset()); return node; } ASSERT(expr->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); - PrefixDotNode* node = new (GLOBAL_DATA) PrefixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); + PrefixDotNode* node = new (globalData) PrefixDotNode(globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->startOffset()); return node; } -static ExpressionNode* makePostfixNode(void* globalPtr, ExpressionNode* expr, Operator op, int start, int divot, int end) +static ExpressionNode* makePostfixNode(JSGlobalData* globalData, ExpressionNode* expr, Operator op, int start, int divot, int end) { if (!expr->isLocation()) - return new (GLOBAL_DATA) PostfixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot); + return new (globalData) PostfixErrorNode(globalData, expr, op, divot, divot - start, end - divot); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (GLOBAL_DATA) PostfixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot); + return new (globalData) PostfixResolveNode(globalData, resolve->identifier(), op, divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - PostfixBracketNode* node = new (GLOBAL_DATA) PostfixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); + PostfixBracketNode* node = new (globalData) PostfixBracketNode(globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); return node; } ASSERT(expr->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); - PostfixDotNode* node = new (GLOBAL_DATA) PostfixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); + PostfixDotNode* node = new (globalData) PostfixDotNode(globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->endOffset()); return node; } -static ExpressionNodeInfo makeFunctionCallNode(void* globalPtr, ExpressionNodeInfo func, ArgumentsNodeInfo args, int start, int divot, int end) +static ExpressionNodeInfo makeFunctionCallNode(JSGlobalData* globalData, ExpressionNodeInfo func, ArgumentsNodeInfo args, int start, int divot, int end) { CodeFeatures features = func.m_features | args.m_features; int numConstants = func.m_numConstants + args.m_numConstants; if (!func.m_node->isLocation()) - return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) FunctionCallValueNode(GLOBAL_DATA, func.m_node, args.m_node, divot, divot - start, end - divot), features, numConstants); + return createNodeInfo<ExpressionNode*>(new (globalData) FunctionCallValueNode(globalData, func.m_node, args.m_node, divot, divot - start, end - divot), features, numConstants); if (func.m_node->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(func.m_node); const Identifier& identifier = resolve->identifier(); - if (identifier == GLOBAL_DATA->propertyNames->eval) - return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EvalFunctionCallNode(GLOBAL_DATA, args.m_node, divot, divot - start, end - divot), EvalFeature | features, numConstants); - return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) FunctionCallResolveNode(GLOBAL_DATA, identifier, args.m_node, divot, divot - start, end - divot), features, numConstants); + if (identifier == globalData->propertyNames->eval) + return createNodeInfo<ExpressionNode*>(new (globalData) EvalFunctionCallNode(globalData, args.m_node, divot, divot - start, end - divot), EvalFeature | features, numConstants); + return createNodeInfo<ExpressionNode*>(new (globalData) FunctionCallResolveNode(globalData, identifier, args.m_node, divot, divot - start, end - divot), features, numConstants); } if (func.m_node->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func.m_node); - FunctionCallBracketNode* node = new (GLOBAL_DATA) FunctionCallBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), args.m_node, divot, divot - start, end - divot); + FunctionCallBracketNode* node = new (globalData) FunctionCallBracketNode(globalData, bracket->base(), bracket->subscript(), args.m_node, divot, divot - start, end - divot); node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); return createNodeInfo<ExpressionNode*>(node, features, numConstants); } ASSERT(func.m_node->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(func.m_node); FunctionCallDotNode* node; - if (dot->identifier() == GLOBAL_DATA->propertyNames->call) - node = new (GLOBAL_DATA) CallFunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); - else if (dot->identifier() == GLOBAL_DATA->propertyNames->apply) - node = new (GLOBAL_DATA) ApplyFunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); + if (dot->identifier() == globalData->propertyNames->call) + node = new (globalData) CallFunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); + else if (dot->identifier() == globalData->propertyNames->apply) + node = new (globalData) ApplyFunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); else - node = new (GLOBAL_DATA) FunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); + node = new (globalData) FunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->endOffset()); return createNodeInfo<ExpressionNode*>(node, features, numConstants); } -static ExpressionNode* makeTypeOfNode(void* globalPtr, ExpressionNode* expr) +static ExpressionNode* makeTypeOfNode(JSGlobalData* globalData, ExpressionNode* expr) { if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (GLOBAL_DATA) TypeOfResolveNode(GLOBAL_DATA, resolve->identifier()); + return new (globalData) TypeOfResolveNode(globalData, resolve->identifier()); } - return new (GLOBAL_DATA) TypeOfValueNode(GLOBAL_DATA, expr); + return new (globalData) TypeOfValueNode(globalData, expr); } -static ExpressionNode* makeDeleteNode(void* globalPtr, ExpressionNode* expr, int start, int divot, int end) +static ExpressionNode* makeDeleteNode(JSGlobalData* globalData, ExpressionNode* expr, int start, int divot, int end) { if (!expr->isLocation()) - return new (GLOBAL_DATA) DeleteValueNode(GLOBAL_DATA, expr); + return new (globalData) DeleteValueNode(globalData, expr); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (GLOBAL_DATA) DeleteResolveNode(GLOBAL_DATA, resolve->identifier(), divot, divot - start, end - divot); + return new (globalData) DeleteResolveNode(globalData, resolve->identifier(), divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - return new (GLOBAL_DATA) DeleteBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), divot, divot - start, end - divot); + return new (globalData) DeleteBracketNode(globalData, bracket->base(), bracket->subscript(), divot, divot - start, end - divot); } ASSERT(expr->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); - return new (GLOBAL_DATA) DeleteDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), divot, divot - start, end - divot); + return new (globalData) DeleteDotNode(globalData, dot->base(), dot->identifier(), divot, divot - start, end - divot); } -static PropertyNode* makeGetterOrSetterPropertyNode(void* globalPtr, const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body, const SourceCode& source) +static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData* globalData, const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body, const SourceCode& source) { PropertyNode::Type type; if (getOrSet == "get") @@ -1970,10 +1981,10 @@ static PropertyNode* makeGetterOrSetterPropertyNode(void* globalPtr, const Ident type = PropertyNode::Setter; else return 0; - return new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, name, new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, body, source, params), type); + return new (globalData) PropertyNode(globalData, name, new (globalData) FuncExprNode(globalData, globalData->propertyNames->nullIdentifier, body, source, params), type); } -static ExpressionNode* makeNegateNode(void* globalPtr, ExpressionNode* n) +static ExpressionNode* makeNegateNode(JSGlobalData* globalData, ExpressionNode* n) { if (n->isNumber()) { NumberNode* number = static_cast<NumberNode*>(n); @@ -1984,92 +1995,92 @@ static ExpressionNode* makeNegateNode(void* globalPtr, ExpressionNode* n) } } - return new (GLOBAL_DATA) NegateNode(GLOBAL_DATA, n); + return new (globalData) NegateNode(globalData, n); } -static NumberNode* makeNumberNode(void* globalPtr, double d) +static NumberNode* makeNumberNode(JSGlobalData* globalData, double d) { - return new (GLOBAL_DATA) NumberNode(GLOBAL_DATA, d); + return new (globalData) NumberNode(globalData, d); } -static ExpressionNode* makeBitwiseNotNode(void* globalPtr, ExpressionNode* expr) +static ExpressionNode* makeBitwiseNotNode(JSGlobalData* globalData, ExpressionNode* expr) { if (expr->isNumber()) - return makeNumberNode(globalPtr, ~toInt32(static_cast<NumberNode*>(expr)->value())); - return new (GLOBAL_DATA) BitwiseNotNode(GLOBAL_DATA, expr); + return makeNumberNode(globalData, ~toInt32(static_cast<NumberNode*>(expr)->value())); + return new (globalData) BitwiseNotNode(globalData, expr); } -static ExpressionNode* makeMultNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeMultNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { expr1 = expr1->stripUnaryPlus(); expr2 = expr2->stripUnaryPlus(); if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value()); + return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value()); if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1) - return new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, expr2); + return new (globalData) UnaryPlusNode(globalData, expr2); if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1) - return new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, expr1); + return new (globalData) UnaryPlusNode(globalData, expr1); - return new (GLOBAL_DATA) MultNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return new (globalData) MultNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeDivNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeDivNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { expr1 = expr1->stripUnaryPlus(); expr2 = expr2->stripUnaryPlus(); if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value()); - return new (GLOBAL_DATA) DivNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value()); + return new (globalData) DivNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeAddNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeAddNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value()); - return new (GLOBAL_DATA) AddNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value()); + return new (globalData) AddNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeSubNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeSubNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { expr1 = expr1->stripUnaryPlus(); expr2 = expr2->stripUnaryPlus(); if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value()); - return new (GLOBAL_DATA) SubNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value()); + return new (globalData) SubNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeLeftShiftNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeLeftShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); - return new (GLOBAL_DATA) LeftShiftNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); + return new (globalData) LeftShiftNode(globalData, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeRightShiftNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeRightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalPtr, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); - return new (GLOBAL_DATA) RightShiftNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalData, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); + return new (globalData) RightShiftNode(globalData, expr1, expr2, rightHasAssignments); } -/* called by yyparse on error */ -int yyerror(const char *) +// Called by yyparse on error. +int yyerror(const char*) { return 1; } -/* may we automatically insert a semicolon ? */ +// May we automatically insert a semicolon? static bool allowAutomaticSemicolon(Lexer& lexer, int yychar) { return yychar == CLOSEBRACE || yychar == 0 || lexer.prevTerminator(); } -static ExpressionNode* combineCommaNodes(void* globalPtr, ExpressionNode* list, ExpressionNode* init) +static ExpressionNode* combineCommaNodes(JSGlobalData* globalData, ExpressionNode* list, ExpressionNode* init) { if (!list) return init; @@ -2077,17 +2088,15 @@ static ExpressionNode* combineCommaNodes(void* globalPtr, ExpressionNode* list, static_cast<CommaNode*>(list)->append(init); return list; } - return new (GLOBAL_DATA) CommaNode(GLOBAL_DATA, list, init); + return new (globalData) CommaNode(globalData, list, init); } // We turn variable declarations into either assignments or empty // statements (which later get stripped out), because the actual // declaration work is hoisted up to the start of the function body -static StatementNode* makeVarStatementNode(void* globalPtr, ExpressionNode* expr) +static StatementNode* makeVarStatementNode(JSGlobalData* globalData, ExpressionNode* expr) { if (!expr) - return new (GLOBAL_DATA) EmptyStatementNode(GLOBAL_DATA); - return new (GLOBAL_DATA) VarStatementNode(GLOBAL_DATA, expr); + return new (globalData) EmptyStatementNode(globalData); + return new (globalData) VarStatementNode(globalData, expr); } - -#undef GLOBAL_DATA diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.cpp b/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.cpp index 8e89c18a9..df3083834 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.cpp @@ -46,12 +46,6 @@ using namespace JSC; #include "Lookup.h" #include "Lexer.lut.h" -// A bridge for yacc from the C world to the C++ world. -int jscyylex(void* lvalp, void* llocp, void* globalData) -{ - return static_cast<JSGlobalData*>(globalData)->lexer->lex(lvalp, llocp); -} - namespace JSC { static const UChar byteOrderMark = 0xFEFF; @@ -141,8 +135,10 @@ ALWAYS_INLINE void Lexer::shift4() m_code += 4; } -void Lexer::setCode(const SourceCode& source) +void Lexer::setCode(const SourceCode& source, ParserArena& arena) { + m_arena = &arena.identifierArena(); + m_lineNumber = source.firstLine(); m_delimited = false; m_lastToken = -1; @@ -204,10 +200,9 @@ void Lexer::shiftLineTerminator() ++m_lineNumber; } -ALWAYS_INLINE Identifier* Lexer::makeIdentifier(const UChar* characters, size_t length) +ALWAYS_INLINE const Identifier* Lexer::makeIdentifier(const UChar* characters, size_t length) { - m_identifiers.append(Identifier(m_globalData, characters, length)); - return &m_identifiers.last(); + return &m_arena->makeIdentifier(m_globalData, characters, length); } inline bool Lexer::lastTokenWasRestrKeyword() const @@ -908,48 +903,110 @@ returnError: return -1; } -bool Lexer::scanRegExp() +bool Lexer::scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix) { ASSERT(m_buffer16.isEmpty()); bool lastWasEscape = false; bool inBrackets = false; + if (patternPrefix) { + ASSERT(!isLineTerminator(patternPrefix)); + ASSERT(patternPrefix != '/'); + ASSERT(patternPrefix != '['); + record16(patternPrefix); + } + while (true) { - if (isLineTerminator(m_current) || m_current == -1) - return false; - if (m_current != '/' || lastWasEscape || inBrackets) { - // keep track of '[' and ']' - if (!lastWasEscape) { - if (m_current == '[' && !inBrackets) - inBrackets = true; - if (m_current == ']' && inBrackets) - inBrackets = false; - } - record16(m_current); - lastWasEscape = !lastWasEscape && m_current == '\\'; - } else { // end of regexp - m_pattern = UString(m_buffer16); + int current = m_current; + + if (isLineTerminator(current) || current == -1) { m_buffer16.resize(0); - shift1(); - break; + return false; } + shift1(); + + if (current == '/' && !lastWasEscape && !inBrackets) + break; + + record16(current); + + if (lastWasEscape) { + lastWasEscape = false; + continue; + } + + switch (current) { + case '[': + inBrackets = true; + break; + case ']': + inBrackets = false; + break; + case '\\': + lastWasEscape = true; + break; + } } + pattern = makeIdentifier(m_buffer16.data(), m_buffer16.size()); + m_buffer16.resize(0); + while (isIdentPart(m_current)) { record16(m_current); shift1(); } - m_flags = UString(m_buffer16); + + flags = makeIdentifier(m_buffer16.data(), m_buffer16.size()); m_buffer16.resize(0); return true; } +bool Lexer::skipRegExp() +{ + bool lastWasEscape = false; + bool inBrackets = false; + + while (true) { + int current = m_current; + + if (isLineTerminator(current) || current == -1) + return false; + + shift1(); + + if (current == '/' && !lastWasEscape && !inBrackets) + break; + + if (lastWasEscape) { + lastWasEscape = false; + continue; + } + + switch (current) { + case '[': + inBrackets = true; + break; + case ']': + inBrackets = false; + break; + case '\\': + lastWasEscape = true; + break; + } + } + + while (isIdentPart(m_current)) + shift1(); + + return true; +} + void Lexer::clear() { - m_identifiers.clear(); + m_arena = 0; m_codeWithoutBOMs.clear(); Vector<char> newBuffer8; @@ -961,9 +1018,6 @@ void Lexer::clear() m_buffer16.swap(newBuffer16); m_isReparsing = false; - - m_pattern = UString(); - m_flags = UString(); } SourceCode Lexer::sourceCode(int openBrace, int closeBrace, int firstLine) diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.h b/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.h index 25831628d..c76696cf3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.h +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Lexer.h @@ -23,6 +23,7 @@ #define Lexer_h #include "Lookup.h" +#include "ParserArena.h" #include "SourceCode.h" #include <wtf/ASCIICType.h> #include <wtf/SegmentedVector.h> @@ -42,7 +43,7 @@ namespace JSC { static UChar convertUnicode(int c1, int c2, int c3, int c4); // Functions to set up parsing. - void setCode(const SourceCode&); + void setCode(const SourceCode&, ParserArena&); void setIsReparsing() { m_isReparsing = true; } // Functions for the parser itself. @@ -50,9 +51,8 @@ namespace JSC { int lineNumber() const { return m_lineNumber; } bool prevTerminator() const { return m_terminator; } SourceCode sourceCode(int openBrace, int closeBrace, int firstLine); - bool scanRegExp(); - const UString& pattern() const { return m_pattern; } - const UString& flags() const { return m_flags; } + bool scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix = 0); + bool skipRegExp(); // Functions for use after parsing. bool sawError() const { return m_error; } @@ -79,12 +79,11 @@ namespace JSC { int currentOffset() const; const UChar* currentCharacter() const; - JSC::Identifier* makeIdentifier(const UChar* buffer, size_t length); + const Identifier* makeIdentifier(const UChar* characters, size_t length); bool lastTokenWasRestrKeyword() const; static const size_t initialReadBufferCapacity = 32; - static const size_t initialIdentifierTableCapacity = 64; int m_lineNumber; @@ -108,13 +107,10 @@ namespace JSC { int m_next2; int m_next3; - WTF::SegmentedVector<JSC::Identifier, initialIdentifierTableCapacity> m_identifiers; + IdentifierArena* m_arena; JSGlobalData* m_globalData; - UString m_pattern; - UString m_flags; - const HashTable m_keywordTable; Vector<UChar> m_codeWithoutBOMs; @@ -140,6 +136,12 @@ namespace JSC { return (convertHex(c1, c2) << 8) | convertHex(c3, c4); } + // A bridge for yacc from the C world to the C++ world. + inline int jscyylex(void* lvalp, void* llocp, void* globalData) + { + return static_cast<JSGlobalData*>(globalData)->lexer->lex(lvalp, llocp); + } + } // namespace JSC #endif // Lexer_h diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/NodeConstructors.h b/src/3rdparty/webkit/JavaScriptCore/parser/NodeConstructors.h index 780a6246e..dd3b9816f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/NodeConstructors.h +++ b/src/3rdparty/webkit/JavaScriptCore/parser/NodeConstructors.h @@ -27,21 +27,14 @@ namespace JSC { - inline void* ParserArenaDeletable::operator new(size_t size, JSGlobalData* globalData) + inline void* ParserArenaFreeable::operator new(size_t size, JSGlobalData* globalData) { - ParserArenaDeletable* deletable = static_cast<ParserArenaDeletable*>(fastMalloc(size)); - globalData->parser->arena().deleteWithArena(deletable); - return deletable; + return globalData->parser->arena().allocateFreeable(size); } - inline void* ParserArenaDeletable::operator new(size_t size) - { - return fastMalloc(size); - } - - inline void ParserArenaDeletable::operator delete(void* p) + inline void* ParserArenaDeletable::operator new(size_t size, JSGlobalData* globalData) { - fastFree(p); + return globalData->parser->arena().allocateDeletable(size); } inline ParserArenaRefCounted::ParserArenaRefCounted(JSGlobalData* globalData) @@ -77,19 +70,19 @@ namespace JSC { { } - inline NumberNode::NumberNode(JSGlobalData* globalData, double v) + inline NumberNode::NumberNode(JSGlobalData* globalData, double value) : ExpressionNode(globalData, ResultType::numberType()) - , m_double(v) + , m_value(value) { } - inline StringNode::StringNode(JSGlobalData* globalData, const Identifier& v) + inline StringNode::StringNode(JSGlobalData* globalData, const Identifier& value) : ExpressionNode(globalData, ResultType::stringType()) - , m_value(v) + , m_value(value) { } - inline RegExpNode::RegExpNode(JSGlobalData* globalData, const UString& pattern, const UString& flags) + inline RegExpNode::RegExpNode(JSGlobalData* globalData, const Identifier& pattern, const Identifier& flags) : ExpressionNode(globalData) , m_pattern(pattern) , m_flags(flags) @@ -154,6 +147,13 @@ namespace JSC { { } + inline PropertyNode::PropertyNode(JSGlobalData* globalData, double name, ExpressionNode* assign, Type type) + : m_name(globalData->parser->arena().identifierArena().makeNumericIdentifier(globalData, name)) + , m_assign(assign) + , m_type(type) + { + } + inline PropertyListNode::PropertyListNode(JSGlobalData* globalData, PropertyNode* node) : Node(globalData) , m_node(node) @@ -741,6 +741,7 @@ namespace JSC { inline ContinueNode::ContinueNode(JSGlobalData* globalData) : StatementNode(globalData) + , m_ident(globalData->propertyNames->nullIdentifier) { } @@ -752,6 +753,7 @@ namespace JSC { inline BreakNode::BreakNode(JSGlobalData* globalData) : StatementNode(globalData) + , m_ident(globalData->propertyNames->nullIdentifier) { } @@ -814,32 +816,22 @@ namespace JSC { inline FuncExprNode::FuncExprNode(JSGlobalData* globalData, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter) : ExpressionNode(globalData) - , ParserArenaRefCounted(globalData) - , m_ident(ident) , m_body(body) { - m_body->finishParsing(source, parameter); + m_body->finishParsing(source, parameter, ident); } inline FuncDeclNode::FuncDeclNode(JSGlobalData* globalData, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter) : StatementNode(globalData) - , ParserArenaRefCounted(globalData) - , m_ident(ident) , m_body(body) { - m_body->finishParsing(source, parameter); - } - - inline CaseClauseNode::CaseClauseNode(JSGlobalData*, ExpressionNode* expr) - : m_expr(expr) - { + m_body->finishParsing(source, parameter, ident); } - inline CaseClauseNode::CaseClauseNode(JSGlobalData*, ExpressionNode* expr, SourceElements* children) + inline CaseClauseNode::CaseClauseNode(JSGlobalData*, ExpressionNode* expr, SourceElements* statements) : m_expr(expr) + , m_statements(statements) { - if (children) - children->releaseContentsIntoVector(m_children); } inline ClauseListNode::ClauseListNode(JSGlobalData*, CaseClauseNode* clause) @@ -877,15 +869,15 @@ namespace JSC { { } - inline BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children) + inline BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* statements) : StatementNode(globalData) + , m_statements(statements) { - if (children) - children->releaseContentsIntoVector(m_children); } inline ForInNode::ForInNode(JSGlobalData* globalData, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement) : StatementNode(globalData) + , m_ident(globalData->propertyNames->nullIdentifier) , m_init(0) , m_lexpr(l) , m_expr(expr) diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp b/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp index 6c0d1af0c..45009dce4 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.cpp @@ -49,7 +49,28 @@ using namespace WTF; namespace JSC { -static void substitute(UString& string, const UString& substring); +/* + Details of the emitBytecode function. + + Return value: The register holding the production's value. + dst: An optional parameter specifying the most efficient destination at + which to store the production's value. The callee must honor dst. + + The dst argument provides for a crude form of copy propagation. For example, + + x = 1 + + becomes + + load r[x], 1 + + instead of + + load r0, 1 + mov r[x], r0 + + because the assignment node, "x =", passes r[x] as dst to the number node, "1". +*/ // ------------------------------ ThrowableExpressionData -------------------------------- @@ -63,24 +84,29 @@ static void substitute(UString& string, const UString& substring) string = newString; } -RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType e, const char* msg) +RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* message) { generator.emitExpressionInfo(divot(), startOffset(), endOffset()); - RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), msg)); + RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message)); generator.emitThrow(exception); return exception; } -RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label) +RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const UString& label) { - UString message = msg; - substitute(message, label.ustring()); + UString message = messageTemplate; + substitute(message, label); generator.emitExpressionInfo(divot(), startOffset(), endOffset()); - RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), message)); + RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message)); generator.emitThrow(exception); return exception; } +inline RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const Identifier& label) +{ + return emitThrowError(generator, type, messageTemplate, label.ustring()); +} + // ------------------------------ StatementNode -------------------------------- void StatementNode::setLoc(int firstLine, int lastLine) @@ -98,6 +124,18 @@ void SourceElements::append(StatementNode* statement) m_statements.append(statement); } +inline StatementNode* SourceElements::singleStatement() const +{ + size_t size = m_statements.size(); + return size == 1 ? m_statements[0] : 0; +} + +inline StatementNode* SourceElements::lastStatement() const +{ + size_t size = m_statements.size(); + return size ? m_statements[size - 1] : 0; +} + // ------------------------------ NullNode ------------------------------------- RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) @@ -122,7 +160,7 @@ RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d { if (dst == generator.ignoredResult()) return 0; - return generator.emitLoad(dst, m_double); + return generator.emitLoad(dst, m_value); } // ------------------------------ StringNode ----------------------------------- @@ -138,9 +176,9 @@ RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern, m_flags); + RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern.ustring(), m_flags.ustring()); if (!regExp->isValid()) - return emitThrowError(generator, SyntaxError, ("Invalid regular expression: " + UString(regExp->errorMessage())).UTF8String().c_str()); + return emitThrowError(generator, SyntaxError, "Invalid regular expression: %s", regExp->errorMessage()); if (dst == generator.ignoredResult()) return 0; return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get()); @@ -355,7 +393,7 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RefPtr<RegisterID> thisRegister = generator.newTemporary(); int identifierStart = divot() - startOffset(); generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0); - generator.emitResolveFunction(thisRegister.get(), func.get(), m_ident); + generator.emitResolveWithBase(thisRegister.get(), func.get(), m_ident); return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); } @@ -375,11 +413,12 @@ RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - RefPtr<RegisterID> base = generator.emitNode(m_base); + RefPtr<RegisterID> function = generator.tempDestination(dst); + RefPtr<RegisterID> thisRegister = generator.newTemporary(); + generator.emitNode(thisRegister.get(), m_base); generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset); generator.emitMethodCheck(); - RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident); - RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get()); + generator.emitGetById(function.get(), thisRegister.get(), m_ident); return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); } @@ -595,7 +634,9 @@ RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterI RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) { - return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Postfix ++ operator applied to value that is not a reference." : "Postfix -- operator applied to value that is not a reference."); + return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus + ? "Postfix ++ operator applied to value that is not a reference." + : "Postfix -- operator applied to value that is not a reference."); } // ------------------------------ DeleteResolveNode ----------------------------------- @@ -757,7 +798,9 @@ RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) { - return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Prefix ++ operator applied to value that is not a reference." : "Prefix -- operator applied to value that is not a reference."); + return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus + ? "Prefix ++ operator applied to value that is not a reference." + : "Prefix -- operator applied to value that is not a reference."); } // ------------------------------ Unary Operation Nodes ----------------------------------- @@ -1204,7 +1247,13 @@ RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator) return generator.emitNode(local, m_init); } - + + if (generator.codeType() != EvalCode) { + if (m_init) + return generator.emitNode(m_init); + else + return generator.emitResolve(generator.newTemporary(), m_ident); + } // FIXME: While this code should only be hit in eval code, it will potentially // assign to the wrong base if m_ident exists in an intervening dynamic scope. RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident); @@ -1229,20 +1278,26 @@ RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, Regis return generator.emitNode(m_next); } -// ------------------------------ Helper functions for handling Vectors of StatementNode ------------------------------- +// ------------------------------ SourceElements ------------------------------- -static inline void statementListEmitCode(const StatementVector& statements, BytecodeGenerator& generator, RegisterID* dst) +inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - size_t size = statements.size(); + size_t size = m_statements.size(); for (size_t i = 0; i < size; ++i) - generator.emitNode(dst, statements[i]); + generator.emitNode(dst, m_statements[i]); } // ------------------------------ BlockNode ------------------------------------ +inline StatementNode* BlockNode::lastStatement() const +{ + return m_statements ? m_statements->lastStatement() : 0; +} + RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - statementListEmitCode(m_children, generator, dst); + if (m_statements) + m_statements->emitBytecode(generator, dst); return 0; } @@ -1373,9 +1428,6 @@ RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - if (dst == generator.ignoredResult()) - dst = 0; - RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop); generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); @@ -1416,20 +1468,24 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds if (!m_lexpr->isLocation()) return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference."); - RefPtr<Label> continueTarget = generator.newLabel(); - generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); if (m_init) generator.emitNode(generator.ignoredResult(), m_init); - RegisterID* forInBase = generator.emitNode(m_expr); - RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase); + + RefPtr<RegisterID> base = generator.newTemporary(); + generator.emitNode(base.get(), m_expr); + RefPtr<RegisterID> i = generator.newTemporary(); + RefPtr<RegisterID> size = generator.newTemporary(); + RefPtr<RegisterID> expectedSubscript; + RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), base.get(), i.get(), size.get(), scope->breakTarget()); generator.emitJump(scope->continueTarget()); RefPtr<Label> loopStart = generator.newLabel(); generator.emitLabel(loopStart.get()); RegisterID* propertyName; + bool optimizedForinAccess = false; if (m_lexpr->isResolveNode()) { const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier(); propertyName = generator.registerFor(ident); @@ -1440,6 +1496,10 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds generator.emitExpressionInfo(divot(), startOffset(), endOffset()); generator.emitPutById(base, ident, propertyName); + } else { + expectedSubscript = generator.emitMove(generator.newTemporary(), propertyName); + generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), propertyName); + optimizedForinAccess = true; } } else if (m_lexpr->isDotAccessorNode()) { DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr); @@ -1464,8 +1524,11 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds generator.emitNode(dst, m_statement); + if (optimizedForinAccess) + generator.popOptimisedForIn(); + generator.emitLabel(scope->continueTarget()); - generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get()); + generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get()); generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); generator.emitLabel(scope->breakTarget()); return dst; @@ -1547,6 +1610,14 @@ RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst return result; } +// ------------------------------ CaseClauseNode -------------------------------- + +inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) +{ + if (m_statements) + m_statements->emitBytecode(generator, dst); +} + // ------------------------------ CaseBlockNode -------------------------------- enum SwitchKind { @@ -1563,13 +1634,11 @@ static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector.append(clauseExpression); if (clauseExpression->isNumber()) { double value = static_cast<NumberNode*>(clauseExpression)->value(); - JSValue jsValue = JSValue::makeInt32Fast(static_cast<int32_t>(value)); - if ((typeForTable & ~SwitchNumber) || !jsValue || (jsValue.getInt32Fast() != value)) { + int32_t intVal = static_cast<int32_t>(value); + if ((typeForTable & ~SwitchNumber) || (intVal != value)) { typeForTable = SwitchNeither; break; } - int32_t intVal = static_cast<int32_t>(value); - ASSERT(intVal == value); if (intVal < min_num) min_num = intVal; if (intVal > max_num) @@ -1668,17 +1737,17 @@ RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, Re size_t i = 0; for (ClauseListNode* list = m_list1; list; list = list->getNext()) { generator.emitLabel(labelVector[i++].get()); - statementListEmitCode(list->getClause()->children(), generator, dst); + list->getClause()->emitBytecode(generator, dst); } if (m_defaultClause) { generator.emitLabel(defaultLabel.get()); - statementListEmitCode(m_defaultClause->children(), generator, dst); + m_defaultClause->emitBytecode(generator, dst); } for (ClauseListNode* list = m_list2; list; list = list->getNext()) { generator.emitLabel(labelVector[i++].get()); - statementListEmitCode(list->getClause()->children(), generator, dst); + list->getClause()->emitBytecode(generator, dst); } if (!m_defaultClause) generator.emitLabel(defaultLabel.get()); @@ -1740,10 +1809,12 @@ RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { + // NOTE: The catch and finally blocks must be labeled explicitly, so the + // optimizer knows they may be jumped to from anywhere. + generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); RefPtr<Label> tryStartLabel = generator.newLabel(); - RefPtr<Label> tryEndLabel = generator.newLabel(); RefPtr<Label> finallyStart; RefPtr<RegisterID> finallyReturnAddr; if (m_finallyBlock) { @@ -1751,14 +1822,19 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) finallyReturnAddr = generator.newTemporary(); generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get()); } + generator.emitLabel(tryStartLabel.get()); generator.emitNode(dst, m_tryBlock); - generator.emitLabel(tryEndLabel.get()); if (m_catchBlock) { - RefPtr<Label> handlerEndLabel = generator.newLabel(); - generator.emitJump(handlerEndLabel.get()); - RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get()); + RefPtr<Label> catchEndLabel = generator.newLabel(); + + // Normal path: jump over the catch block. + generator.emitJump(catchEndLabel.get()); + + // Uncaught exception path: the catch block. + RefPtr<Label> here = generator.emitLabel(generator.newLabel().get()); + RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get()); if (m_catchHasEval) { RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary()); generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get()); @@ -1768,7 +1844,7 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get()); generator.emitNode(dst, m_catchBlock); generator.emitPopScope(); - generator.emitLabel(handlerEndLabel.get()); + generator.emitLabel(catchEndLabel.get()); } if (m_finallyBlock) { @@ -1779,21 +1855,18 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) // approach to not clobbering anything important RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister(); RefPtr<Label> finallyEndLabel = generator.newLabel(); + + // Normal path: invoke the finally block, then jump over it. generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get()); - // Use a label to record the subtle fact that sret will return to the - // next instruction. sret is the only way to jump without an explicit label. - generator.emitLabel(generator.newLabel().get()); generator.emitJump(finallyEndLabel.get()); - // Finally block for exception path - RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get()); + // Uncaught exception path: invoke the finally block, then re-throw the exception. + RefPtr<Label> here = generator.emitLabel(generator.newLabel().get()); + RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get()); generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get()); - // Use a label to record the subtle fact that sret will return to the - // next instruction. sret is the only way to jump without an explicit label. - generator.emitLabel(generator.newLabel().get()); generator.emitThrow(tempExceptionRegister.get()); - // emit the finally block itself + // The finally block. generator.emitLabel(finallyStart.get()); generator.emitNode(dst, m_finallyBlock); generator.emitSubroutineReturn(finallyReturnAddr.get()); @@ -1806,27 +1879,15 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) // -----------------------------ScopeNodeData --------------------------- -ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants) +ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, VarStack* varStack, FunctionStack* funcStack, int numConstants) : m_numConstants(numConstants) + , m_statements(statements) { m_arena.swap(arena); if (varStack) m_varStack.swap(*varStack); if (funcStack) m_functionStack.swap(*funcStack); - if (children) - children->releaseContentsIntoVector(m_children); -} - -void ScopeNodeData::mark() -{ - FunctionStack::iterator end = m_functionStack.end(); - for (FunctionStack::iterator ptr = m_functionStack.begin(); ptr != end; ++ptr) { - FunctionBodyNode* body = (*ptr)->body(); - if (!body->isGenerated()) - continue; - body->generatedBytecode().mark(); - } } // ------------------------------ ScopeNode ----------------------------- @@ -1836,10 +1897,6 @@ ScopeNode::ScopeNode(JSGlobalData* globalData) , ParserArenaRefCounted(globalData) , m_features(NoFeatures) { -#if ENABLE(CODEBLOCK_SAMPLING) - if (SamplingTool* sampler = globalData->interpreter->sampler()) - sampler->notifyOfScope(this); -#endif } ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants) @@ -1849,10 +1906,17 @@ ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceE , m_features(features) , m_source(source) { -#if ENABLE(CODEBLOCK_SAMPLING) - if (SamplingTool* sampler = globalData->interpreter->sampler()) - sampler->notifyOfScope(this); -#endif +} + +inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst) +{ + if (m_data->m_statements) + m_data->m_statements->emitBytecode(generator, dst); +} + +StatementNode* ScopeNode::singleStatement() const +{ + return m_data->m_statements ? m_data->m_statements->singleStatement() : 0; } // ------------------------------ ProgramNode ----------------------------- @@ -1879,37 +1943,13 @@ RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) RefPtr<RegisterID> dstRegister = generator.newTemporary(); generator.emitLoad(dstRegister.get(), jsUndefined()); - statementListEmitCode(children(), generator, dstRegister.get()); + emitStatementsBytecode(generator, dstRegister.get()); generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine()); generator.emitEnd(dstRegister.get()); return 0; } -void ProgramNode::generateBytecode(ScopeChainNode* scopeChainNode) -{ - ScopeChain scopeChain(scopeChainNode); - JSGlobalObject* globalObject = scopeChain.globalObject(); - - m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider())); - - OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get())); - generator->generate(); - - destroyData(); -} - -#if ENABLE(JIT) -void ProgramNode::generateJITCode(ScopeChainNode* scopeChainNode) -{ - bytecode(scopeChainNode); - ASSERT(m_code); - ASSERT(!m_jitCode); - JIT::compile(scopeChainNode->globalData, m_code.get()); - ASSERT(m_jitCode); -} -#endif - // ------------------------------ EvalNode ----------------------------- inline EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants) @@ -1934,122 +1974,42 @@ RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) RefPtr<RegisterID> dstRegister = generator.newTemporary(); generator.emitLoad(dstRegister.get(), jsUndefined()); - statementListEmitCode(children(), generator, dstRegister.get()); + emitStatementsBytecode(generator, dstRegister.get()); generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine()); generator.emitEnd(dstRegister.get()); return 0; } -void EvalNode::generateBytecode(ScopeChainNode* scopeChainNode) -{ - ScopeChain scopeChain(scopeChainNode); - JSGlobalObject* globalObject = scopeChain.globalObject(); - - m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth())); - - OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get())); - generator->generate(); - - // Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time, - // so the entire ScopeNodeData cannot be destoyed. - children().clear(); -} - -EvalCodeBlock& EvalNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeChainNode, CodeBlock* codeBlockBeingRegeneratedFrom) -{ - ASSERT(!m_code); - - ScopeChain scopeChain(scopeChainNode); - JSGlobalObject* globalObject = scopeChain.globalObject(); - - m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth())); - - OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get())); - generator->setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom); - generator->generate(); - - return *m_code; -} - -void EvalNode::mark() -{ - // We don't need to mark our own CodeBlock as the JSGlobalObject takes care of that - data()->mark(); -} +// ------------------------------ FunctionBodyNode ----------------------------- -#if ENABLE(JIT) -void EvalNode::generateJITCode(ScopeChainNode* scopeChainNode) +FunctionParameters::FunctionParameters(ParameterNode* firstParameter) { - bytecode(scopeChainNode); - ASSERT(m_code); - ASSERT(!m_jitCode); - JIT::compile(scopeChainNode->globalData, m_code.get()); - ASSERT(m_jitCode); + for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam()) + append(parameter->ident()); } -#endif - -// ------------------------------ FunctionBodyNode ----------------------------- inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData) : ScopeNode(globalData) - , m_parameters(0) - , m_parameterCount(0) { } inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants) : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants) - , m_parameters(0) - , m_parameterCount(0) -{ -} - -FunctionBodyNode::~FunctionBodyNode() { - for (size_t i = 0; i < m_parameterCount; ++i) - m_parameters[i].~Identifier(); - fastFree(m_parameters); } -void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter) +void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident) { - Vector<Identifier> parameters; - for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam()) - parameters.append(parameter->ident()); - size_t count = parameters.size(); - setSource(source); - finishParsing(parameters.releaseBuffer(), count); + finishParsing(FunctionParameters::create(firstParameter), ident); } -void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCount) +void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident) { ASSERT(!source().isNull()); m_parameters = parameters; - m_parameterCount = parameterCount; -} - -void FunctionBodyNode::mark() -{ - if (m_code) - m_code->mark(); -} - -#if ENABLE(JIT) -PassRefPtr<FunctionBodyNode> FunctionBodyNode::createNativeThunk(JSGlobalData* globalData) -{ - RefPtr<FunctionBodyNode> body = new FunctionBodyNode(globalData); - globalData->parser->arena().reset(); - body->m_code.set(new CodeBlock(body.get())); - body->m_jitCode = JITCode(JITCode::HostFunction(globalData->jitStubs.ctiNativeCallThunk())); - return body.release(); -} -#endif - -bool FunctionBodyNode::isHostFunction() const -{ - return m_code && m_code->codeType() == NativeCode; + m_ident = ident; } FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData) @@ -2068,59 +2028,14 @@ PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, return node.release(); } -void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode) -{ - // This branch is only necessary since you can still create a non-stub FunctionBodyNode by - // calling Parser::parse<FunctionBodyNode>(). - if (!data()) - scopeChainNode->globalData->parser->reparseInPlace(scopeChainNode->globalData, this); - ASSERT(data()); - - ScopeChain scopeChain(scopeChainNode); - JSGlobalObject* globalObject = scopeChain.globalObject(); - - m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset())); - - OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get())); - generator->generate(); - - destroyData(); -} - -#if ENABLE(JIT) -void FunctionBodyNode::generateJITCode(ScopeChainNode* scopeChainNode) -{ - bytecode(scopeChainNode); - ASSERT(m_code); - ASSERT(!m_jitCode); - JIT::compile(scopeChainNode->globalData, m_code.get()); - ASSERT(m_jitCode); -} -#endif - -CodeBlock& FunctionBodyNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeChainNode, CodeBlock* codeBlockBeingRegeneratedFrom) -{ - ASSERT(!m_code); - - ScopeChain scopeChain(scopeChainNode); - JSGlobalObject* globalObject = scopeChain.globalObject(); - - m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset())); - - OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get())); - generator->setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom); - generator->generate(); - - return *m_code; -} - RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) { generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine()); - statementListEmitCode(children(), generator, generator.ignoredResult()); - if (children().size() && children().last()->isBlock()) { - BlockNode* blockNode = static_cast<BlockNode*>(children().last()); - if (blockNode->children().size() && blockNode->children().last()->isReturnNode()) + emitStatementsBytecode(generator, generator.ignoredResult()); + StatementNode* singleStatement = this->singleStatement(); + if (singleStatement && singleStatement->isBlock()) { + StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement(); + if (lastStatementInBlock && lastStatementInBlock->isReturnNode()) return 0; } @@ -2130,32 +2045,8 @@ RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, Registe return 0; } -UString FunctionBodyNode::paramString() const -{ - UString s(""); - for (size_t pos = 0; pos < m_parameterCount; ++pos) { - if (!s.isEmpty()) - s += ", "; - s += parameters()[pos].ustring(); - } - - return s; -} - -Identifier* FunctionBodyNode::copyParameters() -{ - Identifier* parameters = static_cast<Identifier*>(fastMalloc(m_parameterCount * sizeof(Identifier))); - VectorCopier<false, Identifier>::uninitializedCopy(m_parameters, m_parameters + m_parameterCount, parameters); - return parameters; -} - // ------------------------------ FuncDeclNode --------------------------------- -JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain) -{ - return new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain); -} - RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { if (dst == generator.ignoredResult()) @@ -2170,24 +2061,4 @@ RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* return generator.emitNewFunctionExpression(generator.finalDestination(dst), this); } -JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain) -{ - JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain); - - /* - The Identifier in a FunctionExpression can be referenced from inside - the FunctionExpression's FunctionBody to allow the function to call - itself recursively. However, unlike in a FunctionDeclaration, the - Identifier in a FunctionExpression cannot be referenced from and - does not affect the scope enclosing the FunctionExpression. - */ - - if (!m_ident.isNull()) { - JSStaticScopeObject* functionScopeObject = new (exec) JSStaticScopeObject(exec, m_ident, func, ReadOnly | DontDelete); - func->scope().push(functionScopeObject); - } - - return func; -} - } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.h b/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.h index 84e8b958a..be84c4a1b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.h +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Nodes.h @@ -34,21 +34,17 @@ #include "SourceCode.h" #include "SymbolTable.h" #include <wtf/MathExtras.h> -#include <wtf/OwnPtr.h> namespace JSC { class ArgumentListNode; - class CodeBlock; class BytecodeGenerator; - class FuncDeclNode; - class EvalCodeBlock; - class JSFunction; - class ProgramCodeBlock; + class FunctionBodyNode; class PropertyListNode; class ReadModifyResolveNode; class RegisterID; class ScopeChainNode; + class ScopeNode; typedef unsigned CodeFeatures; @@ -86,8 +82,8 @@ namespace JSC { namespace DeclarationStacks { enum VarAttrs { IsConstant = 1, HasInitializer = 2 }; - typedef Vector<std::pair<Identifier, unsigned> > VarStack; - typedef Vector<FuncDeclNode*> FunctionStack; + typedef Vector<std::pair<const Identifier*, unsigned> > VarStack; + typedef Vector<FunctionBodyNode*> FunctionStack; } struct SwitchInfo { @@ -96,24 +92,23 @@ namespace JSC { SwitchType switchType; }; - class ParserArenaDeletable { - protected: - ParserArenaDeletable() { } + class ParserArenaFreeable { + public: + // ParserArenaFreeable objects are are freed when the arena is deleted. + // Destructors are not called. Clients must not call delete on such objects. + void* operator new(size_t, JSGlobalData*); + }; + class ParserArenaDeletable { public: virtual ~ParserArenaDeletable() { } - // Objects created with this version of new are deleted when the arena is deleted. + // ParserArenaDeletable objects are deleted when the arena is deleted. + // Clients must not call delete directly on such objects. void* operator new(size_t, JSGlobalData*); - - // Objects created with this version of new are not deleted when the arena is deleted. - // Other arrangements must be made. - void* operator new(size_t); - - void operator delete(void*); }; - class ParserArenaRefCounted : public RefCountedCustomAllocated<ParserArenaRefCounted> { + class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> { protected: ParserArenaRefCounted(JSGlobalData*); @@ -124,34 +119,14 @@ namespace JSC { } }; - class Node : public ParserArenaDeletable { + class Node : public ParserArenaFreeable { protected: Node(JSGlobalData*); public: - /* - Return value: The register holding the production's value. - dst: An optional parameter specifying the most efficient - destination at which to store the production's value. - The callee must honor dst. - - dst provides for a crude form of copy propagation. For example, - - x = 1 + virtual ~Node() { } - becomes - - load r[x], 1 - - instead of - - load r0, 1 - mov r[x], r0 - - because the assignment node, "x =", passes r[x] as dst to the number - node, "1". - */ - virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0) = 0; + virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0; int lineNo() const { return m_line; } @@ -160,9 +135,10 @@ namespace JSC { }; class ExpressionNode : public Node { - public: + protected: ExpressionNode(JSGlobalData*, ResultType = ResultType::unknownType()); + public: virtual bool isNumber() const { return false; } virtual bool isString() const { return false; } virtual bool isNull() const { return false; } @@ -180,18 +156,16 @@ namespace JSC { ResultType resultDescriptor() const { return m_resultType; } - // This needs to be in public in order to compile using GCC 3.x - typedef enum { EvalOperator, FunctionCall } CallerType; - private: ResultType m_resultType; }; class StatementNode : public Node { - public: + protected: StatementNode(JSGlobalData*); - void setLoc(int line0, int line1); + public: + void setLoc(int firstLine, int lastLine); int firstLine() const { return lineNo(); } int lastLine() const { return m_lastLine; } @@ -229,10 +203,10 @@ namespace JSC { class NumberNode : public ExpressionNode { public: - NumberNode(JSGlobalData*, double v); + NumberNode(JSGlobalData*, double value); - double value() const { return m_double; } - void setValue(double d) { m_double = d; } + double value() const { return m_value; } + void setValue(double value) { m_value = value; } private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -240,22 +214,23 @@ namespace JSC { virtual bool isNumber() const { return true; } virtual bool isPure(BytecodeGenerator&) const { return true; } - double m_double; + double m_value; }; class StringNode : public ExpressionNode { public: - StringNode(JSGlobalData*, const Identifier& v); + StringNode(JSGlobalData*, const Identifier&); const Identifier& value() { return m_value; } - virtual bool isPure(BytecodeGenerator&) const { return true; } private: + virtual bool isPure(BytecodeGenerator&) const { return true; } + virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); virtual bool isString() const { return true; } - Identifier m_value; + const Identifier& m_value; }; class ThrowableExpressionData { @@ -286,8 +261,9 @@ namespace JSC { uint16_t endOffset() const { return m_endOffset; } protected: - RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg); - RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg, const Identifier&); + RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message); + RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message, const UString&); + RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message, const Identifier&); private: uint32_t m_divot; @@ -298,8 +274,7 @@ namespace JSC { class ThrowableSubExpressionData : public ThrowableExpressionData { public: ThrowableSubExpressionData() - : ThrowableExpressionData() - , m_subexpressionDivotOffset(0) + : m_subexpressionDivotOffset(0) , m_subexpressionEndOffset(0) { } @@ -328,8 +303,7 @@ namespace JSC { class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData { public: ThrowablePrefixedSubExpressionData() - : ThrowableExpressionData() - , m_subexpressionDivotOffset(0) + : m_subexpressionDivotOffset(0) , m_subexpressionStartOffset(0) { } @@ -357,13 +331,13 @@ namespace JSC { class RegExpNode : public ExpressionNode, public ThrowableExpressionData { public: - RegExpNode(JSGlobalData*, const UString& pattern, const UString& flags); + RegExpNode(JSGlobalData*, const Identifier& pattern, const Identifier& flags); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - UString m_pattern; - UString m_flags; + const Identifier& m_pattern; + const Identifier& m_flags; }; class ThisNode : public ExpressionNode { @@ -387,11 +361,11 @@ namespace JSC { virtual bool isLocation() const { return true; } virtual bool isResolveNode() const { return true; } - Identifier m_ident; + const Identifier& m_ident; int32_t m_startOffset; }; - class ElementNode : public ParserArenaDeletable { + class ElementNode : public ParserArenaFreeable { public: ElementNode(JSGlobalData*, int elision, ExpressionNode*); ElementNode(JSGlobalData*, ElementNode*, int elision, ExpressionNode*); @@ -424,17 +398,18 @@ namespace JSC { bool m_optional; }; - class PropertyNode : public ParserArenaDeletable { + class PropertyNode : public ParserArenaFreeable { public: enum Type { Constant, Getter, Setter }; PropertyNode(JSGlobalData*, const Identifier& name, ExpressionNode* value, Type); + PropertyNode(JSGlobalData*, double name, ExpressionNode* value, Type); const Identifier& name() const { return m_name; } private: friend class PropertyListNode; - Identifier m_name; + const Identifier& m_name; ExpressionNode* m_assign; Type m_type; }; @@ -494,7 +469,7 @@ namespace JSC { virtual bool isDotAccessorNode() const { return true; } ExpressionNode* m_base; - Identifier m_ident; + const Identifier& m_ident; }; class ArgumentListNode : public Node { @@ -509,7 +484,7 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); }; - class ArgumentsNode : public ParserArenaDeletable { + class ArgumentsNode : public ParserArenaFreeable { public: ArgumentsNode(JSGlobalData*); ArgumentsNode(JSGlobalData*, ArgumentListNode*); @@ -557,7 +532,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; ArgumentsNode* m_args; size_t m_index; // Used by LocalVarFunctionCallNode. size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode @@ -584,7 +559,7 @@ namespace JSC { protected: ExpressionNode* m_base; - const Identifier m_ident; + const Identifier& m_ident; ArgumentsNode* m_args; }; @@ -609,7 +584,7 @@ namespace JSC { PrePostResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset); protected: - const Identifier m_ident; + const Identifier& m_ident; }; class PostfixResolveNode : public PrePostResolveNode { @@ -642,7 +617,7 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); ExpressionNode* m_base; - Identifier m_ident; + const Identifier& m_ident; Operator m_operator; }; @@ -664,7 +639,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; }; class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData { @@ -686,7 +661,7 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); ExpressionNode* m_base; - Identifier m_ident; + const Identifier& m_ident; }; class DeleteValueNode : public ExpressionNode { @@ -718,7 +693,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; }; class TypeOfValueNode : public ExpressionNode { @@ -761,7 +736,7 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); ExpressionNode* m_base; - Identifier m_ident; + const Identifier& m_ident; Operator m_operator; }; @@ -820,7 +795,7 @@ namespace JSC { BinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); BinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); - RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0); + RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -1003,7 +978,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; ExpressionNode* m_right; size_t m_index; // Used by ReadModifyLocalVarNode. Operator m_operator; @@ -1017,7 +992,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; ExpressionNode* m_right; size_t m_index; // Used by ReadModifyLocalVarNode. bool m_rightHasAssignments; @@ -1060,7 +1035,7 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); ExpressionNode* m_base; - Identifier m_ident; + const Identifier& m_ident; ExpressionNode* m_right; bool m_rightHasAssignments; }; @@ -1073,7 +1048,7 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); ExpressionNode* m_base; - Identifier m_ident; + const Identifier& m_ident; ExpressionNode* m_right; Operator m_operator : 31; bool m_rightHasAssignments : 1; @@ -1093,10 +1068,12 @@ namespace JSC { typedef Vector<ExpressionNode*, 8> ExpressionVector; - class CommaNode : public ExpressionNode { + class CommaNode : public ExpressionNode, public ParserArenaDeletable { public: CommaNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2); + using ParserArenaDeletable::operator new; + void append(ExpressionNode* expr) { m_expressions.append(expr); } private: @@ -1117,7 +1094,7 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); virtual RegisterID* emitCodeSingle(BytecodeGenerator&); - Identifier m_ident; + const Identifier& m_ident; public: ConstDeclNode* m_next; @@ -1136,36 +1113,33 @@ namespace JSC { ConstDeclNode* m_next; }; - typedef Vector<StatementNode*> StatementVector; - class SourceElements : public ParserArenaDeletable { public: SourceElements(JSGlobalData*); void append(StatementNode*); - void releaseContentsIntoVector(StatementVector& destination) - { - ASSERT(destination.isEmpty()); - m_statements.swap(destination); - destination.shrinkToFit(); - } + + StatementNode* singleStatement() const; + StatementNode* lastStatement() const; + + void emitBytecode(BytecodeGenerator&, RegisterID* destination); private: - StatementVector m_statements; + Vector<StatementNode*> m_statements; }; class BlockNode : public StatementNode { public: - BlockNode(JSGlobalData*, SourceElements* children); + BlockNode(JSGlobalData*, SourceElements* = 0); - StatementVector& children() { return m_children; } + StatementNode* lastStatement() const; private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); virtual bool isBlock() const { return true; } - StatementVector m_children; + SourceElements* m_statements; }; class EmptyStatementNode : public StatementNode { @@ -1275,7 +1249,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; ExpressionNode* m_init; ExpressionNode* m_lexpr; ExpressionNode* m_expr; @@ -1291,7 +1265,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; }; class BreakNode : public StatementNode, public ThrowableExpressionData { @@ -1302,7 +1276,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_ident; + const Identifier& m_ident; }; class ReturnNode : public StatementNode, public ThrowableExpressionData { @@ -1337,7 +1311,7 @@ namespace JSC { private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_name; + const Identifier& m_name; StatementNode* m_statement; }; @@ -1356,16 +1330,16 @@ namespace JSC { TryNode(JSGlobalData*, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock); private: - virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0); + virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); StatementNode* m_tryBlock; - Identifier m_exceptionIdent; + const Identifier& m_exceptionIdent; StatementNode* m_catchBlock; StatementNode* m_finallyBlock; bool m_catchHasEval; }; - class ParameterNode : public ParserArenaDeletable { + class ParameterNode : public ParserArenaFreeable { public: ParameterNode(JSGlobalData*, const Identifier&); ParameterNode(JSGlobalData*, ParameterNode*, const Identifier&); @@ -1374,11 +1348,11 @@ namespace JSC { ParameterNode* nextParam() const { return m_next; } private: - Identifier m_ident; + const Identifier& m_ident; ParameterNode* m_next; }; - struct ScopeNodeData { + struct ScopeNodeData : FastAllocBase { typedef DeclarationStacks::VarStack VarStack; typedef DeclarationStacks::FunctionStack FunctionStack; @@ -1388,9 +1362,7 @@ namespace JSC { VarStack m_varStack; FunctionStack m_functionStack; int m_numConstants; - StatementVector m_children; - - void mark(); + SourceElements* m_statements; }; class ScopeNode : public StatementNode, public ParserArenaRefCounted { @@ -1401,6 +1373,8 @@ namespace JSC { ScopeNode(JSGlobalData*); ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants); + using ParserArenaRefCounted::operator new; + void adoptData(std::auto_ptr<ScopeNodeData> data) { ASSERT(!data->m_arena.contains(this)); @@ -1426,8 +1400,6 @@ namespace JSC { VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; } FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; } - StatementVector& children() { ASSERT(m_data); return m_data->m_children; } - int neededConstants() { ASSERT(m_data); @@ -1436,33 +1408,13 @@ namespace JSC { return m_data->m_numConstants + 2; } - virtual void mark() { } + StatementNode* singleStatement() const; -#if ENABLE(JIT) - JITCode& generatedJITCode() - { - ASSERT(m_jitCode); - return m_jitCode; - } - - ExecutablePool* getExecutablePool() - { - return m_jitCode.getExecutablePool(); - } - - void setJITCode(const JITCode jitCode) - { - m_jitCode = jitCode; - } -#endif + void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination); protected: void setSource(const SourceCode& source) { m_source = source; } -#if ENABLE(JIT) - JITCode m_jitCode; -#endif - private: OwnPtr<ScopeNodeData> m_data; CodeFeatures m_features; @@ -1473,187 +1425,99 @@ namespace JSC { public: static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); - ProgramCodeBlock& bytecode(ScopeChainNode* scopeChain) - { - if (!m_code) - generateBytecode(scopeChain); - return *m_code; - } - -#if ENABLE(JIT) - JITCode& jitCode(ScopeChainNode* scopeChain) - { - if (!m_jitCode) - generateJITCode(scopeChain); - return m_jitCode; - } -#endif + static const bool scopeIsFunction = false; private: ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); - void generateBytecode(ScopeChainNode*); virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - -#if ENABLE(JIT) - void generateJITCode(ScopeChainNode*); -#endif - - OwnPtr<ProgramCodeBlock> m_code; }; class EvalNode : public ScopeNode { public: static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); - EvalCodeBlock& bytecode(ScopeChainNode* scopeChain) - { - if (!m_code) - generateBytecode(scopeChain); - return *m_code; - } - - EvalCodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*); - - virtual void mark(); - -#if ENABLE(JIT) - JITCode& jitCode(ScopeChainNode* scopeChain) - { - if (!m_jitCode) - generateJITCode(scopeChain); - return m_jitCode; - } -#endif + static const bool scopeIsFunction = false; private: EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); - void generateBytecode(ScopeChainNode*); virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); + }; -#if ENABLE(JIT) - void generateJITCode(ScopeChainNode*); -#endif - - OwnPtr<EvalCodeBlock> m_code; + class FunctionParameters : public Vector<Identifier>, public RefCounted<FunctionParameters> { + public: + static PassRefPtr<FunctionParameters> create(ParameterNode* firstParameter) { return adoptRef(new FunctionParameters(firstParameter)); } + + private: + FunctionParameters(ParameterNode*); }; class FunctionBodyNode : public ScopeNode { - friend class JIT; public: -#if ENABLE(JIT) - static PassRefPtr<FunctionBodyNode> createNativeThunk(JSGlobalData*); -#endif static FunctionBodyNode* create(JSGlobalData*); static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); - virtual ~FunctionBodyNode(); - const Identifier* parameters() const { return m_parameters; } - size_t parameterCount() const { return m_parameterCount; } - UString paramString() const ; - Identifier* copyParameters(); + FunctionParameters* parameters() const { return m_parameters.get(); } + size_t parameterCount() const { return m_parameters->size(); } virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - bool isGenerated() const - { - return m_code; - } - - bool isHostFunction() const; - - virtual void mark(); - - void finishParsing(const SourceCode&, ParameterNode*); - void finishParsing(Identifier* parameters, size_t parameterCount); + void finishParsing(const SourceCode&, ParameterNode*, const Identifier&); + void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&); - UString toSourceString() const { return source().toString(); } + const Identifier& ident() { return m_ident; } - CodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*); -#if ENABLE(JIT) - JITCode& jitCode(ScopeChainNode* scopeChain) - { - if (!m_jitCode) - generateJITCode(scopeChain); - return m_jitCode; - } -#endif + static const bool scopeIsFunction = true; - CodeBlock& bytecode(ScopeChainNode* scopeChain) - { - ASSERT(scopeChain); - if (!m_code) - generateBytecode(scopeChain); - return *m_code; - } - - CodeBlock& generatedBytecode() - { - ASSERT(m_code); - return *m_code; - } - private: FunctionBodyNode(JSGlobalData*); FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); - void generateBytecode(ScopeChainNode*); -#if ENABLE(JIT) - void generateJITCode(ScopeChainNode*); -#endif - Identifier* m_parameters; - size_t m_parameterCount; - OwnPtr<CodeBlock> m_code; + Identifier m_ident; + RefPtr<FunctionParameters> m_parameters; }; - class FuncExprNode : public ExpressionNode, public ParserArenaRefCounted { + class FuncExprNode : public ExpressionNode { public: FuncExprNode(JSGlobalData*, const Identifier&, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0); - JSFunction* makeFunction(ExecState*, ScopeChainNode*); - - FunctionBodyNode* body() { return m_body.get(); } + FunctionBodyNode* body() { return m_body; } private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); virtual bool isFuncExprNode() const { return true; } - Identifier m_ident; - RefPtr<FunctionBodyNode> m_body; + FunctionBodyNode* m_body; }; - class FuncDeclNode : public StatementNode, public ParserArenaRefCounted { + class FuncDeclNode : public StatementNode { public: FuncDeclNode(JSGlobalData*, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0); - JSFunction* makeFunction(ExecState*, ScopeChainNode*); - - Identifier m_ident; - - FunctionBodyNode* body() { return m_body.get(); } + FunctionBodyNode* body() { return m_body; } private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - RefPtr<FunctionBodyNode> m_body; + FunctionBodyNode* m_body; }; - class CaseClauseNode : public ParserArenaDeletable { + class CaseClauseNode : public ParserArenaFreeable { public: - CaseClauseNode(JSGlobalData*, ExpressionNode*); - CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements*); + CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements* = 0); ExpressionNode* expr() const { return m_expr; } - StatementVector& children() { return m_children; } + + void emitBytecode(BytecodeGenerator&, RegisterID* destination); private: ExpressionNode* m_expr; - StatementVector m_children; + SourceElements* m_statements; }; - class ClauseListNode : public ParserArenaDeletable { + class ClauseListNode : public ParserArenaFreeable { public: ClauseListNode(JSGlobalData*, CaseClauseNode*); ClauseListNode(JSGlobalData*, ClauseListNode*, CaseClauseNode*); @@ -1666,11 +1530,11 @@ namespace JSC { ClauseListNode* m_next; }; - class CaseBlockNode : public ParserArenaDeletable { + class CaseBlockNode : public ParserArenaFreeable { public: CaseBlockNode(JSGlobalData*, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2); - RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* dst = 0); + RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination); private: SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num); diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Parser.cpp b/src/3rdparty/webkit/JavaScriptCore/parser/Parser.cpp index 96f4ae6ae..4c046d062 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Parser.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Parser.cpp @@ -53,7 +53,7 @@ void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg) *errMsg = 0; Lexer& lexer = *globalData->lexer; - lexer.setCode(*m_source); + lexer.setCode(*m_source, m_arena); int parseError = jscyyparse(globalData); bool lexError = lexer.sawError(); @@ -67,33 +67,6 @@ void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg) } } -void Parser::reparseInPlace(JSGlobalData* globalData, FunctionBodyNode* functionBodyNode) -{ - ASSERT(!functionBodyNode->data()); - - m_source = &functionBodyNode->source(); - globalData->lexer->setIsReparsing(); - parse(globalData, 0, 0); - ASSERT(m_sourceElements); - - functionBodyNode->adoptData(std::auto_ptr<ScopeNodeData>(new ScopeNodeData(globalData->parser->arena(), - m_sourceElements, - m_varDeclarations ? &m_varDeclarations->data : 0, - m_funcDeclarations ? &m_funcDeclarations->data : 0, - m_numConstants))); - bool usesArguments = functionBodyNode->usesArguments(); - functionBodyNode->setFeatures(m_features); - if (usesArguments && !functionBodyNode->usesArguments()) - functionBodyNode->setUsesArguments(); - - ASSERT(globalData->parser->arena().isEmpty()); - - m_source = 0; - m_sourceElements = 0; - m_varDeclarations = 0; - m_funcDeclarations = 0; -} - void Parser::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack, ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants) { diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/Parser.h b/src/3rdparty/webkit/JavaScriptCore/parser/Parser.h index 373dc0008..894f70982 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/Parser.h +++ b/src/3rdparty/webkit/JavaScriptCore/parser/Parser.h @@ -24,7 +24,11 @@ #define Parser_h #include "Debugger.h" +#include "Executable.h" +#include "JSGlobalObject.h" +#include "Lexer.h" #include "Nodes.h" +#include "ParserArena.h" #include "SourceProvider.h" #include <wtf/Forward.h> #include <wtf/Noncopyable.h> @@ -41,9 +45,8 @@ namespace JSC { class Parser : public Noncopyable { public: - template <class ParsedNode> PassRefPtr<ParsedNode> parse(ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0); - template <class ParsedNode> PassRefPtr<ParsedNode> reparse(JSGlobalData*, ParsedNode*); - void reparseInPlace(JSGlobalData*, FunctionBodyNode*); + template <class ParsedNode> + PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, Debugger*, ExecState*, const SourceCode& source, int* errLine = 0, UString* errMsg = 0); void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures features, int lastLine, int numConstants); @@ -63,55 +66,35 @@ namespace JSC { int m_numConstants; }; - template <class ParsedNode> PassRefPtr<ParsedNode> Parser::parse(ExecState* exec, Debugger* debugger, const SourceCode& source, int* errLine, UString* errMsg) + template <class ParsedNode> + PassRefPtr<ParsedNode> Parser::parse(JSGlobalData* globalData, Debugger* debugger, ExecState* debuggerExecState, const SourceCode& source, int* errLine, UString* errMsg) { m_source = &source; - parse(&exec->globalData(), errLine, errMsg); - RefPtr<ParsedNode> result; - if (m_sourceElements) { - result = ParsedNode::create(&exec->globalData(), - m_sourceElements, - m_varDeclarations ? &m_varDeclarations->data : 0, - m_funcDeclarations ? &m_funcDeclarations->data : 0, - *m_source, - m_features, - m_numConstants); - result->setLoc(m_source->firstLine(), m_lastLine); - } - - m_arena.reset(); - - m_source = 0; - m_varDeclarations = 0; - m_funcDeclarations = 0; + if (ParsedNode::scopeIsFunction) + globalData->lexer->setIsReparsing(); + parse(globalData, errLine, errMsg); - if (debugger) - debugger->sourceParsed(exec, source, *errLine, *errMsg); - return result.release(); - } - - template <class ParsedNode> PassRefPtr<ParsedNode> Parser::reparse(JSGlobalData* globalData, ParsedNode* oldParsedNode) - { - m_source = &oldParsedNode->source(); - parse(globalData, 0, 0); RefPtr<ParsedNode> result; if (m_sourceElements) { result = ParsedNode::create(globalData, - m_sourceElements, - m_varDeclarations ? &m_varDeclarations->data : 0, - m_funcDeclarations ? &m_funcDeclarations->data : 0, - *m_source, - oldParsedNode->features(), - m_numConstants); + m_sourceElements, + m_varDeclarations ? &m_varDeclarations->data : 0, + m_funcDeclarations ? &m_funcDeclarations->data : 0, + source, + m_features, + m_numConstants); result->setLoc(m_source->firstLine(), m_lastLine); } m_arena.reset(); m_source = 0; + m_sourceElements = 0; m_varDeclarations = 0; m_funcDeclarations = 0; + if (debugger && !ParsedNode::scopeIsFunction) + debugger->sourceParsed(debuggerExecState, source, *errLine, *errMsg); return result.release(); } diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.cpp b/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.cpp index 261750668..a8e815953 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.cpp @@ -30,9 +30,39 @@ namespace JSC { +ParserArena::ParserArena() + : m_freeableMemory(0) + , m_freeablePoolEnd(0) + , m_identifierArena(new IdentifierArena) +{ +} + +inline void* ParserArena::freeablePool() +{ + ASSERT(m_freeablePoolEnd); + return m_freeablePoolEnd - freeablePoolSize; +} + +inline void ParserArena::deallocateObjects() +{ + if (m_freeablePoolEnd) + fastFree(freeablePool()); + + size_t size = m_freeablePools.size(); + for (size_t i = 0; i < size; ++i) + fastFree(m_freeablePools[i]); + + size = m_deletableObjects.size(); + for (size_t i = 0; i < size; ++i) { + ParserArenaDeletable* object = m_deletableObjects[i]; + object->~ParserArenaDeletable(); + fastFree(object); + } +} + ParserArena::~ParserArena() { - deleteAllValues(m_deletableObjects); + deallocateObjects(); } bool ParserArena::contains(ParserArenaRefCounted* object) const @@ -52,9 +82,43 @@ void ParserArena::removeLast() void ParserArena::reset() { - deleteAllValues(m_deletableObjects); - m_deletableObjects.shrink(0); - m_refCountedObjects.shrink(0); + // Since this code path is used only when parsing fails, it's not bothering to reuse + // any of the memory the arena allocated. We could improve that later if we want to + // efficiently reuse the same arena. + + deallocateObjects(); + + m_freeableMemory = 0; + m_freeablePoolEnd = 0; + m_identifierArena->clear(); + m_freeablePools.clear(); + m_deletableObjects.clear(); + m_refCountedObjects.clear(); +} + +void ParserArena::allocateFreeablePool() +{ + if (m_freeablePoolEnd) + m_freeablePools.append(freeablePool()); + + char* pool = static_cast<char*>(fastMalloc(freeablePoolSize)); + m_freeableMemory = pool; + m_freeablePoolEnd = pool + freeablePoolSize; + ASSERT(freeablePool() == pool); +} + +bool ParserArena::isEmpty() const +{ + return !m_freeablePoolEnd + && m_identifierArena->isEmpty() + && m_freeablePools.isEmpty() + && m_deletableObjects.isEmpty() + && m_refCountedObjects.isEmpty(); +} + +void ParserArena::derefWithArena(PassRefPtr<ParserArenaRefCounted> object) +{ + m_refCountedObjects.append(object); } } diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.h b/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.h index 66c8529ab..eef8e9393 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.h +++ b/src/3rdparty/webkit/JavaScriptCore/parser/ParserArena.h @@ -26,35 +26,101 @@ #ifndef ParserArena_h #define ParserArena_h -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> -#include <wtf/Vector.h> +#include "Identifier.h" +#include <wtf/SegmentedVector.h> namespace JSC { class ParserArenaDeletable; class ParserArenaRefCounted; - class ParserArena { + class IdentifierArena : public FastAllocBase { public: + ALWAYS_INLINE const Identifier& makeIdentifier(JSGlobalData*, const UChar* characters, size_t length); + const Identifier& makeNumericIdentifier(JSGlobalData*, double number); + + void clear() { m_identifiers.clear(); } + bool isEmpty() const { return m_identifiers.isEmpty(); } + + private: + typedef SegmentedVector<Identifier, 64> IdentifierVector; + IdentifierVector m_identifiers; + }; + + ALWAYS_INLINE const Identifier& IdentifierArena::makeIdentifier(JSGlobalData* globalData, const UChar* characters, size_t length) + { + m_identifiers.append(Identifier(globalData, characters, length)); + return m_identifiers.last(); + } + + inline const Identifier& IdentifierArena::makeNumericIdentifier(JSGlobalData* globalData, double number) + { + m_identifiers.append(Identifier(globalData, UString::from(number))); + return m_identifiers.last(); + } + + class ParserArena : Noncopyable { + public: + ParserArena(); + ~ParserArena(); + void swap(ParserArena& otherArena) { + std::swap(m_freeableMemory, otherArena.m_freeableMemory); + std::swap(m_freeablePoolEnd, otherArena.m_freeablePoolEnd); + m_identifierArena.swap(otherArena.m_identifierArena); + m_freeablePools.swap(otherArena.m_freeablePools); m_deletableObjects.swap(otherArena.m_deletableObjects); m_refCountedObjects.swap(otherArena.m_refCountedObjects); } - ~ParserArena(); - void deleteWithArena(ParserArenaDeletable* object) { m_deletableObjects.append(object); } - void derefWithArena(PassRefPtr<ParserArenaRefCounted> object) { m_refCountedObjects.append(object); } + void* allocateFreeable(size_t size) + { + ASSERT(size); + ASSERT(size <= freeablePoolSize); + size_t alignedSize = alignSize(size); + ASSERT(alignedSize <= freeablePoolSize); + if (UNLIKELY(static_cast<size_t>(m_freeablePoolEnd - m_freeableMemory) < alignedSize)) + allocateFreeablePool(); + void* block = m_freeableMemory; + m_freeableMemory += alignedSize; + return block; + } + + void* allocateDeletable(size_t size) + { + ParserArenaDeletable* deletable = static_cast<ParserArenaDeletable*>(fastMalloc(size)); + m_deletableObjects.append(deletable); + return deletable; + } + void derefWithArena(PassRefPtr<ParserArenaRefCounted>); bool contains(ParserArenaRefCounted*) const; ParserArenaRefCounted* last() const; void removeLast(); - bool isEmpty() const { return m_deletableObjects.isEmpty() && m_refCountedObjects.isEmpty(); } + bool isEmpty() const; void reset(); + IdentifierArena& identifierArena() { return *m_identifierArena; } + private: + static const size_t freeablePoolSize = 8000; + + static size_t alignSize(size_t size) + { + return (size + sizeof(WTF::AllocAlignmentInteger) - 1) & ~(sizeof(WTF::AllocAlignmentInteger) - 1); + } + + void* freeablePool(); + void allocateFreeablePool(); + void deallocateObjects(); + + char* m_freeableMemory; + char* m_freeablePoolEnd; + + OwnPtr<IdentifierArena> m_identifierArena; + Vector<void*> m_freeablePools; Vector<ParserArenaDeletable*> m_deletableObjects; Vector<RefPtr<ParserArenaRefCounted> > m_refCountedObjects; }; diff --git a/src/3rdparty/webkit/JavaScriptCore/parser/SourceCode.h b/src/3rdparty/webkit/JavaScriptCore/parser/SourceCode.h index 84360b84c..9ba4da3d8 100644 --- a/src/3rdparty/webkit/JavaScriptCore/parser/SourceCode.h +++ b/src/3rdparty/webkit/JavaScriptCore/parser/SourceCode.h @@ -37,7 +37,8 @@ namespace JSC { class SourceCode { public: SourceCode() - : m_startChar(0) + : m_provider(0) + , m_startChar(0) , m_endChar(0) , m_firstLine(0) { |