1 /* 2 * Copyright (C) 2010 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 "NodeConstructors.h" 30 #include "SyntaxChecker.h" 31 #include <utility> 32 33 namespace JSC { 34 35 class ASTBuilder { 36 struct BinaryOpInfo { 37 BinaryOpInfo() {} 38 BinaryOpInfo(int s, int d, int e, bool r) 39 : start(s) 40 , divot(d) 41 , end(e) 42 , hasAssignment(r) 43 { 44 } 45 BinaryOpInfo(const BinaryOpInfo& lhs, const BinaryOpInfo& rhs) 46 : start(lhs.start) 47 , divot(rhs.start) 48 , end(rhs.end) 49 , hasAssignment(lhs.hasAssignment || rhs.hasAssignment) 50 { 51 } 52 int start; 53 int divot; 54 int end; 55 bool hasAssignment; 56 }; 57 58 59 struct AssignmentInfo { 60 AssignmentInfo() {} 61 AssignmentInfo(ExpressionNode* node, int start, int divot, int initAssignments, Operator op) 62 : m_node(node) 63 , m_start(start) 64 , m_divot(divot) 65 , m_initAssignments(initAssignments) 66 , m_op(op) 67 { 68 } 69 ExpressionNode* m_node; 70 int m_start; 71 int m_divot; 72 int m_initAssignments; 73 Operator m_op; 74 }; 75 public: 76 ASTBuilder(JSGlobalData* globalData, Lexer* lexer) 77 : m_globalData(globalData) 78 , m_lexer(lexer) 79 , m_scope(globalData) 80 , m_evalCount(0) 81 { 82 } 83 84 struct BinaryExprContext { 85 BinaryExprContext(ASTBuilder&) {} 86 }; 87 struct UnaryExprContext { 88 UnaryExprContext(ASTBuilder&) {} 89 }; 90 91 typedef SyntaxChecker FunctionBodyBuilder; 92 93 typedef ExpressionNode* Expression; 94 typedef JSC::SourceElements* SourceElements; 95 typedef ArgumentsNode* Arguments; 96 typedef CommaNode* Comma; 97 typedef PropertyNode* Property; 98 typedef PropertyListNode* PropertyList; 99 typedef ElementNode* ElementList; 100 typedef ArgumentListNode* ArgumentsList; 101 typedef ParameterNode* FormalParameterList; 102 typedef FunctionBodyNode* FunctionBody; 103 typedef StatementNode* Statement; 104 typedef ClauseListNode* ClauseList; 105 typedef CaseClauseNode* Clause; 106 typedef ConstDeclNode* ConstDeclList; 107 typedef std::pair<ExpressionNode*, BinaryOpInfo> BinaryOperand; 108 109 static const bool CreatesAST = true; 110 static const bool NeedsFreeVariableInfo = true; 111 static const bool CanUseFunctionCache = true; 112 113 ExpressionNode* makeBinaryNode(int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>); 114 ExpressionNode* makeFunctionCallNode(ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end); 115 116 JSC::SourceElements* createSourceElements() { return new (m_globalData) JSC::SourceElements(m_globalData); } 117 118 ParserArenaData<DeclarationStacks::VarStack>* varDeclarations() { return m_scope.m_varDeclarations; } 119 ParserArenaData<DeclarationStacks::FunctionStack>* funcDeclarations() { return m_scope.m_funcDeclarations; } 120 int features() const { return m_scope.m_features; } 121 int numConstants() const { return m_scope.m_numConstants; } 122 123 void appendToComma(CommaNode* commaNode, ExpressionNode* expr) { commaNode->append(expr); } 124 125 CommaNode* createCommaExpr(ExpressionNode* lhs, ExpressionNode* rhs) { return new (m_globalData) CommaNode(m_globalData, lhs, rhs); } 126 127 ExpressionNode* makeAssignNode(ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, int start, int divot, int end); 128 ExpressionNode* makePrefixNode(ExpressionNode*, Operator, int start, int divot, int end); 129 ExpressionNode* makePostfixNode(ExpressionNode*, Operator, int start, int divot, int end); 130 ExpressionNode* makeTypeOfNode(ExpressionNode*); 131 ExpressionNode* makeDeleteNode(ExpressionNode*, int start, int divot, int end); 132 ExpressionNode* makeNegateNode(ExpressionNode*); 133 ExpressionNode* makeBitwiseNotNode(ExpressionNode*); 134 ExpressionNode* makeMultNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); 135 ExpressionNode* makeDivNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); 136 ExpressionNode* makeModNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); 137 ExpressionNode* makeAddNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); 138 ExpressionNode* makeSubNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); 139 ExpressionNode* makeBitXOrNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); 140 ExpressionNode* makeBitAndNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); 141 ExpressionNode* makeBitOrNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); 142 ExpressionNode* makeLeftShiftNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); 143 ExpressionNode* makeRightShiftNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); 144 ExpressionNode* makeURightShiftNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); 145 146 ExpressionNode* createLogicalNot(ExpressionNode* expr) { return new (m_globalData) LogicalNotNode(m_globalData, expr); } 147 ExpressionNode* createUnaryPlus(ExpressionNode* expr) { return new (m_globalData) UnaryPlusNode(m_globalData, expr); } 148 ExpressionNode* createVoid(ExpressionNode* expr) 149 { 150 incConstants(); 151 return new (m_globalData) VoidNode(m_globalData, expr); 152 } 153 ExpressionNode* thisExpr() 154 { 155 usesThis(); 156 return new (m_globalData) ThisNode(m_globalData); 157 } 158 ExpressionNode* createResolve(const Identifier* ident, int start) 159 { 160 if (m_globalData->propertyNames->arguments == *ident) 161 usesArguments(); 162 return new (m_globalData) ResolveNode(m_globalData, *ident, start); 163 } 164 ExpressionNode* createObjectLiteral() { return new (m_globalData) ObjectLiteralNode(m_globalData); } 165 ExpressionNode* createObjectLiteral(PropertyListNode* properties) { return new (m_globalData) ObjectLiteralNode(m_globalData, properties); } 166 167 ExpressionNode* createArray(int elisions) 168 { 169 if (elisions) 170 incConstants(); 171 return new (m_globalData) ArrayNode(m_globalData, elisions); 172 } 173 174 ExpressionNode* createArray(ElementNode* elems) { return new (m_globalData) ArrayNode(m_globalData, elems); } 175 ExpressionNode* createArray(int elisions, ElementNode* elems) 176 { 177 if (elisions) 178 incConstants(); 179 return new (m_globalData) ArrayNode(m_globalData, elisions, elems); 180 } 181 ExpressionNode* createNumberExpr(double d) 182 { 183 incConstants(); 184 return new (m_globalData) NumberNode(m_globalData, d); 185 } 186 187 ExpressionNode* createString(const Identifier* string) 188 { 189 incConstants(); 190 return new (m_globalData) StringNode(m_globalData, *string); 191 } 192 193 ExpressionNode* createBoolean(bool b) 194 { 195 incConstants(); 196 return new (m_globalData) BooleanNode(m_globalData, b); 197 } 198 199 ExpressionNode* createNull() 200 { 201 incConstants(); 202 return new (m_globalData) NullNode(m_globalData); 203 } 204 205 ExpressionNode* createBracketAccess(ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, int start, int divot, int end) 206 { 207 BracketAccessorNode* node = new (m_globalData) BracketAccessorNode(m_globalData, base, property, propertyHasAssignments); 208 setExceptionLocation(node, start, divot, end); 209 return node; 210 } 211 212 ExpressionNode* createDotAccess(ExpressionNode* base, const Identifier& property, int start, int divot, int end) 213 { 214 DotAccessorNode* node = new (m_globalData) DotAccessorNode(m_globalData, base, property); 215 setExceptionLocation(node, start, divot, end); 216 return node; 217 } 218 219 ExpressionNode* createRegExp(const Identifier& pattern, const Identifier& flags, int start) 220 { 221 if (Yarr::checkSyntax(pattern.ustring())) 222 return 0; 223 RegExpNode* node = new (m_globalData) RegExpNode(m_globalData, pattern, flags); 224 int size = pattern.length() + 2; // + 2 for the two /'s 225 setExceptionLocation(node, start, start + size, start + size); 226 return node; 227 } 228 229 ExpressionNode* createNewExpr(ExpressionNode* expr, ArgumentsNode* arguments, int start, int divot, int end) 230 { 231 NewExprNode* node = new (m_globalData) NewExprNode(m_globalData, expr, arguments); 232 setExceptionLocation(node, start, divot, end); 233 return node; 234 } 235 236 ExpressionNode* createNewExpr(ExpressionNode* expr, int start, int end) 237 { 238 NewExprNode* node = new (m_globalData) NewExprNode(m_globalData, expr); 239 setExceptionLocation(node, start, end, end); 240 return node; 241 } 242 243 ExpressionNode* createConditionalExpr(ExpressionNode* condition, ExpressionNode* lhs, ExpressionNode* rhs) 244 { 245 return new (m_globalData) ConditionalNode(m_globalData, condition, lhs, rhs); 246 } 247 248 ExpressionNode* createAssignResolve(const Identifier& ident, ExpressionNode* rhs, bool rhsHasAssignment, int start, int divot, int end) 249 { 250 AssignResolveNode* node = new (m_globalData) AssignResolveNode(m_globalData, ident, rhs, rhsHasAssignment); 251 setExceptionLocation(node, start, divot, end); 252 return node; 253 } 254 255 ExpressionNode* createFunctionExpr(const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine) 256 { 257 FuncExprNode* result = new (m_globalData) FuncExprNode(m_globalData, *name, body, m_lexer->sourceCode(openBracePos, closeBracePos, bodyStartLine), parameters); 258 body->setLoc(bodyStartLine, bodyEndLine); 259 return result; 260 } 261 262 FunctionBodyNode* createFunctionBody(bool inStrictContext) 263 { 264 usesClosures(); 265 return FunctionBodyNode::create(m_globalData, inStrictContext); 266 } 267 268 template <bool> PropertyNode* createGetterOrSetterProperty(PropertyNode::Type type, const Identifier* name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine) 269 { 270 ASSERT(name); 271 body->setLoc(bodyStartLine, bodyEndLine); 272 return new (m_globalData) PropertyNode(m_globalData, *name, new (m_globalData) FuncExprNode(m_globalData, m_globalData->propertyNames->nullIdentifier, body, m_lexer->sourceCode(openBracePos, closeBracePos, bodyStartLine), params), type); 273 } 274 275 276 ArgumentsNode* createArguments() { return new (m_globalData) ArgumentsNode(m_globalData); } 277 ArgumentsNode* createArguments(ArgumentListNode* args) { return new (m_globalData) ArgumentsNode(m_globalData, args); } 278 ArgumentListNode* createArgumentsList(ExpressionNode* arg) { return new (m_globalData) ArgumentListNode(m_globalData, arg); } 279 ArgumentListNode* createArgumentsList(ArgumentListNode* args, ExpressionNode* arg) { return new (m_globalData) ArgumentListNode(m_globalData, args, arg); } 280 281 template <bool> PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type) { return new (m_globalData) PropertyNode(m_globalData, *propertyName, node, type); } 282 template <bool> PropertyNode* createProperty(JSGlobalData*, double propertyName, ExpressionNode* node, PropertyNode::Type type) { return new (m_globalData) PropertyNode(m_globalData, propertyName, node, type); } 283 PropertyListNode* createPropertyList(PropertyNode* property) { return new (m_globalData) PropertyListNode(m_globalData, property); } 284 PropertyListNode* createPropertyList(PropertyNode* property, PropertyListNode* tail) { return new (m_globalData) PropertyListNode(m_globalData, property, tail); } 285 286 ElementNode* createElementList(int elisions, ExpressionNode* expr) { return new (m_globalData) ElementNode(m_globalData, elisions, expr); } 287 ElementNode* createElementList(ElementNode* elems, int elisions, ExpressionNode* expr) { return new (m_globalData) ElementNode(m_globalData, elems, elisions, expr); } 288 289 ParameterNode* createFormalParameterList(const Identifier& ident) { return new (m_globalData) ParameterNode(m_globalData, ident); } 290 ParameterNode* createFormalParameterList(ParameterNode* list, const Identifier& ident) { return new (m_globalData) ParameterNode(m_globalData, list, ident); } 291 292 CaseClauseNode* createClause(ExpressionNode* expr, JSC::SourceElements* statements) { return new (m_globalData) CaseClauseNode(m_globalData, expr, statements); } 293 ClauseListNode* createClauseList(CaseClauseNode* clause) { return new (m_globalData) ClauseListNode(m_globalData, clause); } 294 ClauseListNode* createClauseList(ClauseListNode* tail, CaseClauseNode* clause) { return new (m_globalData) ClauseListNode(m_globalData, tail, clause); } 295 296 void setUsesArguments(FunctionBodyNode* node) { node->setUsesArguments(); } 297 298 StatementNode* createFuncDeclStatement(const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine) 299 { 300 FuncDeclNode* decl = new (m_globalData) FuncDeclNode(m_globalData, *name, body, m_lexer->sourceCode(openBracePos, closeBracePos, bodyStartLine), parameters); 301 if (*name == m_globalData->propertyNames->arguments) 302 usesArguments(); 303 m_scope.m_funcDeclarations->data.append(decl->body()); 304 body->setLoc(bodyStartLine, bodyEndLine); 305 return decl; 306 } 307 308 StatementNode* createBlockStatement(JSC::SourceElements* elements, int startLine, int endLine) 309 { 310 BlockNode* block = new (m_globalData) BlockNode(m_globalData, elements); 311 block->setLoc(startLine, endLine); 312 return block; 313 } 314 315 StatementNode* createExprStatement(ExpressionNode* expr, int start, int end) 316 { 317 ExprStatementNode* result = new (m_globalData) ExprStatementNode(m_globalData, expr); 318 result->setLoc(start, end); 319 return result; 320 } 321 322 StatementNode* createIfStatement(ExpressionNode* condition, StatementNode* trueBlock, int start, int end) 323 { 324 IfNode* result = new (m_globalData) IfNode(m_globalData, condition, trueBlock); 325 result->setLoc(start, end); 326 return result; 327 } 328 329 StatementNode* createIfStatement(ExpressionNode* condition, StatementNode* trueBlock, StatementNode* falseBlock, int start, int end) 330 { 331 IfNode* result = new (m_globalData) IfElseNode(m_globalData, condition, trueBlock, falseBlock); 332 result->setLoc(start, end); 333 return result; 334 } 335 336 StatementNode* createForLoop(ExpressionNode* initializer, ExpressionNode* condition, ExpressionNode* iter, StatementNode* statements, bool b, int start, int end) 337 { 338 ForNode* result = new (m_globalData) ForNode(m_globalData, initializer, condition, iter, statements, b); 339 result->setLoc(start, end); 340 return result; 341 } 342 343 StatementNode* createForInLoop(const Identifier* ident, ExpressionNode* initializer, ExpressionNode* iter, StatementNode* statements, int start, int divot, int end, int initStart, int initEnd, int startLine, int endLine) 344 { 345 ForInNode* result = new (m_globalData) ForInNode(m_globalData, *ident, initializer, iter, statements, initStart, initStart - start, initEnd - initStart); 346 result->setLoc(startLine, endLine); 347 setExceptionLocation(result, start, divot + 1, end); 348 return result; 349 } 350 351 StatementNode* createForInLoop(ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, int eStart, int eDivot, int eEnd, int start, int end) 352 { 353 ForInNode* result = new (m_globalData) ForInNode(m_globalData, lhs, iter, statements); 354 result->setLoc(start, end); 355 setExceptionLocation(result, eStart, eDivot, eEnd); 356 return result; 357 } 358 359 StatementNode* createEmptyStatement() { return new (m_globalData) EmptyStatementNode(m_globalData); } 360 361 StatementNode* createVarStatement(ExpressionNode* expr, int start, int end) 362 { 363 StatementNode* result; 364 if (!expr) 365 result = new (m_globalData) EmptyStatementNode(m_globalData); 366 else 367 result = new (m_globalData) VarStatementNode(m_globalData, expr); 368 result->setLoc(start, end); 369 return result; 370 } 371 372 StatementNode* createReturnStatement(ExpressionNode* expression, int eStart, int eEnd, int startLine, int endLine) 373 { 374 ReturnNode* result = new (m_globalData) ReturnNode(m_globalData, expression); 375 setExceptionLocation(result, eStart, eEnd, eEnd); 376 result->setLoc(startLine, endLine); 377 return result; 378 } 379 380 StatementNode* createBreakStatement(int eStart, int eEnd, int startLine, int endLine) 381 { 382 BreakNode* result = new (m_globalData) BreakNode(m_globalData); 383 setExceptionLocation(result, eStart, eEnd, eEnd); 384 result->setLoc(startLine, endLine); 385 return result; 386 } 387 388 StatementNode* createBreakStatement(const Identifier* ident, int eStart, int eEnd, int startLine, int endLine) 389 { 390 BreakNode* result = new (m_globalData) BreakNode(m_globalData, *ident); 391 setExceptionLocation(result, eStart, eEnd, eEnd); 392 result->setLoc(startLine, endLine); 393 return result; 394 } 395 396 StatementNode* createContinueStatement(int eStart, int eEnd, int startLine, int endLine) 397 { 398 ContinueNode* result = new (m_globalData) ContinueNode(m_globalData); 399 setExceptionLocation(result, eStart, eEnd, eEnd); 400 result->setLoc(startLine, endLine); 401 return result; 402 } 403 404 StatementNode* createContinueStatement(const Identifier* ident, int eStart, int eEnd, int startLine, int endLine) 405 { 406 ContinueNode* result = new (m_globalData) ContinueNode(m_globalData, *ident); 407 setExceptionLocation(result, eStart, eEnd, eEnd); 408 result->setLoc(startLine, endLine); 409 return result; 410 } 411 412 StatementNode* createTryStatement(StatementNode* tryBlock, const Identifier* ident, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine) 413 { 414 TryNode* result = new (m_globalData) TryNode(m_globalData, tryBlock, *ident, catchHasEval, catchBlock, finallyBlock); 415 if (catchBlock) 416 usesCatch(); 417 result->setLoc(startLine, endLine); 418 return result; 419 } 420 421 StatementNode* createSwitchStatement(ExpressionNode* expr, ClauseListNode* firstClauses, CaseClauseNode* defaultClause, ClauseListNode* secondClauses, int startLine, int endLine) 422 { 423 CaseBlockNode* cases = new (m_globalData) CaseBlockNode(m_globalData, firstClauses, defaultClause, secondClauses); 424 SwitchNode* result = new (m_globalData) SwitchNode(m_globalData, expr, cases); 425 result->setLoc(startLine, endLine); 426 return result; 427 } 428 429 StatementNode* createWhileStatement(ExpressionNode* expr, StatementNode* statement, int startLine, int endLine) 430 { 431 WhileNode* result = new (m_globalData) WhileNode(m_globalData, expr, statement); 432 result->setLoc(startLine, endLine); 433 return result; 434 } 435 436 StatementNode* createDoWhileStatement(StatementNode* statement, ExpressionNode* expr, int startLine, int endLine) 437 { 438 DoWhileNode* result = new (m_globalData) DoWhileNode(m_globalData, statement, expr); 439 result->setLoc(startLine, endLine); 440 return result; 441 } 442 443 StatementNode* createLabelStatement(const Identifier* ident, StatementNode* statement, int start, int end) 444 { 445 LabelNode* result = new (m_globalData) LabelNode(m_globalData, *ident, statement); 446 setExceptionLocation(result, start, end, end); 447 return result; 448 } 449 450 StatementNode* createWithStatement(ExpressionNode* expr, StatementNode* statement, int start, int end, int startLine, int endLine) 451 { 452 usesWith(); 453 WithNode* result = new (m_globalData) WithNode(m_globalData, expr, statement, end, end - start); 454 result->setLoc(startLine, endLine); 455 return result; 456 } 457 458 StatementNode* createThrowStatement(ExpressionNode* expr, int start, int end, int startLine, int endLine) 459 { 460 ThrowNode* result = new (m_globalData) ThrowNode(m_globalData, expr); 461 result->setLoc(startLine, endLine); 462 setExceptionLocation(result, start, end, end); 463 return result; 464 } 465 466 StatementNode* createDebugger(int startLine, int endLine) 467 { 468 DebuggerStatementNode* result = new (m_globalData) DebuggerStatementNode(m_globalData); 469 result->setLoc(startLine, endLine); 470 return result; 471 } 472 473 StatementNode* createConstStatement(ConstDeclNode* decls, int startLine, int endLine) 474 { 475 ConstStatementNode* result = new (m_globalData) ConstStatementNode(m_globalData, decls); 476 result->setLoc(startLine, endLine); 477 return result; 478 } 479 480 ConstDeclNode* appendConstDecl(ConstDeclNode* tail, const Identifier* name, ExpressionNode* initializer) 481 { 482 ConstDeclNode* result = new (m_globalData) ConstDeclNode(m_globalData, *name, initializer); 483 if (tail) 484 tail->m_next = result; 485 return result; 486 } 487 488 void appendStatement(JSC::SourceElements* elements, JSC::StatementNode* statement) 489 { 490 elements->append(statement); 491 } 492 493 void addVar(const Identifier* ident, int attrs) 494 { 495 if (m_globalData->propertyNames->arguments == *ident) 496 usesArguments(); 497 m_scope.m_varDeclarations->data.append(std::make_pair(ident, attrs)); 498 } 499 500 ExpressionNode* combineCommaNodes(ExpressionNode* list, ExpressionNode* init) 501 { 502 if (!list) 503 return init; 504 if (list->isCommaNode()) { 505 static_cast<CommaNode*>(list)->append(init); 506 return list; 507 } 508 return new (m_globalData) CommaNode(m_globalData, list, init); 509 } 510 511 int evalCount() const { return m_evalCount; } 512 513 void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, int exprStart, int lhs, int rhs, bool hasAssignments) 514 { 515 operandStackDepth++; 516 m_binaryOperandStack.append(std::make_pair(current, BinaryOpInfo(exprStart, lhs, rhs, hasAssignments))); 517 } 518 519 // Logic to handle datastructures used during parsing of binary expressions 520 void operatorStackPop(int& operatorStackDepth) 521 { 522 operatorStackDepth--; 523 m_binaryOperatorStack.removeLast(); 524 } 525 bool operatorStackHasHigherPrecedence(int&, int precedence) 526 { 527 return precedence <= m_binaryOperatorStack.last().second; 528 } 529 const BinaryOperand& getFromOperandStack(int i) { return m_binaryOperandStack[m_binaryOperandStack.size() + i]; } 530 void shrinkOperandStackBy(int& operandStackDepth, int amount) 531 { 532 operandStackDepth -= amount; 533 ASSERT(operandStackDepth >= 0); 534 m_binaryOperandStack.resize(m_binaryOperandStack.size() - amount); 535 } 536 void appendBinaryOperation(int& operandStackDepth, int&, const BinaryOperand& lhs, const BinaryOperand& rhs) 537 { 538 operandStackDepth++; 539 m_binaryOperandStack.append(std::make_pair(makeBinaryNode(m_binaryOperatorStack.last().first, lhs, rhs), BinaryOpInfo(lhs.second, rhs.second))); 540 } 541 void operatorStackAppend(int& operatorStackDepth, int op, int precedence) 542 { 543 operatorStackDepth++; 544 m_binaryOperatorStack.append(std::make_pair(op, precedence)); 545 } 546 ExpressionNode* popOperandStack(int&) 547 { 548 ExpressionNode* result = m_binaryOperandStack.last().first; 549 m_binaryOperandStack.removeLast(); 550 return result; 551 } 552 553 void appendUnaryToken(int& tokenStackDepth, int type, int start) 554 { 555 tokenStackDepth++; 556 m_unaryTokenStack.append(std::make_pair(type, start)); 557 } 558 559 int unaryTokenStackLastType(int&) 560 { 561 return m_unaryTokenStack.last().first; 562 } 563 564 int unaryTokenStackLastStart(int&) 565 { 566 return m_unaryTokenStack.last().second; 567 } 568 569 void unaryTokenStackRemoveLast(int& tokenStackDepth) 570 { 571 tokenStackDepth--; 572 m_unaryTokenStack.removeLast(); 573 } 574 575 void assignmentStackAppend(int& assignmentStackDepth, ExpressionNode* node, int start, int divot, int assignmentCount, Operator op) 576 { 577 assignmentStackDepth++; 578 m_assignmentInfoStack.append(AssignmentInfo(node, start, divot, assignmentCount, op)); 579 } 580 581 ExpressionNode* createAssignment(int& assignmentStackDepth, ExpressionNode* rhs, int initialAssignmentCount, int currentAssignmentCount, int lastTokenEnd) 582 { 583 ExpressionNode* result = makeAssignNode(m_assignmentInfoStack.last().m_node, m_assignmentInfoStack.last().m_op, rhs, m_assignmentInfoStack.last().m_initAssignments != initialAssignmentCount, m_assignmentInfoStack.last().m_initAssignments != currentAssignmentCount, m_assignmentInfoStack.last().m_start, m_assignmentInfoStack.last().m_divot + 1, lastTokenEnd); 584 m_assignmentInfoStack.removeLast(); 585 assignmentStackDepth--; 586 return result; 587 } 588 589 const Identifier& getName(Property property) const { return property->name(); } 590 PropertyNode::Type getType(Property property) const { return property->type(); } 591 592 bool isResolve(ExpressionNode* expr) const { return expr->isResolveNode(); } 593 594 private: 595 struct Scope { 596 Scope(JSGlobalData* globalData) 597 : m_varDeclarations(new (globalData) ParserArenaData<DeclarationStacks::VarStack>) 598 , m_funcDeclarations(new (globalData) ParserArenaData<DeclarationStacks::FunctionStack>) 599 , m_features(0) 600 , m_numConstants(0) 601 { 602 } 603 ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations; 604 ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations; 605 int m_features; 606 int m_numConstants; 607 }; 608 609 static void setExceptionLocation(ThrowableExpressionData* node, unsigned start, unsigned divot, unsigned end) 610 { 611 node->setExceptionSourceCode(divot, divot - start, end - divot); 612 } 613 614 void incConstants() { m_scope.m_numConstants++; } 615 void usesThis() { m_scope.m_features |= ThisFeature; } 616 void usesCatch() { m_scope.m_features |= CatchFeature; } 617 void usesClosures() { m_scope.m_features |= ClosureFeature; } 618 void usesArguments() { m_scope.m_features |= ArgumentsFeature; } 619 void usesAssignment() { m_scope.m_features |= AssignFeature; } 620 void usesWith() { m_scope.m_features |= WithFeature; } 621 void usesEval() 622 { 623 m_evalCount++; 624 m_scope.m_features |= EvalFeature; 625 } 626 ExpressionNode* createNumber(double d) 627 { 628 return new (m_globalData) NumberNode(m_globalData, d); 629 } 630 631 JSGlobalData* m_globalData; 632 Lexer* m_lexer; 633 Scope m_scope; 634 Vector<BinaryOperand, 10> m_binaryOperandStack; 635 Vector<AssignmentInfo, 10> m_assignmentInfoStack; 636 Vector<pair<int, int>, 10> m_binaryOperatorStack; 637 Vector<pair<int, int>, 10> m_unaryTokenStack; 638 int m_evalCount; 639 }; 640 641 ExpressionNode* ASTBuilder::makeTypeOfNode(ExpressionNode* expr) 642 { 643 if (expr->isResolveNode()) { 644 ResolveNode* resolve = static_cast<ResolveNode*>(expr); 645 return new (m_globalData) TypeOfResolveNode(m_globalData, resolve->identifier()); 646 } 647 return new (m_globalData) TypeOfValueNode(m_globalData, expr); 648 } 649 650 ExpressionNode* ASTBuilder::makeDeleteNode(ExpressionNode* expr, int start, int divot, int end) 651 { 652 if (!expr->isLocation()) 653 return new (m_globalData) DeleteValueNode(m_globalData, expr); 654 if (expr->isResolveNode()) { 655 ResolveNode* resolve = static_cast<ResolveNode*>(expr); 656 return new (m_globalData) DeleteResolveNode(m_globalData, resolve->identifier(), divot, divot - start, end - divot); 657 } 658 if (expr->isBracketAccessorNode()) { 659 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); 660 return new (m_globalData) DeleteBracketNode(m_globalData, bracket->base(), bracket->subscript(), divot, divot - start, end - divot); 661 } 662 ASSERT(expr->isDotAccessorNode()); 663 DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); 664 return new (m_globalData) DeleteDotNode(m_globalData, dot->base(), dot->identifier(), divot, divot - start, end - divot); 665 } 666 667 ExpressionNode* ASTBuilder::makeNegateNode(ExpressionNode* n) 668 { 669 if (n->isNumber()) { 670 NumberNode* numberNode = static_cast<NumberNode*>(n); 671 numberNode->setValue(-numberNode->value()); 672 return numberNode; 673 } 674 675 return new (m_globalData) NegateNode(m_globalData, n); 676 } 677 678 ExpressionNode* ASTBuilder::makeBitwiseNotNode(ExpressionNode* expr) 679 { 680 if (expr->isNumber()) 681 return createNumber(~toInt32(static_cast<NumberNode*>(expr)->value())); 682 return new (m_globalData) BitwiseNotNode(m_globalData, expr); 683 } 684 685 ExpressionNode* ASTBuilder::makeMultNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) 686 { 687 expr1 = expr1->stripUnaryPlus(); 688 expr2 = expr2->stripUnaryPlus(); 689 690 if (expr1->isNumber() && expr2->isNumber()) 691 return createNumber(static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value()); 692 693 if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1) 694 return new (m_globalData) UnaryPlusNode(m_globalData, expr2); 695 696 if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1) 697 return new (m_globalData) UnaryPlusNode(m_globalData, expr1); 698 699 return new (m_globalData) MultNode(m_globalData, expr1, expr2, rightHasAssignments); 700 } 701 702 ExpressionNode* ASTBuilder::makeDivNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) 703 { 704 expr1 = expr1->stripUnaryPlus(); 705 expr2 = expr2->stripUnaryPlus(); 706 707 if (expr1->isNumber() && expr2->isNumber()) 708 return createNumber(static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value()); 709 return new (m_globalData) DivNode(m_globalData, expr1, expr2, rightHasAssignments); 710 } 711 712 ExpressionNode* ASTBuilder::makeModNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) 713 { 714 expr1 = expr1->stripUnaryPlus(); 715 expr2 = expr2->stripUnaryPlus(); 716 717 if (expr1->isNumber() && expr2->isNumber()) 718 return createNumber(fmod(static_cast<NumberNode*>(expr1)->value(), static_cast<NumberNode*>(expr2)->value())); 719 return new (m_globalData) ModNode(m_globalData, expr1, expr2, rightHasAssignments); 720 } 721 722 ExpressionNode* ASTBuilder::makeAddNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) 723 { 724 if (expr1->isNumber() && expr2->isNumber()) 725 return createNumber(static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value()); 726 return new (m_globalData) AddNode(m_globalData, expr1, expr2, rightHasAssignments); 727 } 728 729 ExpressionNode* ASTBuilder::makeSubNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) 730 { 731 expr1 = expr1->stripUnaryPlus(); 732 expr2 = expr2->stripUnaryPlus(); 733 734 if (expr1->isNumber() && expr2->isNumber()) 735 return createNumber(static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value()); 736 return new (m_globalData) SubNode(m_globalData, expr1, expr2, rightHasAssignments); 737 } 738 739 ExpressionNode* ASTBuilder::makeLeftShiftNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) 740 { 741 if (expr1->isNumber() && expr2->isNumber()) 742 return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); 743 return new (m_globalData) LeftShiftNode(m_globalData, expr1, expr2, rightHasAssignments); 744 } 745 746 ExpressionNode* ASTBuilder::makeRightShiftNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) 747 { 748 if (expr1->isNumber() && expr2->isNumber()) 749 return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); 750 return new (m_globalData) RightShiftNode(m_globalData, expr1, expr2, rightHasAssignments); 751 } 752 753 ExpressionNode* ASTBuilder::makeURightShiftNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) 754 { 755 if (expr1->isNumber() && expr2->isNumber()) 756 return createNumber(toUInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f)); 757 return new (m_globalData) UnsignedRightShiftNode(m_globalData, expr1, expr2, rightHasAssignments); 758 } 759 760 ExpressionNode* ASTBuilder::makeBitOrNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) 761 { 762 if (expr1->isNumber() && expr2->isNumber()) 763 return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) | toInt32(static_cast<NumberNode*>(expr2)->value())); 764 return new (m_globalData) BitOrNode(m_globalData, expr1, expr2, rightHasAssignments); 765 } 766 767 ExpressionNode* ASTBuilder::makeBitAndNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) 768 { 769 if (expr1->isNumber() && expr2->isNumber()) 770 return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) & toInt32(static_cast<NumberNode*>(expr2)->value())); 771 return new (m_globalData) BitAndNode(m_globalData, expr1, expr2, rightHasAssignments); 772 } 773 774 ExpressionNode* ASTBuilder::makeBitXOrNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) 775 { 776 if (expr1->isNumber() && expr2->isNumber()) 777 return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) ^ toInt32(static_cast<NumberNode*>(expr2)->value())); 778 return new (m_globalData) BitXOrNode(m_globalData, expr1, expr2, rightHasAssignments); 779 } 780 781 ExpressionNode* ASTBuilder::makeFunctionCallNode(ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end) 782 { 783 if (!func->isLocation()) 784 return new (m_globalData) FunctionCallValueNode(m_globalData, func, args, divot, divot - start, end - divot); 785 if (func->isResolveNode()) { 786 ResolveNode* resolve = static_cast<ResolveNode*>(func); 787 const Identifier& identifier = resolve->identifier(); 788 if (identifier == m_globalData->propertyNames->eval) { 789 usesEval(); 790 return new (m_globalData) EvalFunctionCallNode(m_globalData, args, divot, divot - start, end - divot); 791 } 792 return new (m_globalData) FunctionCallResolveNode(m_globalData, identifier, args, divot, divot - start, end - divot); 793 } 794 if (func->isBracketAccessorNode()) { 795 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func); 796 FunctionCallBracketNode* node = new (m_globalData) FunctionCallBracketNode(m_globalData, bracket->base(), bracket->subscript(), args, divot, divot - start, end - divot); 797 node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); 798 return node; 799 } 800 ASSERT(func->isDotAccessorNode()); 801 DotAccessorNode* dot = static_cast<DotAccessorNode*>(func); 802 FunctionCallDotNode* node; 803 if (dot->identifier() == m_globalData->propertyNames->call) 804 node = new (m_globalData) CallFunctionCallDotNode(m_globalData, dot->base(), dot->identifier(), args, divot, divot - start, end - divot); 805 else if (dot->identifier() == m_globalData->propertyNames->apply) 806 node = new (m_globalData) ApplyFunctionCallDotNode(m_globalData, dot->base(), dot->identifier(), args, divot, divot - start, end - divot); 807 else 808 node = new (m_globalData) FunctionCallDotNode(m_globalData, dot->base(), dot->identifier(), args, divot, divot - start, end - divot); 809 node->setSubexpressionInfo(dot->divot(), dot->endOffset()); 810 return node; 811 } 812 813 ExpressionNode* ASTBuilder::makeBinaryNode(int token, pair<ExpressionNode*, BinaryOpInfo> lhs, pair<ExpressionNode*, BinaryOpInfo> rhs) 814 { 815 switch (token) { 816 case OR: 817 return new (m_globalData) LogicalOpNode(m_globalData, lhs.first, rhs.first, OpLogicalOr); 818 819 case AND: 820 return new (m_globalData) LogicalOpNode(m_globalData, lhs.first, rhs.first, OpLogicalAnd); 821 822 case BITOR: 823 return makeBitOrNode(lhs.first, rhs.first, rhs.second.hasAssignment); 824 825 case BITXOR: 826 return makeBitXOrNode(lhs.first, rhs.first, rhs.second.hasAssignment); 827 828 case BITAND: 829 return makeBitAndNode(lhs.first, rhs.first, rhs.second.hasAssignment); 830 831 case EQEQ: 832 return new (m_globalData) EqualNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); 833 834 case NE: 835 return new (m_globalData) NotEqualNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); 836 837 case STREQ: 838 return new (m_globalData) StrictEqualNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); 839 840 case STRNEQ: 841 return new (m_globalData) NotStrictEqualNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); 842 843 case LT: 844 return new (m_globalData) LessNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); 845 846 case GT: 847 return new (m_globalData) GreaterNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); 848 849 case LE: 850 return new (m_globalData) LessEqNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); 851 852 case GE: 853 return new (m_globalData) GreaterEqNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); 854 855 case INSTANCEOF: { 856 InstanceOfNode* node = new (m_globalData) InstanceOfNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); 857 setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end); 858 return node; 859 } 860 861 case INTOKEN: { 862 InNode* node = new (m_globalData) InNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment); 863 setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end); 864 return node; 865 } 866 867 case LSHIFT: 868 return makeLeftShiftNode(lhs.first, rhs.first, rhs.second.hasAssignment); 869 870 case RSHIFT: 871 return makeRightShiftNode(lhs.first, rhs.first, rhs.second.hasAssignment); 872 873 case URSHIFT: 874 return makeURightShiftNode(lhs.first, rhs.first, rhs.second.hasAssignment); 875 876 case PLUS: 877 return makeAddNode(lhs.first, rhs.first, rhs.second.hasAssignment); 878 879 case MINUS: 880 return makeSubNode(lhs.first, rhs.first, rhs.second.hasAssignment); 881 882 case TIMES: 883 return makeMultNode(lhs.first, rhs.first, rhs.second.hasAssignment); 884 885 case DIVIDE: 886 return makeDivNode(lhs.first, rhs.first, rhs.second.hasAssignment); 887 888 case MOD: 889 return makeModNode(lhs.first, rhs.first, rhs.second.hasAssignment); 890 } 891 CRASH(); 892 return 0; 893 } 894 895 ExpressionNode* ASTBuilder::makeAssignNode(ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end) 896 { 897 usesAssignment(); 898 if (!loc->isLocation()) 899 return new (m_globalData) AssignErrorNode(m_globalData, loc, op, expr, divot, divot - start, end - divot); 900 901 if (loc->isResolveNode()) { 902 ResolveNode* resolve = static_cast<ResolveNode*>(loc); 903 if (op == OpEqual) { 904 AssignResolveNode* node = new (m_globalData) AssignResolveNode(m_globalData, resolve->identifier(), expr, exprHasAssignments); 905 setExceptionLocation(node, start, divot, end); 906 return node; 907 } 908 return new (m_globalData) ReadModifyResolveNode(m_globalData, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); 909 } 910 if (loc->isBracketAccessorNode()) { 911 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc); 912 if (op == OpEqual) 913 return new (m_globalData) AssignBracketNode(m_globalData, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot()); 914 ReadModifyBracketNode* node = new (m_globalData) ReadModifyBracketNode(m_globalData, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot); 915 node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); 916 return node; 917 } 918 ASSERT(loc->isDotAccessorNode()); 919 DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc); 920 if (op == OpEqual) 921 return new (m_globalData) AssignDotNode(m_globalData, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot()); 922 923 ReadModifyDotNode* node = new (m_globalData) ReadModifyDotNode(m_globalData, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); 924 node->setSubexpressionInfo(dot->divot(), dot->endOffset()); 925 return node; 926 } 927 928 ExpressionNode* ASTBuilder::makePrefixNode(ExpressionNode* expr, Operator op, int start, int divot, int end) 929 { 930 usesAssignment(); 931 if (!expr->isLocation()) 932 return new (m_globalData) PrefixErrorNode(m_globalData, expr, op, divot, divot - start, end - divot); 933 934 if (expr->isResolveNode()) { 935 ResolveNode* resolve = static_cast<ResolveNode*>(expr); 936 return new (m_globalData) PrefixResolveNode(m_globalData, resolve->identifier(), op, divot, divot - start, end - divot); 937 } 938 if (expr->isBracketAccessorNode()) { 939 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); 940 PrefixBracketNode* node = new (m_globalData) PrefixBracketNode(m_globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); 941 node->setSubexpressionInfo(bracket->divot(), bracket->startOffset()); 942 return node; 943 } 944 ASSERT(expr->isDotAccessorNode()); 945 DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); 946 PrefixDotNode* node = new (m_globalData) PrefixDotNode(m_globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); 947 node->setSubexpressionInfo(dot->divot(), dot->startOffset()); 948 return node; 949 } 950 951 ExpressionNode* ASTBuilder::makePostfixNode(ExpressionNode* expr, Operator op, int start, int divot, int end) 952 { 953 usesAssignment(); 954 if (!expr->isLocation()) 955 return new (m_globalData) PostfixErrorNode(m_globalData, expr, op, divot, divot - start, end - divot); 956 957 if (expr->isResolveNode()) { 958 ResolveNode* resolve = static_cast<ResolveNode*>(expr); 959 return new (m_globalData) PostfixResolveNode(m_globalData, resolve->identifier(), op, divot, divot - start, end - divot); 960 } 961 if (expr->isBracketAccessorNode()) { 962 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); 963 PostfixBracketNode* node = new (m_globalData) PostfixBracketNode(m_globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); 964 node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); 965 return node; 966 967 } 968 ASSERT(expr->isDotAccessorNode()); 969 DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); 970 PostfixDotNode* node = new (m_globalData) PostfixDotNode(m_globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); 971 node->setSubexpressionInfo(dot->divot(), dot->endOffset()); 972 return node; 973 } 974 975 } 976 977 #endif 978