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