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