]> git.saurik.com Git - apple/javascriptcore.git/blame - parser/ASTBuilder.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / parser / ASTBuilder.h
CommitLineData
14957cd0 1/*
93a37866 2 * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
14957cd0
A
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
81345200 29#include "BuiltinNames.h"
ed1e77d3 30#include "BytecodeIntrinsicRegistry.h"
14957cd0
A
31#include "NodeConstructors.h"
32#include "SyntaxChecker.h"
33#include <utility>
34
35namespace JSC {
36
37class ASTBuilder {
38 struct BinaryOpInfo {
39 BinaryOpInfo() {}
81345200 40 BinaryOpInfo(const JSTextPosition& otherStart, const JSTextPosition& otherDivot, const JSTextPosition& otherEnd, bool rhsHasAssignment)
93a37866
A
41 : start(otherStart)
42 , divot(otherDivot)
43 , end(otherEnd)
93a37866 44 , hasAssignment(rhsHasAssignment)
14957cd0
A
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 }
81345200
A
54 JSTextPosition start;
55 JSTextPosition divot;
56 JSTextPosition end;
14957cd0
A
57 bool hasAssignment;
58 };
59
60
61 struct AssignmentInfo {
62 AssignmentInfo() {}
81345200 63 AssignmentInfo(ExpressionNode* node, const JSTextPosition& start, const JSTextPosition& divot, int initAssignments, Operator op)
14957cd0
A
64 : m_node(node)
65 , m_start(start)
66 , m_divot(divot)
67 , m_initAssignments(initAssignments)
68 , m_op(op)
69 {
81345200
A
70 ASSERT(m_divot.offset >= m_divot.lineStartOffset);
71 ASSERT(m_start.offset >= m_start.lineStartOffset);
14957cd0
A
72 }
73 ExpressionNode* m_node;
81345200
A
74 JSTextPosition m_start;
75 JSTextPosition m_divot;
14957cd0
A
76 int m_initAssignments;
77 Operator m_op;
78 };
79public:
ed1e77d3 80 ASTBuilder(VM* vm, ParserArena& parserArena, SourceCode* sourceCode)
93a37866 81 : m_vm(vm)
ed1e77d3 82 , m_parserArena(parserArena)
6fe7ccc8 83 , m_sourceCode(sourceCode)
14957cd0
A
84 , m_evalCount(0)
85 {
86 }
87
88 struct BinaryExprContext {
89 BinaryExprContext(ASTBuilder&) {}
90 };
91 struct UnaryExprContext {
92 UnaryExprContext(ASTBuilder&) {}
93 };
94
81345200 95
14957cd0
A
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;
ed1e77d3
A
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
14957cd0
A
112 typedef ParameterNode* FormalParameterList;
113 typedef FunctionBodyNode* FunctionBody;
ed1e77d3
A
114#if ENABLE(ES6_CLASS_SYNTAX)
115 typedef ClassExprNode* ClassExpression;
116#endif
14957cd0
A
117 typedef StatementNode* Statement;
118 typedef ClauseListNode* ClauseList;
119 typedef CaseClauseNode* Clause;
120 typedef ConstDeclNode* ConstDeclList;
121 typedef std::pair<ExpressionNode*, BinaryOpInfo> BinaryOperand;
ed1e77d3 122 typedef RefPtr<DestructuringPatternNode> DestructuringPattern;
81345200
A
123 typedef RefPtr<ArrayPatternNode> ArrayPattern;
124 typedef RefPtr<ObjectPatternNode> ObjectPattern;
125 typedef RefPtr<BindingNode> BindingPattern;
14957cd0
A
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
93a37866 132 ExpressionNode* makeBinaryNode(const JSTokenLocation&, int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>);
81345200 133 ExpressionNode* makeFunctionCallNode(const JSTokenLocation&, ExpressionNode* func, ArgumentsNode* args, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd);
14957cd0 134
ed1e77d3 135 JSC::SourceElements* createSourceElements() { return new (m_parserArena) JSC::SourceElements(); }
14957cd0 136
ed1e77d3
A
137 DeclarationStacks::VarStack& varDeclarations() { return m_scope.m_varDeclarations; }
138 DeclarationStacks::FunctionStack& funcDeclarations() { return m_scope.m_funcDeclarations; }
14957cd0
A
139 int features() const { return m_scope.m_features; }
140 int numConstants() const { return m_scope.m_numConstants; }
141
81345200
A
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);
93a37866 145 ExpressionNode* makeTypeOfNode(const JSTokenLocation&, ExpressionNode*);
81345200 146 ExpressionNode* makeDeleteNode(const JSTokenLocation&, ExpressionNode*, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end);
93a37866
A
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
ed1e77d3 166 return new (m_parserArena) LogicalNotNode(location, expr);
93a37866 167 }
ed1e77d3 168 ExpressionNode* createUnaryPlus(const JSTokenLocation& location, ExpressionNode* expr) { return new (m_parserArena) UnaryPlusNode(location, expr); }
93a37866 169 ExpressionNode* createVoid(const JSTokenLocation& location, ExpressionNode* expr)
14957cd0
A
170 {
171 incConstants();
ed1e77d3 172 return new (m_parserArena) VoidNode(location, expr);
14957cd0 173 }
ed1e77d3 174 ExpressionNode* thisExpr(const JSTokenLocation& location, ThisTDZMode thisTDZMode)
14957cd0
A
175 {
176 usesThis();
ed1e77d3
A
177 return new (m_parserArena) ThisNode(location, thisTDZMode);
178 }
179 ExpressionNode* superExpr(const JSTokenLocation& location)
180 {
181 return new (m_parserArena) SuperNode(location);
14957cd0 182 }
81345200 183 ExpressionNode* createResolve(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start)
14957cd0 184 {
93a37866 185 if (m_vm->propertyNames->arguments == *ident)
14957cd0 186 usesArguments();
ed1e77d3 187 return new (m_parserArena) ResolveNode(location, *ident, start);
14957cd0 188 }
ed1e77d3
A
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); }
14957cd0 191
93a37866 192 ExpressionNode* createArray(const JSTokenLocation& location, int elisions)
14957cd0
A
193 {
194 if (elisions)
195 incConstants();
ed1e77d3 196 return new (m_parserArena) ArrayNode(location, elisions);
14957cd0
A
197 }
198
ed1e77d3 199 ExpressionNode* createArray(const JSTokenLocation& location, ElementNode* elems) { return new (m_parserArena) ArrayNode(location, elems); }
93a37866 200 ExpressionNode* createArray(const JSTokenLocation& location, int elisions, ElementNode* elems)
14957cd0
A
201 {
202 if (elisions)
203 incConstants();
ed1e77d3 204 return new (m_parserArena) ArrayNode(location, elisions, elems);
14957cd0 205 }
ed1e77d3 206 ExpressionNode* createDoubleExpr(const JSTokenLocation& location, double d)
14957cd0
A
207 {
208 incConstants();
ed1e77d3
A
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);
14957cd0
A
215 }
216
93a37866 217 ExpressionNode* createString(const JSTokenLocation& location, const Identifier* string)
14957cd0
A
218 {
219 incConstants();
ed1e77d3 220 return new (m_parserArena) StringNode(location, *string);
14957cd0
A
221 }
222
93a37866 223 ExpressionNode* createBoolean(const JSTokenLocation& location, bool b)
14957cd0
A
224 {
225 incConstants();
ed1e77d3 226 return new (m_parserArena) BooleanNode(location, b);
14957cd0
A
227 }
228
93a37866 229 ExpressionNode* createNull(const JSTokenLocation& location)
14957cd0
A
230 {
231 incConstants();
ed1e77d3 232 return new (m_parserArena) NullNode(location);
14957cd0
A
233 }
234
81345200 235 ExpressionNode* createBracketAccess(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
14957cd0 236 {
ed1e77d3 237 BracketAccessorNode* node = new (m_parserArena) BracketAccessorNode(location, base, property, propertyHasAssignments);
81345200 238 setExceptionLocation(node, start, divot, end);
14957cd0
A
239 return node;
240 }
241
81345200 242 ExpressionNode* createDotAccess(const JSTokenLocation& location, ExpressionNode* base, const Identifier* property, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
14957cd0 243 {
ed1e77d3 244 DotAccessorNode* node = new (m_parserArena) DotAccessorNode(location, base, *property);
81345200
A
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 {
ed1e77d3
A
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);
81345200 295 setExceptionLocation(node, start, divot, end);
14957cd0
A
296 return node;
297 }
ed1e77d3 298#endif
14957cd0 299
81345200 300 ExpressionNode* createRegExp(const JSTokenLocation& location, const Identifier& pattern, const Identifier& flags, const JSTextPosition& start)
14957cd0 301 {
93a37866 302 if (Yarr::checkSyntax(pattern.string()))
14957cd0 303 return 0;
ed1e77d3 304 RegExpNode* node = new (m_parserArena) RegExpNode(location, pattern, flags);
14957cd0 305 int size = pattern.length() + 2; // + 2 for the two /'s
81345200
A
306 JSTextPosition end = start + size;
307 setExceptionLocation(node, start, end, end);
14957cd0
A
308 return node;
309 }
310
81345200 311 ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* arguments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
14957cd0 312 {
ed1e77d3 313 NewExprNode* node = new (m_parserArena) NewExprNode(location, expr, arguments);
81345200 314 setExceptionLocation(node, start, divot, end);
14957cd0
A
315 return node;
316 }
317
81345200 318 ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& end)
14957cd0 319 {
ed1e77d3 320 NewExprNode* node = new (m_parserArena) NewExprNode(location, expr);
81345200 321 setExceptionLocation(node, start, end, end);
14957cd0
A
322 return node;
323 }
324
93a37866 325 ExpressionNode* createConditionalExpr(const JSTokenLocation& location, ExpressionNode* condition, ExpressionNode* lhs, ExpressionNode* rhs)
14957cd0 326 {
ed1e77d3 327 return new (m_parserArena) ConditionalNode(location, condition, lhs, rhs);
14957cd0
A
328 }
329
81345200 330 ExpressionNode* createAssignResolve(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* rhs, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
14957cd0 331 {
6fe7ccc8
A
332 if (rhs->isFuncExprNode())
333 static_cast<FuncExprNode*>(rhs)->body()->setInferredName(ident);
ed1e77d3 334 AssignResolveNode* node = new (m_parserArena) AssignResolveNode(location, ident, rhs);
81345200 335 setExceptionLocation(node, start, divot, end);
14957cd0
A
336 return node;
337 }
338
ed1e77d3
A
339#if ENABLE(ES6_CLASS_SYNTAX)
340 ClassExprNode* createClassExpr(const JSTokenLocation& location, const Identifier& name, ExpressionNode* constructor,
341 ExpressionNode* parentClass, PropertyListNode* instanceMethods, PropertyListNode* staticMethods)
14957cd0 342 {
ed1e77d3
A
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);
14957cd0
A
352 return result;
353 }
354
ed1e77d3
A
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)
93a37866 360 {
ed1e77d3
A
361 return new (m_parserArena) FunctionBodyNode(
362 m_parserArena, startLocation, endLocation, startColumn, endColumn,
363 functionKeywordStart, functionNameStart, parametersStart,
364 inStrictContext, constructorKind);
93a37866
A
365 }
366
ed1e77d3
A
367#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
368 ExpressionNode* createArrowFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& info)
14957cd0 369 {
ed1e77d3
A
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;
14957cd0 377 }
ed1e77d3
A
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)
14957cd0
A
382 {
383 ASSERT(name);
ed1e77d3
A
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);
14957cd0
A
389 }
390
ed1e77d3
A
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)
6fe7ccc8 393 {
ed1e77d3
A
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);
6fe7ccc8 399 }
14957cd0 400
ed1e77d3
A
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); }
14957cd0 405
ed1e77d3 406 PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding = SuperBinding::NotNeeded)
6fe7ccc8
A
407 {
408 if (node->isFuncExprNode())
409 static_cast<FuncExprNode*>(node)->body()->setInferredName(*propertyName);
ed1e77d3 410 return new (m_parserArena) PropertyNode(*propertyName, node, type, putType, superBinding);
6fe7ccc8 411 }
ed1e77d3
A
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); }
14957cd0 419
ed1e77d3
A
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); }
14957cd0 422
ed1e77d3
A
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); }
14957cd0 425
ed1e77d3
A
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); }
14957cd0 429
ed1e77d3 430 StatementNode* createFuncDeclStatement(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& info)
14957cd0 431 {
ed1e77d3
A
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)
14957cd0 435 usesArguments();
ed1e77d3
A
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);
14957cd0
A
449 return decl;
450 }
ed1e77d3 451#endif
14957cd0 452
93a37866 453 StatementNode* createBlockStatement(const JSTokenLocation& location, JSC::SourceElements* elements, int startLine, int endLine)
14957cd0 454 {
ed1e77d3 455 BlockNode* block = new (m_parserArena) BlockNode(location, elements);
93a37866 456 block->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
14957cd0
A
457 return block;
458 }
459
81345200 460 StatementNode* createExprStatement(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, int end)
14957cd0 461 {
ed1e77d3 462 ExprStatementNode* result = new (m_parserArena) ExprStatementNode(location, expr);
81345200 463 result->setLoc(start.line, end, start.offset, start.lineStartOffset);
14957cd0
A
464 return result;
465 }
466
93a37866 467 StatementNode* createIfStatement(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* trueBlock, StatementNode* falseBlock, int start, int end)
14957cd0 468 {
ed1e77d3 469 IfElseNode* result = new (m_parserArena) IfElseNode(location, condition, trueBlock, falseBlock);
93a37866 470 result->setLoc(start, end, location.startOffset, location.lineStartOffset);
14957cd0
A
471 return result;
472 }
473
93a37866 474 StatementNode* createForLoop(const JSTokenLocation& location, ExpressionNode* initializer, ExpressionNode* condition, ExpressionNode* iter, StatementNode* statements, int start, int end)
14957cd0 475 {
ed1e77d3 476 ForNode* result = new (m_parserArena) ForNode(location, initializer, condition, iter, statements);
93a37866 477 result->setLoc(start, end, location.startOffset, location.lineStartOffset);
14957cd0
A
478 return result;
479 }
480
81345200 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)
14957cd0 482 {
ed1e77d3 483 ForInNode* result = new (m_parserArena) ForInNode(location, lhs, iter, statements);
81345200
A
484 result->setLoc(start, end, location.startOffset, location.lineStartOffset);
485 setExceptionLocation(result, eStart, eDivot, eEnd);
14957cd0
A
486 return result;
487 }
81345200 488
ed1e77d3 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)
14957cd0 490 {
ed1e77d3
A
491 auto lexpr = new (m_parserArena) DestructuringAssignmentNode(location, pattern.get(), 0);
492 return createForInLoop(location, lexpr, iter, statements, eStart, eDivot, eEnd, start, end);
81345200
A
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 {
ed1e77d3 497 ForOfNode* result = new (m_parserArena) ForOfNode(location, lhs, iter, statements);
81345200
A
498 result->setLoc(start, end, location.startOffset, location.lineStartOffset);
499 setExceptionLocation(result, eStart, eDivot, eEnd);
500 return result;
501 }
502
ed1e77d3 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)
81345200 504 {
ed1e77d3
A
505 auto lexpr = new (m_parserArena) DestructuringAssignmentNode(location, pattern.get(), 0);
506 return createForOfLoop(location, lexpr, iter, statements, eStart, eDivot, eEnd, start, end);
14957cd0
A
507 }
508
ed1e77d3 509 bool isBindingNode(const DestructuringPattern& pattern)
81345200
A
510 {
511 return pattern->isBindingNode();
512 }
513
ed1e77d3 514 StatementNode* createEmptyStatement(const JSTokenLocation& location) { return new (m_parserArena) EmptyStatementNode(location); }
14957cd0 515
93a37866 516 StatementNode* createVarStatement(const JSTokenLocation& location, ExpressionNode* expr, int start, int end)
14957cd0
A
517 {
518 StatementNode* result;
ed1e77d3 519 result = new (m_parserArena) VarStatementNode(location, expr);
93a37866 520 result->setLoc(start, end, location.startOffset, location.lineStartOffset);
14957cd0
A
521 return result;
522 }
523
ed1e77d3 524 ExpressionNode* createEmptyVarExpression(const JSTokenLocation& location, const Identifier& identifier)
14957cd0 525 {
ed1e77d3 526 return new (m_parserArena) EmptyVarExpression(location, identifier);
14957cd0
A
527 }
528
ed1e77d3 529 StatementNode* createReturnStatement(const JSTokenLocation& location, ExpressionNode* expression, const JSTextPosition& start, const JSTextPosition& end)
14957cd0 530 {
ed1e77d3 531 ReturnNode* result = new (m_parserArena) ReturnNode(location, expression);
81345200
A
532 setExceptionLocation(result, start, end, end);
533 result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
14957cd0
A
534 return result;
535 }
536
81345200 537 StatementNode* createBreakStatement(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end)
14957cd0 538 {
ed1e77d3 539 BreakNode* result = new (m_parserArena) BreakNode(location, *ident);
81345200
A
540 setExceptionLocation(result, start, end, end);
541 result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
14957cd0
A
542 return result;
543 }
544
81345200 545 StatementNode* createContinueStatement(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end)
14957cd0 546 {
ed1e77d3 547 ContinueNode* result = new (m_parserArena) ContinueNode(location, *ident);
81345200
A
548 setExceptionLocation(result, start, end, end);
549 result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
14957cd0
A
550 return result;
551 }
552
93a37866 553 StatementNode* createTryStatement(const JSTokenLocation& location, StatementNode* tryBlock, const Identifier* ident, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
14957cd0 554 {
ed1e77d3 555 TryNode* result = new (m_parserArena) TryNode(location, tryBlock, *ident, catchBlock, finallyBlock);
14957cd0
A
556 if (catchBlock)
557 usesCatch();
93a37866 558 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
14957cd0
A
559 return result;
560 }
561
93a37866 562 StatementNode* createSwitchStatement(const JSTokenLocation& location, ExpressionNode* expr, ClauseListNode* firstClauses, CaseClauseNode* defaultClause, ClauseListNode* secondClauses, int startLine, int endLine)
14957cd0 563 {
ed1e77d3
A
564 CaseBlockNode* cases = new (m_parserArena) CaseBlockNode(firstClauses, defaultClause, secondClauses);
565 SwitchNode* result = new (m_parserArena) SwitchNode(location, expr, cases);
93a37866 566 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
14957cd0
A
567 return result;
568 }
569
93a37866 570 StatementNode* createWhileStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, int startLine, int endLine)
14957cd0 571 {
ed1e77d3 572 WhileNode* result = new (m_parserArena) WhileNode(location, expr, statement);
93a37866 573 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
14957cd0
A
574 return result;
575 }
576
93a37866 577 StatementNode* createDoWhileStatement(const JSTokenLocation& location, StatementNode* statement, ExpressionNode* expr, int startLine, int endLine)
14957cd0 578 {
ed1e77d3 579 DoWhileNode* result = new (m_parserArena) DoWhileNode(location, statement, expr);
93a37866 580 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
14957cd0
A
581 return result;
582 }
583
81345200 584 StatementNode* createLabelStatement(const JSTokenLocation& location, const Identifier* ident, StatementNode* statement, const JSTextPosition& start, const JSTextPosition& end)
14957cd0 585 {
ed1e77d3 586 LabelNode* result = new (m_parserArena) LabelNode(location, *ident, statement);
81345200 587 setExceptionLocation(result, start, end, end);
14957cd0
A
588 return result;
589 }
590
81345200 591 StatementNode* createWithStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, unsigned start, const JSTextPosition& end, unsigned startLine, unsigned endLine)
14957cd0
A
592 {
593 usesWith();
ed1e77d3 594 WithNode* result = new (m_parserArena) WithNode(location, expr, statement, end, end - start);
93a37866 595 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
14957cd0
A
596 return result;
597 }
598
81345200 599 StatementNode* createThrowStatement(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& end)
14957cd0 600 {
ed1e77d3 601 ThrowNode* result = new (m_parserArena) ThrowNode(location, expr);
81345200
A
602 result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
603 setExceptionLocation(result, start, end, end);
14957cd0
A
604 return result;
605 }
606
93a37866 607 StatementNode* createDebugger(const JSTokenLocation& location, int startLine, int endLine)
14957cd0 608 {
ed1e77d3 609 DebuggerStatementNode* result = new (m_parserArena) DebuggerStatementNode(location);
93a37866 610 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
14957cd0
A
611 return result;
612 }
613
93a37866 614 StatementNode* createConstStatement(const JSTokenLocation& location, ConstDeclNode* decls, int startLine, int endLine)
14957cd0 615 {
ed1e77d3 616 ConstStatementNode* result = new (m_parserArena) ConstStatementNode(location, decls);
93a37866 617 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
14957cd0
A
618 return result;
619 }
620
93a37866 621 ConstDeclNode* appendConstDecl(const JSTokenLocation& location, ConstDeclNode* tail, const Identifier* name, ExpressionNode* initializer)
14957cd0 622 {
ed1e77d3 623 ConstDeclNode* result = new (m_parserArena) ConstDeclNode(location, *name, initializer);
14957cd0
A
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 {
93a37866 636 if (m_vm->propertyNames->arguments == *ident)
14957cd0 637 usesArguments();
ed1e77d3
A
638 ASSERT(ident->impl()->isAtomic() || ident->impl()->isSymbol());
639 m_scope.m_varDeclarations.append(std::make_pair(*ident, attrs));
14957cd0
A
640 }
641
ed1e77d3 642 CommaNode* createCommaExpr(const JSTokenLocation& location, ExpressionNode* node)
14957cd0 643 {
ed1e77d3
A
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;
14957cd0
A
653 }
654
655 int evalCount() const { return m_evalCount; }
656
81345200 657 void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, const JSTextPosition& exprStart, const JSTextPosition& lhs, const JSTextPosition& rhs, bool hasAssignments)
14957cd0
A
658 {
659 operandStackDepth++;
81345200 660 m_binaryOperandStack.append(std::make_pair(current, BinaryOpInfo(exprStart, lhs, rhs, hasAssignments)));
14957cd0
A
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 }
93a37866 680 void appendBinaryOperation(const JSTokenLocation& location, int& operandStackDepth, int&, const BinaryOperand& lhs, const BinaryOperand& rhs)
14957cd0
A
681 {
682 operandStackDepth++;
93a37866 683 m_binaryOperandStack.append(std::make_pair(makeBinaryNode(location, m_binaryOperatorStack.last().first, lhs, rhs), BinaryOpInfo(lhs.second, rhs.second)));
14957cd0
A
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
81345200 697 void appendUnaryToken(int& tokenStackDepth, int type, const JSTextPosition& start)
14957cd0
A
698 {
699 tokenStackDepth++;
81345200 700 m_unaryTokenStack.append(std::make_pair(type, start));
14957cd0
A
701 }
702
703 int unaryTokenStackLastType(int&)
704 {
705 return m_unaryTokenStack.last().first;
706 }
707
81345200 708 const JSTextPosition& unaryTokenStackLastStart(int&)
14957cd0 709 {
81345200 710 return m_unaryTokenStack.last().second;
14957cd0
A
711 }
712
713 void unaryTokenStackRemoveLast(int& tokenStackDepth)
714 {
715 tokenStackDepth--;
716 m_unaryTokenStack.removeLast();
717 }
718
81345200 719 void assignmentStackAppend(int& assignmentStackDepth, ExpressionNode* node, const JSTextPosition& start, const JSTextPosition& divot, int assignmentCount, Operator op)
14957cd0
A
720 {
721 assignmentStackDepth++;
81345200
A
722 ASSERT(start.offset >= start.lineStartOffset);
723 ASSERT(divot.offset >= divot.lineStartOffset);
724 m_assignmentInfoStack.append(AssignmentInfo(node, start, divot, assignmentCount, op));
14957cd0
A
725 }
726
81345200 727 ExpressionNode* createAssignment(const JSTokenLocation& location, int& assignmentStackDepth, ExpressionNode* rhs, int initialAssignmentCount, int currentAssignmentCount, const JSTextPosition& lastTokenEnd)
14957cd0 728 {
93a37866 729 AssignmentInfo& info = m_assignmentInfoStack.last();
81345200 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);
14957cd0
A
731 m_assignmentInfoStack.removeLast();
732 assignmentStackDepth--;
733 return result;
734 }
ed1e77d3
A
735
736 const Identifier* getName(const Property& property) const { return property->name(); }
737 PropertyNode::Type getType(const Property& property) const { return property->type(); }
14957cd0
A
738
739 bool isResolve(ExpressionNode* expr) const { return expr->isResolveNode(); }
740
ed1e77d3 741 ExpressionNode* createDestructuringAssignment(const JSTokenLocation& location, PassRefPtr<DestructuringPatternNode> pattern, ExpressionNode* initializer)
81345200 742 {
ed1e77d3 743 return new (m_parserArena) DestructuringAssignmentNode(location, pattern.get(), initializer);
81345200
A
744 }
745
746 ArrayPattern createArrayPattern(const JSTokenLocation&)
747 {
ed1e77d3 748 return ArrayPatternNode::create();
81345200
A
749 }
750
751 void appendArrayPatternSkipEntry(ArrayPattern node, const JSTokenLocation& location)
752 {
ed1e77d3
A
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);
81345200
A
764 }
765
ed1e77d3 766 void finishArrayPattern(ArrayPattern node, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd)
81345200 767 {
ed1e77d3 768 setExceptionLocation(node.get(), divotStart, divot, divotEnd);
81345200
A
769 }
770
771 ObjectPattern createObjectPattern(const JSTokenLocation&)
772 {
ed1e77d3 773 return ObjectPatternNode::create();
81345200
A
774 }
775
ed1e77d3 776 void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation& location, bool wasString, const Identifier& identifier, DestructuringPattern pattern, ExpressionNode* defaultValue)
81345200 777 {
ed1e77d3 778 node->appendEntry(location, identifier, wasString, pattern.get(), defaultValue);
81345200
A
779 }
780
781 BindingPattern createBindingLocation(const JSTokenLocation&, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end)
782 {
ed1e77d3
A
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);
81345200
A
804 }
805
14957cd0
A
806private:
807 struct Scope {
ed1e77d3
A
808 Scope()
809 : m_features(0)
14957cd0
A
810 , m_numConstants(0)
811 {
812 }
ed1e77d3
A
813 DeclarationStacks::VarStack m_varDeclarations;
814 DeclarationStacks::FunctionStack m_funcDeclarations;
14957cd0
A
815 int m_features;
816 int m_numConstants;
817 };
818
81345200 819 static void setExceptionLocation(ThrowableExpressionData* node, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd)
14957cd0 820 {
81345200
A
821 ASSERT(divot.offset >= divot.lineStartOffset);
822 node->setExceptionSourceCode(divot, divotStart, divotEnd);
14957cd0
A
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; }
14957cd0 828 void usesArguments() { m_scope.m_features |= ArgumentsFeature; }
14957cd0
A
829 void usesWith() { m_scope.m_features |= WithFeature; }
830 void usesEval()
831 {
832 m_evalCount++;
833 m_scope.m_features |= EvalFeature;
834 }
ed1e77d3 835 ExpressionNode* createIntegerLikeNumber(const JSTokenLocation& location, double d)
14957cd0 836 {
ed1e77d3 837 return new (m_parserArena) IntegerNode(location, d);
14957cd0 838 }
ed1e77d3
A
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
93a37866 856 VM* m_vm;
ed1e77d3 857 ParserArena& m_parserArena;
6fe7ccc8 858 SourceCode* m_sourceCode;
14957cd0 859 Scope m_scope;
93a37866
A
860 Vector<BinaryOperand, 10, UnsafeVectorOverflow> m_binaryOperandStack;
861 Vector<AssignmentInfo, 10, UnsafeVectorOverflow> m_assignmentInfoStack;
81345200
A
862 Vector<std::pair<int, int>, 10, UnsafeVectorOverflow> m_binaryOperatorStack;
863 Vector<std::pair<int, JSTextPosition>, 10, UnsafeVectorOverflow> m_unaryTokenStack;
14957cd0
A
864 int m_evalCount;
865};
866
93a37866 867ExpressionNode* ASTBuilder::makeTypeOfNode(const JSTokenLocation& location, ExpressionNode* expr)
14957cd0
A
868{
869 if (expr->isResolveNode()) {
870 ResolveNode* resolve = static_cast<ResolveNode*>(expr);
ed1e77d3 871 return new (m_parserArena) TypeOfResolveNode(location, resolve->identifier());
14957cd0 872 }
ed1e77d3 873 return new (m_parserArena) TypeOfValueNode(location, expr);
14957cd0
A
874}
875
81345200 876ExpressionNode* ASTBuilder::makeDeleteNode(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
14957cd0
A
877{
878 if (!expr->isLocation())
ed1e77d3 879 return new (m_parserArena) DeleteValueNode(location, expr);
14957cd0
A
880 if (expr->isResolveNode()) {
881 ResolveNode* resolve = static_cast<ResolveNode*>(expr);
ed1e77d3 882 return new (m_parserArena) DeleteResolveNode(location, resolve->identifier(), divot, start, end);
14957cd0
A
883 }
884 if (expr->isBracketAccessorNode()) {
885 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
ed1e77d3 886 return new (m_parserArena) DeleteBracketNode(location, bracket->base(), bracket->subscript(), divot, start, end);
14957cd0
A
887 }
888 ASSERT(expr->isDotAccessorNode());
889 DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
ed1e77d3 890 return new (m_parserArena) DeleteDotNode(location, dot->base(), dot->identifier(), divot, start, end);
14957cd0
A
891}
892
93a37866 893ExpressionNode* ASTBuilder::makeNegateNode(const JSTokenLocation& location, ExpressionNode* n)
14957cd0
A
894{
895 if (n->isNumber()) {
ed1e77d3
A
896 const NumberNode& numberNode = static_cast<const NumberNode&>(*n);
897 return createNumberFromUnaryOperation(location, -numberNode.value(), numberNode);
14957cd0
A
898 }
899
ed1e77d3 900 return new (m_parserArena) NegateNode(location, n);
14957cd0
A
901}
902
93a37866 903ExpressionNode* ASTBuilder::makeBitwiseNotNode(const JSTokenLocation& location, ExpressionNode* expr)
14957cd0
A
904{
905 if (expr->isNumber())
ed1e77d3
A
906 return createIntegerLikeNumber(location, ~toInt32(static_cast<NumberNode*>(expr)->value()));
907 return new (m_parserArena) BitwiseNotNode(location, expr);
14957cd0
A
908}
909
93a37866 910ExpressionNode* ASTBuilder::makeMultNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
14957cd0
A
911{
912 expr1 = expr1->stripUnaryPlus();
913 expr2 = expr2->stripUnaryPlus();
914
ed1e77d3
A
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 }
14957cd0
A
920
921 if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1)
ed1e77d3 922 return new (m_parserArena) UnaryPlusNode(location, expr2);
14957cd0
A
923
924 if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1)
ed1e77d3 925 return new (m_parserArena) UnaryPlusNode(location, expr1);
14957cd0 926
ed1e77d3 927 return new (m_parserArena) MultNode(location, expr1, expr2, rightHasAssignments);
14957cd0
A
928}
929
93a37866 930ExpressionNode* ASTBuilder::makeDivNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
14957cd0
A
931{
932 expr1 = expr1->stripUnaryPlus();
933 expr2 = expr2->stripUnaryPlus();
934
ed1e77d3
A
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);
14957cd0
A
944}
945
93a37866 946ExpressionNode* ASTBuilder::makeModNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
14957cd0
A
947{
948 expr1 = expr1->stripUnaryPlus();
949 expr2 = expr2->stripUnaryPlus();
ed1e77d3
A
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);
14957cd0
A
957}
958
93a37866 959ExpressionNode* ASTBuilder::makeAddNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
14957cd0 960{
ed1e77d3
A
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);
14957cd0
A
968}
969
93a37866 970ExpressionNode* ASTBuilder::makeSubNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
14957cd0
A
971{
972 expr1 = expr1->stripUnaryPlus();
973 expr2 = expr2->stripUnaryPlus();
974
ed1e77d3
A
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);
14957cd0
A
981}
982
93a37866 983ExpressionNode* ASTBuilder::makeLeftShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
14957cd0 984{
ed1e77d3
A
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);
14957cd0
A
991}
992
93a37866 993ExpressionNode* ASTBuilder::makeRightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
14957cd0 994{
ed1e77d3
A
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);
14957cd0
A
1001}
1002
93a37866 1003ExpressionNode* ASTBuilder::makeURightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
14957cd0 1004{
ed1e77d3
A
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);
14957cd0
A
1011}
1012
93a37866 1013ExpressionNode* ASTBuilder::makeBitOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
14957cd0 1014{
ed1e77d3
A
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);
14957cd0
A
1021}
1022
93a37866 1023ExpressionNode* ASTBuilder::makeBitAndNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
14957cd0 1024{
ed1e77d3
A
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);
14957cd0
A
1031}
1032
93a37866 1033ExpressionNode* ASTBuilder::makeBitXOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
14957cd0 1034{
ed1e77d3
A
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);
14957cd0
A
1041}
1042
81345200 1043ExpressionNode* ASTBuilder::makeFunctionCallNode(const JSTokenLocation& location, ExpressionNode* func, ArgumentsNode* args, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd)
14957cd0 1044{
81345200 1045 ASSERT(divot.offset >= divot.lineStartOffset);
14957cd0 1046 if (!func->isLocation())
ed1e77d3 1047 return new (m_parserArena) FunctionCallValueNode(location, func, args, divot, divotStart, divotEnd);
14957cd0
A
1048 if (func->isResolveNode()) {
1049 ResolveNode* resolve = static_cast<ResolveNode*>(func);
1050 const Identifier& identifier = resolve->identifier();
93a37866 1051 if (identifier == m_vm->propertyNames->eval) {
14957cd0 1052 usesEval();
ed1e77d3 1053 return new (m_parserArena) EvalFunctionCallNode(location, args, divot, divotStart, divotEnd);
14957cd0 1054 }
ed1e77d3
A
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);
14957cd0
A
1058 }
1059 if (func->isBracketAccessorNode()) {
1060 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func);
ed1e77d3 1061 FunctionCallBracketNode* node = new (m_parserArena) FunctionCallBracketNode(location, bracket->base(), bracket->subscript(), bracket->subscriptHasAssignments(), args, divot, divotStart, divotEnd);
81345200 1062 node->setSubexpressionInfo(bracket->divot(), bracket->divotEnd().offset);
14957cd0
A
1063 return node;
1064 }
1065 ASSERT(func->isDotAccessorNode());
1066 DotAccessorNode* dot = static_cast<DotAccessorNode*>(func);
1067 FunctionCallDotNode* node;
81345200 1068 if (dot->identifier() == m_vm->propertyNames->builtinNames().callPublicName() || dot->identifier() == m_vm->propertyNames->builtinNames().callPrivateName())
ed1e77d3 1069 node = new (m_parserArena) CallFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
81345200 1070 else if (dot->identifier() == m_vm->propertyNames->builtinNames().applyPublicName() || dot->identifier() == m_vm->propertyNames->builtinNames().applyPrivateName())
ed1e77d3 1071 node = new (m_parserArena) ApplyFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
14957cd0 1072 else
ed1e77d3 1073 node = new (m_parserArena) FunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
81345200 1074 node->setSubexpressionInfo(dot->divot(), dot->divotEnd().offset);
14957cd0
A
1075 return node;
1076}
1077
81345200 1078ExpressionNode* ASTBuilder::makeBinaryNode(const JSTokenLocation& location, int token, std::pair<ExpressionNode*, BinaryOpInfo> lhs, std::pair<ExpressionNode*, BinaryOpInfo> rhs)
14957cd0
A
1079{
1080 switch (token) {
1081 case OR:
ed1e77d3 1082 return new (m_parserArena) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalOr);
14957cd0
A
1083
1084 case AND:
ed1e77d3 1085 return new (m_parserArena) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalAnd);
14957cd0
A
1086
1087 case BITOR:
93a37866 1088 return makeBitOrNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1089
1090 case BITXOR:
93a37866 1091 return makeBitXOrNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1092
1093 case BITAND:
93a37866 1094 return makeBitAndNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1095
1096 case EQEQ:
ed1e77d3 1097 return new (m_parserArena) EqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1098
1099 case NE:
ed1e77d3 1100 return new (m_parserArena) NotEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1101
1102 case STREQ:
ed1e77d3 1103 return new (m_parserArena) StrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1104
1105 case STRNEQ:
ed1e77d3 1106 return new (m_parserArena) NotStrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1107
1108 case LT:
ed1e77d3 1109 return new (m_parserArena) LessNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1110
1111 case GT:
ed1e77d3 1112 return new (m_parserArena) GreaterNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1113
1114 case LE:
ed1e77d3 1115 return new (m_parserArena) LessEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1116
1117 case GE:
ed1e77d3 1118 return new (m_parserArena) GreaterEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1119
1120 case INSTANCEOF: {
ed1e77d3 1121 InstanceOfNode* node = new (m_parserArena) InstanceOfNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
81345200 1122 setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
14957cd0
A
1123 return node;
1124 }
1125
1126 case INTOKEN: {
ed1e77d3 1127 InNode* node = new (m_parserArena) InNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
81345200 1128 setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
14957cd0
A
1129 return node;
1130 }
1131
1132 case LSHIFT:
93a37866 1133 return makeLeftShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1134
1135 case RSHIFT:
93a37866 1136 return makeRightShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1137
1138 case URSHIFT:
93a37866 1139 return makeURightShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1140
1141 case PLUS:
93a37866 1142 return makeAddNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1143
1144 case MINUS:
93a37866 1145 return makeSubNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1146
1147 case TIMES:
93a37866 1148 return makeMultNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1149
1150 case DIVIDE:
93a37866 1151 return makeDivNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1152
1153 case MOD:
93a37866 1154 return makeModNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
14957cd0
A
1155 }
1156 CRASH();
1157 return 0;
1158}
1159
81345200 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)
14957cd0 1161{
14957cd0 1162 if (!loc->isLocation())
ed1e77d3 1163 return new (m_parserArena) AssignErrorNode(location, divot, start, end);
14957cd0
A
1164
1165 if (loc->isResolveNode()) {
1166 ResolveNode* resolve = static_cast<ResolveNode*>(loc);
1167 if (op == OpEqual) {
6fe7ccc8
A
1168 if (expr->isFuncExprNode())
1169 static_cast<FuncExprNode*>(expr)->body()->setInferredName(resolve->identifier());
ed1e77d3 1170 AssignResolveNode* node = new (m_parserArena) AssignResolveNode(location, resolve->identifier(), expr);
81345200 1171 setExceptionLocation(node, start, divot, end);
14957cd0
A
1172 return node;
1173 }
ed1e77d3 1174 return new (m_parserArena) ReadModifyResolveNode(location, resolve->identifier(), op, expr, exprHasAssignments, divot, start, end);
14957cd0
A
1175 }
1176 if (loc->isBracketAccessorNode()) {
1177 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc);
1178 if (op == OpEqual)
ed1e77d3
A
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);
81345200 1181 node->setSubexpressionInfo(bracket->divot(), bracket->divotEnd().offset);
14957cd0
A
1182 return node;
1183 }
1184 ASSERT(loc->isDotAccessorNode());
1185 DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc);
6fe7ccc8
A
1186 if (op == OpEqual) {
1187 if (expr->isFuncExprNode())
1188 static_cast<FuncExprNode*>(expr)->body()->setInferredName(dot->identifier());
ed1e77d3 1189 return new (m_parserArena) AssignDotNode(location, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), start, end);
6fe7ccc8 1190 }
14957cd0 1191
ed1e77d3 1192 ReadModifyDotNode* node = new (m_parserArena) ReadModifyDotNode(location, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, start, end);
81345200 1193 node->setSubexpressionInfo(dot->divot(), dot->divotEnd().offset);
14957cd0
A
1194 return node;
1195}
1196
81345200 1197ExpressionNode* ASTBuilder::makePrefixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
14957cd0 1198{
ed1e77d3 1199 return new (m_parserArena) PrefixNode(location, expr, op, divot, start, end);
14957cd0
A
1200}
1201
81345200 1202ExpressionNode* ASTBuilder::makePostfixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
14957cd0 1203{
ed1e77d3 1204 return new (m_parserArena) PostfixNode(location, expr, op, divot, start, end);
14957cd0
A
1205}
1206
1207}
1208
1209#endif