2 * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #include "NodeConstructors.h"
30 #include "SyntaxChecker.h"
39 unsigned lineStartPos
;
44 BinaryOpInfo(int otherStart
, int otherDivot
, int otherEnd
, unsigned otherDivotLine
, unsigned otherDivotLineStart
, bool rhsHasAssignment
)
48 , divotLine(otherDivotLine
)
49 , divotLineStart(otherDivotLineStart
)
50 , hasAssignment(rhsHasAssignment
)
53 BinaryOpInfo(const BinaryOpInfo
& lhs
, const BinaryOpInfo
& rhs
)
57 , divotLine(rhs
.divotLine
)
58 , divotLineStart(rhs
.divotLineStart
)
59 , hasAssignment(lhs
.hasAssignment
|| rhs
.hasAssignment
)
66 unsigned divotLineStart
;
71 struct AssignmentInfo
{
73 AssignmentInfo(ExpressionNode
* node
, unsigned start
, unsigned divot
, unsigned divotLine
, unsigned divotLineStart
, int initAssignments
, Operator op
)
77 , m_divotLine(divotLine
)
78 , m_divotLineStart(divotLineStart
)
79 , m_initAssignments(initAssignments
)
82 ASSERT(m_divot
>= m_divotLineStart
);
83 ASSERT(m_start
>= m_divotLineStart
);
85 ExpressionNode
* m_node
;
89 unsigned m_divotLineStart
;
90 int m_initAssignments
;
94 ASTBuilder(VM
* vm
, SourceCode
* sourceCode
)
96 , m_sourceCode(sourceCode
)
102 struct BinaryExprContext
{
103 BinaryExprContext(ASTBuilder
&) {}
105 struct UnaryExprContext
{
106 UnaryExprContext(ASTBuilder
&) {}
109 typedef SyntaxChecker FunctionBodyBuilder
;
111 typedef ExpressionNode
* Expression
;
112 typedef JSC::SourceElements
* SourceElements
;
113 typedef ArgumentsNode
* Arguments
;
114 typedef CommaNode
* Comma
;
115 typedef PropertyNode
* Property
;
116 typedef PropertyListNode
* PropertyList
;
117 typedef ElementNode
* ElementList
;
118 typedef ArgumentListNode
* ArgumentsList
;
119 typedef ParameterNode
* FormalParameterList
;
120 typedef FunctionBodyNode
* FunctionBody
;
121 typedef StatementNode
* Statement
;
122 typedef ClauseListNode
* ClauseList
;
123 typedef CaseClauseNode
* Clause
;
124 typedef ConstDeclNode
* ConstDeclList
;
125 typedef std::pair
<ExpressionNode
*, BinaryOpInfo
> BinaryOperand
;
127 static const bool CreatesAST
= true;
128 static const bool NeedsFreeVariableInfo
= true;
129 static const bool CanUseFunctionCache
= true;
130 static const int DontBuildKeywords
= 0;
131 static const int DontBuildStrings
= 0;
133 ExpressionNode
* makeBinaryNode(const JSTokenLocation
&, int token
, std::pair
<ExpressionNode
*, BinaryOpInfo
>, std::pair
<ExpressionNode
*, BinaryOpInfo
>);
134 ExpressionNode
* makeFunctionCallNode(const JSTokenLocation
&, ExpressionNode
* func
, ArgumentsNode
* args
, int start
, unsigned divot
, int end
, unsigned divotLine
, unsigned divotLineStart
);
136 JSC::SourceElements
* createSourceElements() { return new (m_vm
) JSC::SourceElements(); }
138 ParserArenaData
<DeclarationStacks::VarStack
>* varDeclarations() { return m_scope
.m_varDeclarations
; }
139 ParserArenaData
<DeclarationStacks::FunctionStack
>* funcDeclarations() { return m_scope
.m_funcDeclarations
; }
140 int features() const { return m_scope
.m_features
; }
141 int numConstants() const { return m_scope
.m_numConstants
; }
143 void appendToComma(CommaNode
* commaNode
, ExpressionNode
* expr
) { commaNode
->append(expr
); }
145 CommaNode
* createCommaExpr(const JSTokenLocation
& location
, ExpressionNode
* lhs
, ExpressionNode
* rhs
) { return new (m_vm
) CommaNode(location
, lhs
, rhs
); }
147 ExpressionNode
* makeAssignNode(const JSTokenLocation
&, ExpressionNode
* left
, Operator
, ExpressionNode
* right
, bool leftHasAssignments
, bool rightHasAssignments
, int start
, int divot
, int end
, unsigned divotLine
, unsigned divotLineStart
);
148 ExpressionNode
* makePrefixNode(const JSTokenLocation
&, ExpressionNode
*, Operator
, int start
, int divot
, int end
, unsigned divotLine
, unsigned divotLineStart
);
149 ExpressionNode
* makePostfixNode(const JSTokenLocation
&, ExpressionNode
*, Operator
, int start
, int divot
, int end
, unsigned divotLine
, unsigned divotLineStart
);
150 ExpressionNode
* makeTypeOfNode(const JSTokenLocation
&, ExpressionNode
*);
151 ExpressionNode
* makeDeleteNode(const JSTokenLocation
&, ExpressionNode
*, int start
, int divot
, int end
, unsigned divotLine
, unsigned divotLineStart
);
152 ExpressionNode
* makeNegateNode(const JSTokenLocation
&, ExpressionNode
*);
153 ExpressionNode
* makeBitwiseNotNode(const JSTokenLocation
&, ExpressionNode
*);
154 ExpressionNode
* makeMultNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
155 ExpressionNode
* makeDivNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
156 ExpressionNode
* makeModNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
157 ExpressionNode
* makeAddNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
158 ExpressionNode
* makeSubNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
159 ExpressionNode
* makeBitXOrNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
160 ExpressionNode
* makeBitAndNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
161 ExpressionNode
* makeBitOrNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
162 ExpressionNode
* makeLeftShiftNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
163 ExpressionNode
* makeRightShiftNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
164 ExpressionNode
* makeURightShiftNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
166 ExpressionNode
* createLogicalNot(const JSTokenLocation
& location
, ExpressionNode
* expr
)
168 if (expr
->isNumber())
169 return createBoolean(location
, isZeroOrUnordered(static_cast<NumberNode
*>(expr
)->value()));
171 return new (m_vm
) LogicalNotNode(location
, expr
);
173 ExpressionNode
* createUnaryPlus(const JSTokenLocation
& location
, ExpressionNode
* expr
) { return new (m_vm
) UnaryPlusNode(location
, expr
); }
174 ExpressionNode
* createVoid(const JSTokenLocation
& location
, ExpressionNode
* expr
)
177 return new (m_vm
) VoidNode(location
, expr
);
179 ExpressionNode
* thisExpr(const JSTokenLocation
& location
)
182 return new (m_vm
) ThisNode(location
);
184 ExpressionNode
* createResolve(const JSTokenLocation
& location
, const Identifier
* ident
, unsigned start
, unsigned divotLine
, unsigned divotLineStart
)
186 if (m_vm
->propertyNames
->arguments
== *ident
)
188 return new (m_vm
) ResolveNode(location
, *ident
, start
, divotLine
, divotLineStart
);
190 ExpressionNode
* createObjectLiteral(const JSTokenLocation
& location
) { return new (m_vm
) ObjectLiteralNode(location
); }
191 ExpressionNode
* createObjectLiteral(const JSTokenLocation
& location
, PropertyListNode
* properties
) { return new (m_vm
) ObjectLiteralNode(location
, properties
); }
193 ExpressionNode
* createArray(const JSTokenLocation
& location
, int elisions
)
197 return new (m_vm
) ArrayNode(location
, elisions
);
200 ExpressionNode
* createArray(const JSTokenLocation
& location
, ElementNode
* elems
) { return new (m_vm
) ArrayNode(location
, elems
); }
201 ExpressionNode
* createArray(const JSTokenLocation
& location
, int elisions
, ElementNode
* elems
)
205 return new (m_vm
) ArrayNode(location
, elisions
, elems
);
207 ExpressionNode
* createNumberExpr(const JSTokenLocation
& location
, double d
)
210 return new (m_vm
) NumberNode(location
, d
);
213 ExpressionNode
* createString(const JSTokenLocation
& location
, const Identifier
* string
)
216 return new (m_vm
) StringNode(location
, *string
);
219 ExpressionNode
* createBoolean(const JSTokenLocation
& location
, bool b
)
222 return new (m_vm
) BooleanNode(location
, b
);
225 ExpressionNode
* createNull(const JSTokenLocation
& location
)
228 return new (m_vm
) NullNode(location
);
231 ExpressionNode
* createBracketAccess(const JSTokenLocation
& location
, ExpressionNode
* base
, ExpressionNode
* property
, bool propertyHasAssignments
, int start
, int divot
, int end
, unsigned divotLine
, unsigned divotLineStart
)
233 BracketAccessorNode
* node
= new (m_vm
) BracketAccessorNode(location
, base
, property
, propertyHasAssignments
);
234 setExceptionLocation(node
, start
, divot
, end
, divotLine
, divotLineStart
);
238 ExpressionNode
* createDotAccess(const JSTokenLocation
& location
, ExpressionNode
* base
, const Identifier
* property
, int start
, int divot
, int end
, unsigned divotLine
, unsigned divotLineStart
)
240 DotAccessorNode
* node
= new (m_vm
) DotAccessorNode(location
, base
, *property
);
241 setExceptionLocation(node
, start
, divot
, end
, divotLine
, divotLineStart
);
245 ExpressionNode
* createRegExp(const JSTokenLocation
& location
, const Identifier
& pattern
, const Identifier
& flags
, int start
, unsigned divotLine
, unsigned divotLineStart
)
247 if (Yarr::checkSyntax(pattern
.string()))
249 RegExpNode
* node
= new (m_vm
) RegExpNode(location
, pattern
, flags
);
250 int size
= pattern
.length() + 2; // + 2 for the two /'s
251 setExceptionLocation(node
, start
, start
+ size
, start
+ size
, divotLine
, divotLineStart
);
255 ExpressionNode
* createNewExpr(const JSTokenLocation
& location
, ExpressionNode
* expr
, ArgumentsNode
* arguments
, int start
, int divot
, int end
, unsigned divotLine
, unsigned divotLineStart
)
257 NewExprNode
* node
= new (m_vm
) NewExprNode(location
, expr
, arguments
);
258 setExceptionLocation(node
, start
, divot
, end
, divotLine
, divotLineStart
);
262 ExpressionNode
* createNewExpr(const JSTokenLocation
& location
, ExpressionNode
* expr
, int start
, int end
, unsigned divotLine
, unsigned divotLineStart
)
264 NewExprNode
* node
= new (m_vm
) NewExprNode(location
, expr
);
265 setExceptionLocation(node
, start
, end
, end
, divotLine
, divotLineStart
);
269 ExpressionNode
* createConditionalExpr(const JSTokenLocation
& location
, ExpressionNode
* condition
, ExpressionNode
* lhs
, ExpressionNode
* rhs
)
271 return new (m_vm
) ConditionalNode(location
, condition
, lhs
, rhs
);
274 ExpressionNode
* createAssignResolve(const JSTokenLocation
& location
, const Identifier
& ident
, ExpressionNode
* rhs
, int start
, int divot
, int end
, unsigned divotLine
, unsigned divotLineStart
)
276 if (rhs
->isFuncExprNode())
277 static_cast<FuncExprNode
*>(rhs
)->body()->setInferredName(ident
);
278 AssignResolveNode
* node
= new (m_vm
) AssignResolveNode(location
, ident
, rhs
);
279 setExceptionLocation(node
, start
, divot
, end
, divotLine
, divotLineStart
);
283 ExpressionNode
* createFunctionExpr(const JSTokenLocation
& location
, const Identifier
* name
, FunctionBodyNode
* body
, ParameterNode
* parameters
, unsigned openBraceOffset
, unsigned closeBraceOffset
, int bodyStartLine
, int bodyEndLine
, unsigned startColumn
)
285 FuncExprNode
* result
= new (m_vm
) FuncExprNode(location
, *name
, body
, m_sourceCode
->subExpression(openBraceOffset
, closeBraceOffset
, bodyStartLine
, startColumn
), parameters
);
286 body
->setLoc(bodyStartLine
, bodyEndLine
, location
.startOffset
, location
.lineStartOffset
);
290 FunctionBodyNode
* createFunctionBody(const JSTokenLocation
& startLocation
, const JSTokenLocation
& endLocation
, unsigned startColumn
, bool inStrictContext
)
292 return FunctionBodyNode::create(m_vm
, startLocation
, endLocation
, startColumn
, inStrictContext
);
295 void setFunctionStart(FunctionBodyNode
* body
, int functionStart
)
297 body
->setFunctionStart(functionStart
);
300 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
)
303 body
->setLoc(bodyStartLine
, bodyEndLine
, location
.startOffset
, location
.lineStartOffset
);
304 body
->setInferredName(*name
);
305 return new (m_vm
) PropertyNode(m_vm
, *name
, new (m_vm
) FuncExprNode(location
, m_vm
->propertyNames
->nullIdentifier
, body
, m_sourceCode
->subExpression(openBraceOffset
, closeBraceOffset
, bodyStartLine
, bodyStartColumn
), params
), type
);
308 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
)
310 body
->setLoc(bodyStartLine
, bodyEndLine
, location
.startOffset
, location
.lineStartOffset
);
311 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
);
314 ArgumentsNode
* createArguments() { return new (m_vm
) ArgumentsNode(); }
315 ArgumentsNode
* createArguments(ArgumentListNode
* args
) { return new (m_vm
) ArgumentsNode(args
); }
316 ArgumentListNode
* createArgumentsList(const JSTokenLocation
& location
, ExpressionNode
* arg
) { return new (m_vm
) ArgumentListNode(location
, arg
); }
317 ArgumentListNode
* createArgumentsList(const JSTokenLocation
& location
, ArgumentListNode
* args
, ExpressionNode
* arg
) { return new (m_vm
) ArgumentListNode(location
, args
, arg
); }
319 template <bool> PropertyNode
* createProperty(const Identifier
* propertyName
, ExpressionNode
* node
, PropertyNode::Type type
)
321 if (node
->isFuncExprNode())
322 static_cast<FuncExprNode
*>(node
)->body()->setInferredName(*propertyName
);
323 return new (m_vm
) PropertyNode(m_vm
, *propertyName
, node
, type
);
325 template <bool> PropertyNode
* createProperty(VM
*, double propertyName
, ExpressionNode
* node
, PropertyNode::Type type
) { return new (m_vm
) PropertyNode(m_vm
, propertyName
, node
, type
); }
326 PropertyListNode
* createPropertyList(const JSTokenLocation
& location
, PropertyNode
* property
) { return new (m_vm
) PropertyListNode(location
, property
); }
327 PropertyListNode
* createPropertyList(const JSTokenLocation
& location
, PropertyNode
* property
, PropertyListNode
* tail
) { return new (m_vm
) PropertyListNode(location
, property
, tail
); }
329 ElementNode
* createElementList(int elisions
, ExpressionNode
* expr
) { return new (m_vm
) ElementNode(elisions
, expr
); }
330 ElementNode
* createElementList(ElementNode
* elems
, int elisions
, ExpressionNode
* expr
) { return new (m_vm
) ElementNode(elems
, elisions
, expr
); }
332 ParameterNode
* createFormalParameterList(const Identifier
& ident
) { return new (m_vm
) ParameterNode(ident
); }
333 ParameterNode
* createFormalParameterList(ParameterNode
* list
, const Identifier
& ident
) { return new (m_vm
) ParameterNode(list
, ident
); }
335 CaseClauseNode
* createClause(ExpressionNode
* expr
, JSC::SourceElements
* statements
) { return new (m_vm
) CaseClauseNode(expr
, statements
); }
336 ClauseListNode
* createClauseList(CaseClauseNode
* clause
) { return new (m_vm
) ClauseListNode(clause
); }
337 ClauseListNode
* createClauseList(ClauseListNode
* tail
, CaseClauseNode
* clause
) { return new (m_vm
) ClauseListNode(tail
, clause
); }
339 void setUsesArguments(FunctionBodyNode
* node
) { node
->setUsesArguments(); }
341 StatementNode
* createFuncDeclStatement(const JSTokenLocation
& location
, const Identifier
* name
, FunctionBodyNode
* body
, ParameterNode
* parameters
, unsigned openBraceOffset
, unsigned closeBraceOffset
, int bodyStartLine
, int bodyEndLine
, unsigned bodyStartColumn
)
343 FuncDeclNode
* decl
= new (m_vm
) FuncDeclNode(location
, *name
, body
, m_sourceCode
->subExpression(openBraceOffset
, closeBraceOffset
, bodyStartLine
, bodyStartColumn
), parameters
);
344 if (*name
== m_vm
->propertyNames
->arguments
)
346 m_scope
.m_funcDeclarations
->data
.append(decl
->body());
347 body
->setLoc(bodyStartLine
, bodyEndLine
, location
.startOffset
, location
.lineStartOffset
);
351 StatementNode
* createBlockStatement(const JSTokenLocation
& location
, JSC::SourceElements
* elements
, int startLine
, int endLine
)
353 BlockNode
* block
= new (m_vm
) BlockNode(location
, elements
);
354 block
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
358 StatementNode
* createExprStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, int start
, int end
)
360 ExprStatementNode
* result
= new (m_vm
) ExprStatementNode(location
, expr
);
361 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
365 StatementNode
* createIfStatement(const JSTokenLocation
& location
, ExpressionNode
* condition
, StatementNode
* trueBlock
, StatementNode
* falseBlock
, int start
, int end
)
367 IfElseNode
* result
= new (m_vm
) IfElseNode(location
, condition
, trueBlock
, falseBlock
);
368 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
372 StatementNode
* createForLoop(const JSTokenLocation
& location
, ExpressionNode
* initializer
, ExpressionNode
* condition
, ExpressionNode
* iter
, StatementNode
* statements
, int start
, int end
)
374 ForNode
* result
= new (m_vm
) ForNode(location
, initializer
, condition
, iter
, statements
);
375 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
379 StatementNode
* createForInLoop(const JSTokenLocation
& location
, const Identifier
* ident
, ExpressionNode
* initializer
, ExpressionNode
* iter
, StatementNode
* statements
, int start
, int divot
, int end
, int initStart
, int initEnd
, int startLine
, int endLine
, unsigned divotLine
, unsigned divotLineStart
)
381 ForInNode
* result
= new (m_vm
) ForInNode(m_vm
, location
, *ident
, initializer
, iter
, statements
, initStart
, initStart
- start
, initEnd
- initStart
, divotLine
, divotLineStart
);
382 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
383 setExceptionLocation(result
, start
, divot
+ 1, end
, divotLine
, divotLineStart
);
387 StatementNode
* createForInLoop(const JSTokenLocation
& location
, ExpressionNode
* lhs
, ExpressionNode
* iter
, StatementNode
* statements
, int eStart
, int eDivot
, int eEnd
, int start
, int end
, unsigned divotLine
, unsigned divotLineStart
)
389 ForInNode
* result
= new (m_vm
) ForInNode(location
, lhs
, iter
, statements
);
390 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
391 setExceptionLocation(result
, eStart
, eDivot
, eEnd
, divotLine
, divotLineStart
);
395 StatementNode
* createEmptyStatement(const JSTokenLocation
& location
) { return new (m_vm
) EmptyStatementNode(location
); }
397 StatementNode
* createVarStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, int start
, int end
)
399 StatementNode
* result
;
401 result
= new (m_vm
) EmptyStatementNode(location
);
403 result
= new (m_vm
) VarStatementNode(location
, expr
);
404 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
408 StatementNode
* createReturnStatement(const JSTokenLocation
& location
, ExpressionNode
* expression
, int eStart
, int eEnd
, int startLine
, int endLine
, unsigned divotLine
, unsigned divotLineStart
)
410 ReturnNode
* result
= new (m_vm
) ReturnNode(location
, expression
);
411 setExceptionLocation(result
, eStart
, eEnd
, eEnd
, divotLine
, divotLineStart
);
412 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
416 StatementNode
* createBreakStatement(const JSTokenLocation
& location
, int eStart
, int eEnd
, int startLine
, int endLine
, unsigned endLineStart
)
418 BreakNode
* result
= new (m_vm
) BreakNode(m_vm
, location
);
419 setExceptionLocation(result
, eStart
, eEnd
, eEnd
, endLine
, endLineStart
);
420 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
424 StatementNode
* createBreakStatement(const JSTokenLocation
& location
, const Identifier
* ident
, int eStart
, int eEnd
, int startLine
, int endLine
, unsigned endLineStart
)
426 BreakNode
* result
= new (m_vm
) BreakNode(location
, *ident
);
427 setExceptionLocation(result
, eStart
, eEnd
, eEnd
, endLine
, endLineStart
);
428 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
432 StatementNode
* createContinueStatement(const JSTokenLocation
& location
, int eStart
, int eEnd
, int startLine
, int endLine
, unsigned endLineStart
)
434 ContinueNode
* result
= new (m_vm
) ContinueNode(m_vm
, location
);
435 setExceptionLocation(result
, eStart
, eEnd
, eEnd
, endLine
, endLineStart
);
436 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
440 StatementNode
* createContinueStatement(const JSTokenLocation
& location
, const Identifier
* ident
, int eStart
, int eEnd
, int startLine
, int endLine
, unsigned endLineStart
)
442 ContinueNode
* result
= new (m_vm
) ContinueNode(location
, *ident
);
443 setExceptionLocation(result
, eStart
, eEnd
, eEnd
, endLine
, endLineStart
);
444 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
448 StatementNode
* createTryStatement(const JSTokenLocation
& location
, StatementNode
* tryBlock
, const Identifier
* ident
, StatementNode
* catchBlock
, StatementNode
* finallyBlock
, int startLine
, int endLine
)
450 TryNode
* result
= new (m_vm
) TryNode(location
, tryBlock
, *ident
, catchBlock
, finallyBlock
);
453 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
457 StatementNode
* createSwitchStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, ClauseListNode
* firstClauses
, CaseClauseNode
* defaultClause
, ClauseListNode
* secondClauses
, int startLine
, int endLine
)
459 CaseBlockNode
* cases
= new (m_vm
) CaseBlockNode(firstClauses
, defaultClause
, secondClauses
);
460 SwitchNode
* result
= new (m_vm
) SwitchNode(location
, expr
, cases
);
461 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
465 StatementNode
* createWhileStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, StatementNode
* statement
, int startLine
, int endLine
)
467 WhileNode
* result
= new (m_vm
) WhileNode(location
, expr
, statement
);
468 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
472 StatementNode
* createDoWhileStatement(const JSTokenLocation
& location
, StatementNode
* statement
, ExpressionNode
* expr
, int startLine
, int endLine
)
474 DoWhileNode
* result
= new (m_vm
) DoWhileNode(location
, statement
, expr
);
475 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
479 StatementNode
* createLabelStatement(const JSTokenLocation
& location
, const Identifier
* ident
, StatementNode
* statement
, unsigned start
, unsigned end
, unsigned divotLine
, unsigned divotLineStart
)
481 LabelNode
* result
= new (m_vm
) LabelNode(location
, *ident
, statement
);
482 setExceptionLocation(result
, start
, end
, end
, divotLine
, divotLineStart
);
486 StatementNode
* createWithStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, StatementNode
* statement
, unsigned start
, unsigned end
, unsigned startLine
, unsigned endLine
, unsigned divotLine
, unsigned divotLineStart
)
489 WithNode
* result
= new (m_vm
) WithNode(location
, expr
, statement
, end
, divotLine
, divotLineStart
, end
- start
);
490 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
494 StatementNode
* createThrowStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, int start
, int end
, int startLine
, int endLine
, unsigned divotLine
, unsigned divotLineStart
)
496 ThrowNode
* result
= new (m_vm
) ThrowNode(location
, expr
);
497 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
498 setExceptionLocation(result
, start
, end
, end
, divotLine
, divotLineStart
);
502 StatementNode
* createDebugger(const JSTokenLocation
& location
, int startLine
, int endLine
)
504 DebuggerStatementNode
* result
= new (m_vm
) DebuggerStatementNode(location
);
505 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
509 StatementNode
* createConstStatement(const JSTokenLocation
& location
, ConstDeclNode
* decls
, int startLine
, int endLine
)
511 ConstStatementNode
* result
= new (m_vm
) ConstStatementNode(location
, decls
);
512 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
516 ConstDeclNode
* appendConstDecl(const JSTokenLocation
& location
, ConstDeclNode
* tail
, const Identifier
* name
, ExpressionNode
* initializer
)
518 ConstDeclNode
* result
= new (m_vm
) ConstDeclNode(location
, *name
, initializer
);
520 tail
->m_next
= result
;
524 void appendStatement(JSC::SourceElements
* elements
, JSC::StatementNode
* statement
)
526 elements
->append(statement
);
529 void addVar(const Identifier
* ident
, int attrs
)
531 if (m_vm
->propertyNames
->arguments
== *ident
)
533 m_scope
.m_varDeclarations
->data
.append(std::make_pair(ident
, attrs
));
536 ExpressionNode
* combineCommaNodes(const JSTokenLocation
& location
, ExpressionNode
* list
, ExpressionNode
* init
)
540 if (list
->isCommaNode()) {
541 static_cast<CommaNode
*>(list
)->append(init
);
544 return new (m_vm
) CommaNode(location
, list
, init
);
547 int evalCount() const { return m_evalCount
; }
549 void appendBinaryExpressionInfo(int& operandStackDepth
, ExpressionNode
* current
, int exprStart
, int lhs
, int rhs
, unsigned divotLine
, unsigned divotLineStart
, bool hasAssignments
)
552 m_binaryOperandStack
.append(std::make_pair(current
, BinaryOpInfo(exprStart
, lhs
, rhs
, divotLine
, divotLineStart
, hasAssignments
)));
555 // Logic to handle datastructures used during parsing of binary expressions
556 void operatorStackPop(int& operatorStackDepth
)
558 operatorStackDepth
--;
559 m_binaryOperatorStack
.removeLast();
561 bool operatorStackHasHigherPrecedence(int&, int precedence
)
563 return precedence
<= m_binaryOperatorStack
.last().second
;
565 const BinaryOperand
& getFromOperandStack(int i
) { return m_binaryOperandStack
[m_binaryOperandStack
.size() + i
]; }
566 void shrinkOperandStackBy(int& operandStackDepth
, int amount
)
568 operandStackDepth
-= amount
;
569 ASSERT(operandStackDepth
>= 0);
570 m_binaryOperandStack
.resize(m_binaryOperandStack
.size() - amount
);
572 void appendBinaryOperation(const JSTokenLocation
& location
, int& operandStackDepth
, int&, const BinaryOperand
& lhs
, const BinaryOperand
& rhs
)
575 m_binaryOperandStack
.append(std::make_pair(makeBinaryNode(location
, m_binaryOperatorStack
.last().first
, lhs
, rhs
), BinaryOpInfo(lhs
.second
, rhs
.second
)));
577 void operatorStackAppend(int& operatorStackDepth
, int op
, int precedence
)
579 operatorStackDepth
++;
580 m_binaryOperatorStack
.append(std::make_pair(op
, precedence
));
582 ExpressionNode
* popOperandStack(int&)
584 ExpressionNode
* result
= m_binaryOperandStack
.last().first
;
585 m_binaryOperandStack
.removeLast();
589 void appendUnaryToken(int& tokenStackDepth
, int type
, unsigned start
, unsigned divotLine
, unsigned divotLineStart
)
592 PositionInfo position
= { start
, divotLine
, divotLineStart
};
593 m_unaryTokenStack
.append(std::make_pair(type
, position
));
596 int unaryTokenStackLastType(int&)
598 return m_unaryTokenStack
.last().first
;
601 unsigned unaryTokenStackLastStart(int&)
603 return m_unaryTokenStack
.last().second
.startPos
;
606 unsigned unaryTokenStackLastLineStartPosition(int&)
608 return m_unaryTokenStack
.last().second
.lineStartPos
;
611 void unaryTokenStackRemoveLast(int& tokenStackDepth
)
614 m_unaryTokenStack
.removeLast();
617 void assignmentStackAppend(int& assignmentStackDepth
, ExpressionNode
* node
, unsigned start
, unsigned divot
, unsigned divotLine
, unsigned divotLineStart
, int assignmentCount
, Operator op
)
619 assignmentStackDepth
++;
620 ASSERT(start
>= divotLineStart
);
621 ASSERT(divot
>= divotLineStart
);
622 m_assignmentInfoStack
.append(AssignmentInfo(node
, start
, divot
, divotLine
, divotLineStart
, assignmentCount
, op
));
625 ExpressionNode
* createAssignment(const JSTokenLocation
& location
, int& assignmentStackDepth
, ExpressionNode
* rhs
, int initialAssignmentCount
, int currentAssignmentCount
, int lastTokenEnd
)
627 AssignmentInfo
& info
= m_assignmentInfoStack
.last();
628 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
, info
.m_divotLine
, info
.m_divotLineStart
);
629 m_assignmentInfoStack
.removeLast();
630 assignmentStackDepth
--;
634 const Identifier
& getName(Property property
) const { return property
->name(); }
635 PropertyNode::Type
getType(Property property
) const { return property
->type(); }
637 bool isResolve(ExpressionNode
* expr
) const { return expr
->isResolveNode(); }
642 : m_varDeclarations(new (vm
) ParserArenaData
<DeclarationStacks::VarStack
>)
643 , m_funcDeclarations(new (vm
) ParserArenaData
<DeclarationStacks::FunctionStack
>)
648 ParserArenaData
<DeclarationStacks::VarStack
>* m_varDeclarations
;
649 ParserArenaData
<DeclarationStacks::FunctionStack
>* m_funcDeclarations
;
654 static void setExceptionLocation(ThrowableExpressionData
* node
, unsigned start
, unsigned divot
, unsigned end
, unsigned divotLine
, unsigned divotLineStart
)
656 ASSERT(divot
>= divotLineStart
);
657 node
->setExceptionSourceCode(divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
660 void incConstants() { m_scope
.m_numConstants
++; }
661 void usesThis() { m_scope
.m_features
|= ThisFeature
; }
662 void usesCatch() { m_scope
.m_features
|= CatchFeature
; }
663 void usesArguments() { m_scope
.m_features
|= ArgumentsFeature
; }
664 void usesWith() { m_scope
.m_features
|= WithFeature
; }
668 m_scope
.m_features
|= EvalFeature
;
670 ExpressionNode
* createNumber(const JSTokenLocation
& location
, double d
)
672 return new (m_vm
) NumberNode(location
, d
);
676 SourceCode
* m_sourceCode
;
678 Vector
<BinaryOperand
, 10, UnsafeVectorOverflow
> m_binaryOperandStack
;
679 Vector
<AssignmentInfo
, 10, UnsafeVectorOverflow
> m_assignmentInfoStack
;
680 Vector
<pair
<int, int>, 10, UnsafeVectorOverflow
> m_binaryOperatorStack
;
681 Vector
<pair
<int, PositionInfo
>, 10, UnsafeVectorOverflow
> m_unaryTokenStack
;
685 ExpressionNode
* ASTBuilder::makeTypeOfNode(const JSTokenLocation
& location
, ExpressionNode
* expr
)
687 if (expr
->isResolveNode()) {
688 ResolveNode
* resolve
= static_cast<ResolveNode
*>(expr
);
689 return new (m_vm
) TypeOfResolveNode(location
, resolve
->identifier());
691 return new (m_vm
) TypeOfValueNode(location
, expr
);
694 ExpressionNode
* ASTBuilder::makeDeleteNode(const JSTokenLocation
& location
, ExpressionNode
* expr
, int start
, int divot
, int end
, unsigned divotLine
, unsigned divotLineStart
)
696 if (!expr
->isLocation())
697 return new (m_vm
) DeleteValueNode(location
, expr
);
698 if (expr
->isResolveNode()) {
699 ResolveNode
* resolve
= static_cast<ResolveNode
*>(expr
);
700 return new (m_vm
) DeleteResolveNode(location
, resolve
->identifier(), divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
702 if (expr
->isBracketAccessorNode()) {
703 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(expr
);
704 return new (m_vm
) DeleteBracketNode(location
, bracket
->base(), bracket
->subscript(), divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
706 ASSERT(expr
->isDotAccessorNode());
707 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(expr
);
708 return new (m_vm
) DeleteDotNode(location
, dot
->base(), dot
->identifier(), divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
711 ExpressionNode
* ASTBuilder::makeNegateNode(const JSTokenLocation
& location
, ExpressionNode
* n
)
714 NumberNode
* numberNode
= static_cast<NumberNode
*>(n
);
715 numberNode
->setValue(-numberNode
->value());
719 return new (m_vm
) NegateNode(location
, n
);
722 ExpressionNode
* ASTBuilder::makeBitwiseNotNode(const JSTokenLocation
& location
, ExpressionNode
* expr
)
724 if (expr
->isNumber())
725 return createNumber(location
, ~toInt32(static_cast<NumberNode
*>(expr
)->value()));
726 return new (m_vm
) BitwiseNotNode(location
, expr
);
729 ExpressionNode
* ASTBuilder::makeMultNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
731 expr1
= expr1
->stripUnaryPlus();
732 expr2
= expr2
->stripUnaryPlus();
734 if (expr1
->isNumber() && expr2
->isNumber())
735 return createNumber(location
, static_cast<NumberNode
*>(expr1
)->value() * static_cast<NumberNode
*>(expr2
)->value());
737 if (expr1
->isNumber() && static_cast<NumberNode
*>(expr1
)->value() == 1)
738 return new (m_vm
) UnaryPlusNode(location
, expr2
);
740 if (expr2
->isNumber() && static_cast<NumberNode
*>(expr2
)->value() == 1)
741 return new (m_vm
) UnaryPlusNode(location
, expr1
);
743 return new (m_vm
) MultNode(location
, expr1
, expr2
, rightHasAssignments
);
746 ExpressionNode
* ASTBuilder::makeDivNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
748 expr1
= expr1
->stripUnaryPlus();
749 expr2
= expr2
->stripUnaryPlus();
751 if (expr1
->isNumber() && expr2
->isNumber())
752 return createNumber(location
, static_cast<NumberNode
*>(expr1
)->value() / static_cast<NumberNode
*>(expr2
)->value());
753 return new (m_vm
) DivNode(location
, expr1
, expr2
, rightHasAssignments
);
756 ExpressionNode
* ASTBuilder::makeModNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
758 expr1
= expr1
->stripUnaryPlus();
759 expr2
= expr2
->stripUnaryPlus();
761 if (expr1
->isNumber() && expr2
->isNumber())
762 return createNumber(location
, fmod(static_cast<NumberNode
*>(expr1
)->value(), static_cast<NumberNode
*>(expr2
)->value()));
763 return new (m_vm
) ModNode(location
, expr1
, expr2
, rightHasAssignments
);
766 ExpressionNode
* ASTBuilder::makeAddNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
768 if (expr1
->isNumber() && expr2
->isNumber())
769 return createNumber(location
, static_cast<NumberNode
*>(expr1
)->value() + static_cast<NumberNode
*>(expr2
)->value());
770 return new (m_vm
) AddNode(location
, expr1
, expr2
, rightHasAssignments
);
773 ExpressionNode
* ASTBuilder::makeSubNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
775 expr1
= expr1
->stripUnaryPlus();
776 expr2
= expr2
->stripUnaryPlus();
778 if (expr1
->isNumber() && expr2
->isNumber())
779 return createNumber(location
, static_cast<NumberNode
*>(expr1
)->value() - static_cast<NumberNode
*>(expr2
)->value());
780 return new (m_vm
) SubNode(location
, expr1
, expr2
, rightHasAssignments
);
783 ExpressionNode
* ASTBuilder::makeLeftShiftNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
785 if (expr1
->isNumber() && expr2
->isNumber())
786 return createNumber(location
, toInt32(static_cast<NumberNode
*>(expr1
)->value()) << (toUInt32(static_cast<NumberNode
*>(expr2
)->value()) & 0x1f));
787 return new (m_vm
) LeftShiftNode(location
, expr1
, expr2
, rightHasAssignments
);
790 ExpressionNode
* ASTBuilder::makeRightShiftNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
792 if (expr1
->isNumber() && expr2
->isNumber())
793 return createNumber(location
, toInt32(static_cast<NumberNode
*>(expr1
)->value()) >> (toUInt32(static_cast<NumberNode
*>(expr2
)->value()) & 0x1f));
794 return new (m_vm
) RightShiftNode(location
, expr1
, expr2
, rightHasAssignments
);
797 ExpressionNode
* ASTBuilder::makeURightShiftNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
799 if (expr1
->isNumber() && expr2
->isNumber())
800 return createNumber(location
, toUInt32(static_cast<NumberNode
*>(expr1
)->value()) >> (toUInt32(static_cast<NumberNode
*>(expr2
)->value()) & 0x1f));
801 return new (m_vm
) UnsignedRightShiftNode(location
, expr1
, expr2
, rightHasAssignments
);
804 ExpressionNode
* ASTBuilder::makeBitOrNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
806 if (expr1
->isNumber() && expr2
->isNumber())
807 return createNumber(location
, toInt32(static_cast<NumberNode
*>(expr1
)->value()) | toInt32(static_cast<NumberNode
*>(expr2
)->value()));
808 return new (m_vm
) BitOrNode(location
, expr1
, expr2
, rightHasAssignments
);
811 ExpressionNode
* ASTBuilder::makeBitAndNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
813 if (expr1
->isNumber() && expr2
->isNumber())
814 return createNumber(location
, toInt32(static_cast<NumberNode
*>(expr1
)->value()) & toInt32(static_cast<NumberNode
*>(expr2
)->value()));
815 return new (m_vm
) BitAndNode(location
, expr1
, expr2
, rightHasAssignments
);
818 ExpressionNode
* ASTBuilder::makeBitXOrNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
820 if (expr1
->isNumber() && expr2
->isNumber())
821 return createNumber(location
, toInt32(static_cast<NumberNode
*>(expr1
)->value()) ^ toInt32(static_cast<NumberNode
*>(expr2
)->value()));
822 return new (m_vm
) BitXOrNode(location
, expr1
, expr2
, rightHasAssignments
);
825 ExpressionNode
* ASTBuilder::makeFunctionCallNode(const JSTokenLocation
& location
, ExpressionNode
* func
, ArgumentsNode
* args
, int start
, unsigned divot
, int end
, unsigned divotLine
, unsigned divotLineStart
)
827 ASSERT(divot
>= divotLineStart
);
828 if (!func
->isLocation())
829 return new (m_vm
) FunctionCallValueNode(location
, func
, args
, divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
830 if (func
->isResolveNode()) {
831 ResolveNode
* resolve
= static_cast<ResolveNode
*>(func
);
832 const Identifier
& identifier
= resolve
->identifier();
833 if (identifier
== m_vm
->propertyNames
->eval
) {
835 return new (m_vm
) EvalFunctionCallNode(location
, args
, divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
837 return new (m_vm
) FunctionCallResolveNode(location
, identifier
, args
, divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
839 if (func
->isBracketAccessorNode()) {
840 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(func
);
841 FunctionCallBracketNode
* node
= new (m_vm
) FunctionCallBracketNode(location
, bracket
->base(), bracket
->subscript(), args
, divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
842 node
->setSubexpressionInfo(bracket
->divot(), bracket
->divotEndOffset(), bracket
->divotLine(), bracket
->divotLineStart());
845 ASSERT(func
->isDotAccessorNode());
846 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(func
);
847 FunctionCallDotNode
* node
;
848 if (dot
->identifier() == m_vm
->propertyNames
->call
)
849 node
= new (m_vm
) CallFunctionCallDotNode(location
, dot
->base(), dot
->identifier(), args
, divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
850 else if (dot
->identifier() == m_vm
->propertyNames
->apply
)
851 node
= new (m_vm
) ApplyFunctionCallDotNode(location
, dot
->base(), dot
->identifier(), args
, divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
853 node
= new (m_vm
) FunctionCallDotNode(location
, dot
->base(), dot
->identifier(), args
, divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
854 node
->setSubexpressionInfo(dot
->divot(), dot
->divotEndOffset(), dot
->divotLine(), dot
->divotLineStart());
858 ExpressionNode
* ASTBuilder::makeBinaryNode(const JSTokenLocation
& location
, int token
, pair
<ExpressionNode
*, BinaryOpInfo
> lhs
, pair
<ExpressionNode
*, BinaryOpInfo
> rhs
)
862 return new (m_vm
) LogicalOpNode(location
, lhs
.first
, rhs
.first
, OpLogicalOr
);
865 return new (m_vm
) LogicalOpNode(location
, lhs
.first
, rhs
.first
, OpLogicalAnd
);
868 return makeBitOrNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
871 return makeBitXOrNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
874 return makeBitAndNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
877 return new (m_vm
) EqualNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
880 return new (m_vm
) NotEqualNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
883 return new (m_vm
) StrictEqualNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
886 return new (m_vm
) NotStrictEqualNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
889 return new (m_vm
) LessNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
892 return new (m_vm
) GreaterNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
895 return new (m_vm
) LessEqNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
898 return new (m_vm
) GreaterEqNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
901 InstanceOfNode
* node
= new (m_vm
) InstanceOfNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
902 setExceptionLocation(node
, lhs
.second
.start
, rhs
.second
.start
, rhs
.second
.end
, rhs
.second
.divotLine
, rhs
.second
.divotLineStart
);
907 InNode
* node
= new (m_vm
) InNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
908 setExceptionLocation(node
, lhs
.second
.start
, rhs
.second
.start
, rhs
.second
.end
, rhs
.second
.divotLine
, rhs
.second
.divotLineStart
);
913 return makeLeftShiftNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
916 return makeRightShiftNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
919 return makeURightShiftNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
922 return makeAddNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
925 return makeSubNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
928 return makeMultNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
931 return makeDivNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
934 return makeModNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
940 ExpressionNode
* ASTBuilder::makeAssignNode(const JSTokenLocation
& location
, ExpressionNode
* loc
, Operator op
, ExpressionNode
* expr
, bool locHasAssignments
, bool exprHasAssignments
, int start
, int divot
, int end
, unsigned divotLine
, unsigned divotLineStart
)
942 if (!loc
->isLocation())
943 return new (m_vm
) AssignErrorNode(location
, divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
945 if (loc
->isResolveNode()) {
946 ResolveNode
* resolve
= static_cast<ResolveNode
*>(loc
);
948 if (expr
->isFuncExprNode())
949 static_cast<FuncExprNode
*>(expr
)->body()->setInferredName(resolve
->identifier());
950 AssignResolveNode
* node
= new (m_vm
) AssignResolveNode(location
, resolve
->identifier(), expr
);
951 setExceptionLocation(node
, start
, divot
, end
, divotLine
, divotLineStart
);
954 return new (m_vm
) ReadModifyResolveNode(location
, resolve
->identifier(), op
, expr
, exprHasAssignments
, divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
956 if (loc
->isBracketAccessorNode()) {
957 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(loc
);
959 return new (m_vm
) AssignBracketNode(location
, bracket
->base(), bracket
->subscript(), expr
, locHasAssignments
, exprHasAssignments
, bracket
->divot(), bracket
->divot() - start
, end
- bracket
->divot(), bracket
->divotLine(), bracket
->divotLineStart());
960 ReadModifyBracketNode
* node
= new (m_vm
) ReadModifyBracketNode(location
, bracket
->base(), bracket
->subscript(), op
, expr
, locHasAssignments
, exprHasAssignments
, divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
961 node
->setSubexpressionInfo(bracket
->divot(), bracket
->divotEndOffset(), bracket
->divotLine(), bracket
->divotLineStart());
964 ASSERT(loc
->isDotAccessorNode());
965 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(loc
);
967 if (expr
->isFuncExprNode())
968 static_cast<FuncExprNode
*>(expr
)->body()->setInferredName(dot
->identifier());
969 return new (m_vm
) AssignDotNode(location
, dot
->base(), dot
->identifier(), expr
, exprHasAssignments
, dot
->divot(), dot
->divot() - start
, end
- dot
->divot(), dot
->divotLine(), dot
->divotLineStart());
972 ReadModifyDotNode
* node
= new (m_vm
) ReadModifyDotNode(location
, dot
->base(), dot
->identifier(), op
, expr
, exprHasAssignments
, divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
973 node
->setSubexpressionInfo(dot
->divot(), dot
->divotEndOffset(), dot
->divotLine(), dot
->divotLineStart());
977 ExpressionNode
* ASTBuilder::makePrefixNode(const JSTokenLocation
& location
, ExpressionNode
* expr
, Operator op
, int start
, int divot
, int end
, unsigned divotLine
, unsigned divotLineStart
)
979 return new (m_vm
) PrefixNode(location
, expr
, op
, divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);
982 ExpressionNode
* ASTBuilder::makePostfixNode(const JSTokenLocation
& location
, ExpressionNode
* expr
, Operator op
, int start
, int divot
, int end
, unsigned divotLine
, unsigned divotLineStart
)
984 return new (m_vm
) PostfixNode(location
, expr
, op
, divot
, divot
- start
, end
- divot
, divotLine
, divotLineStart
);