]> git.saurik.com Git - apple/javascriptcore.git/blame_incremental - parser/ASTBuilder.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / parser / ASTBuilder.h
... / ...
CommitLineData
1/*
2 * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef ASTBuilder_h
27#define ASTBuilder_h
28
29#include "BuiltinNames.h"
30#include "BytecodeIntrinsicRegistry.h"
31#include "NodeConstructors.h"
32#include "SyntaxChecker.h"
33#include <utility>
34
35namespace JSC {
36
37class ASTBuilder {
38 struct BinaryOpInfo {
39 BinaryOpInfo() {}
40 BinaryOpInfo(const JSTextPosition& otherStart, const JSTextPosition& otherDivot, const JSTextPosition& otherEnd, bool rhsHasAssignment)
41 : start(otherStart)
42 , divot(otherDivot)
43 , end(otherEnd)
44 , hasAssignment(rhsHasAssignment)
45 {
46 }
47 BinaryOpInfo(const BinaryOpInfo& lhs, const BinaryOpInfo& rhs)
48 : start(lhs.start)
49 , divot(rhs.start)
50 , end(rhs.end)
51 , hasAssignment(lhs.hasAssignment || rhs.hasAssignment)
52 {
53 }
54 JSTextPosition start;
55 JSTextPosition divot;
56 JSTextPosition end;
57 bool hasAssignment;
58 };
59
60
61 struct AssignmentInfo {
62 AssignmentInfo() {}
63 AssignmentInfo(ExpressionNode* node, const JSTextPosition& start, const JSTextPosition& divot, int initAssignments, Operator op)
64 : m_node(node)
65 , m_start(start)
66 , m_divot(divot)
67 , m_initAssignments(initAssignments)
68 , m_op(op)
69 {
70 ASSERT(m_divot.offset >= m_divot.lineStartOffset);
71 ASSERT(m_start.offset >= m_start.lineStartOffset);
72 }
73 ExpressionNode* m_node;
74 JSTextPosition m_start;
75 JSTextPosition m_divot;
76 int m_initAssignments;
77 Operator m_op;
78 };
79public:
80 ASTBuilder(VM* vm, ParserArena& parserArena, SourceCode* sourceCode)
81 : m_vm(vm)
82 , m_parserArena(parserArena)
83 , m_sourceCode(sourceCode)
84 , m_evalCount(0)
85 {
86 }
87
88 struct BinaryExprContext {
89 BinaryExprContext(ASTBuilder&) {}
90 };
91 struct UnaryExprContext {
92 UnaryExprContext(ASTBuilder&) {}
93 };
94
95
96 typedef SyntaxChecker FunctionBodyBuilder;
97
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;
111#endif
112 typedef ParameterNode* FormalParameterList;
113 typedef FunctionBodyNode* FunctionBody;
114#if ENABLE(ES6_CLASS_SYNTAX)
115 typedef ClassExprNode* ClassExpression;
116#endif
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;
131
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);
134
135 JSC::SourceElements* createSourceElements() { return new (m_parserArena) JSC::SourceElements(); }
136
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; }
141
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);
160
161 ExpressionNode* createLogicalNot(const JSTokenLocation& location, ExpressionNode* expr)
162 {
163 if (expr->isNumber())
164 return createBoolean(location, isZeroOrUnordered(static_cast<NumberNode*>(expr)->value()));
165
166 return new (m_parserArena) LogicalNotNode(location, expr);
167 }
168 ExpressionNode* createUnaryPlus(const JSTokenLocation& location, ExpressionNode* expr) { return new (m_parserArena) UnaryPlusNode(location, expr); }
169 ExpressionNode* createVoid(const JSTokenLocation& location, ExpressionNode* expr)
170 {
171 incConstants();
172 return new (m_parserArena) VoidNode(location, expr);
173 }
174 ExpressionNode* thisExpr(const JSTokenLocation& location, ThisTDZMode thisTDZMode)
175 {
176 usesThis();
177 return new (m_parserArena) ThisNode(location, thisTDZMode);
178 }
179 ExpressionNode* superExpr(const JSTokenLocation& location)
180 {
181 return new (m_parserArena) SuperNode(location);
182 }
183 ExpressionNode* createResolve(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start)
184 {
185 if (m_vm->propertyNames->arguments == *ident)
186 usesArguments();
187 return new (m_parserArena) ResolveNode(location, *ident, start);
188 }
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); }
191
192 ExpressionNode* createArray(const JSTokenLocation& location, int elisions)
193 {
194 if (elisions)
195 incConstants();
196 return new (m_parserArena) ArrayNode(location, elisions);
197 }
198
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)
201 {
202 if (elisions)
203 incConstants();
204 return new (m_parserArena) ArrayNode(location, elisions, elems);
205 }
206 ExpressionNode* createDoubleExpr(const JSTokenLocation& location, double d)
207 {
208 incConstants();
209 return new (m_parserArena) DoubleNode(location, d);
210 }
211 ExpressionNode* createIntegerExpr(const JSTokenLocation& location, double d)
212 {
213 incConstants();
214 return new (m_parserArena) IntegerNode(location, d);
215 }
216
217 ExpressionNode* createString(const JSTokenLocation& location, const Identifier* string)
218 {
219 incConstants();
220 return new (m_parserArena) StringNode(location, *string);
221 }
222
223 ExpressionNode* createBoolean(const JSTokenLocation& location, bool b)
224 {
225 incConstants();
226 return new (m_parserArena) BooleanNode(location, b);
227 }
228
229 ExpressionNode* createNull(const JSTokenLocation& location)
230 {
231 incConstants();
232 return new (m_parserArena) NullNode(location);
233 }
234
235 ExpressionNode* createBracketAccess(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
236 {
237 BracketAccessorNode* node = new (m_parserArena) BracketAccessorNode(location, base, property, propertyHasAssignments);
238 setExceptionLocation(node, start, divot, end);
239 return node;
240 }
241
242 ExpressionNode* createDotAccess(const JSTokenLocation& location, ExpressionNode* base, const Identifier* property, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
243 {
244 DotAccessorNode* node = new (m_parserArena) DotAccessorNode(location, base, *property);
245 setExceptionLocation(node, start, divot, end);
246 return node;
247 }
248
249 ExpressionNode* createSpreadExpression(const JSTokenLocation& location, ExpressionNode* expression, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
250 {
251 auto node = new (m_parserArena) SpreadExpressionNode(location, expression);
252 setExceptionLocation(node, start, divot, end);
253 return node;
254 }
255
256#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
257 TemplateStringNode* createTemplateString(const JSTokenLocation& location, const Identifier& cooked, const Identifier& raw)
258 {
259 return new (m_parserArena) TemplateStringNode(location, cooked, raw);
260 }
261
262 TemplateStringListNode* createTemplateStringList(TemplateStringNode* templateString)
263 {
264 return new (m_parserArena) TemplateStringListNode(templateString);
265 }
266
267 TemplateStringListNode* createTemplateStringList(TemplateStringListNode* templateStringList, TemplateStringNode* templateString)
268 {
269 return new (m_parserArena) TemplateStringListNode(templateStringList, templateString);
270 }
271
272 TemplateExpressionListNode* createTemplateExpressionList(ExpressionNode* expression)
273 {
274 return new (m_parserArena) TemplateExpressionListNode(expression);
275 }
276
277 TemplateExpressionListNode* createTemplateExpressionList(TemplateExpressionListNode* templateExpressionListNode, ExpressionNode* expression)
278 {
279 return new (m_parserArena) TemplateExpressionListNode(templateExpressionListNode, expression);
280 }
281
282 TemplateLiteralNode* createTemplateLiteral(const JSTokenLocation& location, TemplateStringListNode* templateStringList)
283 {
284 return new (m_parserArena) TemplateLiteralNode(location, templateStringList);
285 }
286
287 TemplateLiteralNode* createTemplateLiteral(const JSTokenLocation& location, TemplateStringListNode* templateStringList, TemplateExpressionListNode* templateExpressionList)
288 {
289 return new (m_parserArena) TemplateLiteralNode(location, templateStringList, templateExpressionList);
290 }
291
292 ExpressionNode* createTaggedTemplate(const JSTokenLocation& location, ExpressionNode* base, TemplateLiteralNode* templateLiteral, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
293 {
294 auto node = new (m_parserArena) TaggedTemplateNode(location, base, templateLiteral);
295 setExceptionLocation(node, start, divot, end);
296 return node;
297 }
298#endif
299
300 ExpressionNode* createRegExp(const JSTokenLocation& location, const Identifier& pattern, const Identifier& flags, const JSTextPosition& start)
301 {
302 if (Yarr::checkSyntax(pattern.string()))
303 return 0;
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);
308 return node;
309 }
310
311 ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* arguments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
312 {
313 NewExprNode* node = new (m_parserArena) NewExprNode(location, expr, arguments);
314 setExceptionLocation(node, start, divot, end);
315 return node;
316 }
317
318 ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& end)
319 {
320 NewExprNode* node = new (m_parserArena) NewExprNode(location, expr);
321 setExceptionLocation(node, start, end, end);
322 return node;
323 }
324
325 ExpressionNode* createConditionalExpr(const JSTokenLocation& location, ExpressionNode* condition, ExpressionNode* lhs, ExpressionNode* rhs)
326 {
327 return new (m_parserArena) ConditionalNode(location, condition, lhs, rhs);
328 }
329
330 ExpressionNode* createAssignResolve(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* rhs, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
331 {
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);
336 return node;
337 }
338
339#if ENABLE(ES6_CLASS_SYNTAX)
340 ClassExprNode* createClassExpr(const JSTokenLocation& location, const Identifier& name, ExpressionNode* constructor,
341 ExpressionNode* parentClass, PropertyListNode* instanceMethods, PropertyListNode* staticMethods)
342 {
343 return new (m_parserArena) ClassExprNode(location, name, constructor, parentClass, instanceMethods, staticMethods);
344 }
345#endif
346
347 ExpressionNode* createFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& info)
348 {
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);
352 return result;
353 }
354
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)
360 {
361 return new (m_parserArena) FunctionBodyNode(
362 m_parserArena, startLocation, endLocation, startColumn, endColumn,
363 functionKeywordStart, functionNameStart, parametersStart,
364 inStrictContext, constructorKind);
365 }
366
367#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
368 ExpressionNode* createArrowFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& info)
369 {
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);
373
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);
376 return result;
377 }
378#endif
379
380 NEVER_INLINE PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type, bool,
381 const Identifier* name, const ParserFunctionInfo<ASTBuilder>& info, SuperBinding superBinding)
382 {
383 ASSERT(name);
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);
389 }
390
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)
393 {
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);
399 }
400
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); }
405
406 PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding = SuperBinding::NotNeeded)
407 {
408 if (node->isFuncExprNode())
409 static_cast<FuncExprNode*>(node)->body()->setInferredName(*propertyName);
410 return new (m_parserArena) PropertyNode(*propertyName, node, type, putType, superBinding);
411 }
412 PropertyNode* createProperty(VM* vm, ParserArena& parserArena, double propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool)
413 {
414 return new (m_parserArena) PropertyNode(parserArena.identifierArena().makeNumericIdentifier(vm, propertyName), node, type, putType);
415 }
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); }
419
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); }
422
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); }
425
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); }
429
430 StatementNode* createFuncDeclStatement(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& info)
431 {
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)
435 usesArguments();
436 m_scope.m_funcDeclarations.append(decl->body());
437 info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset);
438 return decl;
439 }
440
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)
444 {
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);
449 return decl;
450 }
451#endif
452
453 StatementNode* createBlockStatement(const JSTokenLocation& location, JSC::SourceElements* elements, int startLine, int endLine)
454 {
455 BlockNode* block = new (m_parserArena) BlockNode(location, elements);
456 block->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
457 return block;
458 }
459
460 StatementNode* createExprStatement(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, int end)
461 {
462 ExprStatementNode* result = new (m_parserArena) ExprStatementNode(location, expr);
463 result->setLoc(start.line, end, start.offset, start.lineStartOffset);
464 return result;
465 }
466
467 StatementNode* createIfStatement(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* trueBlock, StatementNode* falseBlock, int start, int end)
468 {
469 IfElseNode* result = new (m_parserArena) IfElseNode(location, condition, trueBlock, falseBlock);
470 result->setLoc(start, end, location.startOffset, location.lineStartOffset);
471 return result;
472 }
473
474 StatementNode* createForLoop(const JSTokenLocation& location, ExpressionNode* initializer, ExpressionNode* condition, ExpressionNode* iter, StatementNode* statements, int start, int end)
475 {
476 ForNode* result = new (m_parserArena) ForNode(location, initializer, condition, iter, statements);
477 result->setLoc(start, end, location.startOffset, location.lineStartOffset);
478 return result;
479 }
480
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)
482 {
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);
486 return result;
487 }
488
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)
490 {
491 auto lexpr = new (m_parserArena) DestructuringAssignmentNode(location, pattern.get(), 0);
492 return createForInLoop(location, lexpr, iter, statements, eStart, eDivot, eEnd, start, end);
493 }
494
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)
496 {
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);
500 return result;
501 }
502
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)
504 {
505 auto lexpr = new (m_parserArena) DestructuringAssignmentNode(location, pattern.get(), 0);
506 return createForOfLoop(location, lexpr, iter, statements, eStart, eDivot, eEnd, start, end);
507 }
508
509 bool isBindingNode(const DestructuringPattern& pattern)
510 {
511 return pattern->isBindingNode();
512 }
513
514 StatementNode* createEmptyStatement(const JSTokenLocation& location) { return new (m_parserArena) EmptyStatementNode(location); }
515
516 StatementNode* createVarStatement(const JSTokenLocation& location, ExpressionNode* expr, int start, int end)
517 {
518 StatementNode* result;
519 result = new (m_parserArena) VarStatementNode(location, expr);
520 result->setLoc(start, end, location.startOffset, location.lineStartOffset);
521 return result;
522 }
523
524 ExpressionNode* createEmptyVarExpression(const JSTokenLocation& location, const Identifier& identifier)
525 {
526 return new (m_parserArena) EmptyVarExpression(location, identifier);
527 }
528
529 StatementNode* createReturnStatement(const JSTokenLocation& location, ExpressionNode* expression, const JSTextPosition& start, const JSTextPosition& end)
530 {
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);
534 return result;
535 }
536
537 StatementNode* createBreakStatement(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end)
538 {
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);
542 return result;
543 }
544
545 StatementNode* createContinueStatement(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end)
546 {
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);
550 return result;
551 }
552
553 StatementNode* createTryStatement(const JSTokenLocation& location, StatementNode* tryBlock, const Identifier* ident, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
554 {
555 TryNode* result = new (m_parserArena) TryNode(location, tryBlock, *ident, catchBlock, finallyBlock);
556 if (catchBlock)
557 usesCatch();
558 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
559 return result;
560 }
561
562 StatementNode* createSwitchStatement(const JSTokenLocation& location, ExpressionNode* expr, ClauseListNode* firstClauses, CaseClauseNode* defaultClause, ClauseListNode* secondClauses, int startLine, int endLine)
563 {
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);
567 return result;
568 }
569
570 StatementNode* createWhileStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, int startLine, int endLine)
571 {
572 WhileNode* result = new (m_parserArena) WhileNode(location, expr, statement);
573 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
574 return result;
575 }
576
577 StatementNode* createDoWhileStatement(const JSTokenLocation& location, StatementNode* statement, ExpressionNode* expr, int startLine, int endLine)
578 {
579 DoWhileNode* result = new (m_parserArena) DoWhileNode(location, statement, expr);
580 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
581 return result;
582 }
583
584 StatementNode* createLabelStatement(const JSTokenLocation& location, const Identifier* ident, StatementNode* statement, const JSTextPosition& start, const JSTextPosition& end)
585 {
586 LabelNode* result = new (m_parserArena) LabelNode(location, *ident, statement);
587 setExceptionLocation(result, start, end, end);
588 return result;
589 }
590
591 StatementNode* createWithStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, unsigned start, const JSTextPosition& end, unsigned startLine, unsigned endLine)
592 {
593 usesWith();
594 WithNode* result = new (m_parserArena) WithNode(location, expr, statement, end, end - start);
595 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
596 return result;
597 }
598
599 StatementNode* createThrowStatement(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& end)
600 {
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);
604 return result;
605 }
606
607 StatementNode* createDebugger(const JSTokenLocation& location, int startLine, int endLine)
608 {
609 DebuggerStatementNode* result = new (m_parserArena) DebuggerStatementNode(location);
610 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
611 return result;
612 }
613
614 StatementNode* createConstStatement(const JSTokenLocation& location, ConstDeclNode* decls, int startLine, int endLine)
615 {
616 ConstStatementNode* result = new (m_parserArena) ConstStatementNode(location, decls);
617 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
618 return result;
619 }
620
621 ConstDeclNode* appendConstDecl(const JSTokenLocation& location, ConstDeclNode* tail, const Identifier* name, ExpressionNode* initializer)
622 {
623 ConstDeclNode* result = new (m_parserArena) ConstDeclNode(location, *name, initializer);
624 if (tail)
625 tail->m_next = result;
626 return result;
627 }
628
629 void appendStatement(JSC::SourceElements* elements, JSC::StatementNode* statement)
630 {
631 elements->append(statement);
632 }
633
634 void addVar(const Identifier* ident, int attrs)
635 {
636 if (m_vm->propertyNames->arguments == *ident)
637 usesArguments();
638 ASSERT(ident->impl()->isAtomic() || ident->impl()->isSymbol());
639 m_scope.m_varDeclarations.append(std::make_pair(*ident, attrs));
640 }
641
642 CommaNode* createCommaExpr(const JSTokenLocation& location, ExpressionNode* node)
643 {
644 return new (m_parserArena) CommaNode(location, node);
645 }
646
647 CommaNode* appendToCommaExpr(const JSTokenLocation& location, ExpressionNode*, ExpressionNode* tail, ExpressionNode* next)
648 {
649 ASSERT(tail->isCommaNode());
650 CommaNode* newTail = new (m_parserArena) CommaNode(location, next);
651 static_cast<CommaNode*>(tail)->setNext(newTail);
652 return newTail;
653 }
654
655 int evalCount() const { return m_evalCount; }
656
657 void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, const JSTextPosition& exprStart, const JSTextPosition& lhs, const JSTextPosition& rhs, bool hasAssignments)
658 {
659 operandStackDepth++;
660 m_binaryOperandStack.append(std::make_pair(current, BinaryOpInfo(exprStart, lhs, rhs, hasAssignments)));
661 }
662
663 // Logic to handle datastructures used during parsing of binary expressions
664 void operatorStackPop(int& operatorStackDepth)
665 {
666 operatorStackDepth--;
667 m_binaryOperatorStack.removeLast();
668 }
669 bool operatorStackHasHigherPrecedence(int&, int precedence)
670 {
671 return precedence <= m_binaryOperatorStack.last().second;
672 }
673 const BinaryOperand& getFromOperandStack(int i) { return m_binaryOperandStack[m_binaryOperandStack.size() + i]; }
674 void shrinkOperandStackBy(int& operandStackDepth, int amount)
675 {
676 operandStackDepth -= amount;
677 ASSERT(operandStackDepth >= 0);
678 m_binaryOperandStack.resize(m_binaryOperandStack.size() - amount);
679 }
680 void appendBinaryOperation(const JSTokenLocation& location, int& operandStackDepth, int&, const BinaryOperand& lhs, const BinaryOperand& rhs)
681 {
682 operandStackDepth++;
683 m_binaryOperandStack.append(std::make_pair(makeBinaryNode(location, m_binaryOperatorStack.last().first, lhs, rhs), BinaryOpInfo(lhs.second, rhs.second)));
684 }
685 void operatorStackAppend(int& operatorStackDepth, int op, int precedence)
686 {
687 operatorStackDepth++;
688 m_binaryOperatorStack.append(std::make_pair(op, precedence));
689 }
690 ExpressionNode* popOperandStack(int&)
691 {
692 ExpressionNode* result = m_binaryOperandStack.last().first;
693 m_binaryOperandStack.removeLast();
694 return result;
695 }
696
697 void appendUnaryToken(int& tokenStackDepth, int type, const JSTextPosition& start)
698 {
699 tokenStackDepth++;
700 m_unaryTokenStack.append(std::make_pair(type, start));
701 }
702
703 int unaryTokenStackLastType(int&)
704 {
705 return m_unaryTokenStack.last().first;
706 }
707
708 const JSTextPosition& unaryTokenStackLastStart(int&)
709 {
710 return m_unaryTokenStack.last().second;
711 }
712
713 void unaryTokenStackRemoveLast(int& tokenStackDepth)
714 {
715 tokenStackDepth--;
716 m_unaryTokenStack.removeLast();
717 }
718
719 void assignmentStackAppend(int& assignmentStackDepth, ExpressionNode* node, const JSTextPosition& start, const JSTextPosition& divot, int assignmentCount, Operator op)
720 {
721 assignmentStackDepth++;
722 ASSERT(start.offset >= start.lineStartOffset);
723 ASSERT(divot.offset >= divot.lineStartOffset);
724 m_assignmentInfoStack.append(AssignmentInfo(node, start, divot, assignmentCount, op));
725 }
726
727 ExpressionNode* createAssignment(const JSTokenLocation& location, int& assignmentStackDepth, ExpressionNode* rhs, int initialAssignmentCount, int currentAssignmentCount, const JSTextPosition& lastTokenEnd)
728 {
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--;
733 return result;
734 }
735
736 const Identifier* getName(const Property& property) const { return property->name(); }
737 PropertyNode::Type getType(const Property& property) const { return property->type(); }
738
739 bool isResolve(ExpressionNode* expr) const { return expr->isResolveNode(); }
740
741 ExpressionNode* createDestructuringAssignment(const JSTokenLocation& location, PassRefPtr<DestructuringPatternNode> pattern, ExpressionNode* initializer)
742 {
743 return new (m_parserArena) DestructuringAssignmentNode(location, pattern.get(), initializer);
744 }
745
746 ArrayPattern createArrayPattern(const JSTokenLocation&)
747 {
748 return ArrayPatternNode::create();
749 }
750
751 void appendArrayPatternSkipEntry(ArrayPattern node, const JSTokenLocation& location)
752 {
753 node->appendIndex(ArrayPatternNode::BindingType::Elision, location, 0, nullptr);
754 }
755
756 void appendArrayPatternEntry(ArrayPattern node, const JSTokenLocation& location, DestructuringPattern pattern, ExpressionNode* defaultValue)
757 {
758 node->appendIndex(ArrayPatternNode::BindingType::Element, location, pattern.get(), defaultValue);
759 }
760
761 void appendArrayPatternRestEntry(ArrayPattern node, const JSTokenLocation& location, DestructuringPattern pattern)
762 {
763 node->appendIndex(ArrayPatternNode::BindingType::RestElement, location, pattern.get(), nullptr);
764 }
765
766 void finishArrayPattern(ArrayPattern node, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd)
767 {
768 setExceptionLocation(node.get(), divotStart, divot, divotEnd);
769 }
770
771 ObjectPattern createObjectPattern(const JSTokenLocation&)
772 {
773 return ObjectPatternNode::create();
774 }
775
776 void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation& location, bool wasString, const Identifier& identifier, DestructuringPattern pattern, ExpressionNode* defaultValue)
777 {
778 node->appendEntry(location, identifier, wasString, pattern.get(), defaultValue);
779 }
780
781 BindingPattern createBindingLocation(const JSTokenLocation&, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end)
782 {
783 return BindingNode::create(boundProperty, start, end);
784 }
785
786 void setEndOffset(Node* node, int offset)
787 {
788 node->setEndOffset(offset);
789 }
790
791 int endOffset(Node* node)
792 {
793 return node->endOffset();
794 }
795
796 void setStartOffset(CaseClauseNode* node, int offset)
797 {
798 node->setStartOffset(offset);
799 }
800
801 void setStartOffset(Node* node, int offset)
802 {
803 node->setStartOffset(offset);
804 }
805
806private:
807 struct Scope {
808 Scope()
809 : m_features(0)
810 , m_numConstants(0)
811 {
812 }
813 DeclarationStacks::VarStack m_varDeclarations;
814 DeclarationStacks::FunctionStack m_funcDeclarations;
815 int m_features;
816 int m_numConstants;
817 };
818
819 static void setExceptionLocation(ThrowableExpressionData* node, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd)
820 {
821 ASSERT(divot.offset >= divot.lineStartOffset);
822 node->setExceptionSourceCode(divot, divotStart, divotEnd);
823 }
824
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; }
830 void usesEval()
831 {
832 m_evalCount++;
833 m_scope.m_features |= EvalFeature;
834 }
835 ExpressionNode* createIntegerLikeNumber(const JSTokenLocation& location, double d)
836 {
837 return new (m_parserArena) IntegerNode(location, d);
838 }
839 ExpressionNode* createDoubleLikeNumber(const JSTokenLocation& location, double d)
840 {
841 return new (m_parserArena) DoubleNode(location, d);
842 }
843 ExpressionNode* createNumberFromBinaryOperation(const JSTokenLocation& location, double value, const NumberNode& originalNodeA, const NumberNode& originalNodeB)
844 {
845 if (originalNodeA.isIntegerNode() && originalNodeB.isIntegerNode())
846 return createIntegerLikeNumber(location, value);
847 return createDoubleLikeNumber(location, value);
848 }
849 ExpressionNode* createNumberFromUnaryOperation(const JSTokenLocation& location, double value, const NumberNode& originalNode)
850 {
851 if (originalNode.isIntegerNode())
852 return createIntegerLikeNumber(location, value);
853 return createDoubleLikeNumber(location, value);
854 }
855
856 VM* m_vm;
857 ParserArena& m_parserArena;
858 SourceCode* m_sourceCode;
859 Scope m_scope;
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;
864 int m_evalCount;
865};
866
867ExpressionNode* ASTBuilder::makeTypeOfNode(const JSTokenLocation& location, ExpressionNode* expr)
868{
869 if (expr->isResolveNode()) {
870 ResolveNode* resolve = static_cast<ResolveNode*>(expr);
871 return new (m_parserArena) TypeOfResolveNode(location, resolve->identifier());
872 }
873 return new (m_parserArena) TypeOfValueNode(location, expr);
874}
875
876ExpressionNode* ASTBuilder::makeDeleteNode(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
877{
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);
883 }
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);
887 }
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);
891}
892
893ExpressionNode* ASTBuilder::makeNegateNode(const JSTokenLocation& location, ExpressionNode* n)
894{
895 if (n->isNumber()) {
896 const NumberNode& numberNode = static_cast<const NumberNode&>(*n);
897 return createNumberFromUnaryOperation(location, -numberNode.value(), numberNode);
898 }
899
900 return new (m_parserArena) NegateNode(location, n);
901}
902
903ExpressionNode* ASTBuilder::makeBitwiseNotNode(const JSTokenLocation& location, ExpressionNode* expr)
904{
905 if (expr->isNumber())
906 return createIntegerLikeNumber(location, ~toInt32(static_cast<NumberNode*>(expr)->value()));
907 return new (m_parserArena) BitwiseNotNode(location, expr);
908}
909
910ExpressionNode* ASTBuilder::makeMultNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
911{
912 expr1 = expr1->stripUnaryPlus();
913 expr2 = expr2->stripUnaryPlus();
914
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);
919 }
920
921 if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1)
922 return new (m_parserArena) UnaryPlusNode(location, expr2);
923
924 if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1)
925 return new (m_parserArena) UnaryPlusNode(location, expr1);
926
927 return new (m_parserArena) MultNode(location, expr1, expr2, rightHasAssignments);
928}
929
930ExpressionNode* ASTBuilder::makeDivNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
931{
932 expr1 = expr1->stripUnaryPlus();
933 expr2 = expr2->stripUnaryPlus();
934
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);
942 }
943 return new (m_parserArena) DivNode(location, expr1, expr2, rightHasAssignments);
944}
945
946ExpressionNode* ASTBuilder::makeModNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
947{
948 expr1 = expr1->stripUnaryPlus();
949 expr2 = expr2->stripUnaryPlus();
950
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()));
955 }
956 return new (m_parserArena) ModNode(location, expr1, expr2, rightHasAssignments);
957}
958
959ExpressionNode* ASTBuilder::makeAddNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
960{
961
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);
966 }
967 return new (m_parserArena) AddNode(location, expr1, expr2, rightHasAssignments);
968}
969
970ExpressionNode* ASTBuilder::makeSubNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
971{
972 expr1 = expr1->stripUnaryPlus();
973 expr2 = expr2->stripUnaryPlus();
974
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);
979 }
980 return new (m_parserArena) SubNode(location, expr1, expr2, rightHasAssignments);
981}
982
983ExpressionNode* ASTBuilder::makeLeftShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
984{
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));
989 }
990 return new (m_parserArena) LeftShiftNode(location, expr1, expr2, rightHasAssignments);
991}
992
993ExpressionNode* ASTBuilder::makeRightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
994{
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));
999 }
1000 return new (m_parserArena) RightShiftNode(location, expr1, expr2, rightHasAssignments);
1001}
1002
1003ExpressionNode* ASTBuilder::makeURightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1004{
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));
1009 }
1010 return new (m_parserArena) UnsignedRightShiftNode(location, expr1, expr2, rightHasAssignments);
1011}
1012
1013ExpressionNode* ASTBuilder::makeBitOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1014{
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()));
1019 }
1020 return new (m_parserArena) BitOrNode(location, expr1, expr2, rightHasAssignments);
1021}
1022
1023ExpressionNode* ASTBuilder::makeBitAndNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1024{
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()));
1029 }
1030 return new (m_parserArena) BitAndNode(location, expr1, expr2, rightHasAssignments);
1031}
1032
1033ExpressionNode* ASTBuilder::makeBitXOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1034{
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()));
1039 }
1040 return new (m_parserArena) BitXOrNode(location, expr1, expr2, rightHasAssignments);
1041}
1042
1043ExpressionNode* ASTBuilder::makeFunctionCallNode(const JSTokenLocation& location, ExpressionNode* func, ArgumentsNode* args, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd)
1044{
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) {
1052 usesEval();
1053 return new (m_parserArena) EvalFunctionCallNode(location, args, divot, divotStart, divotEnd);
1054 }
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);
1058 }
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);
1063 return node;
1064 }
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);
1072 else
1073 node = new (m_parserArena) FunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
1074 node->setSubexpressionInfo(dot->divot(), dot->divotEnd().offset);
1075 return node;
1076}
1077
1078ExpressionNode* ASTBuilder::makeBinaryNode(const JSTokenLocation& location, int token, std::pair<ExpressionNode*, BinaryOpInfo> lhs, std::pair<ExpressionNode*, BinaryOpInfo> rhs)
1079{
1080 switch (token) {
1081 case OR:
1082 return new (m_parserArena) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalOr);
1083
1084 case AND:
1085 return new (m_parserArena) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalAnd);
1086
1087 case BITOR:
1088 return makeBitOrNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1089
1090 case BITXOR:
1091 return makeBitXOrNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1092
1093 case BITAND:
1094 return makeBitAndNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1095
1096 case EQEQ:
1097 return new (m_parserArena) EqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1098
1099 case NE:
1100 return new (m_parserArena) NotEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1101
1102 case STREQ:
1103 return new (m_parserArena) StrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1104
1105 case STRNEQ:
1106 return new (m_parserArena) NotStrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1107
1108 case LT:
1109 return new (m_parserArena) LessNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1110
1111 case GT:
1112 return new (m_parserArena) GreaterNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1113
1114 case LE:
1115 return new (m_parserArena) LessEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1116
1117 case GE:
1118 return new (m_parserArena) GreaterEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1119
1120 case INSTANCEOF: {
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);
1123 return node;
1124 }
1125
1126 case INTOKEN: {
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);
1129 return node;
1130 }
1131
1132 case LSHIFT:
1133 return makeLeftShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1134
1135 case RSHIFT:
1136 return makeRightShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1137
1138 case URSHIFT:
1139 return makeURightShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1140
1141 case PLUS:
1142 return makeAddNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1143
1144 case MINUS:
1145 return makeSubNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1146
1147 case TIMES:
1148 return makeMultNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1149
1150 case DIVIDE:
1151 return makeDivNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1152
1153 case MOD:
1154 return makeModNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1155 }
1156 CRASH();
1157 return 0;
1158}
1159
1160ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
1161{
1162 if (!loc->isLocation())
1163 return new (m_parserArena) AssignErrorNode(location, divot, start, end);
1164
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);
1172 return node;
1173 }
1174 return new (m_parserArena) ReadModifyResolveNode(location, resolve->identifier(), op, expr, exprHasAssignments, divot, start, end);
1175 }
1176 if (loc->isBracketAccessorNode()) {
1177 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc);
1178 if (op == OpEqual)
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);
1182 return node;
1183 }
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);
1190 }
1191
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);
1194 return node;
1195}
1196
1197ExpressionNode* ASTBuilder::makePrefixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
1198{
1199 return new (m_parserArena) PrefixNode(location, expr, op, divot, start, end);
1200}
1201
1202ExpressionNode* ASTBuilder::makePostfixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
1203{
1204 return new (m_parserArena) PostfixNode(location, expr, op, divot, start, end);
1205}
1206
1207}
1208
1209#endif