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 "BytecodeIntrinsicRegistry.h"
31 #include "NodeConstructors.h"
32 #include "SyntaxChecker.h"
40 BinaryOpInfo(const JSTextPosition
& otherStart
, const JSTextPosition
& otherDivot
, const JSTextPosition
& otherEnd
, bool rhsHasAssignment
)
44 , hasAssignment(rhsHasAssignment
)
47 BinaryOpInfo(const BinaryOpInfo
& lhs
, const BinaryOpInfo
& rhs
)
51 , hasAssignment(lhs
.hasAssignment
|| rhs
.hasAssignment
)
61 struct AssignmentInfo
{
63 AssignmentInfo(ExpressionNode
* node
, const JSTextPosition
& start
, const JSTextPosition
& divot
, int initAssignments
, Operator op
)
67 , m_initAssignments(initAssignments
)
70 ASSERT(m_divot
.offset
>= m_divot
.lineStartOffset
);
71 ASSERT(m_start
.offset
>= m_start
.lineStartOffset
);
73 ExpressionNode
* m_node
;
74 JSTextPosition m_start
;
75 JSTextPosition m_divot
;
76 int m_initAssignments
;
80 ASTBuilder(VM
* vm
, ParserArena
& parserArena
, SourceCode
* sourceCode
)
82 , m_parserArena(parserArena
)
83 , m_sourceCode(sourceCode
)
88 struct BinaryExprContext
{
89 BinaryExprContext(ASTBuilder
&) {}
91 struct UnaryExprContext
{
92 UnaryExprContext(ASTBuilder
&) {}
96 typedef SyntaxChecker FunctionBodyBuilder
;
98 typedef ExpressionNode
* Expression
;
99 typedef JSC::SourceElements
* SourceElements
;
100 typedef ArgumentsNode
* Arguments
;
101 typedef CommaNode
* Comma
;
102 typedef PropertyNode
* Property
;
103 typedef PropertyListNode
* PropertyList
;
104 typedef ElementNode
* ElementList
;
105 typedef ArgumentListNode
* ArgumentsList
;
106 #if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
107 typedef TemplateExpressionListNode
* TemplateExpressionList
;
108 typedef TemplateStringNode
* TemplateString
;
109 typedef TemplateStringListNode
* TemplateStringList
;
110 typedef TemplateLiteralNode
* TemplateLiteral
;
112 typedef ParameterNode
* FormalParameterList
;
113 typedef FunctionBodyNode
* FunctionBody
;
114 #if ENABLE(ES6_CLASS_SYNTAX)
115 typedef ClassExprNode
* ClassExpression
;
117 typedef StatementNode
* Statement
;
118 typedef ClauseListNode
* ClauseList
;
119 typedef CaseClauseNode
* Clause
;
120 typedef ConstDeclNode
* ConstDeclList
;
121 typedef std::pair
<ExpressionNode
*, BinaryOpInfo
> BinaryOperand
;
122 typedef RefPtr
<DestructuringPatternNode
> DestructuringPattern
;
123 typedef RefPtr
<ArrayPatternNode
> ArrayPattern
;
124 typedef RefPtr
<ObjectPatternNode
> ObjectPattern
;
125 typedef RefPtr
<BindingNode
> BindingPattern
;
126 static const bool CreatesAST
= true;
127 static const bool NeedsFreeVariableInfo
= true;
128 static const bool CanUseFunctionCache
= true;
129 static const int DontBuildKeywords
= 0;
130 static const int DontBuildStrings
= 0;
132 ExpressionNode
* makeBinaryNode(const JSTokenLocation
&, int token
, std::pair
<ExpressionNode
*, BinaryOpInfo
>, std::pair
<ExpressionNode
*, BinaryOpInfo
>);
133 ExpressionNode
* makeFunctionCallNode(const JSTokenLocation
&, ExpressionNode
* func
, ArgumentsNode
* args
, const JSTextPosition
& divotStart
, const JSTextPosition
& divot
, const JSTextPosition
& divotEnd
);
135 JSC::SourceElements
* createSourceElements() { return new (m_parserArena
) JSC::SourceElements(); }
137 DeclarationStacks::VarStack
& varDeclarations() { return m_scope
.m_varDeclarations
; }
138 DeclarationStacks::FunctionStack
& funcDeclarations() { return m_scope
.m_funcDeclarations
; }
139 int features() const { return m_scope
.m_features
; }
140 int numConstants() const { return m_scope
.m_numConstants
; }
142 ExpressionNode
* makeAssignNode(const JSTokenLocation
&, ExpressionNode
* left
, Operator
, ExpressionNode
* right
, bool leftHasAssignments
, bool rightHasAssignments
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
);
143 ExpressionNode
* makePrefixNode(const JSTokenLocation
&, ExpressionNode
*, Operator
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
);
144 ExpressionNode
* makePostfixNode(const JSTokenLocation
&, ExpressionNode
*, Operator
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
);
145 ExpressionNode
* makeTypeOfNode(const JSTokenLocation
&, ExpressionNode
*);
146 ExpressionNode
* makeDeleteNode(const JSTokenLocation
&, ExpressionNode
*, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
);
147 ExpressionNode
* makeNegateNode(const JSTokenLocation
&, ExpressionNode
*);
148 ExpressionNode
* makeBitwiseNotNode(const JSTokenLocation
&, ExpressionNode
*);
149 ExpressionNode
* makeMultNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
150 ExpressionNode
* makeDivNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
151 ExpressionNode
* makeModNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
152 ExpressionNode
* makeAddNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
153 ExpressionNode
* makeSubNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
154 ExpressionNode
* makeBitXOrNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
155 ExpressionNode
* makeBitAndNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
156 ExpressionNode
* makeBitOrNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
157 ExpressionNode
* makeLeftShiftNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
158 ExpressionNode
* makeRightShiftNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
159 ExpressionNode
* makeURightShiftNode(const JSTokenLocation
&, ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
161 ExpressionNode
* createLogicalNot(const JSTokenLocation
& location
, ExpressionNode
* expr
)
163 if (expr
->isNumber())
164 return createBoolean(location
, isZeroOrUnordered(static_cast<NumberNode
*>(expr
)->value()));
166 return new (m_parserArena
) LogicalNotNode(location
, expr
);
168 ExpressionNode
* createUnaryPlus(const JSTokenLocation
& location
, ExpressionNode
* expr
) { return new (m_parserArena
) UnaryPlusNode(location
, expr
); }
169 ExpressionNode
* createVoid(const JSTokenLocation
& location
, ExpressionNode
* expr
)
172 return new (m_parserArena
) VoidNode(location
, expr
);
174 ExpressionNode
* thisExpr(const JSTokenLocation
& location
, ThisTDZMode thisTDZMode
)
177 return new (m_parserArena
) ThisNode(location
, thisTDZMode
);
179 ExpressionNode
* superExpr(const JSTokenLocation
& location
)
181 return new (m_parserArena
) SuperNode(location
);
183 ExpressionNode
* createResolve(const JSTokenLocation
& location
, const Identifier
* ident
, const JSTextPosition
& start
)
185 if (m_vm
->propertyNames
->arguments
== *ident
)
187 return new (m_parserArena
) ResolveNode(location
, *ident
, start
);
189 ExpressionNode
* createObjectLiteral(const JSTokenLocation
& location
) { return new (m_parserArena
) ObjectLiteralNode(location
); }
190 ExpressionNode
* createObjectLiteral(const JSTokenLocation
& location
, PropertyListNode
* properties
) { return new (m_parserArena
) ObjectLiteralNode(location
, properties
); }
192 ExpressionNode
* createArray(const JSTokenLocation
& location
, int elisions
)
196 return new (m_parserArena
) ArrayNode(location
, elisions
);
199 ExpressionNode
* createArray(const JSTokenLocation
& location
, ElementNode
* elems
) { return new (m_parserArena
) ArrayNode(location
, elems
); }
200 ExpressionNode
* createArray(const JSTokenLocation
& location
, int elisions
, ElementNode
* elems
)
204 return new (m_parserArena
) ArrayNode(location
, elisions
, elems
);
206 ExpressionNode
* createDoubleExpr(const JSTokenLocation
& location
, double d
)
209 return new (m_parserArena
) DoubleNode(location
, d
);
211 ExpressionNode
* createIntegerExpr(const JSTokenLocation
& location
, double d
)
214 return new (m_parserArena
) IntegerNode(location
, d
);
217 ExpressionNode
* createString(const JSTokenLocation
& location
, const Identifier
* string
)
220 return new (m_parserArena
) StringNode(location
, *string
);
223 ExpressionNode
* createBoolean(const JSTokenLocation
& location
, bool b
)
226 return new (m_parserArena
) BooleanNode(location
, b
);
229 ExpressionNode
* createNull(const JSTokenLocation
& location
)
232 return new (m_parserArena
) NullNode(location
);
235 ExpressionNode
* createBracketAccess(const JSTokenLocation
& location
, ExpressionNode
* base
, ExpressionNode
* property
, bool propertyHasAssignments
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
237 BracketAccessorNode
* node
= new (m_parserArena
) BracketAccessorNode(location
, base
, property
, propertyHasAssignments
);
238 setExceptionLocation(node
, start
, divot
, end
);
242 ExpressionNode
* createDotAccess(const JSTokenLocation
& location
, ExpressionNode
* base
, const Identifier
* property
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
244 DotAccessorNode
* node
= new (m_parserArena
) DotAccessorNode(location
, base
, *property
);
245 setExceptionLocation(node
, start
, divot
, end
);
249 ExpressionNode
* createSpreadExpression(const JSTokenLocation
& location
, ExpressionNode
* expression
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
251 auto node
= new (m_parserArena
) SpreadExpressionNode(location
, expression
);
252 setExceptionLocation(node
, start
, divot
, end
);
256 #if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
257 TemplateStringNode
* createTemplateString(const JSTokenLocation
& location
, const Identifier
& cooked
, const Identifier
& raw
)
259 return new (m_parserArena
) TemplateStringNode(location
, cooked
, raw
);
262 TemplateStringListNode
* createTemplateStringList(TemplateStringNode
* templateString
)
264 return new (m_parserArena
) TemplateStringListNode(templateString
);
267 TemplateStringListNode
* createTemplateStringList(TemplateStringListNode
* templateStringList
, TemplateStringNode
* templateString
)
269 return new (m_parserArena
) TemplateStringListNode(templateStringList
, templateString
);
272 TemplateExpressionListNode
* createTemplateExpressionList(ExpressionNode
* expression
)
274 return new (m_parserArena
) TemplateExpressionListNode(expression
);
277 TemplateExpressionListNode
* createTemplateExpressionList(TemplateExpressionListNode
* templateExpressionListNode
, ExpressionNode
* expression
)
279 return new (m_parserArena
) TemplateExpressionListNode(templateExpressionListNode
, expression
);
282 TemplateLiteralNode
* createTemplateLiteral(const JSTokenLocation
& location
, TemplateStringListNode
* templateStringList
)
284 return new (m_parserArena
) TemplateLiteralNode(location
, templateStringList
);
287 TemplateLiteralNode
* createTemplateLiteral(const JSTokenLocation
& location
, TemplateStringListNode
* templateStringList
, TemplateExpressionListNode
* templateExpressionList
)
289 return new (m_parserArena
) TemplateLiteralNode(location
, templateStringList
, templateExpressionList
);
292 ExpressionNode
* createTaggedTemplate(const JSTokenLocation
& location
, ExpressionNode
* base
, TemplateLiteralNode
* templateLiteral
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
294 auto node
= new (m_parserArena
) TaggedTemplateNode(location
, base
, templateLiteral
);
295 setExceptionLocation(node
, start
, divot
, end
);
300 ExpressionNode
* createRegExp(const JSTokenLocation
& location
, const Identifier
& pattern
, const Identifier
& flags
, const JSTextPosition
& start
)
302 if (Yarr::checkSyntax(pattern
.string()))
304 RegExpNode
* node
= new (m_parserArena
) RegExpNode(location
, pattern
, flags
);
305 int size
= pattern
.length() + 2; // + 2 for the two /'s
306 JSTextPosition end
= start
+ size
;
307 setExceptionLocation(node
, start
, end
, end
);
311 ExpressionNode
* createNewExpr(const JSTokenLocation
& location
, ExpressionNode
* expr
, ArgumentsNode
* arguments
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
313 NewExprNode
* node
= new (m_parserArena
) NewExprNode(location
, expr
, arguments
);
314 setExceptionLocation(node
, start
, divot
, end
);
318 ExpressionNode
* createNewExpr(const JSTokenLocation
& location
, ExpressionNode
* expr
, const JSTextPosition
& start
, const JSTextPosition
& end
)
320 NewExprNode
* node
= new (m_parserArena
) NewExprNode(location
, expr
);
321 setExceptionLocation(node
, start
, end
, end
);
325 ExpressionNode
* createConditionalExpr(const JSTokenLocation
& location
, ExpressionNode
* condition
, ExpressionNode
* lhs
, ExpressionNode
* rhs
)
327 return new (m_parserArena
) ConditionalNode(location
, condition
, lhs
, rhs
);
330 ExpressionNode
* createAssignResolve(const JSTokenLocation
& location
, const Identifier
& ident
, ExpressionNode
* rhs
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
332 if (rhs
->isFuncExprNode())
333 static_cast<FuncExprNode
*>(rhs
)->body()->setInferredName(ident
);
334 AssignResolveNode
* node
= new (m_parserArena
) AssignResolveNode(location
, ident
, rhs
);
335 setExceptionLocation(node
, start
, divot
, end
);
339 #if ENABLE(ES6_CLASS_SYNTAX)
340 ClassExprNode
* createClassExpr(const JSTokenLocation
& location
, const Identifier
& name
, ExpressionNode
* constructor
,
341 ExpressionNode
* parentClass
, PropertyListNode
* instanceMethods
, PropertyListNode
* staticMethods
)
343 return new (m_parserArena
) ClassExprNode(location
, name
, constructor
, parentClass
, instanceMethods
, staticMethods
);
347 ExpressionNode
* createFunctionExpr(const JSTokenLocation
& location
, const ParserFunctionInfo
<ASTBuilder
>& info
)
349 FuncExprNode
* result
= new (m_parserArena
) FuncExprNode(location
, *info
.name
, info
.body
,
350 m_sourceCode
->subExpression(info
.startFunctionOffset
, info
.endFunctionOffset
, info
.bodyStartLine
, info
.bodyStartColumn
), info
.parameters
);
351 info
.body
->setLoc(info
.bodyStartLine
, info
.bodyEndLine
, location
.startOffset
, location
.lineStartOffset
);
355 FunctionBodyNode
* createFunctionBody(
356 const JSTokenLocation
& startLocation
, const JSTokenLocation
& endLocation
,
357 unsigned startColumn
, unsigned endColumn
, int functionKeywordStart
,
358 int functionNameStart
, int parametersStart
, bool inStrictContext
,
359 ConstructorKind constructorKind
)
361 return new (m_parserArena
) FunctionBodyNode(
362 m_parserArena
, startLocation
, endLocation
, startColumn
, endColumn
,
363 functionKeywordStart
, functionNameStart
, parametersStart
,
364 inStrictContext
, constructorKind
);
367 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
368 ExpressionNode
* createArrowFunctionExpr(const JSTokenLocation
& location
, const ParserFunctionInfo
<ASTBuilder
>& info
)
370 SourceCode source
= info
.functionBodyType
== ArrowFunctionBodyExpression
371 ? m_sourceCode
->subArrowExpression(info
.arrowFunctionOffset
, info
.endFunctionOffset
, info
.bodyStartLine
, info
.bodyStartColumn
)
372 : m_sourceCode
->subExpression(info
.startFunctionOffset
, info
.endFunctionOffset
, info
.bodyStartLine
, info
.bodyStartColumn
);
374 FuncExprNode
* result
= new (m_parserArena
) FuncExprNode(location
, *info
.name
, info
.body
, source
, info
.parameters
);
375 info
.body
->setLoc(info
.bodyStartLine
, info
.bodyEndLine
, location
.startOffset
, location
.lineStartOffset
);
380 NEVER_INLINE PropertyNode
* createGetterOrSetterProperty(const JSTokenLocation
& location
, PropertyNode::Type type
, bool,
381 const Identifier
* name
, const ParserFunctionInfo
<ASTBuilder
>& info
, SuperBinding superBinding
)
384 info
.body
->setLoc(info
.bodyStartLine
, info
.bodyEndLine
, location
.startOffset
, location
.lineStartOffset
);
385 info
.body
->setInferredName(*name
);
386 SourceCode source
= m_sourceCode
->subExpression(info
.startFunctionOffset
, info
.endFunctionOffset
, info
.bodyStartLine
, info
.bodyStartColumn
);
387 FuncExprNode
* funcExpr
= new (m_parserArena
) FuncExprNode(location
, m_vm
->propertyNames
->nullIdentifier
, info
.body
, source
, info
.parameters
);
388 return new (m_parserArena
) PropertyNode(*name
, funcExpr
, type
, PropertyNode::Unknown
, superBinding
);
391 NEVER_INLINE PropertyNode
* createGetterOrSetterProperty(VM
* vm
, ParserArena
& parserArena
, const JSTokenLocation
& location
, PropertyNode::Type type
, bool,
392 double name
, const ParserFunctionInfo
<ASTBuilder
>& info
, SuperBinding superBinding
)
394 info
.body
->setLoc(info
.bodyStartLine
, info
.bodyEndLine
, location
.startOffset
, location
.lineStartOffset
);
395 const Identifier
& ident
= parserArena
.identifierArena().makeNumericIdentifier(vm
, name
);
396 SourceCode source
= m_sourceCode
->subExpression(info
.startFunctionOffset
, info
.endFunctionOffset
, info
.bodyStartLine
, info
.bodyStartColumn
);
397 FuncExprNode
* funcExpr
= new (m_parserArena
) FuncExprNode(location
, vm
->propertyNames
->nullIdentifier
, info
.body
, source
, info
.parameters
);
398 return new (m_parserArena
) PropertyNode(ident
, funcExpr
, type
, PropertyNode::Unknown
, superBinding
);
401 ArgumentsNode
* createArguments() { return new (m_parserArena
) ArgumentsNode(); }
402 ArgumentsNode
* createArguments(ArgumentListNode
* args
) { return new (m_parserArena
) ArgumentsNode(args
); }
403 ArgumentListNode
* createArgumentsList(const JSTokenLocation
& location
, ExpressionNode
* arg
) { return new (m_parserArena
) ArgumentListNode(location
, arg
); }
404 ArgumentListNode
* createArgumentsList(const JSTokenLocation
& location
, ArgumentListNode
* args
, ExpressionNode
* arg
) { return new (m_parserArena
) ArgumentListNode(location
, args
, arg
); }
406 PropertyNode
* createProperty(const Identifier
* propertyName
, ExpressionNode
* node
, PropertyNode::Type type
, PropertyNode::PutType putType
, bool, SuperBinding superBinding
= SuperBinding::NotNeeded
)
408 if (node
->isFuncExprNode())
409 static_cast<FuncExprNode
*>(node
)->body()->setInferredName(*propertyName
);
410 return new (m_parserArena
) PropertyNode(*propertyName
, node
, type
, putType
, superBinding
);
412 PropertyNode
* createProperty(VM
* vm
, ParserArena
& parserArena
, double propertyName
, ExpressionNode
* node
, PropertyNode::Type type
, PropertyNode::PutType putType
, bool)
414 return new (m_parserArena
) PropertyNode(parserArena
.identifierArena().makeNumericIdentifier(vm
, propertyName
), node
, type
, putType
);
416 PropertyNode
* createProperty(ExpressionNode
* propertyName
, ExpressionNode
* node
, PropertyNode::Type type
, PropertyNode::PutType putType
, bool) { return new (m_parserArena
) PropertyNode(propertyName
, node
, type
, putType
); }
417 PropertyListNode
* createPropertyList(const JSTokenLocation
& location
, PropertyNode
* property
) { return new (m_parserArena
) PropertyListNode(location
, property
); }
418 PropertyListNode
* createPropertyList(const JSTokenLocation
& location
, PropertyNode
* property
, PropertyListNode
* tail
) { return new (m_parserArena
) PropertyListNode(location
, property
, tail
); }
420 ElementNode
* createElementList(int elisions
, ExpressionNode
* expr
) { return new (m_parserArena
) ElementNode(elisions
, expr
); }
421 ElementNode
* createElementList(ElementNode
* elems
, int elisions
, ExpressionNode
* expr
) { return new (m_parserArena
) ElementNode(elems
, elisions
, expr
); }
423 ParameterNode
* createFormalParameterList(DestructuringPattern pattern
) { return new (m_parserArena
) ParameterNode(pattern
); }
424 ParameterNode
* createFormalParameterList(ParameterNode
* list
, DestructuringPattern pattern
) { return new (m_parserArena
) ParameterNode(list
, pattern
); }
426 CaseClauseNode
* createClause(ExpressionNode
* expr
, JSC::SourceElements
* statements
) { return new (m_parserArena
) CaseClauseNode(expr
, statements
); }
427 ClauseListNode
* createClauseList(CaseClauseNode
* clause
) { return new (m_parserArena
) ClauseListNode(clause
); }
428 ClauseListNode
* createClauseList(ClauseListNode
* tail
, CaseClauseNode
* clause
) { return new (m_parserArena
) ClauseListNode(tail
, clause
); }
430 StatementNode
* createFuncDeclStatement(const JSTokenLocation
& location
, const ParserFunctionInfo
<ASTBuilder
>& info
)
432 FuncDeclNode
* decl
= new (m_parserArena
) FuncDeclNode(location
, *info
.name
, info
.body
,
433 m_sourceCode
->subExpression(info
.startFunctionOffset
, info
.endFunctionOffset
, info
.bodyStartLine
, info
.bodyStartColumn
), info
.parameters
);
434 if (*info
.name
== m_vm
->propertyNames
->arguments
)
436 m_scope
.m_funcDeclarations
.append(decl
->body());
437 info
.body
->setLoc(info
.bodyStartLine
, info
.bodyEndLine
, location
.startOffset
, location
.lineStartOffset
);
441 #if ENABLE(ES6_CLASS_SYNTAX)
442 StatementNode
* createClassDeclStatement(const JSTokenLocation
& location
, ClassExprNode
* classExpression
,
443 const JSTextPosition
& classStart
, const JSTextPosition
& classEnd
, unsigned startLine
, unsigned endLine
)
445 // FIXME: Use "let" declaration.
446 ExpressionNode
* assign
= createAssignResolve(location
, classExpression
->name(), classExpression
, classStart
, classStart
+ 1, classEnd
);
447 ClassDeclNode
* decl
= new (m_parserArena
) ClassDeclNode(location
, assign
);
448 decl
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
453 StatementNode
* createBlockStatement(const JSTokenLocation
& location
, JSC::SourceElements
* elements
, int startLine
, int endLine
)
455 BlockNode
* block
= new (m_parserArena
) BlockNode(location
, elements
);
456 block
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
460 StatementNode
* createExprStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, const JSTextPosition
& start
, int end
)
462 ExprStatementNode
* result
= new (m_parserArena
) ExprStatementNode(location
, expr
);
463 result
->setLoc(start
.line
, end
, start
.offset
, start
.lineStartOffset
);
467 StatementNode
* createIfStatement(const JSTokenLocation
& location
, ExpressionNode
* condition
, StatementNode
* trueBlock
, StatementNode
* falseBlock
, int start
, int end
)
469 IfElseNode
* result
= new (m_parserArena
) IfElseNode(location
, condition
, trueBlock
, falseBlock
);
470 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
474 StatementNode
* createForLoop(const JSTokenLocation
& location
, ExpressionNode
* initializer
, ExpressionNode
* condition
, ExpressionNode
* iter
, StatementNode
* statements
, int start
, int end
)
476 ForNode
* result
= new (m_parserArena
) ForNode(location
, initializer
, condition
, iter
, statements
);
477 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
481 StatementNode
* createForInLoop(const JSTokenLocation
& location
, ExpressionNode
* lhs
, ExpressionNode
* iter
, StatementNode
* statements
, const JSTextPosition
& eStart
, const JSTextPosition
& eDivot
, const JSTextPosition
& eEnd
, int start
, int end
)
483 ForInNode
* result
= new (m_parserArena
) ForInNode(location
, lhs
, iter
, statements
);
484 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
485 setExceptionLocation(result
, eStart
, eDivot
, eEnd
);
489 StatementNode
* createForInLoop(const JSTokenLocation
& location
, PassRefPtr
<DestructuringPatternNode
> pattern
, ExpressionNode
* iter
, StatementNode
* statements
, const JSTextPosition
& eStart
, const JSTextPosition
& eDivot
, const JSTextPosition
& eEnd
, int start
, int end
)
491 auto lexpr
= new (m_parserArena
) DestructuringAssignmentNode(location
, pattern
.get(), 0);
492 return createForInLoop(location
, lexpr
, iter
, statements
, eStart
, eDivot
, eEnd
, start
, end
);
495 StatementNode
* createForOfLoop(const JSTokenLocation
& location
, ExpressionNode
* lhs
, ExpressionNode
* iter
, StatementNode
* statements
, const JSTextPosition
& eStart
, const JSTextPosition
& eDivot
, const JSTextPosition
& eEnd
, int start
, int end
)
497 ForOfNode
* result
= new (m_parserArena
) ForOfNode(location
, lhs
, iter
, statements
);
498 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
499 setExceptionLocation(result
, eStart
, eDivot
, eEnd
);
503 StatementNode
* createForOfLoop(const JSTokenLocation
& location
, PassRefPtr
<DestructuringPatternNode
> pattern
, ExpressionNode
* iter
, StatementNode
* statements
, const JSTextPosition
& eStart
, const JSTextPosition
& eDivot
, const JSTextPosition
& eEnd
, int start
, int end
)
505 auto lexpr
= new (m_parserArena
) DestructuringAssignmentNode(location
, pattern
.get(), 0);
506 return createForOfLoop(location
, lexpr
, iter
, statements
, eStart
, eDivot
, eEnd
, start
, end
);
509 bool isBindingNode(const DestructuringPattern
& pattern
)
511 return pattern
->isBindingNode();
514 StatementNode
* createEmptyStatement(const JSTokenLocation
& location
) { return new (m_parserArena
) EmptyStatementNode(location
); }
516 StatementNode
* createVarStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, int start
, int end
)
518 StatementNode
* result
;
519 result
= new (m_parserArena
) VarStatementNode(location
, expr
);
520 result
->setLoc(start
, end
, location
.startOffset
, location
.lineStartOffset
);
524 ExpressionNode
* createEmptyVarExpression(const JSTokenLocation
& location
, const Identifier
& identifier
)
526 return new (m_parserArena
) EmptyVarExpression(location
, identifier
);
529 StatementNode
* createReturnStatement(const JSTokenLocation
& location
, ExpressionNode
* expression
, const JSTextPosition
& start
, const JSTextPosition
& end
)
531 ReturnNode
* result
= new (m_parserArena
) ReturnNode(location
, expression
);
532 setExceptionLocation(result
, start
, end
, end
);
533 result
->setLoc(start
.line
, end
.line
, start
.offset
, start
.lineStartOffset
);
537 StatementNode
* createBreakStatement(const JSTokenLocation
& location
, const Identifier
* ident
, const JSTextPosition
& start
, const JSTextPosition
& end
)
539 BreakNode
* result
= new (m_parserArena
) BreakNode(location
, *ident
);
540 setExceptionLocation(result
, start
, end
, end
);
541 result
->setLoc(start
.line
, end
.line
, start
.offset
, start
.lineStartOffset
);
545 StatementNode
* createContinueStatement(const JSTokenLocation
& location
, const Identifier
* ident
, const JSTextPosition
& start
, const JSTextPosition
& end
)
547 ContinueNode
* result
= new (m_parserArena
) ContinueNode(location
, *ident
);
548 setExceptionLocation(result
, start
, end
, end
);
549 result
->setLoc(start
.line
, end
.line
, start
.offset
, start
.lineStartOffset
);
553 StatementNode
* createTryStatement(const JSTokenLocation
& location
, StatementNode
* tryBlock
, const Identifier
* ident
, StatementNode
* catchBlock
, StatementNode
* finallyBlock
, int startLine
, int endLine
)
555 TryNode
* result
= new (m_parserArena
) TryNode(location
, tryBlock
, *ident
, catchBlock
, finallyBlock
);
558 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
562 StatementNode
* createSwitchStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, ClauseListNode
* firstClauses
, CaseClauseNode
* defaultClause
, ClauseListNode
* secondClauses
, int startLine
, int endLine
)
564 CaseBlockNode
* cases
= new (m_parserArena
) CaseBlockNode(firstClauses
, defaultClause
, secondClauses
);
565 SwitchNode
* result
= new (m_parserArena
) SwitchNode(location
, expr
, cases
);
566 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
570 StatementNode
* createWhileStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, StatementNode
* statement
, int startLine
, int endLine
)
572 WhileNode
* result
= new (m_parserArena
) WhileNode(location
, expr
, statement
);
573 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
577 StatementNode
* createDoWhileStatement(const JSTokenLocation
& location
, StatementNode
* statement
, ExpressionNode
* expr
, int startLine
, int endLine
)
579 DoWhileNode
* result
= new (m_parserArena
) DoWhileNode(location
, statement
, expr
);
580 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
584 StatementNode
* createLabelStatement(const JSTokenLocation
& location
, const Identifier
* ident
, StatementNode
* statement
, const JSTextPosition
& start
, const JSTextPosition
& end
)
586 LabelNode
* result
= new (m_parserArena
) LabelNode(location
, *ident
, statement
);
587 setExceptionLocation(result
, start
, end
, end
);
591 StatementNode
* createWithStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, StatementNode
* statement
, unsigned start
, const JSTextPosition
& end
, unsigned startLine
, unsigned endLine
)
594 WithNode
* result
= new (m_parserArena
) WithNode(location
, expr
, statement
, end
, end
- start
);
595 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
599 StatementNode
* createThrowStatement(const JSTokenLocation
& location
, ExpressionNode
* expr
, const JSTextPosition
& start
, const JSTextPosition
& end
)
601 ThrowNode
* result
= new (m_parserArena
) ThrowNode(location
, expr
);
602 result
->setLoc(start
.line
, end
.line
, start
.offset
, start
.lineStartOffset
);
603 setExceptionLocation(result
, start
, end
, end
);
607 StatementNode
* createDebugger(const JSTokenLocation
& location
, int startLine
, int endLine
)
609 DebuggerStatementNode
* result
= new (m_parserArena
) DebuggerStatementNode(location
);
610 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
614 StatementNode
* createConstStatement(const JSTokenLocation
& location
, ConstDeclNode
* decls
, int startLine
, int endLine
)
616 ConstStatementNode
* result
= new (m_parserArena
) ConstStatementNode(location
, decls
);
617 result
->setLoc(startLine
, endLine
, location
.startOffset
, location
.lineStartOffset
);
621 ConstDeclNode
* appendConstDecl(const JSTokenLocation
& location
, ConstDeclNode
* tail
, const Identifier
* name
, ExpressionNode
* initializer
)
623 ConstDeclNode
* result
= new (m_parserArena
) ConstDeclNode(location
, *name
, initializer
);
625 tail
->m_next
= result
;
629 void appendStatement(JSC::SourceElements
* elements
, JSC::StatementNode
* statement
)
631 elements
->append(statement
);
634 void addVar(const Identifier
* ident
, int attrs
)
636 if (m_vm
->propertyNames
->arguments
== *ident
)
638 ASSERT(ident
->impl()->isAtomic() || ident
->impl()->isSymbol());
639 m_scope
.m_varDeclarations
.append(std::make_pair(*ident
, attrs
));
642 CommaNode
* createCommaExpr(const JSTokenLocation
& location
, ExpressionNode
* node
)
644 return new (m_parserArena
) CommaNode(location
, node
);
647 CommaNode
* appendToCommaExpr(const JSTokenLocation
& location
, ExpressionNode
*, ExpressionNode
* tail
, ExpressionNode
* next
)
649 ASSERT(tail
->isCommaNode());
650 CommaNode
* newTail
= new (m_parserArena
) CommaNode(location
, next
);
651 static_cast<CommaNode
*>(tail
)->setNext(newTail
);
655 int evalCount() const { return m_evalCount
; }
657 void appendBinaryExpressionInfo(int& operandStackDepth
, ExpressionNode
* current
, const JSTextPosition
& exprStart
, const JSTextPosition
& lhs
, const JSTextPosition
& rhs
, bool hasAssignments
)
660 m_binaryOperandStack
.append(std::make_pair(current
, BinaryOpInfo(exprStart
, lhs
, rhs
, hasAssignments
)));
663 // Logic to handle datastructures used during parsing of binary expressions
664 void operatorStackPop(int& operatorStackDepth
)
666 operatorStackDepth
--;
667 m_binaryOperatorStack
.removeLast();
669 bool operatorStackHasHigherPrecedence(int&, int precedence
)
671 return precedence
<= m_binaryOperatorStack
.last().second
;
673 const BinaryOperand
& getFromOperandStack(int i
) { return m_binaryOperandStack
[m_binaryOperandStack
.size() + i
]; }
674 void shrinkOperandStackBy(int& operandStackDepth
, int amount
)
676 operandStackDepth
-= amount
;
677 ASSERT(operandStackDepth
>= 0);
678 m_binaryOperandStack
.resize(m_binaryOperandStack
.size() - amount
);
680 void appendBinaryOperation(const JSTokenLocation
& location
, int& operandStackDepth
, int&, const BinaryOperand
& lhs
, const BinaryOperand
& rhs
)
683 m_binaryOperandStack
.append(std::make_pair(makeBinaryNode(location
, m_binaryOperatorStack
.last().first
, lhs
, rhs
), BinaryOpInfo(lhs
.second
, rhs
.second
)));
685 void operatorStackAppend(int& operatorStackDepth
, int op
, int precedence
)
687 operatorStackDepth
++;
688 m_binaryOperatorStack
.append(std::make_pair(op
, precedence
));
690 ExpressionNode
* popOperandStack(int&)
692 ExpressionNode
* result
= m_binaryOperandStack
.last().first
;
693 m_binaryOperandStack
.removeLast();
697 void appendUnaryToken(int& tokenStackDepth
, int type
, const JSTextPosition
& start
)
700 m_unaryTokenStack
.append(std::make_pair(type
, start
));
703 int unaryTokenStackLastType(int&)
705 return m_unaryTokenStack
.last().first
;
708 const JSTextPosition
& unaryTokenStackLastStart(int&)
710 return m_unaryTokenStack
.last().second
;
713 void unaryTokenStackRemoveLast(int& tokenStackDepth
)
716 m_unaryTokenStack
.removeLast();
719 void assignmentStackAppend(int& assignmentStackDepth
, ExpressionNode
* node
, const JSTextPosition
& start
, const JSTextPosition
& divot
, int assignmentCount
, Operator op
)
721 assignmentStackDepth
++;
722 ASSERT(start
.offset
>= start
.lineStartOffset
);
723 ASSERT(divot
.offset
>= divot
.lineStartOffset
);
724 m_assignmentInfoStack
.append(AssignmentInfo(node
, start
, divot
, assignmentCount
, op
));
727 ExpressionNode
* createAssignment(const JSTokenLocation
& location
, int& assignmentStackDepth
, ExpressionNode
* rhs
, int initialAssignmentCount
, int currentAssignmentCount
, const JSTextPosition
& lastTokenEnd
)
729 AssignmentInfo
& info
= m_assignmentInfoStack
.last();
730 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
);
731 m_assignmentInfoStack
.removeLast();
732 assignmentStackDepth
--;
736 const Identifier
* getName(const Property
& property
) const { return property
->name(); }
737 PropertyNode::Type
getType(const Property
& property
) const { return property
->type(); }
739 bool isResolve(ExpressionNode
* expr
) const { return expr
->isResolveNode(); }
741 ExpressionNode
* createDestructuringAssignment(const JSTokenLocation
& location
, PassRefPtr
<DestructuringPatternNode
> pattern
, ExpressionNode
* initializer
)
743 return new (m_parserArena
) DestructuringAssignmentNode(location
, pattern
.get(), initializer
);
746 ArrayPattern
createArrayPattern(const JSTokenLocation
&)
748 return ArrayPatternNode::create();
751 void appendArrayPatternSkipEntry(ArrayPattern node
, const JSTokenLocation
& location
)
753 node
->appendIndex(ArrayPatternNode::BindingType::Elision
, location
, 0, nullptr);
756 void appendArrayPatternEntry(ArrayPattern node
, const JSTokenLocation
& location
, DestructuringPattern pattern
, ExpressionNode
* defaultValue
)
758 node
->appendIndex(ArrayPatternNode::BindingType::Element
, location
, pattern
.get(), defaultValue
);
761 void appendArrayPatternRestEntry(ArrayPattern node
, const JSTokenLocation
& location
, DestructuringPattern pattern
)
763 node
->appendIndex(ArrayPatternNode::BindingType::RestElement
, location
, pattern
.get(), nullptr);
766 void finishArrayPattern(ArrayPattern node
, const JSTextPosition
& divotStart
, const JSTextPosition
& divot
, const JSTextPosition
& divotEnd
)
768 setExceptionLocation(node
.get(), divotStart
, divot
, divotEnd
);
771 ObjectPattern
createObjectPattern(const JSTokenLocation
&)
773 return ObjectPatternNode::create();
776 void appendObjectPatternEntry(ObjectPattern node
, const JSTokenLocation
& location
, bool wasString
, const Identifier
& identifier
, DestructuringPattern pattern
, ExpressionNode
* defaultValue
)
778 node
->appendEntry(location
, identifier
, wasString
, pattern
.get(), defaultValue
);
781 BindingPattern
createBindingLocation(const JSTokenLocation
&, const Identifier
& boundProperty
, const JSTextPosition
& start
, const JSTextPosition
& end
)
783 return BindingNode::create(boundProperty
, start
, end
);
786 void setEndOffset(Node
* node
, int offset
)
788 node
->setEndOffset(offset
);
791 int endOffset(Node
* node
)
793 return node
->endOffset();
796 void setStartOffset(CaseClauseNode
* node
, int offset
)
798 node
->setStartOffset(offset
);
801 void setStartOffset(Node
* node
, int offset
)
803 node
->setStartOffset(offset
);
813 DeclarationStacks::VarStack m_varDeclarations
;
814 DeclarationStacks::FunctionStack m_funcDeclarations
;
819 static void setExceptionLocation(ThrowableExpressionData
* node
, const JSTextPosition
& divotStart
, const JSTextPosition
& divot
, const JSTextPosition
& divotEnd
)
821 ASSERT(divot
.offset
>= divot
.lineStartOffset
);
822 node
->setExceptionSourceCode(divot
, divotStart
, divotEnd
);
825 void incConstants() { m_scope
.m_numConstants
++; }
826 void usesThis() { m_scope
.m_features
|= ThisFeature
; }
827 void usesCatch() { m_scope
.m_features
|= CatchFeature
; }
828 void usesArguments() { m_scope
.m_features
|= ArgumentsFeature
; }
829 void usesWith() { m_scope
.m_features
|= WithFeature
; }
833 m_scope
.m_features
|= EvalFeature
;
835 ExpressionNode
* createIntegerLikeNumber(const JSTokenLocation
& location
, double d
)
837 return new (m_parserArena
) IntegerNode(location
, d
);
839 ExpressionNode
* createDoubleLikeNumber(const JSTokenLocation
& location
, double d
)
841 return new (m_parserArena
) DoubleNode(location
, d
);
843 ExpressionNode
* createNumberFromBinaryOperation(const JSTokenLocation
& location
, double value
, const NumberNode
& originalNodeA
, const NumberNode
& originalNodeB
)
845 if (originalNodeA
.isIntegerNode() && originalNodeB
.isIntegerNode())
846 return createIntegerLikeNumber(location
, value
);
847 return createDoubleLikeNumber(location
, value
);
849 ExpressionNode
* createNumberFromUnaryOperation(const JSTokenLocation
& location
, double value
, const NumberNode
& originalNode
)
851 if (originalNode
.isIntegerNode())
852 return createIntegerLikeNumber(location
, value
);
853 return createDoubleLikeNumber(location
, value
);
857 ParserArena
& m_parserArena
;
858 SourceCode
* m_sourceCode
;
860 Vector
<BinaryOperand
, 10, UnsafeVectorOverflow
> m_binaryOperandStack
;
861 Vector
<AssignmentInfo
, 10, UnsafeVectorOverflow
> m_assignmentInfoStack
;
862 Vector
<std::pair
<int, int>, 10, UnsafeVectorOverflow
> m_binaryOperatorStack
;
863 Vector
<std::pair
<int, JSTextPosition
>, 10, UnsafeVectorOverflow
> m_unaryTokenStack
;
867 ExpressionNode
* ASTBuilder::makeTypeOfNode(const JSTokenLocation
& location
, ExpressionNode
* expr
)
869 if (expr
->isResolveNode()) {
870 ResolveNode
* resolve
= static_cast<ResolveNode
*>(expr
);
871 return new (m_parserArena
) TypeOfResolveNode(location
, resolve
->identifier());
873 return new (m_parserArena
) TypeOfValueNode(location
, expr
);
876 ExpressionNode
* ASTBuilder::makeDeleteNode(const JSTokenLocation
& location
, ExpressionNode
* expr
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
878 if (!expr
->isLocation())
879 return new (m_parserArena
) DeleteValueNode(location
, expr
);
880 if (expr
->isResolveNode()) {
881 ResolveNode
* resolve
= static_cast<ResolveNode
*>(expr
);
882 return new (m_parserArena
) DeleteResolveNode(location
, resolve
->identifier(), divot
, start
, end
);
884 if (expr
->isBracketAccessorNode()) {
885 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(expr
);
886 return new (m_parserArena
) DeleteBracketNode(location
, bracket
->base(), bracket
->subscript(), divot
, start
, end
);
888 ASSERT(expr
->isDotAccessorNode());
889 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(expr
);
890 return new (m_parserArena
) DeleteDotNode(location
, dot
->base(), dot
->identifier(), divot
, start
, end
);
893 ExpressionNode
* ASTBuilder::makeNegateNode(const JSTokenLocation
& location
, ExpressionNode
* n
)
896 const NumberNode
& numberNode
= static_cast<const NumberNode
&>(*n
);
897 return createNumberFromUnaryOperation(location
, -numberNode
.value(), numberNode
);
900 return new (m_parserArena
) NegateNode(location
, n
);
903 ExpressionNode
* ASTBuilder::makeBitwiseNotNode(const JSTokenLocation
& location
, ExpressionNode
* expr
)
905 if (expr
->isNumber())
906 return createIntegerLikeNumber(location
, ~toInt32(static_cast<NumberNode
*>(expr
)->value()));
907 return new (m_parserArena
) BitwiseNotNode(location
, expr
);
910 ExpressionNode
* ASTBuilder::makeMultNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
912 expr1
= expr1
->stripUnaryPlus();
913 expr2
= expr2
->stripUnaryPlus();
915 if (expr1
->isNumber() && expr2
->isNumber()) {
916 const NumberNode
& numberExpr1
= static_cast<NumberNode
&>(*expr1
);
917 const NumberNode
& numberExpr2
= static_cast<NumberNode
&>(*expr2
);
918 return createNumberFromBinaryOperation(location
, numberExpr1
.value() * numberExpr2
.value(), numberExpr1
, numberExpr2
);
921 if (expr1
->isNumber() && static_cast<NumberNode
*>(expr1
)->value() == 1)
922 return new (m_parserArena
) UnaryPlusNode(location
, expr2
);
924 if (expr2
->isNumber() && static_cast<NumberNode
*>(expr2
)->value() == 1)
925 return new (m_parserArena
) UnaryPlusNode(location
, expr1
);
927 return new (m_parserArena
) MultNode(location
, expr1
, expr2
, rightHasAssignments
);
930 ExpressionNode
* ASTBuilder::makeDivNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
932 expr1
= expr1
->stripUnaryPlus();
933 expr2
= expr2
->stripUnaryPlus();
935 if (expr1
->isNumber() && expr2
->isNumber()) {
936 const NumberNode
& numberExpr1
= static_cast<NumberNode
&>(*expr1
);
937 const NumberNode
& numberExpr2
= static_cast<NumberNode
&>(*expr2
);
938 double result
= numberExpr1
.value() / numberExpr2
.value();
939 if (static_cast<int64_t>(result
) == result
)
940 return createNumberFromBinaryOperation(location
, result
, numberExpr1
, numberExpr2
);
941 return createDoubleLikeNumber(location
, result
);
943 return new (m_parserArena
) DivNode(location
, expr1
, expr2
, rightHasAssignments
);
946 ExpressionNode
* ASTBuilder::makeModNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
948 expr1
= expr1
->stripUnaryPlus();
949 expr2
= expr2
->stripUnaryPlus();
951 if (expr1
->isNumber() && expr2
->isNumber()) {
952 const NumberNode
& numberExpr1
= static_cast<NumberNode
&>(*expr1
);
953 const NumberNode
& numberExpr2
= static_cast<NumberNode
&>(*expr2
);
954 return createIntegerLikeNumber(location
, fmod(numberExpr1
.value(), numberExpr2
.value()));
956 return new (m_parserArena
) ModNode(location
, expr1
, expr2
, rightHasAssignments
);
959 ExpressionNode
* ASTBuilder::makeAddNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
962 if (expr1
->isNumber() && expr2
->isNumber()) {
963 const NumberNode
& numberExpr1
= static_cast<NumberNode
&>(*expr1
);
964 const NumberNode
& numberExpr2
= static_cast<NumberNode
&>(*expr2
);
965 return createNumberFromBinaryOperation(location
, numberExpr1
.value() + numberExpr2
.value(), numberExpr1
, numberExpr2
);
967 return new (m_parserArena
) AddNode(location
, expr1
, expr2
, rightHasAssignments
);
970 ExpressionNode
* ASTBuilder::makeSubNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
972 expr1
= expr1
->stripUnaryPlus();
973 expr2
= expr2
->stripUnaryPlus();
975 if (expr1
->isNumber() && expr2
->isNumber()) {
976 const NumberNode
& numberExpr1
= static_cast<NumberNode
&>(*expr1
);
977 const NumberNode
& numberExpr2
= static_cast<NumberNode
&>(*expr2
);
978 return createNumberFromBinaryOperation(location
, numberExpr1
.value() - numberExpr2
.value(), numberExpr1
, numberExpr2
);
980 return new (m_parserArena
) SubNode(location
, expr1
, expr2
, rightHasAssignments
);
983 ExpressionNode
* ASTBuilder::makeLeftShiftNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
985 if (expr1
->isNumber() && expr2
->isNumber()) {
986 const NumberNode
& numberExpr1
= static_cast<NumberNode
&>(*expr1
);
987 const NumberNode
& numberExpr2
= static_cast<NumberNode
&>(*expr2
);
988 return createIntegerLikeNumber(location
, toInt32(numberExpr1
.value()) << (toUInt32(numberExpr2
.value()) & 0x1f));
990 return new (m_parserArena
) LeftShiftNode(location
, expr1
, expr2
, rightHasAssignments
);
993 ExpressionNode
* ASTBuilder::makeRightShiftNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
995 if (expr1
->isNumber() && expr2
->isNumber()) {
996 const NumberNode
& numberExpr1
= static_cast<NumberNode
&>(*expr1
);
997 const NumberNode
& numberExpr2
= static_cast<NumberNode
&>(*expr2
);
998 return createIntegerLikeNumber(location
, toInt32(numberExpr1
.value()) >> (toUInt32(numberExpr2
.value()) & 0x1f));
1000 return new (m_parserArena
) RightShiftNode(location
, expr1
, expr2
, rightHasAssignments
);
1003 ExpressionNode
* ASTBuilder::makeURightShiftNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
1005 if (expr1
->isNumber() && expr2
->isNumber()) {
1006 const NumberNode
& numberExpr1
= static_cast<NumberNode
&>(*expr1
);
1007 const NumberNode
& numberExpr2
= static_cast<NumberNode
&>(*expr2
);
1008 return createIntegerLikeNumber(location
, toUInt32(numberExpr1
.value()) >> (toUInt32(numberExpr2
.value()) & 0x1f));
1010 return new (m_parserArena
) UnsignedRightShiftNode(location
, expr1
, expr2
, rightHasAssignments
);
1013 ExpressionNode
* ASTBuilder::makeBitOrNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
1015 if (expr1
->isNumber() && expr2
->isNumber()) {
1016 const NumberNode
& numberExpr1
= static_cast<NumberNode
&>(*expr1
);
1017 const NumberNode
& numberExpr2
= static_cast<NumberNode
&>(*expr2
);
1018 return createIntegerLikeNumber(location
, toInt32(numberExpr1
.value()) | toInt32(numberExpr2
.value()));
1020 return new (m_parserArena
) BitOrNode(location
, expr1
, expr2
, rightHasAssignments
);
1023 ExpressionNode
* ASTBuilder::makeBitAndNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
1025 if (expr1
->isNumber() && expr2
->isNumber()) {
1026 const NumberNode
& numberExpr1
= static_cast<NumberNode
&>(*expr1
);
1027 const NumberNode
& numberExpr2
= static_cast<NumberNode
&>(*expr2
);
1028 return createIntegerLikeNumber(location
, toInt32(numberExpr1
.value()) & toInt32(numberExpr2
.value()));
1030 return new (m_parserArena
) BitAndNode(location
, expr1
, expr2
, rightHasAssignments
);
1033 ExpressionNode
* ASTBuilder::makeBitXOrNode(const JSTokenLocation
& location
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
1035 if (expr1
->isNumber() && expr2
->isNumber()) {
1036 const NumberNode
& numberExpr1
= static_cast<NumberNode
&>(*expr1
);
1037 const NumberNode
& numberExpr2
= static_cast<NumberNode
&>(*expr2
);
1038 return createIntegerLikeNumber(location
, toInt32(numberExpr1
.value()) ^ toInt32(numberExpr2
.value()));
1040 return new (m_parserArena
) BitXOrNode(location
, expr1
, expr2
, rightHasAssignments
);
1043 ExpressionNode
* ASTBuilder::makeFunctionCallNode(const JSTokenLocation
& location
, ExpressionNode
* func
, ArgumentsNode
* args
, const JSTextPosition
& divotStart
, const JSTextPosition
& divot
, const JSTextPosition
& divotEnd
)
1045 ASSERT(divot
.offset
>= divot
.lineStartOffset
);
1046 if (!func
->isLocation())
1047 return new (m_parserArena
) FunctionCallValueNode(location
, func
, args
, divot
, divotStart
, divotEnd
);
1048 if (func
->isResolveNode()) {
1049 ResolveNode
* resolve
= static_cast<ResolveNode
*>(func
);
1050 const Identifier
& identifier
= resolve
->identifier();
1051 if (identifier
== m_vm
->propertyNames
->eval
) {
1053 return new (m_parserArena
) EvalFunctionCallNode(location
, args
, divot
, divotStart
, divotEnd
);
1055 if (BytecodeIntrinsicNode::EmitterType emitter
= m_vm
->propertyNames
->bytecodeIntrinsicRegistry().lookup(identifier
))
1056 return new (m_parserArena
) BytecodeIntrinsicNode(location
, emitter
, identifier
, args
, divot
, divotStart
, divotEnd
);
1057 return new (m_parserArena
) FunctionCallResolveNode(location
, identifier
, args
, divot
, divotStart
, divotEnd
);
1059 if (func
->isBracketAccessorNode()) {
1060 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(func
);
1061 FunctionCallBracketNode
* node
= new (m_parserArena
) FunctionCallBracketNode(location
, bracket
->base(), bracket
->subscript(), bracket
->subscriptHasAssignments(), args
, divot
, divotStart
, divotEnd
);
1062 node
->setSubexpressionInfo(bracket
->divot(), bracket
->divotEnd().offset
);
1065 ASSERT(func
->isDotAccessorNode());
1066 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(func
);
1067 FunctionCallDotNode
* node
;
1068 if (dot
->identifier() == m_vm
->propertyNames
->builtinNames().callPublicName() || dot
->identifier() == m_vm
->propertyNames
->builtinNames().callPrivateName())
1069 node
= new (m_parserArena
) CallFunctionCallDotNode(location
, dot
->base(), dot
->identifier(), args
, divot
, divotStart
, divotEnd
);
1070 else if (dot
->identifier() == m_vm
->propertyNames
->builtinNames().applyPublicName() || dot
->identifier() == m_vm
->propertyNames
->builtinNames().applyPrivateName())
1071 node
= new (m_parserArena
) ApplyFunctionCallDotNode(location
, dot
->base(), dot
->identifier(), args
, divot
, divotStart
, divotEnd
);
1073 node
= new (m_parserArena
) FunctionCallDotNode(location
, dot
->base(), dot
->identifier(), args
, divot
, divotStart
, divotEnd
);
1074 node
->setSubexpressionInfo(dot
->divot(), dot
->divotEnd().offset
);
1078 ExpressionNode
* ASTBuilder::makeBinaryNode(const JSTokenLocation
& location
, int token
, std::pair
<ExpressionNode
*, BinaryOpInfo
> lhs
, std::pair
<ExpressionNode
*, BinaryOpInfo
> rhs
)
1082 return new (m_parserArena
) LogicalOpNode(location
, lhs
.first
, rhs
.first
, OpLogicalOr
);
1085 return new (m_parserArena
) LogicalOpNode(location
, lhs
.first
, rhs
.first
, OpLogicalAnd
);
1088 return makeBitOrNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1091 return makeBitXOrNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1094 return makeBitAndNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1097 return new (m_parserArena
) EqualNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1100 return new (m_parserArena
) NotEqualNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1103 return new (m_parserArena
) StrictEqualNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1106 return new (m_parserArena
) NotStrictEqualNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1109 return new (m_parserArena
) LessNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1112 return new (m_parserArena
) GreaterNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1115 return new (m_parserArena
) LessEqNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1118 return new (m_parserArena
) GreaterEqNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1121 InstanceOfNode
* node
= new (m_parserArena
) InstanceOfNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1122 setExceptionLocation(node
, lhs
.second
.start
, rhs
.second
.start
, rhs
.second
.end
);
1127 InNode
* node
= new (m_parserArena
) InNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1128 setExceptionLocation(node
, lhs
.second
.start
, rhs
.second
.start
, rhs
.second
.end
);
1133 return makeLeftShiftNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1136 return makeRightShiftNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1139 return makeURightShiftNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1142 return makeAddNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1145 return makeSubNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1148 return makeMultNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1151 return makeDivNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1154 return makeModNode(location
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
1160 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
)
1162 if (!loc
->isLocation())
1163 return new (m_parserArena
) AssignErrorNode(location
, divot
, start
, end
);
1165 if (loc
->isResolveNode()) {
1166 ResolveNode
* resolve
= static_cast<ResolveNode
*>(loc
);
1167 if (op
== OpEqual
) {
1168 if (expr
->isFuncExprNode())
1169 static_cast<FuncExprNode
*>(expr
)->body()->setInferredName(resolve
->identifier());
1170 AssignResolveNode
* node
= new (m_parserArena
) AssignResolveNode(location
, resolve
->identifier(), expr
);
1171 setExceptionLocation(node
, start
, divot
, end
);
1174 return new (m_parserArena
) ReadModifyResolveNode(location
, resolve
->identifier(), op
, expr
, exprHasAssignments
, divot
, start
, end
);
1176 if (loc
->isBracketAccessorNode()) {
1177 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(loc
);
1179 return new (m_parserArena
) AssignBracketNode(location
, bracket
->base(), bracket
->subscript(), expr
, locHasAssignments
, exprHasAssignments
, bracket
->divot(), start
, end
);
1180 ReadModifyBracketNode
* node
= new (m_parserArena
) ReadModifyBracketNode(location
, bracket
->base(), bracket
->subscript(), op
, expr
, locHasAssignments
, exprHasAssignments
, divot
, start
, end
);
1181 node
->setSubexpressionInfo(bracket
->divot(), bracket
->divotEnd().offset
);
1184 ASSERT(loc
->isDotAccessorNode());
1185 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(loc
);
1186 if (op
== OpEqual
) {
1187 if (expr
->isFuncExprNode())
1188 static_cast<FuncExprNode
*>(expr
)->body()->setInferredName(dot
->identifier());
1189 return new (m_parserArena
) AssignDotNode(location
, dot
->base(), dot
->identifier(), expr
, exprHasAssignments
, dot
->divot(), start
, end
);
1192 ReadModifyDotNode
* node
= new (m_parserArena
) ReadModifyDotNode(location
, dot
->base(), dot
->identifier(), op
, expr
, exprHasAssignments
, divot
, start
, end
);
1193 node
->setSubexpressionInfo(dot
->divot(), dot
->divotEnd().offset
);
1197 ExpressionNode
* ASTBuilder::makePrefixNode(const JSTokenLocation
& location
, ExpressionNode
* expr
, Operator op
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
1199 return new (m_parserArena
) PrefixNode(location
, expr
, op
, divot
, start
, end
);
1202 ExpressionNode
* ASTBuilder::makePostfixNode(const JSTokenLocation
& location
, ExpressionNode
* expr
, Operator op
, const JSTextPosition
& start
, const JSTextPosition
& divot
, const JSTextPosition
& end
)
1204 return new (m_parserArena
) PostfixNode(location
, expr
, op
, divot
, start
, end
);