• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #ifndef ASTBuilder_h
27 #define ASTBuilder_h
28 
29 #include "NodeConstructors.h"
30 #include "SyntaxChecker.h"
31 #include <utility>
32 
33 namespace JSC {
34 
35 class ASTBuilder {
36     struct BinaryOpInfo {
BinaryOpInfoBinaryOpInfo37         BinaryOpInfo() {}
BinaryOpInfoBinaryOpInfo38         BinaryOpInfo(int s, int d, int e, bool r)
39             : start(s)
40             , divot(d)
41             , end(e)
42             , hasAssignment(r)
43         {
44         }
BinaryOpInfoBinaryOpInfo45         BinaryOpInfo(const BinaryOpInfo& lhs, const BinaryOpInfo& rhs)
46             : start(lhs.start)
47             , divot(rhs.start)
48             , end(rhs.end)
49             , hasAssignment(lhs.hasAssignment || rhs.hasAssignment)
50         {
51         }
52         int start;
53         int divot;
54         int end;
55         bool hasAssignment;
56     };
57 
58 
59     struct AssignmentInfo {
AssignmentInfoAssignmentInfo60         AssignmentInfo() {}
AssignmentInfoAssignmentInfo61         AssignmentInfo(ExpressionNode* node, int start, int divot, int initAssignments, Operator op)
62             : m_node(node)
63             , m_start(start)
64             , m_divot(divot)
65             , m_initAssignments(initAssignments)
66             , m_op(op)
67         {
68         }
69         ExpressionNode* m_node;
70         int m_start;
71         int m_divot;
72         int m_initAssignments;
73         Operator m_op;
74     };
75 public:
ASTBuilder(JSGlobalData * globalData,Lexer * lexer)76     ASTBuilder(JSGlobalData* globalData, Lexer* lexer)
77         : m_globalData(globalData)
78         , m_lexer(lexer)
79         , m_scope(globalData)
80         , m_evalCount(0)
81     {
82     }
83 
84     struct BinaryExprContext {
BinaryExprContextBinaryExprContext85         BinaryExprContext(ASTBuilder&) {}
86     };
87     struct UnaryExprContext {
UnaryExprContextUnaryExprContext88         UnaryExprContext(ASTBuilder&) {}
89     };
90 
91     typedef SyntaxChecker FunctionBodyBuilder;
92 
93     typedef ExpressionNode* Expression;
94     typedef JSC::SourceElements* SourceElements;
95     typedef ArgumentsNode* Arguments;
96     typedef CommaNode* Comma;
97     typedef PropertyNode* Property;
98     typedef PropertyListNode* PropertyList;
99     typedef ElementNode* ElementList;
100     typedef ArgumentListNode* ArgumentsList;
101     typedef ParameterNode* FormalParameterList;
102     typedef FunctionBodyNode* FunctionBody;
103     typedef StatementNode* Statement;
104     typedef ClauseListNode* ClauseList;
105     typedef CaseClauseNode* Clause;
106     typedef ConstDeclNode* ConstDeclList;
107     typedef std::pair<ExpressionNode*, BinaryOpInfo> BinaryOperand;
108 
109     static const bool CreatesAST = true;
110     static const bool NeedsFreeVariableInfo = true;
111     static const bool CanUseFunctionCache = true;
112 
113     ExpressionNode* makeBinaryNode(int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>);
114     ExpressionNode* makeFunctionCallNode(ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end);
115 
createSourceElements()116     JSC::SourceElements* createSourceElements() { return new (m_globalData) JSC::SourceElements(m_globalData); }
117 
varDeclarations()118     ParserArenaData<DeclarationStacks::VarStack>* varDeclarations() { return m_scope.m_varDeclarations; }
funcDeclarations()119     ParserArenaData<DeclarationStacks::FunctionStack>* funcDeclarations() { return m_scope.m_funcDeclarations; }
features()120     int features() const { return m_scope.m_features; }
numConstants()121     int numConstants() const { return m_scope.m_numConstants; }
122 
appendToComma(CommaNode * commaNode,ExpressionNode * expr)123     void appendToComma(CommaNode* commaNode, ExpressionNode* expr) { commaNode->append(expr); }
124 
createCommaExpr(ExpressionNode * lhs,ExpressionNode * rhs)125     CommaNode* createCommaExpr(ExpressionNode* lhs, ExpressionNode* rhs) { return new (m_globalData) CommaNode(m_globalData, lhs, rhs); }
126 
127     ExpressionNode* makeAssignNode(ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, int start, int divot, int end);
128     ExpressionNode* makePrefixNode(ExpressionNode*, Operator, int start, int divot, int end);
129     ExpressionNode* makePostfixNode(ExpressionNode*, Operator, int start, int divot, int end);
130     ExpressionNode* makeTypeOfNode(ExpressionNode*);
131     ExpressionNode* makeDeleteNode(ExpressionNode*, int start, int divot, int end);
132     ExpressionNode* makeNegateNode(ExpressionNode*);
133     ExpressionNode* makeBitwiseNotNode(ExpressionNode*);
134     ExpressionNode* makeMultNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
135     ExpressionNode* makeDivNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
136     ExpressionNode* makeModNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
137     ExpressionNode* makeAddNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
138     ExpressionNode* makeSubNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
139     ExpressionNode* makeBitXOrNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
140     ExpressionNode* makeBitAndNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
141     ExpressionNode* makeBitOrNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
142     ExpressionNode* makeLeftShiftNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
143     ExpressionNode* makeRightShiftNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
144     ExpressionNode* makeURightShiftNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
145 
createLogicalNot(ExpressionNode * expr)146     ExpressionNode* createLogicalNot(ExpressionNode* expr) { return new (m_globalData) LogicalNotNode(m_globalData, expr); }
createUnaryPlus(ExpressionNode * expr)147     ExpressionNode* createUnaryPlus(ExpressionNode* expr) { return new (m_globalData) UnaryPlusNode(m_globalData, expr); }
createVoid(ExpressionNode * expr)148     ExpressionNode* createVoid(ExpressionNode* expr)
149     {
150         incConstants();
151         return new (m_globalData) VoidNode(m_globalData, expr);
152     }
thisExpr()153     ExpressionNode* thisExpr()
154     {
155         usesThis();
156         return new (m_globalData) ThisNode(m_globalData);
157     }
createResolve(const Identifier * ident,int start)158     ExpressionNode* createResolve(const Identifier* ident, int start)
159     {
160         if (m_globalData->propertyNames->arguments == *ident)
161             usesArguments();
162         return new (m_globalData) ResolveNode(m_globalData, *ident, start);
163     }
createObjectLiteral()164     ExpressionNode* createObjectLiteral() { return new (m_globalData) ObjectLiteralNode(m_globalData); }
createObjectLiteral(PropertyListNode * properties)165     ExpressionNode* createObjectLiteral(PropertyListNode* properties) { return new (m_globalData) ObjectLiteralNode(m_globalData, properties); }
166 
createArray(int elisions)167     ExpressionNode* createArray(int elisions)
168     {
169         if (elisions)
170             incConstants();
171         return new (m_globalData) ArrayNode(m_globalData, elisions);
172     }
173 
createArray(ElementNode * elems)174     ExpressionNode* createArray(ElementNode* elems) { return new (m_globalData) ArrayNode(m_globalData, elems); }
createArray(int elisions,ElementNode * elems)175     ExpressionNode* createArray(int elisions, ElementNode* elems)
176     {
177         if (elisions)
178             incConstants();
179         return new (m_globalData) ArrayNode(m_globalData, elisions, elems);
180     }
createNumberExpr(double d)181     ExpressionNode* createNumberExpr(double d)
182     {
183         incConstants();
184         return new (m_globalData) NumberNode(m_globalData, d);
185     }
186 
createString(const Identifier * string)187     ExpressionNode* createString(const Identifier* string)
188     {
189         incConstants();
190         return new (m_globalData) StringNode(m_globalData, *string);
191     }
192 
createBoolean(bool b)193     ExpressionNode* createBoolean(bool b)
194     {
195         incConstants();
196         return new (m_globalData) BooleanNode(m_globalData, b);
197     }
198 
createNull()199     ExpressionNode* createNull()
200     {
201         incConstants();
202         return new (m_globalData) NullNode(m_globalData);
203     }
204 
createBracketAccess(ExpressionNode * base,ExpressionNode * property,bool propertyHasAssignments,int start,int divot,int end)205     ExpressionNode* createBracketAccess(ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, int start, int divot, int end)
206     {
207         BracketAccessorNode* node = new (m_globalData) BracketAccessorNode(m_globalData, base, property, propertyHasAssignments);
208         setExceptionLocation(node, start, divot, end);
209         return node;
210     }
211 
createDotAccess(ExpressionNode * base,const Identifier & property,int start,int divot,int end)212     ExpressionNode* createDotAccess(ExpressionNode* base, const Identifier& property, int start, int divot, int end)
213     {
214         DotAccessorNode* node = new (m_globalData) DotAccessorNode(m_globalData, base, property);
215         setExceptionLocation(node, start, divot, end);
216         return node;
217     }
218 
createRegExp(const Identifier & pattern,const Identifier & flags,int start)219     ExpressionNode* createRegExp(const Identifier& pattern, const Identifier& flags, int start)
220     {
221         if (Yarr::checkSyntax(pattern.ustring()))
222             return 0;
223         RegExpNode* node = new (m_globalData) RegExpNode(m_globalData, pattern, flags);
224         int size = pattern.length() + 2; // + 2 for the two /'s
225         setExceptionLocation(node, start, start + size, start + size);
226         return node;
227     }
228 
createNewExpr(ExpressionNode * expr,ArgumentsNode * arguments,int start,int divot,int end)229     ExpressionNode* createNewExpr(ExpressionNode* expr, ArgumentsNode* arguments, int start, int divot, int end)
230     {
231         NewExprNode* node = new (m_globalData) NewExprNode(m_globalData, expr, arguments);
232         setExceptionLocation(node, start, divot, end);
233         return node;
234     }
235 
createNewExpr(ExpressionNode * expr,int start,int end)236     ExpressionNode* createNewExpr(ExpressionNode* expr, int start, int end)
237     {
238         NewExprNode* node = new (m_globalData) NewExprNode(m_globalData, expr);
239         setExceptionLocation(node, start, end, end);
240         return node;
241     }
242 
createConditionalExpr(ExpressionNode * condition,ExpressionNode * lhs,ExpressionNode * rhs)243     ExpressionNode* createConditionalExpr(ExpressionNode* condition, ExpressionNode* lhs, ExpressionNode* rhs)
244     {
245         return new (m_globalData) ConditionalNode(m_globalData, condition, lhs, rhs);
246     }
247 
createAssignResolve(const Identifier & ident,ExpressionNode * rhs,bool rhsHasAssignment,int start,int divot,int end)248     ExpressionNode* createAssignResolve(const Identifier& ident, ExpressionNode* rhs, bool rhsHasAssignment, int start, int divot, int end)
249     {
250         AssignResolveNode* node = new (m_globalData) AssignResolveNode(m_globalData, ident, rhs, rhsHasAssignment);
251         setExceptionLocation(node, start, divot, end);
252         return node;
253     }
254 
createFunctionExpr(const Identifier * name,FunctionBodyNode * body,ParameterNode * parameters,int openBracePos,int closeBracePos,int bodyStartLine,int bodyEndLine)255     ExpressionNode* createFunctionExpr(const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
256     {
257         FuncExprNode* result = new (m_globalData) FuncExprNode(m_globalData, *name, body, m_lexer->sourceCode(openBracePos, closeBracePos, bodyStartLine), parameters);
258         body->setLoc(bodyStartLine, bodyEndLine);
259         return result;
260     }
261 
createFunctionBody(bool inStrictContext)262     FunctionBodyNode* createFunctionBody(bool inStrictContext)
263     {
264         usesClosures();
265         return FunctionBodyNode::create(m_globalData, inStrictContext);
266     }
267 
createGetterOrSetterProperty(PropertyNode::Type type,const Identifier * name,ParameterNode * params,FunctionBodyNode * body,int openBracePos,int closeBracePos,int bodyStartLine,int bodyEndLine)268     template <bool> PropertyNode* createGetterOrSetterProperty(PropertyNode::Type type, const Identifier* name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
269     {
270         ASSERT(name);
271         body->setLoc(bodyStartLine, bodyEndLine);
272         return new (m_globalData) PropertyNode(m_globalData, *name, new (m_globalData) FuncExprNode(m_globalData, m_globalData->propertyNames->nullIdentifier, body, m_lexer->sourceCode(openBracePos, closeBracePos, bodyStartLine), params), type);
273     }
274 
275 
createArguments()276     ArgumentsNode* createArguments() { return new (m_globalData) ArgumentsNode(m_globalData); }
createArguments(ArgumentListNode * args)277     ArgumentsNode* createArguments(ArgumentListNode* args) { return new (m_globalData) ArgumentsNode(m_globalData, args); }
createArgumentsList(ExpressionNode * arg)278     ArgumentListNode* createArgumentsList(ExpressionNode* arg) { return new (m_globalData) ArgumentListNode(m_globalData, arg); }
createArgumentsList(ArgumentListNode * args,ExpressionNode * arg)279     ArgumentListNode* createArgumentsList(ArgumentListNode* args, ExpressionNode* arg) { return new (m_globalData) ArgumentListNode(m_globalData, args, arg); }
280 
createProperty(const Identifier * propertyName,ExpressionNode * node,PropertyNode::Type type)281     template <bool> PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type) { return new (m_globalData) PropertyNode(m_globalData, *propertyName, node, type); }
createProperty(JSGlobalData *,double propertyName,ExpressionNode * node,PropertyNode::Type type)282     template <bool> PropertyNode* createProperty(JSGlobalData*, double propertyName, ExpressionNode* node, PropertyNode::Type type) { return new (m_globalData) PropertyNode(m_globalData, propertyName, node, type); }
createPropertyList(PropertyNode * property)283     PropertyListNode* createPropertyList(PropertyNode* property) { return new (m_globalData) PropertyListNode(m_globalData, property); }
createPropertyList(PropertyNode * property,PropertyListNode * tail)284     PropertyListNode* createPropertyList(PropertyNode* property, PropertyListNode* tail) { return new (m_globalData) PropertyListNode(m_globalData, property, tail); }
285 
createElementList(int elisions,ExpressionNode * expr)286     ElementNode* createElementList(int elisions, ExpressionNode* expr) { return new (m_globalData) ElementNode(m_globalData, elisions, expr); }
createElementList(ElementNode * elems,int elisions,ExpressionNode * expr)287     ElementNode* createElementList(ElementNode* elems, int elisions, ExpressionNode* expr) { return new (m_globalData) ElementNode(m_globalData, elems, elisions, expr); }
288 
createFormalParameterList(const Identifier & ident)289     ParameterNode* createFormalParameterList(const Identifier& ident) { return new (m_globalData) ParameterNode(m_globalData, ident); }
createFormalParameterList(ParameterNode * list,const Identifier & ident)290     ParameterNode* createFormalParameterList(ParameterNode* list, const Identifier& ident) { return new (m_globalData) ParameterNode(m_globalData, list, ident); }
291 
createClause(ExpressionNode * expr,JSC::SourceElements * statements)292     CaseClauseNode* createClause(ExpressionNode* expr, JSC::SourceElements* statements) { return new (m_globalData) CaseClauseNode(m_globalData, expr, statements); }
createClauseList(CaseClauseNode * clause)293     ClauseListNode* createClauseList(CaseClauseNode* clause) { return new (m_globalData) ClauseListNode(m_globalData, clause); }
createClauseList(ClauseListNode * tail,CaseClauseNode * clause)294     ClauseListNode* createClauseList(ClauseListNode* tail, CaseClauseNode* clause) { return new (m_globalData) ClauseListNode(m_globalData, tail, clause); }
295 
setUsesArguments(FunctionBodyNode * node)296     void setUsesArguments(FunctionBodyNode* node) { node->setUsesArguments(); }
297 
createFuncDeclStatement(const Identifier * name,FunctionBodyNode * body,ParameterNode * parameters,int openBracePos,int closeBracePos,int bodyStartLine,int bodyEndLine)298     StatementNode* createFuncDeclStatement(const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
299     {
300         FuncDeclNode* decl = new (m_globalData) FuncDeclNode(m_globalData, *name, body, m_lexer->sourceCode(openBracePos, closeBracePos, bodyStartLine), parameters);
301         if (*name == m_globalData->propertyNames->arguments)
302             usesArguments();
303         m_scope.m_funcDeclarations->data.append(decl->body());
304         body->setLoc(bodyStartLine, bodyEndLine);
305         return decl;
306     }
307 
createBlockStatement(JSC::SourceElements * elements,int startLine,int endLine)308     StatementNode* createBlockStatement(JSC::SourceElements* elements, int startLine, int endLine)
309     {
310         BlockNode* block = new (m_globalData) BlockNode(m_globalData, elements);
311         block->setLoc(startLine, endLine);
312         return block;
313     }
314 
createExprStatement(ExpressionNode * expr,int start,int end)315     StatementNode* createExprStatement(ExpressionNode* expr, int start, int end)
316     {
317         ExprStatementNode* result = new (m_globalData) ExprStatementNode(m_globalData, expr);
318         result->setLoc(start, end);
319         return result;
320     }
321 
createIfStatement(ExpressionNode * condition,StatementNode * trueBlock,int start,int end)322     StatementNode* createIfStatement(ExpressionNode* condition, StatementNode* trueBlock, int start, int end)
323     {
324         IfNode* result = new (m_globalData) IfNode(m_globalData, condition, trueBlock);
325         result->setLoc(start, end);
326         return result;
327     }
328 
createIfStatement(ExpressionNode * condition,StatementNode * trueBlock,StatementNode * falseBlock,int start,int end)329     StatementNode* createIfStatement(ExpressionNode* condition, StatementNode* trueBlock, StatementNode* falseBlock, int start, int end)
330     {
331         IfNode* result = new (m_globalData) IfElseNode(m_globalData, condition, trueBlock, falseBlock);
332         result->setLoc(start, end);
333         return result;
334     }
335 
createForLoop(ExpressionNode * initializer,ExpressionNode * condition,ExpressionNode * iter,StatementNode * statements,bool b,int start,int end)336     StatementNode* createForLoop(ExpressionNode* initializer, ExpressionNode* condition, ExpressionNode* iter, StatementNode* statements, bool b, int start, int end)
337     {
338         ForNode* result = new (m_globalData) ForNode(m_globalData, initializer, condition, iter, statements, b);
339         result->setLoc(start, end);
340         return result;
341     }
342 
createForInLoop(const Identifier * ident,ExpressionNode * initializer,ExpressionNode * iter,StatementNode * statements,int start,int divot,int end,int initStart,int initEnd,int startLine,int endLine)343     StatementNode* createForInLoop(const Identifier* ident, ExpressionNode* initializer, ExpressionNode* iter, StatementNode* statements, int start, int divot, int end, int initStart, int initEnd, int startLine, int endLine)
344     {
345         ForInNode* result = new (m_globalData) ForInNode(m_globalData, *ident, initializer, iter, statements, initStart, initStart - start, initEnd - initStart);
346         result->setLoc(startLine, endLine);
347         setExceptionLocation(result, start, divot + 1, end);
348         return result;
349     }
350 
createForInLoop(ExpressionNode * lhs,ExpressionNode * iter,StatementNode * statements,int eStart,int eDivot,int eEnd,int start,int end)351     StatementNode* createForInLoop(ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, int eStart, int eDivot, int eEnd, int start, int end)
352     {
353         ForInNode* result = new (m_globalData) ForInNode(m_globalData, lhs, iter, statements);
354         result->setLoc(start, end);
355         setExceptionLocation(result, eStart, eDivot, eEnd);
356         return result;
357     }
358 
createEmptyStatement()359     StatementNode* createEmptyStatement() { return new (m_globalData) EmptyStatementNode(m_globalData); }
360 
createVarStatement(ExpressionNode * expr,int start,int end)361     StatementNode* createVarStatement(ExpressionNode* expr, int start, int end)
362     {
363         StatementNode* result;
364         if (!expr)
365             result = new (m_globalData) EmptyStatementNode(m_globalData);
366         else
367             result = new (m_globalData) VarStatementNode(m_globalData, expr);
368         result->setLoc(start, end);
369         return result;
370     }
371 
createReturnStatement(ExpressionNode * expression,int eStart,int eEnd,int startLine,int endLine)372     StatementNode* createReturnStatement(ExpressionNode* expression, int eStart, int eEnd, int startLine, int endLine)
373     {
374         ReturnNode* result = new (m_globalData) ReturnNode(m_globalData, expression);
375         setExceptionLocation(result, eStart, eEnd, eEnd);
376         result->setLoc(startLine, endLine);
377         return result;
378     }
379 
createBreakStatement(int eStart,int eEnd,int startLine,int endLine)380     StatementNode* createBreakStatement(int eStart, int eEnd, int startLine, int endLine)
381     {
382         BreakNode* result = new (m_globalData) BreakNode(m_globalData);
383         setExceptionLocation(result, eStart, eEnd, eEnd);
384         result->setLoc(startLine, endLine);
385         return result;
386     }
387 
createBreakStatement(const Identifier * ident,int eStart,int eEnd,int startLine,int endLine)388     StatementNode* createBreakStatement(const Identifier* ident, int eStart, int eEnd, int startLine, int endLine)
389     {
390         BreakNode* result = new (m_globalData) BreakNode(m_globalData, *ident);
391         setExceptionLocation(result, eStart, eEnd, eEnd);
392         result->setLoc(startLine, endLine);
393         return result;
394     }
395 
createContinueStatement(int eStart,int eEnd,int startLine,int endLine)396     StatementNode* createContinueStatement(int eStart, int eEnd, int startLine, int endLine)
397     {
398         ContinueNode* result = new (m_globalData) ContinueNode(m_globalData);
399         setExceptionLocation(result, eStart, eEnd, eEnd);
400         result->setLoc(startLine, endLine);
401         return result;
402     }
403 
createContinueStatement(const Identifier * ident,int eStart,int eEnd,int startLine,int endLine)404     StatementNode* createContinueStatement(const Identifier* ident, int eStart, int eEnd, int startLine, int endLine)
405     {
406         ContinueNode* result = new (m_globalData) ContinueNode(m_globalData, *ident);
407         setExceptionLocation(result, eStart, eEnd, eEnd);
408         result->setLoc(startLine, endLine);
409         return result;
410     }
411 
createTryStatement(StatementNode * tryBlock,const Identifier * ident,bool catchHasEval,StatementNode * catchBlock,StatementNode * finallyBlock,int startLine,int endLine)412     StatementNode* createTryStatement(StatementNode* tryBlock, const Identifier* ident, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
413     {
414         TryNode* result = new (m_globalData) TryNode(m_globalData, tryBlock, *ident, catchHasEval, catchBlock, finallyBlock);
415         if (catchBlock)
416             usesCatch();
417         result->setLoc(startLine, endLine);
418         return result;
419     }
420 
createSwitchStatement(ExpressionNode * expr,ClauseListNode * firstClauses,CaseClauseNode * defaultClause,ClauseListNode * secondClauses,int startLine,int endLine)421     StatementNode* createSwitchStatement(ExpressionNode* expr, ClauseListNode* firstClauses, CaseClauseNode* defaultClause, ClauseListNode* secondClauses, int startLine, int endLine)
422     {
423         CaseBlockNode* cases = new (m_globalData) CaseBlockNode(m_globalData, firstClauses, defaultClause, secondClauses);
424         SwitchNode* result = new (m_globalData) SwitchNode(m_globalData, expr, cases);
425         result->setLoc(startLine, endLine);
426         return result;
427     }
428 
createWhileStatement(ExpressionNode * expr,StatementNode * statement,int startLine,int endLine)429     StatementNode* createWhileStatement(ExpressionNode* expr, StatementNode* statement, int startLine, int endLine)
430     {
431         WhileNode* result = new (m_globalData) WhileNode(m_globalData, expr, statement);
432         result->setLoc(startLine, endLine);
433         return result;
434     }
435 
createDoWhileStatement(StatementNode * statement,ExpressionNode * expr,int startLine,int endLine)436     StatementNode* createDoWhileStatement(StatementNode* statement, ExpressionNode* expr, int startLine, int endLine)
437     {
438         DoWhileNode* result = new (m_globalData) DoWhileNode(m_globalData, statement, expr);
439         result->setLoc(startLine, endLine);
440         return result;
441     }
442 
createLabelStatement(const Identifier * ident,StatementNode * statement,int start,int end)443     StatementNode* createLabelStatement(const Identifier* ident, StatementNode* statement, int start, int end)
444     {
445         LabelNode* result = new (m_globalData) LabelNode(m_globalData, *ident, statement);
446         setExceptionLocation(result, start, end, end);
447         return result;
448     }
449 
createWithStatement(ExpressionNode * expr,StatementNode * statement,int start,int end,int startLine,int endLine)450     StatementNode* createWithStatement(ExpressionNode* expr, StatementNode* statement, int start, int end, int startLine, int endLine)
451     {
452         usesWith();
453         WithNode* result = new (m_globalData) WithNode(m_globalData, expr, statement, end, end - start);
454         result->setLoc(startLine, endLine);
455         return result;
456     }
457 
createThrowStatement(ExpressionNode * expr,int start,int end,int startLine,int endLine)458     StatementNode* createThrowStatement(ExpressionNode* expr, int start, int end, int startLine, int endLine)
459     {
460         ThrowNode* result = new (m_globalData) ThrowNode(m_globalData, expr);
461         result->setLoc(startLine, endLine);
462         setExceptionLocation(result, start, end, end);
463         return result;
464     }
465 
createDebugger(int startLine,int endLine)466     StatementNode* createDebugger(int startLine, int endLine)
467     {
468         DebuggerStatementNode* result = new (m_globalData) DebuggerStatementNode(m_globalData);
469         result->setLoc(startLine, endLine);
470         return result;
471     }
472 
createConstStatement(ConstDeclNode * decls,int startLine,int endLine)473     StatementNode* createConstStatement(ConstDeclNode* decls, int startLine, int endLine)
474     {
475         ConstStatementNode* result = new (m_globalData) ConstStatementNode(m_globalData, decls);
476         result->setLoc(startLine, endLine);
477         return result;
478     }
479 
appendConstDecl(ConstDeclNode * tail,const Identifier * name,ExpressionNode * initializer)480     ConstDeclNode* appendConstDecl(ConstDeclNode* tail, const Identifier* name, ExpressionNode* initializer)
481     {
482         ConstDeclNode* result = new (m_globalData) ConstDeclNode(m_globalData, *name, initializer);
483         if (tail)
484             tail->m_next = result;
485         return result;
486     }
487 
appendStatement(JSC::SourceElements * elements,JSC::StatementNode * statement)488     void appendStatement(JSC::SourceElements* elements, JSC::StatementNode* statement)
489     {
490         elements->append(statement);
491     }
492 
addVar(const Identifier * ident,int attrs)493     void addVar(const Identifier* ident, int attrs)
494     {
495         if (m_globalData->propertyNames->arguments == *ident)
496             usesArguments();
497         m_scope.m_varDeclarations->data.append(std::make_pair(ident, attrs));
498     }
499 
combineCommaNodes(ExpressionNode * list,ExpressionNode * init)500     ExpressionNode* combineCommaNodes(ExpressionNode* list, ExpressionNode* init)
501     {
502         if (!list)
503             return init;
504         if (list->isCommaNode()) {
505             static_cast<CommaNode*>(list)->append(init);
506             return list;
507         }
508         return new (m_globalData) CommaNode(m_globalData, list, init);
509     }
510 
evalCount()511     int evalCount() const { return m_evalCount; }
512 
appendBinaryExpressionInfo(int & operandStackDepth,ExpressionNode * current,int exprStart,int lhs,int rhs,bool hasAssignments)513     void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, int exprStart, int lhs, int rhs, bool hasAssignments)
514     {
515         operandStackDepth++;
516         m_binaryOperandStack.append(std::make_pair(current, BinaryOpInfo(exprStart, lhs, rhs, hasAssignments)));
517     }
518 
519     // Logic to handle datastructures used during parsing of binary expressions
operatorStackPop(int & operatorStackDepth)520     void operatorStackPop(int& operatorStackDepth)
521     {
522         operatorStackDepth--;
523         m_binaryOperatorStack.removeLast();
524     }
operatorStackHasHigherPrecedence(int &,int precedence)525     bool operatorStackHasHigherPrecedence(int&, int precedence)
526     {
527         return precedence <= m_binaryOperatorStack.last().second;
528     }
getFromOperandStack(int i)529     const BinaryOperand& getFromOperandStack(int i) { return m_binaryOperandStack[m_binaryOperandStack.size() + i]; }
shrinkOperandStackBy(int & operandStackDepth,int amount)530     void shrinkOperandStackBy(int& operandStackDepth, int amount)
531     {
532         operandStackDepth -= amount;
533         ASSERT(operandStackDepth >= 0);
534         m_binaryOperandStack.resize(m_binaryOperandStack.size() - amount);
535     }
appendBinaryOperation(int & operandStackDepth,int &,const BinaryOperand & lhs,const BinaryOperand & rhs)536     void appendBinaryOperation(int& operandStackDepth, int&, const BinaryOperand& lhs, const BinaryOperand& rhs)
537     {
538         operandStackDepth++;
539         m_binaryOperandStack.append(std::make_pair(makeBinaryNode(m_binaryOperatorStack.last().first, lhs, rhs), BinaryOpInfo(lhs.second, rhs.second)));
540     }
operatorStackAppend(int & operatorStackDepth,int op,int precedence)541     void operatorStackAppend(int& operatorStackDepth, int op, int precedence)
542     {
543         operatorStackDepth++;
544         m_binaryOperatorStack.append(std::make_pair(op, precedence));
545     }
popOperandStack(int &)546     ExpressionNode* popOperandStack(int&)
547     {
548         ExpressionNode* result = m_binaryOperandStack.last().first;
549         m_binaryOperandStack.removeLast();
550         return result;
551     }
552 
appendUnaryToken(int & tokenStackDepth,int type,int start)553     void appendUnaryToken(int& tokenStackDepth, int type, int start)
554     {
555         tokenStackDepth++;
556         m_unaryTokenStack.append(std::make_pair(type, start));
557     }
558 
unaryTokenStackLastType(int &)559     int unaryTokenStackLastType(int&)
560     {
561         return m_unaryTokenStack.last().first;
562     }
563 
unaryTokenStackLastStart(int &)564     int unaryTokenStackLastStart(int&)
565     {
566         return m_unaryTokenStack.last().second;
567     }
568 
unaryTokenStackRemoveLast(int & tokenStackDepth)569     void unaryTokenStackRemoveLast(int& tokenStackDepth)
570     {
571         tokenStackDepth--;
572         m_unaryTokenStack.removeLast();
573     }
574 
assignmentStackAppend(int & assignmentStackDepth,ExpressionNode * node,int start,int divot,int assignmentCount,Operator op)575     void assignmentStackAppend(int& assignmentStackDepth, ExpressionNode* node, int start, int divot, int assignmentCount, Operator op)
576     {
577         assignmentStackDepth++;
578         m_assignmentInfoStack.append(AssignmentInfo(node, start, divot, assignmentCount, op));
579     }
580 
createAssignment(int & assignmentStackDepth,ExpressionNode * rhs,int initialAssignmentCount,int currentAssignmentCount,int lastTokenEnd)581     ExpressionNode* createAssignment(int& assignmentStackDepth, ExpressionNode* rhs, int initialAssignmentCount, int currentAssignmentCount, int lastTokenEnd)
582     {
583         ExpressionNode* result = makeAssignNode(m_assignmentInfoStack.last().m_node, m_assignmentInfoStack.last().m_op, rhs, m_assignmentInfoStack.last().m_initAssignments != initialAssignmentCount, m_assignmentInfoStack.last().m_initAssignments != currentAssignmentCount, m_assignmentInfoStack.last().m_start, m_assignmentInfoStack.last().m_divot + 1, lastTokenEnd);
584         m_assignmentInfoStack.removeLast();
585         assignmentStackDepth--;
586         return result;
587     }
588 
getName(Property property)589     const Identifier& getName(Property property) const { return property->name(); }
getType(Property property)590     PropertyNode::Type getType(Property property) const { return property->type(); }
591 
isResolve(ExpressionNode * expr)592     bool isResolve(ExpressionNode* expr) const { return expr->isResolveNode(); }
593 
594 private:
595     struct Scope {
ScopeScope596         Scope(JSGlobalData* globalData)
597             : m_varDeclarations(new (globalData) ParserArenaData<DeclarationStacks::VarStack>)
598             , m_funcDeclarations(new (globalData) ParserArenaData<DeclarationStacks::FunctionStack>)
599             , m_features(0)
600             , m_numConstants(0)
601         {
602         }
603         ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
604         ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
605         int m_features;
606         int m_numConstants;
607     };
608 
setExceptionLocation(ThrowableExpressionData * node,unsigned start,unsigned divot,unsigned end)609     static void setExceptionLocation(ThrowableExpressionData* node, unsigned start, unsigned divot, unsigned end)
610     {
611         node->setExceptionSourceCode(divot, divot - start, end - divot);
612     }
613 
incConstants()614     void incConstants() { m_scope.m_numConstants++; }
usesThis()615     void usesThis() { m_scope.m_features |= ThisFeature; }
usesCatch()616     void usesCatch() { m_scope.m_features |= CatchFeature; }
usesClosures()617     void usesClosures() { m_scope.m_features |= ClosureFeature; }
usesArguments()618     void usesArguments() { m_scope.m_features |= ArgumentsFeature; }
usesAssignment()619     void usesAssignment() { m_scope.m_features |= AssignFeature; }
usesWith()620     void usesWith() { m_scope.m_features |= WithFeature; }
usesEval()621     void usesEval()
622     {
623         m_evalCount++;
624         m_scope.m_features |= EvalFeature;
625     }
createNumber(double d)626     ExpressionNode* createNumber(double d)
627     {
628         return new (m_globalData) NumberNode(m_globalData, d);
629     }
630 
631     JSGlobalData* m_globalData;
632     Lexer* m_lexer;
633     Scope m_scope;
634     Vector<BinaryOperand, 10> m_binaryOperandStack;
635     Vector<AssignmentInfo, 10> m_assignmentInfoStack;
636     Vector<pair<int, int>, 10> m_binaryOperatorStack;
637     Vector<pair<int, int>, 10> m_unaryTokenStack;
638     int m_evalCount;
639 };
640 
makeTypeOfNode(ExpressionNode * expr)641 ExpressionNode* ASTBuilder::makeTypeOfNode(ExpressionNode* expr)
642 {
643     if (expr->isResolveNode()) {
644         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
645         return new (m_globalData) TypeOfResolveNode(m_globalData, resolve->identifier());
646     }
647     return new (m_globalData) TypeOfValueNode(m_globalData, expr);
648 }
649 
makeDeleteNode(ExpressionNode * expr,int start,int divot,int end)650 ExpressionNode* ASTBuilder::makeDeleteNode(ExpressionNode* expr, int start, int divot, int end)
651 {
652     if (!expr->isLocation())
653         return new (m_globalData) DeleteValueNode(m_globalData, expr);
654     if (expr->isResolveNode()) {
655         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
656         return new (m_globalData) DeleteResolveNode(m_globalData, resolve->identifier(), divot, divot - start, end - divot);
657     }
658     if (expr->isBracketAccessorNode()) {
659         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
660         return new (m_globalData) DeleteBracketNode(m_globalData, bracket->base(), bracket->subscript(), divot, divot - start, end - divot);
661     }
662     ASSERT(expr->isDotAccessorNode());
663     DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
664     return new (m_globalData) DeleteDotNode(m_globalData, dot->base(), dot->identifier(), divot, divot - start, end - divot);
665 }
666 
makeNegateNode(ExpressionNode * n)667 ExpressionNode* ASTBuilder::makeNegateNode(ExpressionNode* n)
668 {
669     if (n->isNumber()) {
670         NumberNode* numberNode = static_cast<NumberNode*>(n);
671         numberNode->setValue(-numberNode->value());
672         return numberNode;
673     }
674 
675     return new (m_globalData) NegateNode(m_globalData, n);
676 }
677 
makeBitwiseNotNode(ExpressionNode * expr)678 ExpressionNode* ASTBuilder::makeBitwiseNotNode(ExpressionNode* expr)
679 {
680     if (expr->isNumber())
681         return createNumber(~toInt32(static_cast<NumberNode*>(expr)->value()));
682     return new (m_globalData) BitwiseNotNode(m_globalData, expr);
683 }
684 
makeMultNode(ExpressionNode * expr1,ExpressionNode * expr2,bool rightHasAssignments)685 ExpressionNode* ASTBuilder::makeMultNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
686 {
687     expr1 = expr1->stripUnaryPlus();
688     expr2 = expr2->stripUnaryPlus();
689 
690     if (expr1->isNumber() && expr2->isNumber())
691         return createNumber(static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value());
692 
693     if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1)
694         return new (m_globalData) UnaryPlusNode(m_globalData, expr2);
695 
696     if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1)
697         return new (m_globalData) UnaryPlusNode(m_globalData, expr1);
698 
699     return new (m_globalData) MultNode(m_globalData, expr1, expr2, rightHasAssignments);
700 }
701 
makeDivNode(ExpressionNode * expr1,ExpressionNode * expr2,bool rightHasAssignments)702 ExpressionNode* ASTBuilder::makeDivNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
703 {
704     expr1 = expr1->stripUnaryPlus();
705     expr2 = expr2->stripUnaryPlus();
706 
707     if (expr1->isNumber() && expr2->isNumber())
708         return createNumber(static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value());
709     return new (m_globalData) DivNode(m_globalData, expr1, expr2, rightHasAssignments);
710 }
711 
makeModNode(ExpressionNode * expr1,ExpressionNode * expr2,bool rightHasAssignments)712 ExpressionNode* ASTBuilder::makeModNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
713 {
714     expr1 = expr1->stripUnaryPlus();
715     expr2 = expr2->stripUnaryPlus();
716 
717     if (expr1->isNumber() && expr2->isNumber())
718         return createNumber(fmod(static_cast<NumberNode*>(expr1)->value(), static_cast<NumberNode*>(expr2)->value()));
719     return new (m_globalData) ModNode(m_globalData, expr1, expr2, rightHasAssignments);
720 }
721 
makeAddNode(ExpressionNode * expr1,ExpressionNode * expr2,bool rightHasAssignments)722 ExpressionNode* ASTBuilder::makeAddNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
723 {
724     if (expr1->isNumber() && expr2->isNumber())
725         return createNumber(static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value());
726     return new (m_globalData) AddNode(m_globalData, expr1, expr2, rightHasAssignments);
727 }
728 
makeSubNode(ExpressionNode * expr1,ExpressionNode * expr2,bool rightHasAssignments)729 ExpressionNode* ASTBuilder::makeSubNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
730 {
731     expr1 = expr1->stripUnaryPlus();
732     expr2 = expr2->stripUnaryPlus();
733 
734     if (expr1->isNumber() && expr2->isNumber())
735         return createNumber(static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value());
736     return new (m_globalData) SubNode(m_globalData, expr1, expr2, rightHasAssignments);
737 }
738 
makeLeftShiftNode(ExpressionNode * expr1,ExpressionNode * expr2,bool rightHasAssignments)739 ExpressionNode* ASTBuilder::makeLeftShiftNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
740 {
741     if (expr1->isNumber() && expr2->isNumber())
742         return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
743     return new (m_globalData) LeftShiftNode(m_globalData, expr1, expr2, rightHasAssignments);
744 }
745 
makeRightShiftNode(ExpressionNode * expr1,ExpressionNode * expr2,bool rightHasAssignments)746 ExpressionNode* ASTBuilder::makeRightShiftNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
747 {
748     if (expr1->isNumber() && expr2->isNumber())
749         return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
750     return new (m_globalData) RightShiftNode(m_globalData, expr1, expr2, rightHasAssignments);
751 }
752 
makeURightShiftNode(ExpressionNode * expr1,ExpressionNode * expr2,bool rightHasAssignments)753 ExpressionNode* ASTBuilder::makeURightShiftNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
754 {
755     if (expr1->isNumber() && expr2->isNumber())
756         return createNumber(toUInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
757     return new (m_globalData) UnsignedRightShiftNode(m_globalData, expr1, expr2, rightHasAssignments);
758 }
759 
makeBitOrNode(ExpressionNode * expr1,ExpressionNode * expr2,bool rightHasAssignments)760 ExpressionNode* ASTBuilder::makeBitOrNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
761 {
762     if (expr1->isNumber() && expr2->isNumber())
763         return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) | toInt32(static_cast<NumberNode*>(expr2)->value()));
764     return new (m_globalData) BitOrNode(m_globalData, expr1, expr2, rightHasAssignments);
765 }
766 
makeBitAndNode(ExpressionNode * expr1,ExpressionNode * expr2,bool rightHasAssignments)767 ExpressionNode* ASTBuilder::makeBitAndNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
768 {
769     if (expr1->isNumber() && expr2->isNumber())
770         return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) & toInt32(static_cast<NumberNode*>(expr2)->value()));
771     return new (m_globalData) BitAndNode(m_globalData, expr1, expr2, rightHasAssignments);
772 }
773 
makeBitXOrNode(ExpressionNode * expr1,ExpressionNode * expr2,bool rightHasAssignments)774 ExpressionNode* ASTBuilder::makeBitXOrNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
775 {
776     if (expr1->isNumber() && expr2->isNumber())
777         return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) ^ toInt32(static_cast<NumberNode*>(expr2)->value()));
778     return new (m_globalData) BitXOrNode(m_globalData, expr1, expr2, rightHasAssignments);
779 }
780 
makeFunctionCallNode(ExpressionNode * func,ArgumentsNode * args,int start,int divot,int end)781 ExpressionNode* ASTBuilder::makeFunctionCallNode(ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end)
782 {
783     if (!func->isLocation())
784         return new (m_globalData) FunctionCallValueNode(m_globalData, func, args, divot, divot - start, end - divot);
785     if (func->isResolveNode()) {
786         ResolveNode* resolve = static_cast<ResolveNode*>(func);
787         const Identifier& identifier = resolve->identifier();
788         if (identifier == m_globalData->propertyNames->eval) {
789             usesEval();
790             return new (m_globalData) EvalFunctionCallNode(m_globalData, args, divot, divot - start, end - divot);
791         }
792         return new (m_globalData) FunctionCallResolveNode(m_globalData, identifier, args, divot, divot - start, end - divot);
793     }
794     if (func->isBracketAccessorNode()) {
795         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func);
796         FunctionCallBracketNode* node = new (m_globalData) FunctionCallBracketNode(m_globalData, bracket->base(), bracket->subscript(), args, divot, divot - start, end - divot);
797         node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
798         return node;
799     }
800     ASSERT(func->isDotAccessorNode());
801     DotAccessorNode* dot = static_cast<DotAccessorNode*>(func);
802     FunctionCallDotNode* node;
803     if (dot->identifier() == m_globalData->propertyNames->call)
804         node = new (m_globalData) CallFunctionCallDotNode(m_globalData, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
805     else if (dot->identifier() == m_globalData->propertyNames->apply)
806         node = new (m_globalData) ApplyFunctionCallDotNode(m_globalData, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
807     else
808         node = new (m_globalData) FunctionCallDotNode(m_globalData, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
809     node->setSubexpressionInfo(dot->divot(), dot->endOffset());
810     return node;
811 }
812 
makeBinaryNode(int token,pair<ExpressionNode *,BinaryOpInfo> lhs,pair<ExpressionNode *,BinaryOpInfo> rhs)813 ExpressionNode* ASTBuilder::makeBinaryNode(int token, pair<ExpressionNode*, BinaryOpInfo> lhs, pair<ExpressionNode*, BinaryOpInfo> rhs)
814 {
815     switch (token) {
816     case OR:
817         return new (m_globalData) LogicalOpNode(m_globalData, lhs.first, rhs.first, OpLogicalOr);
818 
819     case AND:
820         return new (m_globalData) LogicalOpNode(m_globalData, lhs.first, rhs.first, OpLogicalAnd);
821 
822     case BITOR:
823         return makeBitOrNode(lhs.first, rhs.first, rhs.second.hasAssignment);
824 
825     case BITXOR:
826         return makeBitXOrNode(lhs.first, rhs.first, rhs.second.hasAssignment);
827 
828     case BITAND:
829         return makeBitAndNode(lhs.first, rhs.first, rhs.second.hasAssignment);
830 
831     case EQEQ:
832         return new (m_globalData) EqualNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
833 
834     case NE:
835         return new (m_globalData) NotEqualNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
836 
837     case STREQ:
838         return new (m_globalData) StrictEqualNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
839 
840     case STRNEQ:
841         return new (m_globalData) NotStrictEqualNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
842 
843     case LT:
844         return new (m_globalData) LessNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
845 
846     case GT:
847         return new (m_globalData) GreaterNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
848 
849     case LE:
850         return new (m_globalData) LessEqNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
851 
852     case GE:
853         return new (m_globalData) GreaterEqNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
854 
855     case INSTANCEOF: {
856         InstanceOfNode* node = new (m_globalData) InstanceOfNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
857         setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
858         return node;
859     }
860 
861     case INTOKEN: {
862         InNode* node = new (m_globalData) InNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
863         setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
864         return node;
865     }
866 
867     case LSHIFT:
868         return makeLeftShiftNode(lhs.first, rhs.first, rhs.second.hasAssignment);
869 
870     case RSHIFT:
871         return makeRightShiftNode(lhs.first, rhs.first, rhs.second.hasAssignment);
872 
873     case URSHIFT:
874         return makeURightShiftNode(lhs.first, rhs.first, rhs.second.hasAssignment);
875 
876     case PLUS:
877         return makeAddNode(lhs.first, rhs.first, rhs.second.hasAssignment);
878 
879     case MINUS:
880         return makeSubNode(lhs.first, rhs.first, rhs.second.hasAssignment);
881 
882     case TIMES:
883         return makeMultNode(lhs.first, rhs.first, rhs.second.hasAssignment);
884 
885     case DIVIDE:
886         return makeDivNode(lhs.first, rhs.first, rhs.second.hasAssignment);
887 
888     case MOD:
889         return makeModNode(lhs.first, rhs.first, rhs.second.hasAssignment);
890     }
891     CRASH();
892     return 0;
893 }
894 
makeAssignNode(ExpressionNode * loc,Operator op,ExpressionNode * expr,bool locHasAssignments,bool exprHasAssignments,int start,int divot,int end)895 ExpressionNode* ASTBuilder::makeAssignNode(ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end)
896 {
897     usesAssignment();
898     if (!loc->isLocation())
899         return new (m_globalData) AssignErrorNode(m_globalData, loc, op, expr, divot, divot - start, end - divot);
900 
901     if (loc->isResolveNode()) {
902         ResolveNode* resolve = static_cast<ResolveNode*>(loc);
903         if (op == OpEqual) {
904             AssignResolveNode* node = new (m_globalData) AssignResolveNode(m_globalData, resolve->identifier(), expr, exprHasAssignments);
905             setExceptionLocation(node, start, divot, end);
906             return node;
907         }
908         return new (m_globalData) ReadModifyResolveNode(m_globalData, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
909     }
910     if (loc->isBracketAccessorNode()) {
911         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc);
912         if (op == OpEqual)
913             return new (m_globalData) AssignBracketNode(m_globalData, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot());
914         ReadModifyBracketNode* node = new (m_globalData) ReadModifyBracketNode(m_globalData, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot);
915         node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
916         return node;
917     }
918     ASSERT(loc->isDotAccessorNode());
919     DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc);
920     if (op == OpEqual)
921         return new (m_globalData) AssignDotNode(m_globalData, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot());
922 
923     ReadModifyDotNode* node = new (m_globalData) ReadModifyDotNode(m_globalData, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
924     node->setSubexpressionInfo(dot->divot(), dot->endOffset());
925     return node;
926 }
927 
makePrefixNode(ExpressionNode * expr,Operator op,int start,int divot,int end)928 ExpressionNode* ASTBuilder::makePrefixNode(ExpressionNode* expr, Operator op, int start, int divot, int end)
929 {
930     usesAssignment();
931     if (!expr->isLocation())
932         return new (m_globalData) PrefixErrorNode(m_globalData, expr, op, divot, divot - start, end - divot);
933 
934     if (expr->isResolveNode()) {
935         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
936         return new (m_globalData) PrefixResolveNode(m_globalData, resolve->identifier(), op, divot, divot - start, end - divot);
937     }
938     if (expr->isBracketAccessorNode()) {
939         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
940         PrefixBracketNode* node = new (m_globalData) PrefixBracketNode(m_globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
941         node->setSubexpressionInfo(bracket->divot(), bracket->startOffset());
942         return node;
943     }
944     ASSERT(expr->isDotAccessorNode());
945     DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
946     PrefixDotNode* node = new (m_globalData) PrefixDotNode(m_globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
947     node->setSubexpressionInfo(dot->divot(), dot->startOffset());
948     return node;
949 }
950 
makePostfixNode(ExpressionNode * expr,Operator op,int start,int divot,int end)951 ExpressionNode* ASTBuilder::makePostfixNode(ExpressionNode* expr, Operator op, int start, int divot, int end)
952 {
953     usesAssignment();
954     if (!expr->isLocation())
955         return new (m_globalData) PostfixErrorNode(m_globalData, expr, op, divot, divot - start, end - divot);
956 
957     if (expr->isResolveNode()) {
958         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
959         return new (m_globalData) PostfixResolveNode(m_globalData, resolve->identifier(), op, divot, divot - start, end - divot);
960     }
961     if (expr->isBracketAccessorNode()) {
962         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
963         PostfixBracketNode* node = new (m_globalData) PostfixBracketNode(m_globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
964         node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
965         return node;
966 
967     }
968     ASSERT(expr->isDotAccessorNode());
969     DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
970     PostfixDotNode* node = new (m_globalData) PostfixDotNode(m_globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
971     node->setSubexpressionInfo(dot->divot(), dot->endOffset());
972     return node;
973 }
974 
975 }
976 
977 #endif
978