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