diff options
Diffstat (limited to 'JavaScriptCore/parser')
-rw-r--r-- | JavaScriptCore/parser/Grammar.y | 486 | ||||
-rw-r--r-- | JavaScriptCore/parser/Lexer.cpp | 101 | ||||
-rw-r--r-- | JavaScriptCore/parser/Lexer.h | 8 | ||||
-rw-r--r-- | JavaScriptCore/parser/NodeConstructors.h | 17 | ||||
-rw-r--r-- | JavaScriptCore/parser/Nodes.cpp | 186 | ||||
-rw-r--r-- | JavaScriptCore/parser/Nodes.h | 154 | ||||
-rw-r--r-- | JavaScriptCore/parser/Parser.h | 63 |
7 files changed, 581 insertions, 434 deletions
diff --git a/JavaScriptCore/parser/Grammar.y b/JavaScriptCore/parser/Grammar.y index 227fdb5..354c786 100644 --- a/JavaScriptCore/parser/Grammar.y +++ b/JavaScriptCore/parser/Grammar.y @@ -25,12 +25,18 @@ #include "config.h" +#include <string.h> +#include <stdlib.h> +#include "JSValue.h" #include "JSObject.h" -#include "JSString.h" #include "NodeConstructors.h" +#include "Lexer.h" +#include "JSString.h" +#include "JSGlobalData.h" +#include "CommonIdentifiers.h" #include "NodeInfo.h" -#include <stdlib.h> -#include <string.h> +#include "Parser.h" +#include <wtf/FastMalloc.h> #include <wtf/MathExtras.h> #define YYMALLOC fastMalloc @@ -39,44 +45,46 @@ #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 by not setting this on the Darwin platform. -// FIXME: Is this still needed? + // avoid triggering warnings in older bison #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 AUTO_SEMICOLON do { if (!allowAutomaticSemicolon(*GLOBAL_DATA->lexer, yychar)) YYABORT; } while (0) +#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) using namespace JSC; using namespace std; -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); +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); #if COMPILER(MSVC) @@ -89,17 +97,17 @@ static ExpressionNode* combineCommaNodes(JSGlobalData*, ExpressionNode* list, Ex #define YYPARSE_PARAM globalPtr #define YYLEX_PARAM globalPtr -template <typename T> inline NodeDeclarationInfo<T> createNodeDeclarationInfo(T node, - ParserArenaData<DeclarationStacks::VarStack>* varDecls, - ParserArenaData<DeclarationStacks::FunctionStack>* funcDecls, - CodeFeatures info, int numConstants) +template <typename T> 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> inline NodeInfo<T> createNodeInfo(T node, CodeFeatures info, int numConstants) +template <typename T> NodeInfo<T> createNodeInfo(T node, CodeFeatures info, int numConstants) { ASSERT((info & ~AllFeatures) == 0); NodeInfo<T> result = { node, info, numConstants }; @@ -125,21 +133,21 @@ template <typename T> inline T mergeDeclarationLists(T decls1, T decls2) return decls1; } -static void appendToVarDeclarationList(JSGlobalData* globalData, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, const Identifier& ident, unsigned attrs) +static void appendToVarDeclarationList(void* globalPtr, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, const Identifier& ident, unsigned attrs) { if (!varDecls) - varDecls = new (globalData) ParserArenaData<DeclarationStacks::VarStack>; + varDecls = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>; varDecls->data.append(make_pair(ident, attrs)); } -static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, ConstDeclNode* decl) +static inline void appendToVarDeclarationList(void* globalPtr, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, ConstDeclNode* decl) { unsigned attrs = DeclarationStacks::IsConstant; if (decl->hasInitializer()) attrs |= DeclarationStacks::HasInitializer; - appendToVarDeclarationList(globalData, varDecls, decl->ident(), attrs); + appendToVarDeclarationList(globalPtr, varDecls, decl->ident(), attrs); } %} @@ -176,20 +184,6 @@ static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserAr 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 */ @@ -297,25 +291,21 @@ 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 = *GLOBAL_DATA->lexer; - const Identifier* pattern; - const Identifier* flags; - if (!l.scanRegExp(pattern, flags)) + Lexer& l = *LEXER; + if (!l.scanRegExp()) YYABORT; - 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); + 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); $$ = createNodeInfo<ExpressionNode*>(node, 0, 0); } | DIVEQUAL /* regexp with /= */ { - Lexer& l = *GLOBAL_DATA->lexer; - const Identifier* pattern; - const Identifier* flags; - if (!l.scanRegExp(pattern, flags, '=')) + Lexer& l = *LEXER; + if (!l.scanRegExp()) YYABORT; - 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); + 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); $$ = createNodeInfo<ExpressionNode*>(node, 0, 0); } ; @@ -323,14 +313,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, $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; } + | 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; } | IDENT IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE { - $$ = 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); + $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(globalPtr, *$1, *$2, $4.m_node.head, $7, LEXER->sourceCode($6, $8, @6.first_line)), $4.m_features | ClosureFeature, 0); if ($4.m_features & ArgumentsFeature) $7->setUsesArguments(); - setStatementLocation($7, @6, @8); + DBG($7, @6, @8); if (!$$.m_node) YYABORT; } @@ -395,15 +385,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); - setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); + SET_EXCEPTION_LOCATION(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); - setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); + SET_EXCEPTION_LOCATION(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); - setExceptionLocation(node, @1.first_column, @2.last_column, @3.last_column); + SET_EXCEPTION_LOCATION(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); } ; @@ -411,15 +401,15 @@ MemberExpr: MemberExprNoBF: PrimaryExprNoBrace | MemberExprNoBF '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); + SET_EXCEPTION_LOCATION(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); - setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); + SET_EXCEPTION_LOCATION(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); - setExceptionLocation(node, @1.first_column, @2.last_column, @3.last_column); + SET_EXCEPTION_LOCATION(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); } ; @@ -427,7 +417,7 @@ MemberExprNoBF: NewExpr: MemberExpr | NEW NewExpr { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features, $2.m_numConstants); } ; @@ -435,32 +425,32 @@ NewExpr: NewExprNoBF: MemberExprNoBF | NEW NewExpr { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features, $2.m_numConstants); } ; CallExpr: - 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); } + 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); } | CallExpr '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); + SET_EXCEPTION_LOCATION(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); - setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); } ; CallExprNoBF: - 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); } + 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); } | CallExprNoBF '[' Expr ']' { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @1.last_column, @4.last_column); + SET_EXCEPTION_LOCATION(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); - setExceptionLocation(node, @1.first_column, @1.last_column, @3.last_column); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column); $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); } ; @@ -578,10 +568,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); - setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); + SET_EXCEPTION_LOCATION(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); - setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); + SET_EXCEPTION_LOCATION(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); } ; @@ -593,7 +583,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); - setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); + SET_EXCEPTION_LOCATION(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); } ; @@ -605,11 +595,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); - setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); + SET_EXCEPTION_LOCATION(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); - setExceptionLocation(node, @1.first_column, @3.first_column, @3.last_column); + SET_EXCEPTION_LOCATION(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); } ; @@ -820,17 +810,17 @@ Statement: ; Block: - 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); } + 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); } ; VariableStatement: VAR VariableDeclarationList ';' { $$ = createNodeDeclarationInfo<StatementNode*>(makeVarStatementNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); - setStatementLocation($$.m_node, @1, @3); } + DBG($$.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); - setStatementLocation($$.m_node, @1, @2); + DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } ; @@ -843,7 +833,7 @@ VariableDeclarationList: $$.m_numConstants = 0; } | IDENT Initializer { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @2.first_column + 1, @2.last_column); + SET_EXCEPTION_LOCATION(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); @@ -861,7 +851,7 @@ VariableDeclarationList: } | VariableDeclarationList ',' IDENT Initializer { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_features & AssignFeature); - setExceptionLocation(node, @3.first_column, @4.first_column + 1, @4.last_column); + SET_EXCEPTION_LOCATION(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); @@ -880,7 +870,7 @@ VariableDeclarationListNoIn: $$.m_numConstants = 0; } | IDENT InitializerNoIn { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_features & AssignFeature); - setExceptionLocation(node, @1.first_column, @2.first_column + 1, @2.last_column); + SET_EXCEPTION_LOCATION(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); @@ -898,7 +888,7 @@ VariableDeclarationListNoIn: } | VariableDeclarationListNoIn ',' IDENT InitializerNoIn { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_features & AssignFeature); - setExceptionLocation(node, @3.first_column, @4.first_column + 1, @4.last_column); + SET_EXCEPTION_LOCATION(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); @@ -910,10 +900,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); - setStatementLocation($$.m_node, @1, @3); } + DBG($$.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); - setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } + DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } ; ConstDeclarationList: @@ -955,36 +945,36 @@ EmptyStatement: ExprStatement: ExprNoBF ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ExprStatementNode(GLOBAL_DATA, $1.m_node), 0, 0, $1.m_features, $1.m_numConstants); - setStatementLocation($$.m_node, @1, @2); } + DBG($$.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); - setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } + DBG($$.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); - setStatementLocation($$.m_node, @1, @4); } + DBG($$.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); - setStatementLocation($$.m_node, @1, @4); } + DBG($$.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); - setStatementLocation($$.m_node, @1, @3); } + DBG($$.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); - setStatementLocation($$.m_node, @1, @3); } // Always performs automatic semicolon insertion. + DBG($$.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); - setStatementLocation($$.m_node, @1, @4); } + DBG($$.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); - setStatementLocation($$.m_node, @1, @8); + DBG($$.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), @@ -992,30 +982,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); - setStatementLocation($$.m_node, @1, @9); } + DBG($$.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); - setExceptionLocation(node, @3.first_column, @3.last_column, @5.last_column); + SET_EXCEPTION_LOCATION(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); - setStatementLocation($$.m_node, @1, @6); + DBG($$.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); - setExceptionLocation(forIn, @4.first_column, @5.first_column + 1, @6.last_column); + SET_EXCEPTION_LOCATION(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); - setStatementLocation($$.m_node, @1, @7); } + DBG($$.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); - setExceptionLocation(forIn, @4.first_column, @6.first_column + 1, @7.last_column); + SET_EXCEPTION_LOCATION(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); - setStatementLocation($$.m_node, @1, @8); } + DBG($$.m_node, @1, @8); } ; ExprOpt: @@ -1030,63 +1020,63 @@ ExprNoInOpt: ContinueStatement: CONTINUE ';' { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA); - setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - setStatementLocation($$.m_node, @1, @2); } + DBG($$.m_node, @1, @2); } | CONTINUE error { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA); - setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } + DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } | CONTINUE IDENT ';' { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *$2); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - setStatementLocation($$.m_node, @1, @3); } + DBG($$.m_node, @1, @3); } | CONTINUE IDENT error { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *$2); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); - setStatementLocation($$.m_node, @1, @2); AUTO_SEMICOLON; } + DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } ; BreakStatement: BREAK ';' { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA); - setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @2); } + 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); } | BREAK error { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA); - 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; } + 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; } | BREAK IDENT ';' { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @3); } + 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); } | BREAK IDENT error { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2); - 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; } + 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; } ; ReturnStatement: RETURN ';' { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0); - setExceptionLocation(node, @1.first_column, @1.last_column, @1.last_column); - $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation($$.m_node, @1, @2); } + 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); } | RETURN error { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0); - 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; } + 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; } | RETURN Expr ';' { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, $2.m_node); - 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); } + 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); } | RETURN Expr error { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, $2.m_node); - 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; } + 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; } ; 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); - setStatementLocation($$.m_node, @1, @4); } + DBG($$.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); - setStatementLocation($$.m_node, @1, @4); } + DBG($$.m_node, @1, @4); } ; CaseBlock: @@ -1100,7 +1090,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 ; @@ -1132,18 +1122,18 @@ DefaultClause: LabelledStatement: IDENT ':' Statement { LabelNode* node = new (GLOBAL_DATA) LabelNode(GLOBAL_DATA, *$1, $3.m_node); - setExceptionLocation(node, @1.first_column, @2.last_column, @2.last_column); + SET_EXCEPTION_LOCATION(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); - 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); + 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); } | THROW Expr error { ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, $2.m_node); - 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; + 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; } ; @@ -1153,57 +1143,57 @@ TryStatement: mergeDeclarationLists($2.m_funcDeclarations, $4.m_funcDeclarations), $2.m_features | $4.m_features, $2.m_numConstants + $4.m_numConstants); - setStatementLocation($$.m_node, @1, @2); } + DBG($$.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); - setStatementLocation($$.m_node, @1, @2); } + DBG($$.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); - setStatementLocation($$.m_node, @1, @2); } + DBG($$.m_node, @1, @2); } ; DebuggerStatement: DEBUGGER ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); - setStatementLocation($$.m_node, @1, @2); } + DBG($$.m_node, @1, @2); } | DEBUGGER error { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); - setStatementLocation($$.m_node, @1, @1); AUTO_SEMICOLON; } + DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } ; FunctionDeclaration: - 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 '(' ')' 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 '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE - { - $$ = 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); + { + $$ = 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); if ($4.m_features & ArgumentsFeature) - $7->setUsesArguments(); - setStatementLocation($7, @6, @8); - $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)->body()); + $7->setUsesArguments(); + DBG($7, @6, @8); + $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)); } ; FunctionExpr: - 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) + 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) $6->setUsesArguments(); - setStatementLocation($6, @5, @7); + DBG($6, @5, @7); } - | 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); + | 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); if ($4.m_features & ArgumentsFeature) $7->setUsesArguments(); - setStatementLocation($7, @6, @8); + DBG($7, @6, @8); } ; @@ -1251,8 +1241,8 @@ Literal_NoNode: | FALSETOKEN | NUMBER { } | STRING { } - | '/' /* regexp */ { if (!GLOBAL_DATA->lexer->skipRegExp()) YYABORT; } - | DIVEQUAL /* regexp with /= */ { if (!GLOBAL_DATA->lexer->skipRegExp()) YYABORT; } + | '/' /* regexp */ { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; } + | DIVEQUAL /* regexp with /= */ { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; } ; Property_NoNode: @@ -1834,28 +1824,26 @@ SourceElements_NoNode: %% -#undef GLOBAL_DATA - -static ExpressionNode* makeAssignNode(JSGlobalData* globalData, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end) +static ExpressionNode* makeAssignNode(void* globalPtr, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end) { if (!loc->isLocation()) - return new (globalData) AssignErrorNode(globalData, loc, op, expr, divot, divot - start, end - divot); + return new (GLOBAL_DATA) AssignErrorNode(GLOBAL_DATA, loc, op, expr, divot, divot - start, end - divot); if (loc->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(loc); if (op == OpEqual) { - AssignResolveNode* node = new (globalData) AssignResolveNode(globalData, resolve->identifier(), expr, exprHasAssignments); - setExceptionLocation(node, start, divot, end); + AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, resolve->identifier(), expr, exprHasAssignments); + SET_EXCEPTION_LOCATION(node, start, divot, end); return node; } else - return new (globalData) ReadModifyResolveNode(globalData, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); + return new (GLOBAL_DATA) ReadModifyResolveNode(GLOBAL_DATA, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); } if (loc->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc); if (op == OpEqual) - return new (globalData) AssignBracketNode(globalData, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot()); + return new (GLOBAL_DATA) AssignBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot()); else { - ReadModifyBracketNode* node = new (globalData) ReadModifyBracketNode(globalData, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot); + ReadModifyBracketNode* node = new (GLOBAL_DATA) ReadModifyBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot); node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); return node; } @@ -1863,117 +1851,117 @@ static ExpressionNode* makeAssignNode(JSGlobalData* globalData, ExpressionNode* ASSERT(loc->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc); if (op == OpEqual) - return new (globalData) AssignDotNode(globalData, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot()); + return new (GLOBAL_DATA) AssignDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot()); - ReadModifyDotNode* node = new (globalData) ReadModifyDotNode(globalData, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); + ReadModifyDotNode* node = new (GLOBAL_DATA) ReadModifyDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->endOffset()); return node; } -static ExpressionNode* makePrefixNode(JSGlobalData* globalData, ExpressionNode* expr, Operator op, int start, int divot, int end) +static ExpressionNode* makePrefixNode(void* globalPtr, ExpressionNode* expr, Operator op, int start, int divot, int end) { if (!expr->isLocation()) - return new (globalData) PrefixErrorNode(globalData, expr, op, divot, divot - start, end - divot); + return new (GLOBAL_DATA) PrefixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (globalData) PrefixResolveNode(globalData, resolve->identifier(), op, divot, divot - start, end - divot); + return new (GLOBAL_DATA) PrefixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - PrefixBracketNode* node = new (globalData) PrefixBracketNode(globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); + PrefixBracketNode* node = new (GLOBAL_DATA) PrefixBracketNode(GLOBAL_DATA, 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 (globalData) PrefixDotNode(globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); + PrefixDotNode* node = new (GLOBAL_DATA) PrefixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->startOffset()); return node; } -static ExpressionNode* makePostfixNode(JSGlobalData* globalData, ExpressionNode* expr, Operator op, int start, int divot, int end) +static ExpressionNode* makePostfixNode(void* globalPtr, ExpressionNode* expr, Operator op, int start, int divot, int end) { if (!expr->isLocation()) - return new (globalData) PostfixErrorNode(globalData, expr, op, divot, divot - start, end - divot); + return new (GLOBAL_DATA) PostfixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (globalData) PostfixResolveNode(globalData, resolve->identifier(), op, divot, divot - start, end - divot); + return new (GLOBAL_DATA) PostfixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - PostfixBracketNode* node = new (globalData) PostfixBracketNode(globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); + PostfixBracketNode* node = new (GLOBAL_DATA) PostfixBracketNode(GLOBAL_DATA, 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 (globalData) PostfixDotNode(globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); + PostfixDotNode* node = new (GLOBAL_DATA) PostfixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); node->setSubexpressionInfo(dot->divot(), dot->endOffset()); return node; } -static ExpressionNodeInfo makeFunctionCallNode(JSGlobalData* globalData, ExpressionNodeInfo func, ArgumentsNodeInfo args, int start, int divot, int end) +static ExpressionNodeInfo makeFunctionCallNode(void* globalPtr, 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 (globalData) FunctionCallValueNode(globalData, func.m_node, args.m_node, divot, divot - start, end - divot), features, numConstants); + return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) FunctionCallValueNode(GLOBAL_DATA, 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 == 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 (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 (func.m_node->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func.m_node); - FunctionCallBracketNode* node = new (globalData) FunctionCallBracketNode(globalData, bracket->base(), bracket->subscript(), args.m_node, divot, divot - start, end - divot); + FunctionCallBracketNode* node = new (GLOBAL_DATA) FunctionCallBracketNode(GLOBAL_DATA, 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() == 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); + 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); else - node = new (globalData) FunctionCallDotNode(globalData, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); + node = new (GLOBAL_DATA) FunctionCallDotNode(GLOBAL_DATA, 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(JSGlobalData* globalData, ExpressionNode* expr) +static ExpressionNode* makeTypeOfNode(void* globalPtr, ExpressionNode* expr) { if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (globalData) TypeOfResolveNode(globalData, resolve->identifier()); + return new (GLOBAL_DATA) TypeOfResolveNode(GLOBAL_DATA, resolve->identifier()); } - return new (globalData) TypeOfValueNode(globalData, expr); + return new (GLOBAL_DATA) TypeOfValueNode(GLOBAL_DATA, expr); } -static ExpressionNode* makeDeleteNode(JSGlobalData* globalData, ExpressionNode* expr, int start, int divot, int end) +static ExpressionNode* makeDeleteNode(void* globalPtr, ExpressionNode* expr, int start, int divot, int end) { if (!expr->isLocation()) - return new (globalData) DeleteValueNode(globalData, expr); + return new (GLOBAL_DATA) DeleteValueNode(GLOBAL_DATA, expr); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (globalData) DeleteResolveNode(globalData, resolve->identifier(), divot, divot - start, end - divot); + return new (GLOBAL_DATA) DeleteResolveNode(GLOBAL_DATA, resolve->identifier(), divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - return new (globalData) DeleteBracketNode(globalData, bracket->base(), bracket->subscript(), divot, divot - start, end - divot); + return new (GLOBAL_DATA) DeleteBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), divot, divot - start, end - divot); } ASSERT(expr->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); - return new (globalData) DeleteDotNode(globalData, dot->base(), dot->identifier(), divot, divot - start, end - divot); + return new (GLOBAL_DATA) DeleteDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), divot, divot - start, end - divot); } -static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData* globalData, const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body, const SourceCode& source) +static PropertyNode* makeGetterOrSetterPropertyNode(void* globalPtr, const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body, const SourceCode& source) { PropertyNode::Type type; if (getOrSet == "get") @@ -1982,10 +1970,10 @@ static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData* globalData, co type = PropertyNode::Setter; else return 0; - return new (globalData) PropertyNode(globalData, name, new (globalData) FuncExprNode(globalData, globalData->propertyNames->nullIdentifier, body, source, params), type); + return new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, name, new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, body, source, params), type); } -static ExpressionNode* makeNegateNode(JSGlobalData* globalData, ExpressionNode* n) +static ExpressionNode* makeNegateNode(void* globalPtr, ExpressionNode* n) { if (n->isNumber()) { NumberNode* number = static_cast<NumberNode*>(n); @@ -1996,92 +1984,92 @@ static ExpressionNode* makeNegateNode(JSGlobalData* globalData, ExpressionNode* } } - return new (globalData) NegateNode(globalData, n); + return new (GLOBAL_DATA) NegateNode(GLOBAL_DATA, n); } -static NumberNode* makeNumberNode(JSGlobalData* globalData, double d) +static NumberNode* makeNumberNode(void* globalPtr, double d) { - return new (globalData) NumberNode(globalData, d); + return new (GLOBAL_DATA) NumberNode(GLOBAL_DATA, d); } -static ExpressionNode* makeBitwiseNotNode(JSGlobalData* globalData, ExpressionNode* expr) +static ExpressionNode* makeBitwiseNotNode(void* globalPtr, ExpressionNode* expr) { if (expr->isNumber()) - return makeNumberNode(globalData, ~toInt32(static_cast<NumberNode*>(expr)->value())); - return new (globalData) BitwiseNotNode(globalData, expr); + return makeNumberNode(globalPtr, ~toInt32(static_cast<NumberNode*>(expr)->value())); + return new (GLOBAL_DATA) BitwiseNotNode(GLOBAL_DATA, expr); } -static ExpressionNode* makeMultNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeMultNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { expr1 = expr1->stripUnaryPlus(); expr2 = expr2->stripUnaryPlus(); if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value()); + return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value()); if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1) - return new (globalData) UnaryPlusNode(globalData, expr2); + return new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, expr2); if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1) - return new (globalData) UnaryPlusNode(globalData, expr1); + return new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, expr1); - return new (globalData) MultNode(globalData, expr1, expr2, rightHasAssignments); + return new (GLOBAL_DATA) MultNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeDivNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeDivNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { expr1 = expr1->stripUnaryPlus(); expr2 = expr2->stripUnaryPlus(); if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value()); - return new (globalData) DivNode(globalData, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value()); + return new (GLOBAL_DATA) DivNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeAddNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeAddNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value()); - return new (globalData) AddNode(globalData, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value()); + return new (GLOBAL_DATA) AddNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeSubNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeSubNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { expr1 = expr1->stripUnaryPlus(); expr2 = expr2->stripUnaryPlus(); if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalData, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value()); - return new (globalData) SubNode(globalData, expr1, expr2, rightHasAssignments); + return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value()); + return new (GLOBAL_DATA) SubNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments); } -static ExpressionNode* makeLeftShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeLeftShiftNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalData, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); - return new (globalData) LeftShiftNode(globalData, expr1, expr2, rightHasAssignments); + 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); } -static ExpressionNode* makeRightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) +static ExpressionNode* makeRightShiftNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) { if (expr1->isNumber() && expr2->isNumber()) - return makeNumberNode(globalData, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); - return new (globalData) RightShiftNode(globalData, expr1, expr2, rightHasAssignments); + 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); } -// 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(JSGlobalData* globalData, ExpressionNode* list, ExpressionNode* init) +static ExpressionNode* combineCommaNodes(void* globalPtr, ExpressionNode* list, ExpressionNode* init) { if (!list) return init; @@ -2089,15 +2077,17 @@ static ExpressionNode* combineCommaNodes(JSGlobalData* globalData, ExpressionNod static_cast<CommaNode*>(list)->append(init); return list; } - return new (globalData) CommaNode(globalData, list, init); + return new (GLOBAL_DATA) CommaNode(GLOBAL_DATA, 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(JSGlobalData* globalData, ExpressionNode* expr) +static StatementNode* makeVarStatementNode(void* globalPtr, ExpressionNode* expr) { if (!expr) - return new (globalData) EmptyStatementNode(globalData); - return new (globalData) VarStatementNode(globalData, expr); + return new (GLOBAL_DATA) EmptyStatementNode(GLOBAL_DATA); + return new (GLOBAL_DATA) VarStatementNode(GLOBAL_DATA, expr); } + +#undef GLOBAL_DATA diff --git a/JavaScriptCore/parser/Lexer.cpp b/JavaScriptCore/parser/Lexer.cpp index febd9a4..8e89c18 100644 --- a/JavaScriptCore/parser/Lexer.cpp +++ b/JavaScriptCore/parser/Lexer.cpp @@ -908,107 +908,45 @@ returnError: return -1; } -bool Lexer::scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix) +bool Lexer::scanRegExp() { ASSERT(m_buffer16.isEmpty()); bool lastWasEscape = false; bool inBrackets = false; - if (patternPrefix) { - ASSERT(!isLineTerminator(patternPrefix)); - ASSERT(patternPrefix != '/'); - ASSERT(patternPrefix != '['); - record16(patternPrefix); - } - while (true) { - int current = m_current; - - if (isLineTerminator(current) || current == -1) { - m_buffer16.resize(0); + if (isLineTerminator(m_current) || m_current == -1) 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; + 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); + m_buffer16.resize(0); + shift1(); break; } + shift1(); } - pattern = makeIdentifier(m_buffer16.data(), m_buffer16.size()); - m_buffer16.resize(0); - while (isIdentPart(m_current)) { record16(m_current); shift1(); } - - flags = makeIdentifier(m_buffer16.data(), m_buffer16.size()); + m_flags = UString(m_buffer16); 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(); @@ -1023,6 +961,9 @@ 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/JavaScriptCore/parser/Lexer.h b/JavaScriptCore/parser/Lexer.h index 23c2890..2583162 100644 --- a/JavaScriptCore/parser/Lexer.h +++ b/JavaScriptCore/parser/Lexer.h @@ -50,8 +50,9 @@ 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 Identifier*& pattern, const Identifier*& flags, UChar patternPrefix = 0); - bool skipRegExp(); + bool scanRegExp(); + const UString& pattern() const { return m_pattern; } + const UString& flags() const { return m_flags; } // Functions for use after parsing. bool sawError() const { return m_error; } @@ -111,6 +112,9 @@ namespace JSC { JSGlobalData* m_globalData; + UString m_pattern; + UString m_flags; + const HashTable m_keywordTable; Vector<UChar> m_codeWithoutBOMs; diff --git a/JavaScriptCore/parser/NodeConstructors.h b/JavaScriptCore/parser/NodeConstructors.h index 0052746..780a624 100644 --- a/JavaScriptCore/parser/NodeConstructors.h +++ b/JavaScriptCore/parser/NodeConstructors.h @@ -89,7 +89,7 @@ namespace JSC { { } - inline RegExpNode::RegExpNode(JSGlobalData* globalData, const Identifier& pattern, const Identifier& flags) + inline RegExpNode::RegExpNode(JSGlobalData* globalData, const UString& pattern, const UString& flags) : ExpressionNode(globalData) , m_pattern(pattern) , m_flags(flags) @@ -154,13 +154,6 @@ namespace JSC { { } - inline PropertyNode::PropertyNode(JSGlobalData* globalData, double name, ExpressionNode* assign, Type type) - : m_name(Identifier(globalData, UString::from(name))) - , m_assign(assign) - , m_type(type) - { - } - inline PropertyListNode::PropertyListNode(JSGlobalData* globalData, PropertyNode* node) : Node(globalData) , m_node(node) @@ -821,16 +814,20 @@ 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, ident); + m_body->finishParsing(source, parameter); } 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, ident); + m_body->finishParsing(source, parameter); } inline CaseClauseNode::CaseClauseNode(JSGlobalData*, ExpressionNode* expr) diff --git a/JavaScriptCore/parser/Nodes.cpp b/JavaScriptCore/parser/Nodes.cpp index 11a24b5..4324a06 100644 --- a/JavaScriptCore/parser/Nodes.cpp +++ b/JavaScriptCore/parser/Nodes.cpp @@ -138,7 +138,7 @@ RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern.ustring(), m_flags.ustring()); + RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern, m_flags); if (!regExp->isValid()) return emitThrowError(generator, SyntaxError, ("Invalid regular expression: " + UString(regExp->errorMessage())).UTF8String().c_str()); if (dst == generator.ignoredResult()) @@ -1205,13 +1205,7 @@ 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); @@ -1824,6 +1818,17 @@ ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* children, VarSt children->releaseContentsIntoVector(m_children); } +void ScopeNodeData::markAggregate(MarkStack& markStack) +{ + 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().markAggregate(markStack); + } +} + // ------------------------------ ScopeNode ----------------------------- ScopeNode::ScopeNode(JSGlobalData* globalData) @@ -1881,6 +1886,30 @@ RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 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) @@ -1912,6 +1941,54 @@ RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 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::markAggregate(MarkStack& markStack) +{ + // We don't need to mark our own CodeBlock as the JSGlobalObject takes care of that + data()->markAggregate(markStack); +} + +#if ENABLE(JIT) +void EvalNode::generateJITCode(ScopeChainNode* scopeChainNode) +{ + bytecode(scopeChainNode); + ASSERT(m_code); + ASSERT(!m_jitCode); + JIT::compile(scopeChainNode->globalData, m_code.get()); + ASSERT(m_jitCode); +} +#endif + // ------------------------------ FunctionBodyNode ----------------------------- inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData) @@ -1935,7 +2012,7 @@ FunctionBodyNode::~FunctionBodyNode() fastFree(m_parameters); } -void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident) +void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter) { Vector<Identifier> parameters; for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam()) @@ -1943,15 +2020,36 @@ void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* fi size_t count = parameters.size(); setSource(source); - finishParsing(parameters.releaseBuffer(), count, ident); + finishParsing(parameters.releaseBuffer(), count); } -void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCount, const Identifier& ident) +void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCount) { ASSERT(!source().isNull()); m_parameters = parameters; m_parameterCount = parameterCount; - m_ident = ident; +} + +void FunctionBodyNode::markAggregate(MarkStack& markStack) +{ + if (m_code) + m_code->markAggregate(markStack); +} + +#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; } FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData) @@ -1970,13 +2068,50 @@ PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, return node.release(); } -void FunctionBodyNode::reparseDataIfNecessary(ScopeChainNode* scopeChainNode) +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*) @@ -2016,6 +2151,11 @@ Identifier* FunctionBodyNode::copyParameters() // ------------------------------ 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()) @@ -2030,4 +2170,24 @@ 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/JavaScriptCore/parser/Nodes.h b/JavaScriptCore/parser/Nodes.h index 58caa19..703b384 100644 --- a/JavaScriptCore/parser/Nodes.h +++ b/JavaScriptCore/parser/Nodes.h @@ -39,16 +39,12 @@ namespace JSC { class ArgumentListNode; - class BytecodeGenerator; class CodeBlock; - class EvalCodeBlock; - class EvalExecutable; + class BytecodeGenerator; class FuncDeclNode; - class FunctionBodyNode; - class FunctionCodeBlock; + class EvalCodeBlock; class JSFunction; class ProgramCodeBlock; - class ProgramExecutable; class PropertyListNode; class ReadModifyResolveNode; class RegisterID; @@ -91,7 +87,7 @@ namespace JSC { namespace DeclarationStacks { enum VarAttrs { IsConstant = 1, HasInitializer = 2 }; typedef Vector<std::pair<Identifier, unsigned> > VarStack; - typedef Vector<FunctionBodyNode*> FunctionStack; + typedef Vector<FuncDeclNode*> FunctionStack; } struct SwitchInfo { @@ -361,13 +357,13 @@ namespace JSC { class RegExpNode : public ExpressionNode, public ThrowableExpressionData { public: - RegExpNode(JSGlobalData*, const Identifier& pattern, const Identifier& flags); + RegExpNode(JSGlobalData*, const UString& pattern, const UString& flags); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - Identifier m_pattern; - Identifier m_flags; + UString m_pattern; + UString m_flags; }; class ThisNode : public ExpressionNode { @@ -433,7 +429,6 @@ namespace JSC { 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; } @@ -1394,6 +1389,8 @@ namespace JSC { FunctionStack m_functionStack; int m_numConstants; StatementVector m_children; + + void markAggregate(MarkStack&); }; class ScopeNode : public StatementNode, public ParserArenaRefCounted { @@ -1439,9 +1436,33 @@ namespace JSC { return m_data->m_numConstants + 2; } + virtual void markAggregate(MarkStack&) { } + +#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 + protected: void setSource(const SourceCode& source) { m_source = source; } +#if ENABLE(JIT) + JITCode m_jitCode; +#endif + private: OwnPtr<ScopeNodeData> m_data; CodeFeatures m_features; @@ -1452,32 +1473,78 @@ 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 + 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); - void partialDestroyData() + EvalCodeBlock& bytecode(ScopeChainNode* scopeChain) + { + if (!m_code) + generateBytecode(scopeChain); + return *m_code; + } + + EvalCodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*); + + virtual void markAggregate(MarkStack&); + +#if ENABLE(JIT) + JITCode& jitCode(ScopeChainNode* scopeChain) { - // 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(); + if (!m_jitCode) + generateJITCode(scopeChain); + return m_jitCode; } +#endif 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 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(); @@ -1489,25 +1556,63 @@ namespace JSC { virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); - void finishParsing(const SourceCode&, ParameterNode*, const Identifier& ident); - void finishParsing(Identifier* parameters, size_t parameterCount, const Identifier& ident); + bool isGenerated() const + { + return m_code; + } + + bool isHostFunction() const; + + virtual void markAggregate(MarkStack&); + + void finishParsing(const SourceCode&, ParameterNode*); + void finishParsing(Identifier* parameters, size_t parameterCount); - const Identifier& ident() { return m_ident; } + UString toSourceString() const { return source().toString(); } - void reparseDataIfNecessary(ScopeChainNode* scopeChainNode); + CodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*); +#if ENABLE(JIT) + JITCode& jitCode(ScopeChainNode* scopeChain) + { + if (!m_jitCode) + generateJITCode(scopeChain); + return m_jitCode; + } +#endif + 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); - Identifier m_ident; + + void generateBytecode(ScopeChainNode*); +#if ENABLE(JIT) + void generateJITCode(ScopeChainNode*); +#endif Identifier* m_parameters; size_t m_parameterCount; + OwnPtr<CodeBlock> m_code; }; - class FuncExprNode : public ExpressionNode { + class FuncExprNode : public ExpressionNode, public ParserArenaRefCounted { public: FuncExprNode(JSGlobalData*, const Identifier&, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0); + JSFunction* makeFunction(ExecState*, ScopeChainNode*); + FunctionBodyNode* body() { return m_body.get(); } private: @@ -1515,13 +1620,18 @@ namespace JSC { virtual bool isFuncExprNode() const { return true; } + Identifier m_ident; RefPtr<FunctionBodyNode> m_body; }; - class FuncDeclNode : public StatementNode { + class FuncDeclNode : public StatementNode, public ParserArenaRefCounted { public: FuncDeclNode(JSGlobalData*, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0); + JSFunction* makeFunction(ExecState*, ScopeChainNode*); + + Identifier m_ident; + FunctionBodyNode* body() { return m_body.get(); } private: diff --git a/JavaScriptCore/parser/Parser.h b/JavaScriptCore/parser/Parser.h index 6166bb2..373dc00 100644 --- a/JavaScriptCore/parser/Parser.h +++ b/JavaScriptCore/parser/Parser.h @@ -24,8 +24,6 @@ #define Parser_h #include "Debugger.h" -#include "Executable.h" -#include "JSGlobalObject.h" #include "Nodes.h" #include "SourceProvider.h" #include <wtf/Forward.h> @@ -43,12 +41,9 @@ 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*); + 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*); - PassRefPtr<FunctionBodyNode> parseFunctionFromGlobalCode(ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0); void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures features, int lastLine, int numConstants); @@ -68,8 +63,7 @@ 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(ExecState* exec, Debugger* debugger, const SourceCode& source, int* errLine, UString* errMsg) { m_source = &source; parse(&exec->globalData(), errLine, errMsg); @@ -96,8 +90,7 @@ namespace JSC { return result.release(); } - template <class ParsedNode> - PassRefPtr<ParsedNode> Parser::reparse(JSGlobalData* globalData, ParsedNode* oldParsedNode) + template <class ParsedNode> PassRefPtr<ParsedNode> Parser::reparse(JSGlobalData* globalData, ParsedNode* oldParsedNode) { m_source = &oldParsedNode->source(); parse(globalData, 0, 0); @@ -122,54 +115,6 @@ namespace JSC { return result.release(); } - inline PassRefPtr<FunctionBodyNode> Parser::parseFunctionFromGlobalCode(ExecState* exec, Debugger* debugger, const SourceCode& source, int* errLine, UString* errMsg) - { - RefPtr<ProgramNode> program = parse<ProgramNode>(exec, debugger, source, errLine, errMsg); - - if (!program) - return 0; - - StatementVector& children = program->children(); - if (children.size() != 1) - return 0; - - StatementNode* exprStatement = children[0]; - ASSERT(exprStatement); - ASSERT(exprStatement->isExprStatement()); - if (!exprStatement || !exprStatement->isExprStatement()) - return 0; - - ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr(); - ASSERT(funcExpr); - ASSERT(funcExpr->isFuncExprNode()); - if (!funcExpr || !funcExpr->isFuncExprNode()) - return 0; - - RefPtr<FunctionBodyNode> body = static_cast<FuncExprNode*>(funcExpr)->body(); - ASSERT(body); - return body.release(); - } - - inline JSObject* EvalExecutable::parse(ExecState* exec, bool allowDebug) - { - int errLine; - UString errMsg; - m_node = exec->globalData().parser->parse<EvalNode>(exec, allowDebug ? exec->dynamicGlobalObject()->debugger() : 0, m_source, &errLine, &errMsg); - if (!m_node) - return Error::create(exec, SyntaxError, errMsg, errLine, m_source.provider()->asID(), m_source.provider()->url()); - return 0; - } - - inline JSObject* ProgramExecutable::parse(ExecState* exec, bool allowDebug) - { - int errLine; - UString errMsg; - m_node = exec->globalData().parser->parse<ProgramNode>(exec, allowDebug ? exec->dynamicGlobalObject()->debugger() : 0, m_source, &errLine, &errMsg); - if (!m_node) - return Error::create(exec, SyntaxError, errMsg, errLine, m_source.provider()->asID(), m_source.provider()->url()); - return 0; - } - } // namespace JSC #endif // Parser_h |