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 "BuiltinNames.h"
30 #include "NodeConstructors.h"
31 #include "SyntaxChecker.h"
39 BinaryOpInfo(const JSTextPosition
& otherStart
, const JSTextPosition
& otherDivot
, const JSTextPosition
& otherEnd
, bool rhsHasAssignment
)
43 , hasAssignment(rhsHasAssignment
)
46 BinaryOpInfo(const BinaryOpInfo
& lhs
, const BinaryOpInfo
& rhs
)
50 , hasAssignment(lhs
.hasAssignment
|| rhs
.hasAssignment
)
60 struct AssignmentInfo
{
62 AssignmentInfo(ExpressionNode
* node
, const JSTextPosition
& start
, const JSTextPosition
& divot
, int initAssignments
, Operator op
)
66 , m_initAssignments(initAssignments
)
69 ASSERT(m_divot
.offset
>= m_divot
.lineStartOffset
);
70 ASSERT(m_start
.offset
>= m_start
.lineStartOffset
);
72 ExpressionNode
* m_node
;
73 JSTextPosition m_start
;
74 JSTextPosition m_divot
;
75 int m_initAssignments
;
79 ASTBuilder(VM
* vm
, SourceCode
* sourceCode
)
81 , m_sourceCode(sourceCode
)
87 struct BinaryExprContext
{
88 BinaryExprContext(ASTBuilder
&) {}
90 struct UnaryExprContext
{
91 UnaryExprContext(ASTBuilder
&) {}
95 typedef SyntaxChecker FunctionBodyBuilder
;
97 typedef ExpressionNode
* Expression
;
98 typedef JSC::SourceElements
* SourceElements
;
99 typedef ArgumentsNode
* Arguments
;
100 typedef CommaNode
* Comma
;
101 typedef PropertyNode
* Property
;
102 typedef PropertyListNode
* PropertyList
;
103 typedef ElementNode
* ElementList
;
104 typedef ArgumentListNode
* ArgumentsList
;
105 typedef ParameterNode
* FormalParameterList
;
106 typedef FunctionBodyNode
* FunctionBody
;
107 typedef StatementNode
* Statement
;
108 typedef ClauseListNode
* ClauseList
;
109 typedef CaseClauseNode
* Clause
;
110 typedef ConstDeclNode
* ConstDeclList
;
111 typedef std::pair
<ExpressionNode
*, BinaryOpInfo
> BinaryOperand
;
112 typedef RefPtr
<DeconstructionPatternNode
> DeconstructionPattern
;
113 typedef RefPtr
<ArrayPatternNode
> ArrayPattern
;
114 typedef RefPtr
<ObjectPatternNode
> ObjectPattern
;
115 typedef RefPtr
<BindingNode
> BindingPattern
;
116 static const bool CreatesAST
= true;
117 static const bool NeedsFreeVariableInfo
= true;
118 static const bool CanUseFunctionCache
= true;
119 static const int DontBuildKeywords
= 0;
120 static const int DontBuildStrings
= 0;
122 ExpressionNode
* makeBinaryNode(const JSTokenLocation
&, int token
, std::pair
<ExpressionNode
*, BinaryOpInfo
>, std::pair
<ExpressionNode
*, BinaryOpInfo
>);
123 ExpressionNode
* makeFunctionCallNode(const JSTokenLocation
&, ExpressionNode
* func
, ArgumentsNode
* args
, const JSTextPosition
& divotStart
, const JSTextPosition
& divot
, const JSTextPosition
& divotEnd
);
125 JSC::SourceElements
* createSourceElements() { return new (m_vm
) JSC::SourceElements(); }
127 ParserArenaData
<DeclarationStacks::VarStack
>* varDeclarations() { return m_scope
.m_varDeclarations
; }
128 ParserArenaData
<DeclarationStacks::FunctionStack
>* funcDeclarations() { return m_scope
.m_funcDeclarations
; }
129 int features() const { return m_scope
.m_features
; }
130 int numConstants() const { return m_scope
.m_numConstants
; }
132 void appendToComma(CommaNode
* commaNode
, ExpressionNode
* expr
) { commaNode
->append(expr
); }
134 CommaNode
* createCommaExpr(const JSTokenLocation
& location
, ExpressionNode
* lhs
, ExpressionNode
* rhs
) { return new (m_vm
) CommaNode(location
, lhs
, rhs
); }
136 ExpressionNode
* makeAssignNode(const JSTokenLocation
&, ExpressionNode
* left
, Operator
, ExpressionNode
* right
, bool leftHasAssignments
, bool rightHasAssignments
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
);
137 ExpressionNode
* makePrefixNode(const JSTokenLocation
&, ExpressionNode
*, Operator
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
);
138 ExpressionNode
* makePostfixNode(const JSTokenLocation
&, ExpressionNode
*, Operator
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
);
139 ExpressionNode
* makeTypeOfNode(const JSTokenLocation
&, ExpressionNode
*);
140 ExpressionNode
* makeDeleteNode(const JSTokenLocation
&, ExpressionNode
*, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
);
141 ExpressionNode
* makeNegateNode(const JSTokenLocation
&, ExpressionNode
*);
142 ExpressionNode
* makeBitwiseNotNode(const JSTokenLocation
&, ExpressionNode
*);
143 ExpressionNode
* makeMultNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
144 ExpressionNode
* makeDivNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
145 ExpressionNode
* makeModNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
146 ExpressionNode
* makeAddNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
147 ExpressionNode
* makeSubNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
148 ExpressionNode
* makeBitXOrNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
149 ExpressionNode
* makeBitAndNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
150 ExpressionNode
* makeBitOrNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
151 ExpressionNode
* makeLeftShiftNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
152 ExpressionNode
* makeRightShiftNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
153 ExpressionNode
* makeURightShiftNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
155 ExpressionNode
* createLogicalNot(const JSTokenLocation
& location
, ExpressionNode
* expr
)
157 if (expr
->isNumber())
158 return createBoolean(location
, isZeroOrUnordered(static_cast<NumberNode
*>(expr
)->value()));
160 return new (m_vm
) LogicalNotNode(location
, expr
);
162 ExpressionNode
* createUnaryPlus(const JSTokenLocation
& location
, ExpressionNode
* expr
) { return new (m_vm
) UnaryPlusNode(location
, expr
); }
163 ExpressionNode
* createVoid(const JSTokenLocation
& location
, ExpressionNode
* expr
)
166 return new (m_vm
) VoidNode(location
, expr
);
168 ExpressionNode
* thisExpr(const JSTokenLocation
& location
)
171 return new (m_vm
) ThisNode(location
);
173 ExpressionNode
* createResolve(const JSTokenLocation
& location
, const Identifier
* ident
, const JSTextPosition
& start
)
175 if (m_vm
->propertyNames
->arguments
== *ident
)
177 return new (m_vm
) ResolveNode(location
, *ident
, start
);
179 ExpressionNode
* createObjectLiteral(const JSTokenLocation
& location
) { return new (m_vm
) ObjectLiteralNode(location
); }
180 ExpressionNode
* createObjectLiteral(const JSTokenLocation
& location
, PropertyListNode
* properties
) { return new (m_vm
) ObjectLiteralNode(location
, properties
); }
182 ExpressionNode
* createArray(const JSTokenLocation
& location
, int elisions
)
186 return new (m_vm
) ArrayNode(location
, elisions
);
189 ExpressionNode
* createArray(const JSTokenLocation
& location
, ElementNode
* elems
) { return new (m_vm
) ArrayNode(location
, elems
); }
190 ExpressionNode
* createArray(const JSTokenLocation
& location
, int elisions
, ElementNode
* elems
)
194 return new (m_vm
) ArrayNode(location
, elisions
, elems
);
196 ExpressionNode
* createNumberExpr(const JSTokenLocation
& location
, double d
)
199 return new (m_vm
) NumberNode(location
, d
);
202 ExpressionNode
* createString(const JSTokenLocation
& location
, const Identifier
* string
)
205 return new (m_vm
) StringNode(location
, *string
);
208 ExpressionNode
* createBoolean(const JSTokenLocation
& location
, bool b
)
211 return new (m_vm
) BooleanNode(location
, b
);
214 ExpressionNode
* createNull(const JSTokenLocation
& location
)
217 return new (m_vm
) NullNode(location
);
220 ExpressionNode
* createBracketAccess(const JSTokenLocation
& location
, ExpressionNode
* base
, ExpressionNode
* property
, bool propertyHasAssignments
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
222 BracketAccessorNode
* node
= new (m_vm
) BracketAccessorNode(location
, base
, property
, propertyHasAssignments
);
223 setExceptionLocation(node
, start
, divot
, end
);
227 ExpressionNode
* createDotAccess(const JSTokenLocation
& location
, ExpressionNode
* base
, const Identifier
* property
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
229 DotAccessorNode
* node
= new (m_vm
) DotAccessorNode(location
, base
, *property
);
230 setExceptionLocation(node
, start
, divot
, end
);
234 ExpressionNode
* createSpreadExpression(const JSTokenLocation
& location
, ExpressionNode
* expression
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
236 auto node
= new (m_vm
) SpreadExpressionNode(location
, expression
);
237 setExceptionLocation(node
, start
, divot
, end
);
241 ExpressionNode
* createRegExp(const JSTokenLocation
& location
, const Identifier
& pattern
, const Identifier
& flags
, const JSTextPosition
& start
)
243 if (Yarr::checkSyntax(pattern
.string()))
245 RegExpNode
* node
= new (m_vm
) RegExpNode(location
, pattern
, flags
);
246 int size
= pattern
.length() + 2; // + 2 for the two /'s
247 JSTextPosition end
= start
+ size
;
248 setExceptionLocation(node
, start
, end
, end
);
252 ExpressionNode
* createNewExpr(const JSTokenLocation
& location
, ExpressionNode
* expr
, ArgumentsNode
* arguments
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
254 NewExprNode
* node
= new (m_vm
) NewExprNode(location
, expr
, arguments
);
255 setExceptionLocation(node
, start
, divot
, end
);
259 ExpressionNode
* createNewExpr(const JSTokenLocation
& location
, ExpressionNode
* expr
, const JSTextPosition
& start
, const JSTextPosition
& end
)
261 NewExprNode
* node
= new (m_vm
) NewExprNode(location
, expr
);
262 setExceptionLocation(node
, start
, end
, end
);
266 ExpressionNode
* createConditionalExpr(const JSTokenLocation
& location
, ExpressionNode
* condition
, ExpressionNode
* lhs
, ExpressionNode
* rhs
)
268 return new (m_vm
) ConditionalNode(location
, condition
, lhs
, rhs
);
271 ExpressionNode
* createAssignResolve(const JSTokenLocation
& location
, const Identifier
& ident
, ExpressionNode
* rhs
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
273 if (rhs
->isFuncExprNode())
274 static_cast<FuncExprNode
*>(rhs
)->body()->setInferredName(ident
);
275 AssignResolveNode
* node
= new (m_vm
) AssignResolveNode(location
, ident
, rhs
);
276 setExceptionLocation(node
, start
, divot
, end
);
280 ExpressionNode
* createFunctionExpr(const JSTokenLocation
& location
, const Identifier
* name
, FunctionBodyNode
* body
, ParameterNode
* parameters
, unsigned openBraceOffset
, unsigned closeBraceOffset
, int bodyStartLine
, int bodyEndLine
, unsigned startColumn
)
282 FuncExprNode
* result
= new (m_vm
) FuncExprNode(location
, *name
, body
, m_sourceCode
->subExpression(openBraceOffset
, closeBraceOffset
, bodyStartLine
, startColumn
), parameters
);
283 body
->setLoc(bodyStartLine
, bodyEndLine
, location
.startOffset
, location
.lineStartOffset
);
287 FunctionBodyNode
* createFunctionBody(const JSTokenLocation
& startLocation
, const JSTokenLocation
& endLocation
, unsigned startColumn
, unsigned endColumn
, bool inStrictContext
)
289 return FunctionBodyNode::create(m_vm
, startLocation
, endLocation
, startColumn
, endColumn
, inStrictContext
);
292 void setFunctionNameStart(FunctionBodyNode
* body
, int functionNameStart
)
294 body
->setFunctionNameStart(functionNameStart
);
297 NEVER_INLINE PropertyNode
* createGetterOrSetterProperty(const JSTokenLocation
& location
, PropertyNode::Type type
, bool, const Identifier
* name
, ParameterNode
* params
, FunctionBodyNode
* body
, unsigned openBraceOffset
, unsigned closeBraceOffset
, int bodyStartLine
, int bodyEndLine
, unsigned bodyStartColumn
)
300 body
->setLoc(bodyStartLine
, bodyEndLine
, location
.startOffset
, location
.lineStartOffset
);
301 body
->setInferredName(*name
);
302 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
);
305 NEVER_INLINE PropertyNode
* createGetterOrSetterProperty(VM
*, const JSTokenLocation
& location
, PropertyNode::Type type
, bool, double name
, ParameterNode
* params
, FunctionBodyNode
* body
, unsigned openBraceOffset
, unsigned closeBraceOffset
, int bodyStartLine
, int bodyEndLine
, unsigned bodyStartColumn
)
307 body
->setLoc(bodyStartLine
, bodyEndLine
, location
.startOffset
, location
.lineStartOffset
);
308 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
);
311 ArgumentsNode
* createArguments() { return new (m_vm
) ArgumentsNode(); }
312 ArgumentsNode
* createArguments(ArgumentListNode
* args
) { return new (m_vm
) ArgumentsNode(args
); }
313 ArgumentListNode
* createArgumentsList(const JSTokenLocation
& location
, ExpressionNode
* arg
) { return new (m_vm
) ArgumentListNode(location
, arg
); }
314 ArgumentListNode
* createArgumentsList(const JSTokenLocation
& location
, ArgumentListNode
* args
, ExpressionNode
* arg
) { return new (m_vm
) ArgumentListNode(location
, args
, arg
); }
316 PropertyNode
* createProperty(const Identifier
* propertyName
, ExpressionNode
* node
, PropertyNode::Type type
, bool)
318 if (node
->isFuncExprNode())
319 static_cast<FuncExprNode
*>(node
)->body()->setInferredName(*propertyName
);
320 return new (m_vm
) PropertyNode(m_vm
, *propertyName
, node
, type
);
322 PropertyNode
* createProperty(VM
*, double propertyName
, ExpressionNode
* node
, PropertyNode::Type type
, bool) { return new (m_vm
) PropertyNode(m_vm
, propertyName
, node
, type
); }
323 PropertyNode
* createProperty(VM
*, ExpressionNode
* propertyName
, ExpressionNode
* node
, PropertyNode::Type type
, bool) { return new (m_vm
) PropertyNode(m_vm
, propertyName
, node
, type
); }
324 PropertyListNode
* createPropertyList(const JSTokenLocation
& location
, PropertyNode
* property
) { return new (m_vm
) PropertyListNode(location
, property
); }
325 PropertyListNode
* createPropertyList(const JSTokenLocation
& location
, PropertyNode
* property
, PropertyListNode
* tail
) { return new (m_vm
) PropertyListNode(location
, property
, tail
); }
327 ElementNode
* createElementList(int elisions
, ExpressionNode
* expr
) { return new (m_vm
) ElementNode(elisions
, expr
); }
328 ElementNode
* createElementList(ElementNode
* elems
, int elisions
, ExpressionNode
* expr
) { return new (m_vm
) ElementNode(elems
, elisions
, expr
); }
330 ParameterNode
* createFormalParameterList(DeconstructionPattern pattern
) { return new (m_vm
) ParameterNode(pattern
); }
331 ParameterNode
* createFormalParameterList(ParameterNode
* list
, DeconstructionPattern pattern
) { return new (m_vm
) ParameterNode(list
, pattern
); }
333 CaseClauseNode
* createClause(ExpressionNode
* expr
, JSC::SourceElements
* statements
) { return new (m_vm
) CaseClauseNode(expr
, statements
); }
334 ClauseListNode
* createClauseList(CaseClauseNode
* clause
) { return new (m_vm
) ClauseListNode(clause
); }
335 ClauseListNode
* createClauseList(ClauseListNode
* tail
, CaseClauseNode
* clause
) { return new (m_vm
) ClauseListNode(tail
, clause
); }
337 void setUsesArguments(FunctionBodyNode
* node
) { node
->setUsesArguments(); }
339 StatementNode
* createFuncDeclStatement(const JSTokenLocation
& location
, const Identifier
* name
, FunctionBodyNode
* body
, ParameterNode
* parameters
, unsigned openBraceOffset
, unsigned closeBraceOffset
, int bodyStartLine
, int bodyEndLine
, unsigned bodyStartColumn
)
341 FuncDeclNode
* decl
= new (m_vm
) FuncDeclNode(location
, *name
, body
, m_sourceCode
->subExpression(openBraceOffset
, closeBraceOffset
, bodyStartLine
, bodyStartColumn
), parameters
);
342 if (*name
== m_vm
->propertyNames
->arguments
)
344 m_scope
.m_funcDeclarations
->data
.append(decl
->body());
345 body
->setLoc(bodyStartLine
, bodyEndLine
, location
.startOffset
, location
.lineStartOffset
);
349 StatementNode
* createBlockStatement(const JSTokenLocation
& location
, JSC::SourceElements
* elements
, int startLine
, int endLine
)
351 BlockNode
* block
= new (m_vm
) BlockNode(location
, elements
);
352 block
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
356 StatementNode
* createExprStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, const JSTextPosition
& start
, int end
)
358 ExprStatementNode
* result
= new (m_vm
) ExprStatementNode(location
, expr
);
359 result
->setLoc(start
.line
, end
, start
.offset
, start
.lineStartOffset
);
363 StatementNode
* createIfStatement(const JSTokenLocation
& location
, ExpressionNode
* condition
, StatementNode
* trueBlock
, StatementNode
* falseBlock
, int start
, int end
)
365 IfElseNode
* result
= new (m_vm
) IfElseNode(location
, condition
, trueBlock
, falseBlock
);
366 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
370 StatementNode
* createForLoop(const JSTokenLocation
& location
, ExpressionNode
* initializer
, ExpressionNode
* condition
, ExpressionNode
* iter
, StatementNode
* statements
, int start
, int end
)
372 ForNode
* result
= new (m_vm
) ForNode(location
, initializer
, condition
, iter
, statements
);
373 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
377 StatementNode
* createForInLoop(const JSTokenLocation
& location
, ExpressionNode
* lhs
, ExpressionNode
* iter
, StatementNode
* statements
, const JSTextPosition
& eStart
, const JSTextPosition
& eDivot
, const JSTextPosition
& eEnd
, int start
, int end
)
379 ForInNode
* result
= new (m_vm
) ForInNode(location
, lhs
, iter
, statements
);
380 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
381 setExceptionLocation(result
, eStart
, eDivot
, eEnd
);
385 StatementNode
* createForInLoop(const JSTokenLocation
& location
, PassRefPtr
<DeconstructionPatternNode
> pattern
, ExpressionNode
* iter
, StatementNode
* statements
, const JSTextPosition
& eStart
, const JSTextPosition
& eDivot
, const JSTextPosition
& eEnd
, int start
, int end
)
387 ForInNode
* result
= new (m_vm
) ForInNode(m_vm
, location
, pattern
.get(), iter
, statements
);
388 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
389 setExceptionLocation(result
, eStart
, eDivot
, eEnd
);
393 StatementNode
* createForOfLoop(const JSTokenLocation
& location
, ExpressionNode
* lhs
, ExpressionNode
* iter
, StatementNode
* statements
, const JSTextPosition
& eStart
, const JSTextPosition
& eDivot
, const JSTextPosition
& eEnd
, int start
, int end
)
395 ForOfNode
* result
= new (m_vm
) ForOfNode(location
, lhs
, iter
, statements
);
396 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
397 setExceptionLocation(result
, eStart
, eDivot
, eEnd
);
401 StatementNode
* createForOfLoop(const JSTokenLocation
& location
, PassRefPtr
<DeconstructionPatternNode
> pattern
, ExpressionNode
* iter
, StatementNode
* statements
, const JSTextPosition
& eStart
, const JSTextPosition
& eDivot
, const JSTextPosition
& eEnd
, int start
, int end
)
403 ForOfNode
* result
= new (m_vm
) ForOfNode(m_vm
, location
, pattern
.get(), iter
, statements
);
404 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
405 setExceptionLocation(result
, eStart
, eDivot
, eEnd
);
409 bool isBindingNode(const DeconstructionPattern
& pattern
)
411 return pattern
->isBindingNode();
414 StatementNode
* createEmptyStatement(const JSTokenLocation
& location
) { return new (m_vm
) EmptyStatementNode(location
); }
416 StatementNode
* createVarStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, int start
, int end
)
418 StatementNode
* result
;
420 result
= new (m_vm
) EmptyStatementNode(location
);
422 result
= new (m_vm
) VarStatementNode(location
, expr
);
423 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
427 StatementNode
* createReturnStatement(const JSTokenLocation
& location
, ExpressionNode
* expression
, const JSTextPosition
& start
, const JSTextPosition
& end
)
429 ReturnNode
* result
= new (m_vm
) ReturnNode(location
, expression
);
430 setExceptionLocation(result
, start
, end
, end
);
431 result
->setLoc(start
.line
, end
.line
, start
.offset
, start
.lineStartOffset
);
435 StatementNode
* createBreakStatement(const JSTokenLocation
& location
, const JSTextPosition
& start
, const JSTextPosition
& end
)
437 BreakNode
* result
= new (m_vm
) BreakNode(m_vm
, location
);
438 setExceptionLocation(result
, start
, end
, end
);
439 result
->setLoc(start
.line
, end
.line
, start
.offset
, start
.lineStartOffset
);
443 StatementNode
* createBreakStatement(const JSTokenLocation
& location
, const Identifier
* ident
, const JSTextPosition
& start
, const JSTextPosition
& end
)
445 BreakNode
* result
= new (m_vm
) BreakNode(location
, *ident
);
446 setExceptionLocation(result
, start
, end
, end
);
447 result
->setLoc(start
.line
, end
.line
, start
.offset
, start
.lineStartOffset
);
451 StatementNode
* createContinueStatement(const JSTokenLocation
& location
, const JSTextPosition
& start
, const JSTextPosition
& end
)
453 ContinueNode
* result
= new (m_vm
) ContinueNode(m_vm
, location
);
454 setExceptionLocation(result
, start
, end
, end
);
455 result
->setLoc(start
.line
, end
.line
, start
.offset
, start
.lineStartOffset
);
459 StatementNode
* createContinueStatement(const JSTokenLocation
& location
, const Identifier
* ident
, const JSTextPosition
& start
, const JSTextPosition
& end
)
461 ContinueNode
* result
= new (m_vm
) ContinueNode(location
, *ident
);
462 setExceptionLocation(result
, start
, end
, end
);
463 result
->setLoc(start
.line
, end
.line
, start
.offset
, start
.lineStartOffset
);
467 StatementNode
* createTryStatement(const JSTokenLocation
& location
, StatementNode
* tryBlock
, const Identifier
* ident
, StatementNode
* catchBlock
, StatementNode
* finallyBlock
, int startLine
, int endLine
)
469 TryNode
* result
= new (m_vm
) TryNode(location
, tryBlock
, *ident
, catchBlock
, finallyBlock
);
472 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
476 StatementNode
* createSwitchStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, ClauseListNode
* firstClauses
, CaseClauseNode
* defaultClause
, ClauseListNode
* secondClauses
, int startLine
, int endLine
)
478 CaseBlockNode
* cases
= new (m_vm
) CaseBlockNode(firstClauses
, defaultClause
, secondClauses
);
479 SwitchNode
* result
= new (m_vm
) SwitchNode(location
, expr
, cases
);
480 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
484 StatementNode
* createWhileStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, StatementNode
* statement
, int startLine
, int endLine
)
486 WhileNode
* result
= new (m_vm
) WhileNode(location
, expr
, statement
);
487 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
491 StatementNode
* createDoWhileStatement(const JSTokenLocation
& location
, StatementNode
* statement
, ExpressionNode
* expr
, int startLine
, int endLine
)
493 DoWhileNode
* result
= new (m_vm
) DoWhileNode(location
, statement
, expr
);
494 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
498 StatementNode
* createLabelStatement(const JSTokenLocation
& location
, const Identifier
* ident
, StatementNode
* statement
, const JSTextPosition
& start
, const JSTextPosition
& end
)
500 LabelNode
* result
= new (m_vm
) LabelNode(location
, *ident
, statement
);
501 setExceptionLocation(result
, start
, end
, end
);
505 StatementNode
* createWithStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, StatementNode
* statement
, unsigned start
, const JSTextPosition
& end
, unsigned startLine
, unsigned endLine
)
508 WithNode
* result
= new (m_vm
) WithNode(location
, expr
, statement
, end
, end
- start
);
509 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
513 StatementNode
* createThrowStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, const JSTextPosition
& start
, const JSTextPosition
& end
)
515 ThrowNode
* result
= new (m_vm
) ThrowNode(location
, expr
);
516 result
->setLoc(start
.line
, end
.line
, start
.offset
, start
.lineStartOffset
);
517 setExceptionLocation(result
, start
, end
, end
);
521 StatementNode
* createDebugger(const JSTokenLocation
& location
, int startLine
, int endLine
)
523 DebuggerStatementNode
* result
= new (m_vm
) DebuggerStatementNode(location
);
524 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
528 StatementNode
* createConstStatement(const JSTokenLocation
& location
, ConstDeclNode
* decls
, int startLine
, int endLine
)
530 ConstStatementNode
* result
= new (m_vm
) ConstStatementNode(location
, decls
);
531 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
535 ConstDeclNode
* appendConstDecl(const JSTokenLocation
& location
, ConstDeclNode
* tail
, const Identifier
* name
, ExpressionNode
* initializer
)
537 ConstDeclNode
* result
= new (m_vm
) ConstDeclNode(location
, *name
, initializer
);
539 tail
->m_next
= result
;
543 void appendStatement(JSC::SourceElements
* elements
, JSC::StatementNode
* statement
)
545 elements
->append(statement
);
548 void addVar(const Identifier
* ident
, int attrs
)
550 if (m_vm
->propertyNames
->arguments
== *ident
)
552 ASSERT(ident
->impl()->isAtomic());
553 m_scope
.m_varDeclarations
->data
.append(std::make_pair(*ident
, attrs
));
556 ExpressionNode
* combineCommaNodes(const JSTokenLocation
& location
, ExpressionNode
* list
, ExpressionNode
* init
)
560 if (list
->isCommaNode()) {
561 static_cast<CommaNode
*>(list
)->append(init
);
564 return new (m_vm
) CommaNode(location
, list
, init
);
567 int evalCount() const { return m_evalCount
; }
569 void appendBinaryExpressionInfo(int& operandStackDepth
, ExpressionNode
* current
, const JSTextPosition
& exprStart
, const JSTextPosition
& lhs
, const JSTextPosition
& rhs
, bool hasAssignments
)
572 m_binaryOperandStack
.append(std::make_pair(current
, BinaryOpInfo(exprStart
, lhs
, rhs
, hasAssignments
)));
575 // Logic to handle datastructures used during parsing of binary expressions
576 void operatorStackPop(int& operatorStackDepth
)
578 operatorStackDepth
--;
579 m_binaryOperatorStack
.removeLast();
581 bool operatorStackHasHigherPrecedence(int&, int precedence
)
583 return precedence
<= m_binaryOperatorStack
.last().second
;
585 const BinaryOperand
& getFromOperandStack(int i
) { return m_binaryOperandStack
[m_binaryOperandStack
.size() + i
]; }
586 void shrinkOperandStackBy(int& operandStackDepth
, int amount
)
588 operandStackDepth
-= amount
;
589 ASSERT(operandStackDepth
>= 0);
590 m_binaryOperandStack
.resize(m_binaryOperandStack
.size() - amount
);
592 void appendBinaryOperation(const JSTokenLocation
& location
, int& operandStackDepth
, int&, const BinaryOperand
& lhs
, const BinaryOperand
& rhs
)
595 m_binaryOperandStack
.append(std::make_pair(makeBinaryNode(location
, m_binaryOperatorStack
.last().first
, lhs
, rhs
), BinaryOpInfo(lhs
.second
, rhs
.second
)));
597 void operatorStackAppend(int& operatorStackDepth
, int op
, int precedence
)
599 operatorStackDepth
++;
600 m_binaryOperatorStack
.append(std::make_pair(op
, precedence
));
602 ExpressionNode
* popOperandStack(int&)
604 ExpressionNode
* result
= m_binaryOperandStack
.last().first
;
605 m_binaryOperandStack
.removeLast();
609 void appendUnaryToken(int& tokenStackDepth
, int type
, const JSTextPosition
& start
)
612 m_unaryTokenStack
.append(std::make_pair(type
, start
));
615 int unaryTokenStackLastType(int&)
617 return m_unaryTokenStack
.last().first
;
620 const JSTextPosition
& unaryTokenStackLastStart(int&)
622 return m_unaryTokenStack
.last().second
;
625 void unaryTokenStackRemoveLast(int& tokenStackDepth
)
628 m_unaryTokenStack
.removeLast();
631 void assignmentStackAppend(int& assignmentStackDepth
, ExpressionNode
* node
, const JSTextPosition
& start
, const JSTextPosition
& divot
, int assignmentCount
, Operator op
)
633 assignmentStackDepth
++;
634 ASSERT(start
.offset
>= start
.lineStartOffset
);
635 ASSERT(divot
.offset
>= divot
.lineStartOffset
);
636 m_assignmentInfoStack
.append(AssignmentInfo(node
, start
, divot
, assignmentCount
, op
));
639 ExpressionNode
* createAssignment(const JSTokenLocation
& location
, int& assignmentStackDepth
, ExpressionNode
* rhs
, int initialAssignmentCount
, int currentAssignmentCount
, const JSTextPosition
& lastTokenEnd
)
641 AssignmentInfo
& info
= m_assignmentInfoStack
.last();
642 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
);
643 m_assignmentInfoStack
.removeLast();
644 assignmentStackDepth
--;
648 const Identifier
* getName(Property property
) const { return property
->name(); }
649 PropertyNode::Type
getType(Property property
) const { return property
->type(); }
651 bool isResolve(ExpressionNode
* expr
) const { return expr
->isResolveNode(); }
653 ExpressionNode
* createDeconstructingAssignment(const JSTokenLocation
& location
, PassRefPtr
<DeconstructionPatternNode
> pattern
, ExpressionNode
* initializer
)
655 return new (m_vm
) DeconstructingAssignmentNode(location
, pattern
.get(), initializer
);
658 ArrayPattern
createArrayPattern(const JSTokenLocation
&)
660 return ArrayPatternNode::create(m_vm
);
663 void appendArrayPatternSkipEntry(ArrayPattern node
, const JSTokenLocation
& location
)
665 node
->appendIndex(location
, 0);
668 void appendArrayPatternEntry(ArrayPattern node
, const JSTokenLocation
& location
, DeconstructionPattern pattern
)
670 node
->appendIndex(location
, pattern
.get());
673 ObjectPattern
createObjectPattern(const JSTokenLocation
&)
675 return ObjectPatternNode::create(m_vm
);
678 void appendObjectPatternEntry(ObjectPattern node
, const JSTokenLocation
& location
, bool wasString
, const Identifier
& identifier
, DeconstructionPattern pattern
)
680 node
->appendEntry(location
, identifier
, wasString
, pattern
.get());
683 BindingPattern
createBindingLocation(const JSTokenLocation
&, const Identifier
& boundProperty
, const JSTextPosition
& start
, const JSTextPosition
& end
)
685 return BindingNode::create(m_vm
, boundProperty
, start
, end
);
691 : m_varDeclarations(new (vm
) ParserArenaData
<DeclarationStacks::VarStack
>)
692 , m_funcDeclarations(new (vm
) ParserArenaData
<DeclarationStacks::FunctionStack
>)
697 ParserArenaData
<DeclarationStacks::VarStack
>* m_varDeclarations
;
698 ParserArenaData
<DeclarationStacks::FunctionStack
>* m_funcDeclarations
;
703 static void setExceptionLocation(ThrowableExpressionData
* node
, const JSTextPosition
& divotStart
, const JSTextPosition
& divot
, const JSTextPosition
& divotEnd
)
705 ASSERT(divot
.offset
>= divot
.lineStartOffset
);
706 node
->setExceptionSourceCode(divot
, divotStart
, divotEnd
);
709 void incConstants() { m_scope
.m_numConstants
++; }
710 void usesThis() { m_scope
.m_features
|= ThisFeature
; }
711 void usesCatch() { m_scope
.m_features
|= CatchFeature
; }
712 void usesArguments() { m_scope
.m_features
|= ArgumentsFeature
; }
713 void usesWith() { m_scope
.m_features
|= WithFeature
; }
717 m_scope
.m_features
|= EvalFeature
;
719 ExpressionNode
* createNumber(const JSTokenLocation
& location
, double d
)
721 return new (m_vm
) NumberNode(location
, d
);
725 SourceCode
* m_sourceCode
;
727 Vector
<BinaryOperand
, 10, UnsafeVectorOverflow
> m_binaryOperandStack
;
728 Vector
<AssignmentInfo
, 10, UnsafeVectorOverflow
> m_assignmentInfoStack
;
729 Vector
<std::pair
<int, int>, 10, UnsafeVectorOverflow
> m_binaryOperatorStack
;
730 Vector
<std::pair
<int, JSTextPosition
>, 10, UnsafeVectorOverflow
> m_unaryTokenStack
;
734 ExpressionNode
* ASTBuilder::makeTypeOfNode(const JSTokenLocation
& location
, ExpressionNode
* expr
)
736 if (expr
->isResolveNode()) {
737 ResolveNode
* resolve
= static_cast<ResolveNode
*>(expr
);
738 return new (m_vm
) TypeOfResolveNode(location
, resolve
->identifier());
740 return new (m_vm
) TypeOfValueNode(location
, expr
);
743 ExpressionNode
* ASTBuilder::makeDeleteNode(const JSTokenLocation
& location
, ExpressionNode
* expr
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
745 if (!expr
->isLocation())
746 return new (m_vm
) DeleteValueNode(location
, expr
);
747 if (expr
->isResolveNode()) {
748 ResolveNode
* resolve
= static_cast<ResolveNode
*>(expr
);
749 return new (m_vm
) DeleteResolveNode(location
, resolve
->identifier(), divot
, start
, end
);
751 if (expr
->isBracketAccessorNode()) {
752 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(expr
);
753 return new (m_vm
) DeleteBracketNode(location
, bracket
->base(), bracket
->subscript(), divot
, start
, end
);
755 ASSERT(expr
->isDotAccessorNode());
756 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(expr
);
757 return new (m_vm
) DeleteDotNode(location
, dot
->base(), dot
->identifier(), divot
, start
, end
);
760 ExpressionNode
* ASTBuilder::makeNegateNode(const JSTokenLocation
& location
, ExpressionNode
* n
)
763 NumberNode
* numberNode
= static_cast<NumberNode
*>(n
);
764 numberNode
->setValue(-numberNode
->value());
768 return new (m_vm
) NegateNode(location
, n
);
771 ExpressionNode
* ASTBuilder::makeBitwiseNotNode(const JSTokenLocation
& location
, ExpressionNode
* expr
)
773 if (expr
->isNumber())
774 return createNumber(location
, ~toInt32(static_cast<NumberNode
*>(expr
)->value()));
775 return new (m_vm
) BitwiseNotNode(location
, expr
);
778 ExpressionNode
* ASTBuilder::makeMultNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
780 expr1
= expr1
->stripUnaryPlus();
781 expr2
= expr2
->stripUnaryPlus();
783 if (expr1
->isNumber() && expr2
->isNumber())
784 return createNumber(location
, static_cast<NumberNode
*>(expr1
)->value() * static_cast<NumberNode
*>(expr2
)->value());
786 if (expr1
->isNumber() && static_cast<NumberNode
*>(expr1
)->value() == 1)
787 return new (m_vm
) UnaryPlusNode(location
, expr2
);
789 if (expr2
->isNumber() && static_cast<NumberNode
*>(expr2
)->value() == 1)
790 return new (m_vm
) UnaryPlusNode(location
, expr1
);
792 return new (m_vm
) MultNode(location
, expr1
, expr2
, rightHasAssignments
);
795 ExpressionNode
* ASTBuilder::makeDivNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
797 expr1
= expr1
->stripUnaryPlus();
798 expr2
= expr2
->stripUnaryPlus();
800 if (expr1
->isNumber() && expr2
->isNumber())
801 return createNumber(location
, static_cast<NumberNode
*>(expr1
)->value() / static_cast<NumberNode
*>(expr2
)->value());
802 return new (m_vm
) DivNode(location
, expr1
, expr2
, rightHasAssignments
);
805 ExpressionNode
* ASTBuilder::makeModNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
807 expr1
= expr1
->stripUnaryPlus();
808 expr2
= expr2
->stripUnaryPlus();
810 if (expr1
->isNumber() && expr2
->isNumber())
811 return createNumber(location
, fmod(static_cast<NumberNode
*>(expr1
)->value(), static_cast<NumberNode
*>(expr2
)->value()));
812 return new (m_vm
) ModNode(location
, expr1
, expr2
, rightHasAssignments
);
815 ExpressionNode
* ASTBuilder::makeAddNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
817 if (expr1
->isNumber() && expr2
->isNumber())
818 return createNumber(location
, static_cast<NumberNode
*>(expr1
)->value() + static_cast<NumberNode
*>(expr2
)->value());
819 return new (m_vm
) AddNode(location
, expr1
, expr2
, rightHasAssignments
);
822 ExpressionNode
* ASTBuilder::makeSubNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
824 expr1
= expr1
->stripUnaryPlus();
825 expr2
= expr2
->stripUnaryPlus();
827 if (expr1
->isNumber() && expr2
->isNumber())
828 return createNumber(location
, static_cast<NumberNode
*>(expr1
)->value() - static_cast<NumberNode
*>(expr2
)->value());
829 return new (m_vm
) SubNode(location
, expr1
, expr2
, rightHasAssignments
);
832 ExpressionNode
* ASTBuilder::makeLeftShiftNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
834 if (expr1
->isNumber() && expr2
->isNumber())
835 return createNumber(location
, toInt32(static_cast<NumberNode
*>(expr1
)->value()) << (toUInt32(static_cast<NumberNode
*>(expr2
)->value()) & 0x1f));
836 return new (m_vm
) LeftShiftNode(location
, expr1
, expr2
, rightHasAssignments
);
839 ExpressionNode
* ASTBuilder::makeRightShiftNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
841 if (expr1
->isNumber() && expr2
->isNumber())
842 return createNumber(location
, toInt32(static_cast<NumberNode
*>(expr1
)->value()) >> (toUInt32(static_cast<NumberNode
*>(expr2
)->value()) & 0x1f));
843 return new (m_vm
) RightShiftNode(location
, expr1
, expr2
, rightHasAssignments
);
846 ExpressionNode
* ASTBuilder::makeURightShiftNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
848 if (expr1
->isNumber() && expr2
->isNumber())
849 return createNumber(location
, toUInt32(static_cast<NumberNode
*>(expr1
)->value()) >> (toUInt32(static_cast<NumberNode
*>(expr2
)->value()) & 0x1f));
850 return new (m_vm
) UnsignedRightShiftNode(location
, expr1
, expr2
, rightHasAssignments
);
853 ExpressionNode
* ASTBuilder::makeBitOrNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
855 if (expr1
->isNumber() && expr2
->isNumber())
856 return createNumber(location
, toInt32(static_cast<NumberNode
*>(expr1
)->value()) | toInt32(static_cast<NumberNode
*>(expr2
)->value()));
857 return new (m_vm
) BitOrNode(location
, expr1
, expr2
, rightHasAssignments
);
860 ExpressionNode
* ASTBuilder::makeBitAndNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
862 if (expr1
->isNumber() && expr2
->isNumber())
863 return createNumber(location
, toInt32(static_cast<NumberNode
*>(expr1
)->value()) & toInt32(static_cast<NumberNode
*>(expr2
)->value()));
864 return new (m_vm
) BitAndNode(location
, expr1
, expr2
, rightHasAssignments
);
867 ExpressionNode
* ASTBuilder::makeBitXOrNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
869 if (expr1
->isNumber() && expr2
->isNumber())
870 return createNumber(location
, toInt32(static_cast<NumberNode
*>(expr1
)->value()) ^ toInt32(static_cast<NumberNode
*>(expr2
)->value()));
871 return new (m_vm
) BitXOrNode(location
, expr1
, expr2
, rightHasAssignments
);
874 ExpressionNode
* ASTBuilder::makeFunctionCallNode(const JSTokenLocation
& location
, ExpressionNode
* func
, ArgumentsNode
* args
, const JSTextPosition
& divotStart
, const JSTextPosition
& divot
, const JSTextPosition
& divotEnd
)
876 ASSERT(divot
.offset
>= divot
.lineStartOffset
);
877 if (!func
->isLocation())
878 return new (m_vm
) FunctionCallValueNode(location
, func
, args
, divot
, divotStart
, divotEnd
);
879 if (func
->isResolveNode()) {
880 ResolveNode
* resolve
= static_cast<ResolveNode
*>(func
);
881 const Identifier
& identifier
= resolve
->identifier();
882 if (identifier
== m_vm
->propertyNames
->eval
) {
884 return new (m_vm
) EvalFunctionCallNode(location
, args
, divot
, divotStart
, divotEnd
);
886 return new (m_vm
) FunctionCallResolveNode(location
, identifier
, args
, divot
, divotStart
, divotEnd
);
888 if (func
->isBracketAccessorNode()) {
889 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(func
);
890 FunctionCallBracketNode
* node
= new (m_vm
) FunctionCallBracketNode(location
, bracket
->base(), bracket
->subscript(), args
, divot
, divotStart
, divotEnd
);
891 node
->setSubexpressionInfo(bracket
->divot(), bracket
->divotEnd().offset
);
894 ASSERT(func
->isDotAccessorNode());
895 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(func
);
896 FunctionCallDotNode
* node
;
897 if (dot
->identifier() == m_vm
->propertyNames
->builtinNames().callPublicName() || dot
->identifier() == m_vm
->propertyNames
->builtinNames().callPrivateName())
898 node
= new (m_vm
) CallFunctionCallDotNode(location
, dot
->base(), dot
->identifier(), args
, divot
, divotStart
, divotEnd
);
899 else if (dot
->identifier() == m_vm
->propertyNames
->builtinNames().applyPublicName() || dot
->identifier() == m_vm
->propertyNames
->builtinNames().applyPrivateName())
900 node
= new (m_vm
) ApplyFunctionCallDotNode(location
, dot
->base(), dot
->identifier(), args
, divot
, divotStart
, divotEnd
);
902 node
= new (m_vm
) FunctionCallDotNode(location
, dot
->base(), dot
->identifier(), args
, divot
, divotStart
, divotEnd
);
903 node
->setSubexpressionInfo(dot
->divot(), dot
->divotEnd().offset
);
907 ExpressionNode
* ASTBuilder::makeBinaryNode(const JSTokenLocation
& location
, int token
, std::pair
<ExpressionNode
*, BinaryOpInfo
> lhs
, std::pair
<ExpressionNode
*, BinaryOpInfo
> rhs
)
911 return new (m_vm
) LogicalOpNode(location
, lhs
.first
, rhs
.first
, OpLogicalOr
);
914 return new (m_vm
) LogicalOpNode(location
, lhs
.first
, rhs
.first
, OpLogicalAnd
);
917 return makeBitOrNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
920 return makeBitXOrNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
923 return makeBitAndNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
926 return new (m_vm
) EqualNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
929 return new (m_vm
) NotEqualNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
932 return new (m_vm
) StrictEqualNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
935 return new (m_vm
) NotStrictEqualNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
938 return new (m_vm
) LessNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
941 return new (m_vm
) GreaterNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
944 return new (m_vm
) LessEqNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
947 return new (m_vm
) GreaterEqNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
950 InstanceOfNode
* node
= new (m_vm
) InstanceOfNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
951 setExceptionLocation(node
, lhs
.second
.start
, rhs
.second
.start
, rhs
.second
.end
);
956 InNode
* node
= new (m_vm
) InNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
957 setExceptionLocation(node
, lhs
.second
.start
, rhs
.second
.start
, rhs
.second
.end
);
962 return makeLeftShiftNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
965 return makeRightShiftNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
968 return makeURightShiftNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
971 return makeAddNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
974 return makeSubNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
977 return makeMultNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
980 return makeDivNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
983 return makeModNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
989 ExpressionNode
* ASTBuilder::makeAssignNode(const JSTokenLocation
& location
, ExpressionNode
* loc
, Operator op
, ExpressionNode
* expr
, bool locHasAssignments
, bool exprHasAssignments
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
991 if (!loc
->isLocation())
992 return new (m_vm
) AssignErrorNode(location
, divot
, start
, end
);
994 if (loc
->isResolveNode()) {
995 ResolveNode
* resolve
= static_cast<ResolveNode
*>(loc
);
997 if (expr
->isFuncExprNode())
998 static_cast<FuncExprNode
*>(expr
)->body()->setInferredName(resolve
->identifier());
999 AssignResolveNode
* node
= new (m_vm
) AssignResolveNode(location
, resolve
->identifier(), expr
);
1000 setExceptionLocation(node
, start
, divot
, end
);
1003 return new (m_vm
) ReadModifyResolveNode(location
, resolve
->identifier(), op
, expr
, exprHasAssignments
, divot
, start
, end
);
1005 if (loc
->isBracketAccessorNode()) {
1006 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(loc
);
1008 return new (m_vm
) AssignBracketNode(location
, bracket
->base(), bracket
->subscript(), expr
, locHasAssignments
, exprHasAssignments
, bracket
->divot(), start
, end
);
1009 ReadModifyBracketNode
* node
= new (m_vm
) ReadModifyBracketNode(location
, bracket
->base(), bracket
->subscript(), op
, expr
, locHasAssignments
, exprHasAssignments
, divot
, start
, end
);
1010 node
->setSubexpressionInfo(bracket
->divot(), bracket
->divotEnd().offset
);
1013 ASSERT(loc
->isDotAccessorNode());
1014 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(loc
);
1015 if (op
== OpEqual
) {
1016 if (expr
->isFuncExprNode())
1017 static_cast<FuncExprNode
*>(expr
)->body()->setInferredName(dot
->identifier());
1018 return new (m_vm
) AssignDotNode(location
, dot
->base(), dot
->identifier(), expr
, exprHasAssignments
, dot
->divot(), start
, end
);
1021 ReadModifyDotNode
* node
= new (m_vm
) ReadModifyDotNode(location
, dot
->base(), dot
->identifier(), op
, expr
, exprHasAssignments
, divot
, start
, end
);
1022 node
->setSubexpressionInfo(dot
->divot(), dot
->divotEnd().offset
);
1026 ExpressionNode
* ASTBuilder::makePrefixNode(const JSTokenLocation
& location
, ExpressionNode
* expr
, Operator op
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
1028 return new (m_vm
) PrefixNode(location
, expr
, op
, divot
, start
, end
);
1031 ExpressionNode
* ASTBuilder::makePostfixNode(const JSTokenLocation
& location
, ExpressionNode
* expr
, Operator op
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
1033 return new (m_vm
) PostfixNode(location
, expr
, op
, divot
, start
, end
);