eval("this.foo") causes a crash if this had not been initialized in a derived class...
[WebKit-https.git] / Source / JavaScriptCore / parser / ASTBuilder.h
1 /*
2  * Copyright (C) 2010, 2013 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 "BuiltinNames.h"
30 #include "NodeConstructors.h"
31 #include "SyntaxChecker.h"
32 #include <utility>
33
34 namespace JSC {
35
36 class ASTBuilder {
37     struct BinaryOpInfo {
38         BinaryOpInfo() {}
39         BinaryOpInfo(const JSTextPosition& otherStart, const JSTextPosition& otherDivot, const JSTextPosition& otherEnd, bool rhsHasAssignment)
40             : start(otherStart)
41             , divot(otherDivot)
42             , end(otherEnd)
43             , hasAssignment(rhsHasAssignment)
44         {
45         }
46         BinaryOpInfo(const BinaryOpInfo& lhs, const BinaryOpInfo& rhs)
47             : start(lhs.start)
48             , divot(rhs.start)
49             , end(rhs.end)
50             , hasAssignment(lhs.hasAssignment || rhs.hasAssignment)
51         {
52         }
53         JSTextPosition start;
54         JSTextPosition divot;
55         JSTextPosition end;
56         bool hasAssignment;
57     };
58     
59     
60     struct AssignmentInfo {
61         AssignmentInfo() {}
62         AssignmentInfo(ExpressionNode* node, const JSTextPosition& start, const JSTextPosition& divot, int initAssignments, Operator op)
63             : m_node(node)
64             , m_start(start)
65             , m_divot(divot)
66             , m_initAssignments(initAssignments)
67             , m_op(op)
68         {
69             ASSERT(m_divot.offset >= m_divot.lineStartOffset);
70             ASSERT(m_start.offset >= m_start.lineStartOffset);
71         }
72         ExpressionNode* m_node;
73         JSTextPosition m_start;
74         JSTextPosition m_divot;
75         int m_initAssignments;
76         Operator m_op;
77     };
78 public:
79     ASTBuilder(VM* vm, ParserArena& parserArena, SourceCode* sourceCode)
80         : m_vm(vm)
81         , m_parserArena(parserArena)
82         , m_sourceCode(sourceCode)
83         , m_evalCount(0)
84     {
85     }
86     
87     struct BinaryExprContext {
88         BinaryExprContext(ASTBuilder&) {}
89     };
90     struct UnaryExprContext {
91         UnaryExprContext(ASTBuilder&) {}
92     };
93
94
95     typedef SyntaxChecker FunctionBodyBuilder;
96
97     typedef ExpressionNode* Expression;
98     typedef JSC::SourceElements* SourceElements;
99     typedef ArgumentsNode* Arguments;
100     typedef CommaNode* Comma;
101     typedef PropertyNode* Property;
102     typedef PropertyListNode* PropertyList;
103     typedef ElementNode* ElementList;
104     typedef ArgumentListNode* ArgumentsList;
105     typedef ParameterNode* FormalParameterList;
106     typedef FunctionBodyNode* FunctionBody;
107 #if ENABLE(ES6_CLASS_SYNTAX)
108     typedef ClassExprNode* ClassExpression;
109 #endif
110     typedef StatementNode* Statement;
111     typedef ClauseListNode* ClauseList;
112     typedef CaseClauseNode* Clause;
113     typedef ConstDeclNode* ConstDeclList;
114     typedef std::pair<ExpressionNode*, BinaryOpInfo> BinaryOperand;
115     typedef RefPtr<DeconstructionPatternNode> DeconstructionPattern;
116     typedef RefPtr<ArrayPatternNode> ArrayPattern;
117     typedef RefPtr<ObjectPatternNode> ObjectPattern;
118     typedef RefPtr<BindingNode> BindingPattern;
119     static const bool CreatesAST = true;
120     static const bool NeedsFreeVariableInfo = true;
121     static const bool CanUseFunctionCache = true;
122     static const int  DontBuildKeywords = 0;
123     static const int  DontBuildStrings = 0;
124
125     ExpressionNode* makeBinaryNode(const JSTokenLocation&, int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>);
126     ExpressionNode* makeFunctionCallNode(const JSTokenLocation&, ExpressionNode* func, ArgumentsNode* args, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd);
127
128     JSC::SourceElements* createSourceElements() { return new (m_parserArena) JSC::SourceElements(); }
129
130     DeclarationStacks::VarStack& varDeclarations() { return m_scope.m_varDeclarations; }
131     DeclarationStacks::FunctionStack& funcDeclarations() { return m_scope.m_funcDeclarations; }
132     int features() const { return m_scope.m_features; }
133     int numConstants() const { return m_scope.m_numConstants; }
134
135     ExpressionNode* makeAssignNode(const JSTokenLocation&, ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end);
136     ExpressionNode* makePrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end);
137     ExpressionNode* makePostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end);
138     ExpressionNode* makeTypeOfNode(const JSTokenLocation&, ExpressionNode*);
139     ExpressionNode* makeDeleteNode(const JSTokenLocation&, ExpressionNode*, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end);
140     ExpressionNode* makeNegateNode(const JSTokenLocation&, ExpressionNode*);
141     ExpressionNode* makeBitwiseNotNode(const JSTokenLocation&, ExpressionNode*);
142     ExpressionNode* makeMultNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
143     ExpressionNode* makeDivNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
144     ExpressionNode* makeModNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
145     ExpressionNode* makeAddNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
146     ExpressionNode* makeSubNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
147     ExpressionNode* makeBitXOrNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
148     ExpressionNode* makeBitAndNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
149     ExpressionNode* makeBitOrNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
150     ExpressionNode* makeLeftShiftNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
151     ExpressionNode* makeRightShiftNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
152     ExpressionNode* makeURightShiftNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
153
154     ExpressionNode* createLogicalNot(const JSTokenLocation& location, ExpressionNode* expr)
155     {
156         if (expr->isNumber())
157             return createBoolean(location, isZeroOrUnordered(static_cast<NumberNode*>(expr)->value()));
158
159         return new (m_parserArena) LogicalNotNode(location, expr);
160     }
161     ExpressionNode* createUnaryPlus(const JSTokenLocation& location, ExpressionNode* expr) { return new (m_parserArena) UnaryPlusNode(location, expr); }
162     ExpressionNode* createVoid(const JSTokenLocation& location, ExpressionNode* expr)
163     {
164         incConstants();
165         return new (m_parserArena) VoidNode(location, expr);
166     }
167     ExpressionNode* thisExpr(const JSTokenLocation& location, ThisTDZMode thisTDZMode)
168     {
169         usesThis();
170         return new (m_parserArena) ThisNode(location, thisTDZMode);
171     }
172     ExpressionNode* superExpr(const JSTokenLocation& location)
173     {
174         return new (m_parserArena) SuperNode(location);
175     }
176     ExpressionNode* createResolve(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start)
177     {
178         if (m_vm->propertyNames->arguments == *ident)
179             usesArguments();
180         return new (m_parserArena) ResolveNode(location, *ident, start);
181     }
182     ExpressionNode* createObjectLiteral(const JSTokenLocation& location) { return new (m_parserArena) ObjectLiteralNode(location); }
183     ExpressionNode* createObjectLiteral(const JSTokenLocation& location, PropertyListNode* properties) { return new (m_parserArena) ObjectLiteralNode(location, properties); }
184
185     ExpressionNode* createArray(const JSTokenLocation& location, int elisions)
186     {
187         if (elisions)
188             incConstants();
189         return new (m_parserArena) ArrayNode(location, elisions);
190     }
191
192     ExpressionNode* createArray(const JSTokenLocation& location, ElementNode* elems) { return new (m_parserArena) ArrayNode(location, elems); }
193     ExpressionNode* createArray(const JSTokenLocation& location, int elisions, ElementNode* elems)
194     {
195         if (elisions)
196             incConstants();
197         return new (m_parserArena) ArrayNode(location, elisions, elems);
198     }
199     ExpressionNode* createDoubleExpr(const JSTokenLocation& location, double d)
200     {
201         incConstants();
202         return new (m_parserArena) DoubleNode(location, d);
203     }
204     ExpressionNode* createIntegerExpr(const JSTokenLocation& location, double d)
205     {
206         incConstants();
207         return new (m_parserArena) IntegerNode(location, d);
208     }
209
210     ExpressionNode* createString(const JSTokenLocation& location, const Identifier* string)
211     {
212         incConstants();
213         return new (m_parserArena) StringNode(location, *string);
214     }
215
216     ExpressionNode* createBoolean(const JSTokenLocation& location, bool b)
217     {
218         incConstants();
219         return new (m_parserArena) BooleanNode(location, b);
220     }
221
222     ExpressionNode* createNull(const JSTokenLocation& location)
223     {
224         incConstants();
225         return new (m_parserArena) NullNode(location);
226     }
227
228     ExpressionNode* createBracketAccess(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
229     {
230         BracketAccessorNode* node = new (m_parserArena) BracketAccessorNode(location, base, property, propertyHasAssignments);
231         setExceptionLocation(node, start, divot, end);
232         return node;
233     }
234
235     ExpressionNode* createDotAccess(const JSTokenLocation& location, ExpressionNode* base, const Identifier* property, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
236     {
237         DotAccessorNode* node = new (m_parserArena) DotAccessorNode(location, base, *property);
238         setExceptionLocation(node, start, divot, end);
239         return node;
240     }
241
242     ExpressionNode* createSpreadExpression(const JSTokenLocation& location, ExpressionNode* expression, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
243     {
244         auto node = new (m_parserArena) SpreadExpressionNode(location, expression);
245         setExceptionLocation(node, start, divot, end);
246         return node;
247     }
248
249     ExpressionNode* createRegExp(const JSTokenLocation& location, const Identifier& pattern, const Identifier& flags, const JSTextPosition& start)
250     {
251         if (Yarr::checkSyntax(pattern.string()))
252             return 0;
253         RegExpNode* node = new (m_parserArena) RegExpNode(location, pattern, flags);
254         int size = pattern.length() + 2; // + 2 for the two /'s
255         JSTextPosition end = start + size;
256         setExceptionLocation(node, start, end, end);
257         return node;
258     }
259
260     ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* arguments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
261     {
262         NewExprNode* node = new (m_parserArena) NewExprNode(location, expr, arguments);
263         setExceptionLocation(node, start, divot, end);
264         return node;
265     }
266
267     ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& end)
268     {
269         NewExprNode* node = new (m_parserArena) NewExprNode(location, expr);
270         setExceptionLocation(node, start, end, end);
271         return node;
272     }
273
274     ExpressionNode* createConditionalExpr(const JSTokenLocation& location, ExpressionNode* condition, ExpressionNode* lhs, ExpressionNode* rhs)
275     {
276         return new (m_parserArena) ConditionalNode(location, condition, lhs, rhs);
277     }
278
279     ExpressionNode* createAssignResolve(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* rhs, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
280     {
281         if (rhs->isFuncExprNode())
282             static_cast<FuncExprNode*>(rhs)->body()->setInferredName(ident);
283         AssignResolveNode* node = new (m_parserArena) AssignResolveNode(location, ident, rhs);
284         setExceptionLocation(node, start, divot, end);
285         return node;
286     }
287
288 #if ENABLE(ES6_CLASS_SYNTAX)
289     ClassExprNode* createClassExpr(const JSTokenLocation& location, const Identifier& name, ExpressionNode* constructor,
290         ExpressionNode* parentClass, PropertyListNode* instanceMethods, PropertyListNode* staticMethods)
291     {
292         return new (m_parserArena) ClassExprNode(location, name, constructor, parentClass, instanceMethods, staticMethods);
293     }
294 #endif
295
296     ExpressionNode* createFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& info)
297     {
298         FuncExprNode* result = new (m_parserArena) FuncExprNode(location, *info.name, info.body,
299             m_sourceCode->subExpression(info.openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn), info.parameters);
300         info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset);
301         return result;
302     }
303
304     FunctionBodyNode* createFunctionBody(
305         const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, 
306         unsigned startColumn, unsigned endColumn, int functionKeywordStart, 
307         int functionNameStart, int parametersStart, bool inStrictContext, 
308         ConstructorKind constructorKind)
309     {
310         return new (m_parserArena) FunctionBodyNode(
311             m_parserArena, startLocation, endLocation, startColumn, endColumn, 
312             functionKeywordStart, functionNameStart, parametersStart, 
313             inStrictContext, constructorKind);
314     }
315
316     NEVER_INLINE PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type, bool,
317         const Identifier* name, const ParserFunctionInfo<ASTBuilder>& info, SuperBinding superBinding)
318     {
319         ASSERT(name);
320         info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset);
321         info.body->setInferredName(*name);
322         SourceCode source = m_sourceCode->subExpression(info.openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn);
323         FuncExprNode* funcExpr = new (m_parserArena) FuncExprNode(location, m_vm->propertyNames->nullIdentifier, info.body, source, info.parameters);
324         return new (m_parserArena) PropertyNode(*name, funcExpr, type, PropertyNode::Unknown, superBinding);
325     }
326     
327     NEVER_INLINE PropertyNode* createGetterOrSetterProperty(VM* vm, ParserArena& parserArena, const JSTokenLocation& location, PropertyNode::Type type, bool,
328         double name, const ParserFunctionInfo<ASTBuilder>& info, SuperBinding superBinding)
329     {
330         info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset);
331         const Identifier& ident = parserArena.identifierArena().makeNumericIdentifier(vm, name);
332         SourceCode source = m_sourceCode->subExpression(info.openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn);
333         FuncExprNode* funcExpr = new (m_parserArena) FuncExprNode(location, vm->propertyNames->nullIdentifier, info.body, source, info.parameters);
334         return new (m_parserArena) PropertyNode(ident, funcExpr, type, PropertyNode::Unknown, superBinding);
335     }
336
337     ArgumentsNode* createArguments() { return new (m_parserArena) ArgumentsNode(); }
338     ArgumentsNode* createArguments(ArgumentListNode* args) { return new (m_parserArena) ArgumentsNode(args); }
339     ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ExpressionNode* arg) { return new (m_parserArena) ArgumentListNode(location, arg); }
340     ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ArgumentListNode* args, ExpressionNode* arg) { return new (m_parserArena) ArgumentListNode(location, args, arg); }
341
342     PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding = SuperBinding::NotNeeded)
343     {
344         if (node->isFuncExprNode())
345             static_cast<FuncExprNode*>(node)->body()->setInferredName(*propertyName);
346         return new (m_parserArena) PropertyNode(*propertyName, node, type, putType, superBinding);
347     }
348     PropertyNode* createProperty(VM* vm, ParserArena& parserArena, double propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool)
349     {
350         return new (m_parserArena) PropertyNode(parserArena.identifierArena().makeNumericIdentifier(vm, propertyName), node, type, putType);
351     }
352     PropertyNode* createProperty(ExpressionNode* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool) { return new (m_parserArena) PropertyNode(propertyName, node, type, putType); }
353     PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property) { return new (m_parserArena) PropertyListNode(location, property); }
354     PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property, PropertyListNode* tail) { return new (m_parserArena) PropertyListNode(location, property, tail); }
355
356     ElementNode* createElementList(int elisions, ExpressionNode* expr) { return new (m_parserArena) ElementNode(elisions, expr); }
357     ElementNode* createElementList(ElementNode* elems, int elisions, ExpressionNode* expr) { return new (m_parserArena) ElementNode(elems, elisions, expr); }
358
359     ParameterNode* createFormalParameterList(DeconstructionPattern pattern) { return new (m_parserArena) ParameterNode(pattern); }
360     ParameterNode* createFormalParameterList(ParameterNode* list, DeconstructionPattern pattern) { return new (m_parserArena) ParameterNode(list, pattern); }
361
362     CaseClauseNode* createClause(ExpressionNode* expr, JSC::SourceElements* statements) { return new (m_parserArena) CaseClauseNode(expr, statements); }
363     ClauseListNode* createClauseList(CaseClauseNode* clause) { return new (m_parserArena) ClauseListNode(clause); }
364     ClauseListNode* createClauseList(ClauseListNode* tail, CaseClauseNode* clause) { return new (m_parserArena) ClauseListNode(tail, clause); }
365
366     StatementNode* createFuncDeclStatement(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& info)
367     {
368         FuncDeclNode* decl = new (m_parserArena) FuncDeclNode(location, *info.name, info.body,
369             m_sourceCode->subExpression(info.openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn), info.parameters);
370         if (*info.name == m_vm->propertyNames->arguments)
371             usesArguments();
372         m_scope.m_funcDeclarations.append(decl->body());
373         info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset);
374         return decl;
375     }
376
377 #if ENABLE(ES6_CLASS_SYNTAX)
378     StatementNode* createClassDeclStatement(const JSTokenLocation& location, ClassExprNode* classExpression,
379         const JSTextPosition& classStart, const JSTextPosition& classEnd, unsigned startLine, unsigned endLine)
380     {
381         // FIXME: Use "let" declaration.
382         ExpressionNode* assign = createAssignResolve(location, classExpression->name(), classExpression, classStart, classStart + 1, classEnd);
383         ClassDeclNode* decl = new (m_parserArena) ClassDeclNode(location, assign);
384         decl->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
385         return decl;
386     }
387 #endif
388
389     StatementNode* createBlockStatement(const JSTokenLocation& location, JSC::SourceElements* elements, int startLine, int endLine)
390     {
391         BlockNode* block = new (m_parserArena) BlockNode(location, elements);
392         block->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
393         return block;
394     }
395
396     StatementNode* createExprStatement(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, int end)
397     {
398         ExprStatementNode* result = new (m_parserArena) ExprStatementNode(location, expr);
399         result->setLoc(start.line, end, start.offset, start.lineStartOffset);
400         return result;
401     }
402
403     StatementNode* createIfStatement(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* trueBlock, StatementNode* falseBlock, int start, int end)
404     {
405         IfElseNode* result = new (m_parserArena) IfElseNode(location, condition, trueBlock, falseBlock);
406         result->setLoc(start, end, location.startOffset, location.lineStartOffset);
407         return result;
408     }
409
410     StatementNode* createForLoop(const JSTokenLocation& location, ExpressionNode* initializer, ExpressionNode* condition, ExpressionNode* iter, StatementNode* statements, int start, int end)
411     {
412         ForNode* result = new (m_parserArena) ForNode(location, initializer, condition, iter, statements);
413         result->setLoc(start, end, location.startOffset, location.lineStartOffset);
414         return result;
415     }
416
417     StatementNode* createForInLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end)
418     {
419         ForInNode* result = new (m_parserArena) ForInNode(location, lhs, iter, statements);
420         result->setLoc(start, end, location.startOffset, location.lineStartOffset);
421         setExceptionLocation(result, eStart, eDivot, eEnd);
422         return result;
423     }
424     
425     StatementNode* createForInLoop(const JSTokenLocation& location, PassRefPtr<DeconstructionPatternNode> pattern, ExpressionNode* iter, StatementNode* statements, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end)
426     {
427         auto lexpr = new (m_parserArena) DeconstructingAssignmentNode(location, pattern.get(), 0);
428         return createForInLoop(location, lexpr, iter, statements, eStart, eDivot, eEnd, start, end);
429     }
430     
431     StatementNode* createForOfLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end)
432     {
433         ForOfNode* result = new (m_parserArena) ForOfNode(location, lhs, iter, statements);
434         result->setLoc(start, end, location.startOffset, location.lineStartOffset);
435         setExceptionLocation(result, eStart, eDivot, eEnd);
436         return result;
437     }
438     
439     StatementNode* createForOfLoop(const JSTokenLocation& location, PassRefPtr<DeconstructionPatternNode> pattern, ExpressionNode* iter, StatementNode* statements, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end)
440     {
441         auto lexpr = new (m_parserArena) DeconstructingAssignmentNode(location, pattern.get(), 0);
442         return createForOfLoop(location, lexpr, iter, statements, eStart, eDivot, eEnd, start, end);
443     }
444
445     bool isBindingNode(const DeconstructionPattern& pattern)
446     {
447         return pattern->isBindingNode();
448     }
449
450     StatementNode* createEmptyStatement(const JSTokenLocation& location) { return new (m_parserArena) EmptyStatementNode(location); }
451
452     StatementNode* createVarStatement(const JSTokenLocation& location, ExpressionNode* expr, int start, int end)
453     {
454         StatementNode* result;
455         result = new (m_parserArena) VarStatementNode(location, expr);
456         result->setLoc(start, end, location.startOffset, location.lineStartOffset);
457         return result;
458     }
459
460     ExpressionNode* createEmptyVarExpression(const JSTokenLocation& location, const Identifier& identifier)
461     {
462         return new (m_parserArena) EmptyVarExpression(location, identifier);
463     }
464
465     StatementNode* createReturnStatement(const JSTokenLocation& location, ExpressionNode* expression, const JSTextPosition& start, const JSTextPosition& end)
466     {
467         ReturnNode* result = new (m_parserArena) ReturnNode(location, expression);
468         setExceptionLocation(result, start, end, end);
469         result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
470         return result;
471     }
472
473     StatementNode* createBreakStatement(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end)
474     {
475         BreakNode* result = new (m_parserArena) BreakNode(location, *ident);
476         setExceptionLocation(result, start, end, end);
477         result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
478         return result;
479     }
480
481     StatementNode* createContinueStatement(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end)
482     {
483         ContinueNode* result = new (m_parserArena) ContinueNode(location, *ident);
484         setExceptionLocation(result, start, end, end);
485         result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
486         return result;
487     }
488
489     StatementNode* createTryStatement(const JSTokenLocation& location, StatementNode* tryBlock, const Identifier* ident, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
490     {
491         TryNode* result = new (m_parserArena) TryNode(location, tryBlock, *ident, catchBlock, finallyBlock);
492         if (catchBlock)
493             usesCatch();
494         result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
495         return result;
496     }
497
498     StatementNode* createSwitchStatement(const JSTokenLocation& location, ExpressionNode* expr, ClauseListNode* firstClauses, CaseClauseNode* defaultClause, ClauseListNode* secondClauses, int startLine, int endLine)
499     {
500         CaseBlockNode* cases = new (m_parserArena) CaseBlockNode(firstClauses, defaultClause, secondClauses);
501         SwitchNode* result = new (m_parserArena) SwitchNode(location, expr, cases);
502         result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
503         return result;
504     }
505
506     StatementNode* createWhileStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, int startLine, int endLine)
507     {
508         WhileNode* result = new (m_parserArena) WhileNode(location, expr, statement);
509         result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
510         return result;
511     }
512
513     StatementNode* createDoWhileStatement(const JSTokenLocation& location, StatementNode* statement, ExpressionNode* expr, int startLine, int endLine)
514     {
515         DoWhileNode* result = new (m_parserArena) DoWhileNode(location, statement, expr);
516         result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
517         return result;
518     }
519
520     StatementNode* createLabelStatement(const JSTokenLocation& location, const Identifier* ident, StatementNode* statement, const JSTextPosition& start, const JSTextPosition& end)
521     {
522         LabelNode* result = new (m_parserArena) LabelNode(location, *ident, statement);
523         setExceptionLocation(result, start, end, end);
524         return result;
525     }
526
527     StatementNode* createWithStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, unsigned start, const JSTextPosition& end, unsigned startLine, unsigned endLine)
528     {
529         usesWith();
530         WithNode* result = new (m_parserArena) WithNode(location, expr, statement, end, end - start);
531         result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
532         return result;
533     }    
534     
535     StatementNode* createThrowStatement(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& end)
536     {
537         ThrowNode* result = new (m_parserArena) ThrowNode(location, expr);
538         result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
539         setExceptionLocation(result, start, end, end);
540         return result;
541     }
542     
543     StatementNode* createDebugger(const JSTokenLocation& location, int startLine, int endLine)
544     {
545         DebuggerStatementNode* result = new (m_parserArena) DebuggerStatementNode(location);
546         result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
547         return result;
548     }
549     
550     StatementNode* createConstStatement(const JSTokenLocation& location, ConstDeclNode* decls, int startLine, int endLine)
551     {
552         ConstStatementNode* result = new (m_parserArena) ConstStatementNode(location, decls);
553         result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
554         return result;
555     }
556
557     ConstDeclNode* appendConstDecl(const JSTokenLocation& location, ConstDeclNode* tail, const Identifier* name, ExpressionNode* initializer)
558     {
559         ConstDeclNode* result = new (m_parserArena) ConstDeclNode(location, *name, initializer);
560         if (tail)
561             tail->m_next = result;
562         return result;
563     }
564
565     void appendStatement(JSC::SourceElements* elements, JSC::StatementNode* statement)
566     {
567         elements->append(statement);
568     }
569
570     void addVar(const Identifier* ident, int attrs)
571     {
572         if (m_vm->propertyNames->arguments == *ident)
573             usesArguments();
574         ASSERT(ident->impl()->isAtomic());
575         m_scope.m_varDeclarations.append(std::make_pair(*ident, attrs));
576     }
577
578     CommaNode* createCommaExpr(const JSTokenLocation& location, ExpressionNode* node)
579     {
580         return new (m_parserArena) CommaNode(location, node);
581     }
582
583     CommaNode* appendToCommaExpr(const JSTokenLocation& location, ExpressionNode*, ExpressionNode* tail, ExpressionNode* next)
584     {
585         ASSERT(tail->isCommaNode());
586         CommaNode* newTail = new (m_parserArena) CommaNode(location, next);
587         static_cast<CommaNode*>(tail)->setNext(newTail);
588         return newTail;
589     }
590
591     int evalCount() const { return m_evalCount; }
592
593     void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, const JSTextPosition& exprStart, const JSTextPosition& lhs, const JSTextPosition& rhs, bool hasAssignments)
594     {
595         operandStackDepth++;
596         m_binaryOperandStack.append(std::make_pair(current, BinaryOpInfo(exprStart, lhs, rhs, hasAssignments)));
597     }
598
599     // Logic to handle datastructures used during parsing of binary expressions
600     void operatorStackPop(int& operatorStackDepth)
601     {
602         operatorStackDepth--;
603         m_binaryOperatorStack.removeLast();
604     }
605     bool operatorStackHasHigherPrecedence(int&, int precedence)
606     {
607         return precedence <= m_binaryOperatorStack.last().second;
608     }
609     const BinaryOperand& getFromOperandStack(int i) { return m_binaryOperandStack[m_binaryOperandStack.size() + i]; }
610     void shrinkOperandStackBy(int& operandStackDepth, int amount)
611     {
612         operandStackDepth -= amount;
613         ASSERT(operandStackDepth >= 0);
614         m_binaryOperandStack.resize(m_binaryOperandStack.size() - amount);
615     }
616     void appendBinaryOperation(const JSTokenLocation& location, int& operandStackDepth, int&, const BinaryOperand& lhs, const BinaryOperand& rhs)
617     {
618         operandStackDepth++;
619         m_binaryOperandStack.append(std::make_pair(makeBinaryNode(location, m_binaryOperatorStack.last().first, lhs, rhs), BinaryOpInfo(lhs.second, rhs.second)));
620     }
621     void operatorStackAppend(int& operatorStackDepth, int op, int precedence)
622     {
623         operatorStackDepth++;
624         m_binaryOperatorStack.append(std::make_pair(op, precedence));
625     }
626     ExpressionNode* popOperandStack(int&)
627     {
628         ExpressionNode* result = m_binaryOperandStack.last().first;
629         m_binaryOperandStack.removeLast();
630         return result;
631     }
632     
633     void appendUnaryToken(int& tokenStackDepth, int type, const JSTextPosition& start)
634     {
635         tokenStackDepth++;
636         m_unaryTokenStack.append(std::make_pair(type, start));
637     }
638
639     int unaryTokenStackLastType(int&)
640     {
641         return m_unaryTokenStack.last().first;
642     }
643     
644     const JSTextPosition& unaryTokenStackLastStart(int&)
645     {
646         return m_unaryTokenStack.last().second;
647     }
648     
649     void unaryTokenStackRemoveLast(int& tokenStackDepth)
650     {
651         tokenStackDepth--;
652         m_unaryTokenStack.removeLast();
653     }
654     
655     void assignmentStackAppend(int& assignmentStackDepth, ExpressionNode* node, const JSTextPosition& start, const JSTextPosition& divot, int assignmentCount, Operator op)
656     {
657         assignmentStackDepth++;
658         ASSERT(start.offset >= start.lineStartOffset);
659         ASSERT(divot.offset >= divot.lineStartOffset);
660         m_assignmentInfoStack.append(AssignmentInfo(node, start, divot, assignmentCount, op));
661     }
662
663     ExpressionNode* createAssignment(const JSTokenLocation& location, int& assignmentStackDepth, ExpressionNode* rhs, int initialAssignmentCount, int currentAssignmentCount, const JSTextPosition& lastTokenEnd)
664     {
665         AssignmentInfo& info = m_assignmentInfoStack.last();
666         ExpressionNode* result = makeAssignNode(location, info.m_node, info.m_op, rhs, info.m_initAssignments != initialAssignmentCount, info.m_initAssignments != currentAssignmentCount, info.m_start, info.m_divot + 1, lastTokenEnd);
667         m_assignmentInfoStack.removeLast();
668         assignmentStackDepth--;
669         return result;
670     }
671     
672     const Identifier* getName(Property property) const { return property->name(); }
673     PropertyNode::Type getType(Property property) const { return property->type(); }
674
675     bool isResolve(ExpressionNode* expr) const { return expr->isResolveNode(); }
676
677     ExpressionNode* createDeconstructingAssignment(const JSTokenLocation& location, PassRefPtr<DeconstructionPatternNode> pattern, ExpressionNode* initializer)
678     {
679         return new (m_parserArena) DeconstructingAssignmentNode(location, pattern.get(), initializer);
680     }
681     
682     ArrayPattern createArrayPattern(const JSTokenLocation&)
683     {
684         return ArrayPatternNode::create();
685     }
686     
687     void appendArrayPatternSkipEntry(ArrayPattern node, const JSTokenLocation& location)
688     {
689         node->appendIndex(location, 0);
690     }
691
692     void appendArrayPatternEntry(ArrayPattern node, const JSTokenLocation& location, DeconstructionPattern pattern)
693     {
694         node->appendIndex(location, pattern.get());
695     }
696     
697     ObjectPattern createObjectPattern(const JSTokenLocation&)
698     {
699         return ObjectPatternNode::create();
700     }
701     
702     void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation& location, bool wasString, const Identifier& identifier, DeconstructionPattern pattern)
703     {
704         node->appendEntry(location, identifier, wasString, pattern.get());
705     }
706     
707     BindingPattern createBindingLocation(const JSTokenLocation&, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end)
708     {
709         return BindingNode::create(boundProperty, start, end);
710     }
711
712     void setEndOffset(Node* node, int offset)
713     {
714         node->setEndOffset(offset);
715     }
716
717     int endOffset(Node* node)
718     {
719         return node->endOffset();
720     }
721
722     void setStartOffset(CaseClauseNode* node, int offset)
723     {
724         node->setStartOffset(offset);
725     }
726
727     void setStartOffset(Node* node, int offset)
728     {
729         node->setStartOffset(offset);
730     }
731     
732 private:
733     struct Scope {
734         Scope()
735             : m_features(0)
736             , m_numConstants(0)
737         {
738         }
739         DeclarationStacks::VarStack m_varDeclarations;
740         DeclarationStacks::FunctionStack m_funcDeclarations;
741         int m_features;
742         int m_numConstants;
743     };
744
745     static void setExceptionLocation(ThrowableExpressionData* node, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd)
746     {
747         ASSERT(divot.offset >= divot.lineStartOffset);
748         node->setExceptionSourceCode(divot, divotStart, divotEnd);
749     }
750
751     void incConstants() { m_scope.m_numConstants++; }
752     void usesThis() { m_scope.m_features |= ThisFeature; }
753     void usesCatch() { m_scope.m_features |= CatchFeature; }
754     void usesArguments() { m_scope.m_features |= ArgumentsFeature; }
755     void usesWith() { m_scope.m_features |= WithFeature; }
756     void usesEval() 
757     {
758         m_evalCount++;
759         m_scope.m_features |= EvalFeature;
760     }
761     ExpressionNode* createIntegerLikeNumber(const JSTokenLocation& location, double d)
762     {
763         return new (m_parserArena) IntegerNode(location, d);
764     }
765     ExpressionNode* createDoubleLikeNumber(const JSTokenLocation& location, double d)
766     {
767         return new (m_parserArena) DoubleNode(location, d);
768     }
769     ExpressionNode* createNumberFromBinaryOperation(const JSTokenLocation& location, double value, const NumberNode& originalNodeA, const NumberNode& originalNodeB)
770     {
771         if (originalNodeA.isIntegerNode() && originalNodeB.isIntegerNode())
772             return createIntegerLikeNumber(location, value);
773         return createDoubleLikeNumber(location, value);
774     }
775     ExpressionNode* createNumberFromUnaryOperation(const JSTokenLocation& location, double value, const NumberNode& originalNode)
776     {
777         if (originalNode.isIntegerNode())
778             return createIntegerLikeNumber(location, value);
779         return createDoubleLikeNumber(location, value);
780     }
781
782     VM* m_vm;
783     ParserArena& m_parserArena;
784     SourceCode* m_sourceCode;
785     Scope m_scope;
786     Vector<BinaryOperand, 10, UnsafeVectorOverflow> m_binaryOperandStack;
787     Vector<AssignmentInfo, 10, UnsafeVectorOverflow> m_assignmentInfoStack;
788     Vector<std::pair<int, int>, 10, UnsafeVectorOverflow> m_binaryOperatorStack;
789     Vector<std::pair<int, JSTextPosition>, 10, UnsafeVectorOverflow> m_unaryTokenStack;
790     int m_evalCount;
791 };
792
793 ExpressionNode* ASTBuilder::makeTypeOfNode(const JSTokenLocation& location, ExpressionNode* expr)
794 {
795     if (expr->isResolveNode()) {
796         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
797         return new (m_parserArena) TypeOfResolveNode(location, resolve->identifier());
798     }
799     return new (m_parserArena) TypeOfValueNode(location, expr);
800 }
801
802 ExpressionNode* ASTBuilder::makeDeleteNode(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
803 {
804     if (!expr->isLocation())
805         return new (m_parserArena) DeleteValueNode(location, expr);
806     if (expr->isResolveNode()) {
807         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
808         return new (m_parserArena) DeleteResolveNode(location, resolve->identifier(), divot, start, end);
809     }
810     if (expr->isBracketAccessorNode()) {
811         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
812         return new (m_parserArena) DeleteBracketNode(location, bracket->base(), bracket->subscript(), divot, start, end);
813     }
814     ASSERT(expr->isDotAccessorNode());
815     DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
816     return new (m_parserArena) DeleteDotNode(location, dot->base(), dot->identifier(), divot, start, end);
817 }
818
819 ExpressionNode* ASTBuilder::makeNegateNode(const JSTokenLocation& location, ExpressionNode* n)
820 {
821     if (n->isNumber()) {
822         const NumberNode& numberNode = static_cast<const NumberNode&>(*n);
823         return createNumberFromUnaryOperation(location, -numberNode.value(), numberNode);
824     }
825
826     return new (m_parserArena) NegateNode(location, n);
827 }
828
829 ExpressionNode* ASTBuilder::makeBitwiseNotNode(const JSTokenLocation& location, ExpressionNode* expr)
830 {
831     if (expr->isNumber())
832         return createIntegerLikeNumber(location, ~toInt32(static_cast<NumberNode*>(expr)->value()));
833     return new (m_parserArena) BitwiseNotNode(location, expr);
834 }
835
836 ExpressionNode* ASTBuilder::makeMultNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
837 {
838     expr1 = expr1->stripUnaryPlus();
839     expr2 = expr2->stripUnaryPlus();
840
841     if (expr1->isNumber() && expr2->isNumber()) {
842         const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
843         const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
844         return createNumberFromBinaryOperation(location, numberExpr1.value() * numberExpr2.value(), numberExpr1, numberExpr2);
845     }
846
847     if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1)
848         return new (m_parserArena) UnaryPlusNode(location, expr2);
849
850     if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1)
851         return new (m_parserArena) UnaryPlusNode(location, expr1);
852
853     return new (m_parserArena) MultNode(location, expr1, expr2, rightHasAssignments);
854 }
855
856 ExpressionNode* ASTBuilder::makeDivNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
857 {
858     expr1 = expr1->stripUnaryPlus();
859     expr2 = expr2->stripUnaryPlus();
860
861     if (expr1->isNumber() && expr2->isNumber()) {
862         const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
863         const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
864         double result = numberExpr1.value() / numberExpr2.value();
865         if (static_cast<int64_t>(result) == result)
866             return createNumberFromBinaryOperation(location, result, numberExpr1, numberExpr2);
867         return createDoubleLikeNumber(location, result);
868     }
869     return new (m_parserArena) DivNode(location, expr1, expr2, rightHasAssignments);
870 }
871
872 ExpressionNode* ASTBuilder::makeModNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
873 {
874     expr1 = expr1->stripUnaryPlus();
875     expr2 = expr2->stripUnaryPlus();
876
877     if (expr1->isNumber() && expr2->isNumber()) {
878         const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
879         const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
880         return createIntegerLikeNumber(location, fmod(numberExpr1.value(), numberExpr2.value()));
881     }
882     return new (m_parserArena) ModNode(location, expr1, expr2, rightHasAssignments);
883 }
884
885 ExpressionNode* ASTBuilder::makeAddNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
886 {
887
888     if (expr1->isNumber() && expr2->isNumber()) {
889         const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
890         const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
891         return createNumberFromBinaryOperation(location, numberExpr1.value() + numberExpr2.value(), numberExpr1, numberExpr2);
892     }
893     return new (m_parserArena) AddNode(location, expr1, expr2, rightHasAssignments);
894 }
895
896 ExpressionNode* ASTBuilder::makeSubNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
897 {
898     expr1 = expr1->stripUnaryPlus();
899     expr2 = expr2->stripUnaryPlus();
900
901     if (expr1->isNumber() && expr2->isNumber()) {
902         const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
903         const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
904         return createNumberFromBinaryOperation(location, numberExpr1.value() - numberExpr2.value(), numberExpr1, numberExpr2);
905     }
906     return new (m_parserArena) SubNode(location, expr1, expr2, rightHasAssignments);
907 }
908
909 ExpressionNode* ASTBuilder::makeLeftShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
910 {
911     if (expr1->isNumber() && expr2->isNumber()) {
912         const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
913         const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
914         return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) << (toUInt32(numberExpr2.value()) & 0x1f));
915     }
916     return new (m_parserArena) LeftShiftNode(location, expr1, expr2, rightHasAssignments);
917 }
918
919 ExpressionNode* ASTBuilder::makeRightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
920 {
921     if (expr1->isNumber() && expr2->isNumber()) {
922         const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
923         const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
924         return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) >> (toUInt32(numberExpr2.value()) & 0x1f));
925     }
926     return new (m_parserArena) RightShiftNode(location, expr1, expr2, rightHasAssignments);
927 }
928
929 ExpressionNode* ASTBuilder::makeURightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
930 {
931     if (expr1->isNumber() && expr2->isNumber()) {
932         const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
933         const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
934         return createIntegerLikeNumber(location, toUInt32(numberExpr1.value()) >> (toUInt32(numberExpr2.value()) & 0x1f));
935     }
936     return new (m_parserArena) UnsignedRightShiftNode(location, expr1, expr2, rightHasAssignments);
937 }
938
939 ExpressionNode* ASTBuilder::makeBitOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
940 {
941     if (expr1->isNumber() && expr2->isNumber()) {
942         const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
943         const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
944         return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) | toInt32(numberExpr2.value()));
945     }
946     return new (m_parserArena) BitOrNode(location, expr1, expr2, rightHasAssignments);
947 }
948
949 ExpressionNode* ASTBuilder::makeBitAndNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
950 {
951     if (expr1->isNumber() && expr2->isNumber()) {
952         const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
953         const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
954         return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) & toInt32(numberExpr2.value()));
955     }
956     return new (m_parserArena) BitAndNode(location, expr1, expr2, rightHasAssignments);
957 }
958
959 ExpressionNode* ASTBuilder::makeBitXOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
960 {
961     if (expr1->isNumber() && expr2->isNumber()) {
962         const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
963         const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
964         return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) ^ toInt32(numberExpr2.value()));
965     }
966     return new (m_parserArena) BitXOrNode(location, expr1, expr2, rightHasAssignments);
967 }
968
969 ExpressionNode* ASTBuilder::makeFunctionCallNode(const JSTokenLocation& location, ExpressionNode* func, ArgumentsNode* args, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd)
970 {
971     ASSERT(divot.offset >= divot.lineStartOffset);
972     if (!func->isLocation())
973         return new (m_parserArena) FunctionCallValueNode(location, func, args, divot, divotStart, divotEnd);
974     if (func->isResolveNode()) {
975         ResolveNode* resolve = static_cast<ResolveNode*>(func);
976         const Identifier& identifier = resolve->identifier();
977         if (identifier == m_vm->propertyNames->eval) {
978             usesEval();
979             return new (m_parserArena) EvalFunctionCallNode(location, args, divot, divotStart, divotEnd);
980         }
981         return new (m_parserArena) FunctionCallResolveNode(location, identifier, args, divot, divotStart, divotEnd);
982     }
983     if (func->isBracketAccessorNode()) {
984         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func);
985         FunctionCallBracketNode* node = new (m_parserArena) FunctionCallBracketNode(location, bracket->base(), bracket->subscript(), args, divot, divotStart, divotEnd);
986         node->setSubexpressionInfo(bracket->divot(), bracket->divotEnd().offset);
987         return node;
988     }
989     ASSERT(func->isDotAccessorNode());
990     DotAccessorNode* dot = static_cast<DotAccessorNode*>(func);
991     FunctionCallDotNode* node;
992     if (dot->identifier() == m_vm->propertyNames->builtinNames().callPublicName() || dot->identifier() == m_vm->propertyNames->builtinNames().callPrivateName())
993         node = new (m_parserArena) CallFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
994     else if (dot->identifier() == m_vm->propertyNames->builtinNames().applyPublicName() || dot->identifier() == m_vm->propertyNames->builtinNames().applyPrivateName())
995         node = new (m_parserArena) ApplyFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
996     else
997         node = new (m_parserArena) FunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
998     node->setSubexpressionInfo(dot->divot(), dot->divotEnd().offset);
999     return node;
1000 }
1001
1002 ExpressionNode* ASTBuilder::makeBinaryNode(const JSTokenLocation& location, int token, std::pair<ExpressionNode*, BinaryOpInfo> lhs, std::pair<ExpressionNode*, BinaryOpInfo> rhs)
1003 {
1004     switch (token) {
1005     case OR:
1006         return new (m_parserArena) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalOr);
1007
1008     case AND:
1009         return new (m_parserArena) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalAnd);
1010
1011     case BITOR:
1012         return makeBitOrNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1013
1014     case BITXOR:
1015         return makeBitXOrNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1016
1017     case BITAND:
1018         return makeBitAndNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1019
1020     case EQEQ:
1021         return new (m_parserArena) EqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1022
1023     case NE:
1024         return new (m_parserArena) NotEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1025
1026     case STREQ:
1027         return new (m_parserArena) StrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1028
1029     case STRNEQ:
1030         return new (m_parserArena) NotStrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1031
1032     case LT:
1033         return new (m_parserArena) LessNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1034
1035     case GT:
1036         return new (m_parserArena) GreaterNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1037
1038     case LE:
1039         return new (m_parserArena) LessEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1040
1041     case GE:
1042         return new (m_parserArena) GreaterEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1043
1044     case INSTANCEOF: {
1045         InstanceOfNode* node = new (m_parserArena) InstanceOfNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1046         setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
1047         return node;
1048     }
1049
1050     case INTOKEN: {
1051         InNode* node = new (m_parserArena) InNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1052         setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
1053         return node;
1054     }
1055
1056     case LSHIFT:
1057         return makeLeftShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1058
1059     case RSHIFT:
1060         return makeRightShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1061
1062     case URSHIFT:
1063         return makeURightShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1064
1065     case PLUS:
1066         return makeAddNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1067
1068     case MINUS:
1069         return makeSubNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1070
1071     case TIMES:
1072         return makeMultNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1073
1074     case DIVIDE:
1075         return makeDivNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1076
1077     case MOD:
1078         return makeModNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1079     }
1080     CRASH();
1081     return 0;
1082 }
1083
1084 ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
1085 {
1086     if (!loc->isLocation())
1087         return new (m_parserArena) AssignErrorNode(location, divot, start, end);
1088
1089     if (loc->isResolveNode()) {
1090         ResolveNode* resolve = static_cast<ResolveNode*>(loc);
1091         if (op == OpEqual) {
1092             if (expr->isFuncExprNode())
1093                 static_cast<FuncExprNode*>(expr)->body()->setInferredName(resolve->identifier());
1094             AssignResolveNode* node = new (m_parserArena) AssignResolveNode(location, resolve->identifier(), expr);
1095             setExceptionLocation(node, start, divot, end);
1096             return node;
1097         }
1098         return new (m_parserArena) ReadModifyResolveNode(location, resolve->identifier(), op, expr, exprHasAssignments, divot, start, end);
1099     }
1100     if (loc->isBracketAccessorNode()) {
1101         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc);
1102         if (op == OpEqual)
1103             return new (m_parserArena) AssignBracketNode(location, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), start, end);
1104         ReadModifyBracketNode* node = new (m_parserArena) ReadModifyBracketNode(location, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, start, end);
1105         node->setSubexpressionInfo(bracket->divot(), bracket->divotEnd().offset);
1106         return node;
1107     }
1108     ASSERT(loc->isDotAccessorNode());
1109     DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc);
1110     if (op == OpEqual) {
1111         if (expr->isFuncExprNode())
1112             static_cast<FuncExprNode*>(expr)->body()->setInferredName(dot->identifier());
1113         return new (m_parserArena) AssignDotNode(location, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), start, end);
1114     }
1115
1116     ReadModifyDotNode* node = new (m_parserArena) ReadModifyDotNode(location, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, start, end);
1117     node->setSubexpressionInfo(dot->divot(), dot->divotEnd().offset);
1118     return node;
1119 }
1120
1121 ExpressionNode* ASTBuilder::makePrefixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
1122 {
1123     return new (m_parserArena) PrefixNode(location, expr, op, divot, start, end);
1124 }
1125
1126 ExpressionNode* ASTBuilder::makePostfixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
1127 {
1128     return new (m_parserArena) PostfixNode(location, expr, op, divot, start, end);
1129 }
1130
1131 }
1132
1133 #endif