1/* 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2001 Peter Kelly (pmk@post.com) 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved. 5 * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) 6 * Copyright (C) 2007 Maks Orlovich 7 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Library General Public 11 * License as published by the Free Software Foundation; either 12 * version 2 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Library General Public License for more details. 18 * 19 * You should have received a copy of the GNU Library General Public License 20 * along with this library; see the file COPYING.LIB. If not, write to 21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 * Boston, MA 02110-1301, USA. 23 * 24 */ 25 26#ifndef Nodes_h 27#define Nodes_h 28 29#include "Error.h" 30#include "JITCode.h" 31#include "Opcode.h" 32#include "ParserArena.h" 33#include "ParserTokens.h" 34#include "ResultType.h" 35#include "SourceCode.h" 36#include "SymbolTable.h" 37#include <wtf/MathExtras.h> 38 39namespace JSC { 40 41 class ArgumentListNode; 42 class BytecodeGenerator; 43 class FunctionBodyNode; 44 class Label; 45 class PropertyListNode; 46 class ReadModifyResolveNode; 47 class RegisterID; 48 class JSScope; 49 class ScopeNode; 50 51 enum Operator { 52 OpEqual, 53 OpPlusEq, 54 OpMinusEq, 55 OpMultEq, 56 OpDivEq, 57 OpPlusPlus, 58 OpMinusMinus, 59 OpAndEq, 60 OpXOrEq, 61 OpOrEq, 62 OpModEq, 63 OpLShift, 64 OpRShift, 65 OpURShift 66 }; 67 68 enum LogicalOperator { 69 OpLogicalAnd, 70 OpLogicalOr 71 }; 72 73 enum FallThroughMode { 74 FallThroughMeansTrue = 0, 75 FallThroughMeansFalse = 1 76 }; 77 inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast<FallThroughMode>(!fallThroughMode); } 78 79 typedef HashSet<RefPtr<StringImpl>, IdentifierRepHash> IdentifierSet; 80 81 namespace DeclarationStacks { 82 enum VarAttrs { IsConstant = 1, HasInitializer = 2 }; 83 typedef Vector<std::pair<Identifier, unsigned>> VarStack; 84 typedef Vector<FunctionBodyNode*> FunctionStack; 85 } 86 87 struct SwitchInfo { 88 enum SwitchType { SwitchNone, SwitchImmediate, SwitchCharacter, SwitchString }; 89 uint32_t bytecodeOffset; 90 SwitchType switchType; 91 }; 92 93 class ParserArenaFreeable { 94 public: 95 // ParserArenaFreeable objects are are freed when the arena is deleted. 96 // Destructors are not called. Clients must not call delete on such objects. 97 void* operator new(size_t, VM*); 98 }; 99 100 class ParserArenaDeletable { 101 public: 102 virtual ~ParserArenaDeletable() { } 103 104 // ParserArenaDeletable objects are deleted when the arena is deleted. 105 // Clients must not call delete directly on such objects. 106 void* operator new(size_t, VM*); 107 }; 108 109 template <typename T> 110 struct ParserArenaData : ParserArenaDeletable { 111 T data; 112 }; 113 114 class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> { 115 WTF_MAKE_FAST_ALLOCATED; 116 protected: 117 ParserArenaRefCounted(VM*); 118 119 public: 120 virtual ~ParserArenaRefCounted() 121 { 122 ASSERT(deletionHasBegun()); 123 } 124 }; 125 126 class Node : public ParserArenaFreeable { 127 protected: 128 Node(const JSTokenLocation&); 129 130 public: 131 virtual ~Node() { } 132 133 int lineNo() const { return m_position.line; } 134 int startOffset() const { return m_position.offset; } 135 int lineStartOffset() const { return m_position.lineStartOffset; } 136 const JSTextPosition& position() const { return m_position; } 137 138 protected: 139 JSTextPosition m_position; 140 }; 141 142 class ExpressionNode : public Node { 143 protected: 144 ExpressionNode(const JSTokenLocation&, ResultType = ResultType::unknownType()); 145 146 public: 147 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0; 148 149 virtual bool isNumber() const { return false; } 150 virtual bool isString() const { return false; } 151 virtual bool isNull() const { return false; } 152 virtual bool isPure(BytecodeGenerator&) const { return false; } 153 virtual bool isConstant() const { return false; } 154 virtual bool isLocation() const { return false; } 155 virtual bool isAssignmentLocation() const { return isLocation(); } 156 virtual bool isResolveNode() const { return false; } 157 virtual bool isBracketAccessorNode() const { return false; } 158 virtual bool isDotAccessorNode() const { return false; } 159 virtual bool isDeconstructionNode() const { return false; } 160 virtual bool isFuncExprNode() const { return false; } 161 virtual bool isCommaNode() const { return false; } 162 virtual bool isSimpleArray() const { return false; } 163 virtual bool isAdd() const { return false; } 164 virtual bool isSubtract() const { return false; } 165 virtual bool isBoolean() const { return false; } 166 virtual bool isSpreadExpression() const { return false; } 167 168 virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, FallThroughMode); 169 170 virtual ExpressionNode* stripUnaryPlus() { return this; } 171 172 ResultType resultDescriptor() const { return m_resultType; } 173 174 private: 175 ResultType m_resultType; 176 }; 177 178 class StatementNode : public Node { 179 protected: 180 StatementNode(const JSTokenLocation&); 181 182 public: 183 virtual void emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0; 184 185 void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset); 186 unsigned firstLine() const { return lineNo(); } 187 unsigned lastLine() const { return m_lastLine; } 188 189 virtual bool isEmptyStatement() const { return false; } 190 virtual bool isReturnNode() const { return false; } 191 virtual bool isExprStatement() const { return false; } 192 virtual bool isBreak() const { return false; } 193 virtual bool isContinue() const { return false; } 194 virtual bool isBlock() const { return false; } 195 196 protected: 197 int m_lastLine; 198 }; 199 200 class ConstantNode : public ExpressionNode { 201 public: 202 ConstantNode(const JSTokenLocation&, ResultType); 203 virtual bool isPure(BytecodeGenerator&) const override { return true; } 204 virtual bool isConstant() const override { return true; } 205 virtual JSValue jsValue(BytecodeGenerator&) const = 0; 206 private: 207 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 208 virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override; 209 }; 210 211 class NullNode : public ConstantNode { 212 public: 213 NullNode(const JSTokenLocation&); 214 215 private: 216 virtual bool isNull() const override { return true; } 217 virtual JSValue jsValue(BytecodeGenerator&) const override { return jsNull(); } 218 }; 219 220 class BooleanNode : public ConstantNode { 221 public: 222 BooleanNode(const JSTokenLocation&, bool value); 223 bool value() { return m_value; } 224 225 private: 226 virtual bool isBoolean() const override { return true; } 227 virtual JSValue jsValue(BytecodeGenerator&) const override { return jsBoolean(m_value); } 228 229 bool m_value; 230 }; 231 232 class NumberNode : public ConstantNode { 233 public: 234 NumberNode(const JSTokenLocation&, double value); 235 double value() { return m_value; } 236 void setValue(double value) { m_value = value; } 237 238 private: 239 virtual bool isNumber() const override { return true; } 240 virtual JSValue jsValue(BytecodeGenerator&) const override { return jsNumber(m_value); } 241 242 double m_value; 243 }; 244 245 class StringNode : public ConstantNode { 246 public: 247 StringNode(const JSTokenLocation&, const Identifier&); 248 const Identifier& value() { return m_value; } 249 250 private: 251 virtual bool isString() const override { return true; } 252 virtual JSValue jsValue(BytecodeGenerator&) const override; 253 254 const Identifier& m_value; 255 }; 256 257 class ThrowableExpressionData { 258 public: 259 ThrowableExpressionData() 260 : m_divot(-1, -1, -1) 261 , m_divotStart(-1, -1, -1) 262 , m_divotEnd(-1, -1, -1) 263 { 264 } 265 266 ThrowableExpressionData(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end) 267 : m_divot(divot) 268 , m_divotStart(start) 269 , m_divotEnd(end) 270 { 271 ASSERT(m_divot.offset >= m_divot.lineStartOffset); 272 ASSERT(m_divotStart.offset >= m_divotStart.lineStartOffset); 273 ASSERT(m_divotEnd.offset >= m_divotEnd.lineStartOffset); 274 } 275 276 void setExceptionSourceCode(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) 277 { 278 ASSERT(divot.offset >= divot.lineStartOffset); 279 ASSERT(divotStart.offset >= divotStart.lineStartOffset); 280 ASSERT(divotEnd.offset >= divotEnd.lineStartOffset); 281 m_divot = divot; 282 m_divotStart = divotStart; 283 m_divotEnd = divotEnd; 284 } 285 286 const JSTextPosition& divot() const { return m_divot; } 287 const JSTextPosition& divotStart() const { return m_divotStart; } 288 const JSTextPosition& divotEnd() const { return m_divotEnd; } 289 290 protected: 291 RegisterID* emitThrowReferenceError(BytecodeGenerator&, const String& message); 292 293 private: 294 JSTextPosition m_divot; 295 JSTextPosition m_divotStart; 296 JSTextPosition m_divotEnd; 297 }; 298 299 class ThrowableSubExpressionData : public ThrowableExpressionData { 300 public: 301 ThrowableSubExpressionData() 302 : m_subexpressionDivotOffset(0) 303 , m_subexpressionEndOffset(0) 304 , m_subexpressionLineOffset(0) 305 , m_subexpressionLineStartOffset(0) 306 { 307 } 308 309 ThrowableSubExpressionData(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) 310 : ThrowableExpressionData(divot, divotStart, divotEnd) 311 , m_subexpressionDivotOffset(0) 312 , m_subexpressionEndOffset(0) 313 , m_subexpressionLineOffset(0) 314 , m_subexpressionLineStartOffset(0) 315 { 316 } 317 318 void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset) 319 { 320 ASSERT(subexpressionDivot.offset <= divot().offset); 321 // Overflow means we can't do this safely, so just point at the primary divot, 322 // divotLine, or divotLineStart. 323 if ((divot() - subexpressionDivot.offset) & ~0xFFFF) 324 return; 325 if ((divot().line - subexpressionDivot.line) & ~0xFFFF) 326 return; 327 if ((divot().lineStartOffset - subexpressionDivot.lineStartOffset) & ~0xFFFF) 328 return; 329 if ((divotEnd() - subexpressionOffset) & ~0xFFFF) 330 return; 331 m_subexpressionDivotOffset = divot() - subexpressionDivot.offset; 332 m_subexpressionEndOffset = divotEnd() - subexpressionOffset; 333 m_subexpressionLineOffset = divot().line - subexpressionDivot.line; 334 m_subexpressionLineStartOffset = divot().lineStartOffset - subexpressionDivot.lineStartOffset; 335 } 336 337 JSTextPosition subexpressionDivot() 338 { 339 int newLine = divot().line - m_subexpressionLineOffset; 340 int newOffset = divot().offset - m_subexpressionDivotOffset; 341 int newLineStartOffset = divot().lineStartOffset - m_subexpressionLineStartOffset; 342 return JSTextPosition(newLine, newOffset, newLineStartOffset); 343 } 344 JSTextPosition subexpressionStart() { return divotStart(); } 345 JSTextPosition subexpressionEnd() { return divotEnd() - static_cast<int>(m_subexpressionEndOffset); } 346 347 protected: 348 uint16_t m_subexpressionDivotOffset; 349 uint16_t m_subexpressionEndOffset; 350 uint16_t m_subexpressionLineOffset; 351 uint16_t m_subexpressionLineStartOffset; 352 }; 353 354 class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData { 355 public: 356 ThrowablePrefixedSubExpressionData() 357 : m_subexpressionDivotOffset(0) 358 , m_subexpressionStartOffset(0) 359 , m_subexpressionLineOffset(0) 360 , m_subexpressionLineStartOffset(0) 361 { 362 } 363 364 ThrowablePrefixedSubExpressionData(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end) 365 : ThrowableExpressionData(divot, start, end) 366 , m_subexpressionDivotOffset(0) 367 , m_subexpressionStartOffset(0) 368 , m_subexpressionLineOffset(0) 369 , m_subexpressionLineStartOffset(0) 370 { 371 } 372 373 void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset) 374 { 375 ASSERT(subexpressionDivot.offset >= divot().offset); 376 // Overflow means we can't do this safely, so just point at the primary divot, 377 // divotLine, or divotLineStart. 378 if ((subexpressionDivot.offset - divot()) & ~0xFFFF) 379 return; 380 if ((subexpressionDivot.line - divot().line) & ~0xFFFF) 381 return; 382 if ((subexpressionDivot.lineStartOffset - divot().lineStartOffset) & ~0xFFFF) 383 return; 384 if ((subexpressionOffset - divotStart()) & ~0xFFFF) 385 return; 386 m_subexpressionDivotOffset = subexpressionDivot.offset - divot(); 387 m_subexpressionStartOffset = subexpressionOffset - divotStart(); 388 m_subexpressionLineOffset = subexpressionDivot.line - divot().line; 389 m_subexpressionLineStartOffset = subexpressionDivot.lineStartOffset - divot().lineStartOffset; 390 } 391 392 JSTextPosition subexpressionDivot() 393 { 394 int newLine = divot().line + m_subexpressionLineOffset; 395 int newOffset = divot().offset + m_subexpressionDivotOffset; 396 int newLineStartOffset = divot().lineStartOffset + m_subexpressionLineStartOffset; 397 return JSTextPosition(newLine, newOffset, newLineStartOffset); 398 } 399 JSTextPosition subexpressionStart() { return divotStart() + static_cast<int>(m_subexpressionStartOffset); } 400 JSTextPosition subexpressionEnd() { return divotEnd(); } 401 402 protected: 403 uint16_t m_subexpressionDivotOffset; 404 uint16_t m_subexpressionStartOffset; 405 uint16_t m_subexpressionLineOffset; 406 uint16_t m_subexpressionLineStartOffset; 407 }; 408 409 class RegExpNode : public ExpressionNode, public ThrowableExpressionData { 410 public: 411 RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags); 412 413 private: 414 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 415 416 const Identifier& m_pattern; 417 const Identifier& m_flags; 418 }; 419 420 class ThisNode : public ExpressionNode { 421 public: 422 ThisNode(const JSTokenLocation&); 423 424 private: 425 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 426 }; 427 428 class ResolveNode : public ExpressionNode { 429 public: 430 ResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& start); 431 432 const Identifier& identifier() const { return m_ident; } 433 434 private: 435 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 436 437 virtual bool isPure(BytecodeGenerator&) const override; 438 virtual bool isLocation() const override { return true; } 439 virtual bool isResolveNode() const override { return true; } 440 441 const Identifier& m_ident; 442 JSTextPosition m_start; 443 }; 444 445 class ElementNode : public ParserArenaFreeable { 446 public: 447 ElementNode(int elision, ExpressionNode*); 448 ElementNode(ElementNode*, int elision, ExpressionNode*); 449 450 int elision() const { return m_elision; } 451 ExpressionNode* value() { return m_node; } 452 ElementNode* next() { return m_next; } 453 454 private: 455 ElementNode* m_next; 456 int m_elision; 457 ExpressionNode* m_node; 458 }; 459 460 class ArrayNode : public ExpressionNode { 461 public: 462 ArrayNode(const JSTokenLocation&, int elision); 463 ArrayNode(const JSTokenLocation&, ElementNode*); 464 ArrayNode(const JSTokenLocation&, int elision, ElementNode*); 465 466 ArgumentListNode* toArgumentList(VM*, int, int) const; 467 468 ElementNode* elements() const { ASSERT(isSimpleArray()); return m_element; } 469 private: 470 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 471 472 virtual bool isSimpleArray() const override; 473 474 ElementNode* m_element; 475 int m_elision; 476 bool m_optional; 477 }; 478 479 class PropertyNode : public ParserArenaFreeable { 480 public: 481 enum Type { Constant = 1, Getter = 2, Setter = 4 }; 482 483 PropertyNode(VM*, const Identifier&, ExpressionNode*, Type); 484 PropertyNode(VM*, double, ExpressionNode*, Type); 485 PropertyNode(VM*, ExpressionNode* propertyName, ExpressionNode*, Type); 486 487 ExpressionNode* expressionName() const { return m_expression; } 488 const Identifier* name() const { return m_name; } 489 490 Type type() const { return m_type; } 491 492 private: 493 friend class PropertyListNode; 494 const Identifier* m_name; 495 ExpressionNode* m_expression; 496 ExpressionNode* m_assign; 497 Type m_type; 498 }; 499 500 class PropertyListNode : public ExpressionNode { 501 public: 502 PropertyListNode(const JSTokenLocation&, PropertyNode*); 503 PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*); 504 505 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 506 507 private: 508 PropertyNode* m_node; 509 PropertyListNode* m_next; 510 }; 511 512 class ObjectLiteralNode : public ExpressionNode { 513 public: 514 ObjectLiteralNode(const JSTokenLocation&); 515 ObjectLiteralNode(const JSTokenLocation&, PropertyListNode*); 516 517 private: 518 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 519 520 PropertyListNode* m_list; 521 }; 522 523 class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData { 524 public: 525 BracketAccessorNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments); 526 527 ExpressionNode* base() const { return m_base; } 528 ExpressionNode* subscript() const { return m_subscript; } 529 530 bool subscriptHasAssignments() const { return m_subscriptHasAssignments; } 531 532 private: 533 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 534 535 virtual bool isLocation() const override { return true; } 536 virtual bool isBracketAccessorNode() const override { return true; } 537 538 ExpressionNode* m_base; 539 ExpressionNode* m_subscript; 540 bool m_subscriptHasAssignments; 541 }; 542 543 class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData { 544 public: 545 DotAccessorNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&); 546 547 ExpressionNode* base() const { return m_base; } 548 const Identifier& identifier() const { return m_ident; } 549 550 private: 551 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 552 553 virtual bool isLocation() const override { return true; } 554 virtual bool isDotAccessorNode() const override { return true; } 555 556 ExpressionNode* m_base; 557 const Identifier& m_ident; 558 }; 559 560 class SpreadExpressionNode : public ExpressionNode, public ThrowableExpressionData { 561 public: 562 SpreadExpressionNode(const JSTokenLocation&, ExpressionNode*); 563 564 ExpressionNode* expression() const { return m_expression; } 565 566 private: 567 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 568 569 virtual bool isSpreadExpression() const override { return true; } 570 ExpressionNode* m_expression; 571 }; 572 573 class ArgumentListNode : public ExpressionNode { 574 public: 575 ArgumentListNode(const JSTokenLocation&, ExpressionNode*); 576 ArgumentListNode(const JSTokenLocation&, ArgumentListNode*, ExpressionNode*); 577 578 ArgumentListNode* m_next; 579 ExpressionNode* m_expr; 580 581 private: 582 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 583 }; 584 585 class ArgumentsNode : public ParserArenaFreeable { 586 public: 587 ArgumentsNode(); 588 ArgumentsNode(ArgumentListNode*); 589 590 ArgumentListNode* m_listNode; 591 }; 592 593 class NewExprNode : public ExpressionNode, public ThrowableExpressionData { 594 public: 595 NewExprNode(const JSTokenLocation&, ExpressionNode*); 596 NewExprNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*); 597 598 private: 599 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 600 601 ExpressionNode* m_expr; 602 ArgumentsNode* m_args; 603 }; 604 605 class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData { 606 public: 607 EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 608 609 private: 610 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 611 612 ArgumentsNode* m_args; 613 }; 614 615 class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData { 616 public: 617 FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 618 619 private: 620 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 621 622 ExpressionNode* m_expr; 623 ArgumentsNode* m_args; 624 }; 625 626 class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData { 627 public: 628 FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 629 630 private: 631 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 632 633 const Identifier& m_ident; 634 ArgumentsNode* m_args; 635 }; 636 637 class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData { 638 public: 639 FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 640 641 private: 642 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 643 644 ExpressionNode* m_base; 645 ExpressionNode* m_subscript; 646 ArgumentsNode* m_args; 647 }; 648 649 class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData { 650 public: 651 FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 652 653 private: 654 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 655 656 protected: 657 ExpressionNode* m_base; 658 const Identifier& m_ident; 659 ArgumentsNode* m_args; 660 }; 661 662 class CallFunctionCallDotNode : public FunctionCallDotNode { 663 public: 664 CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 665 666 private: 667 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 668 }; 669 670 class ApplyFunctionCallDotNode : public FunctionCallDotNode { 671 public: 672 ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 673 674 private: 675 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 676 }; 677 678 class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData { 679 public: 680 DeleteResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 681 682 private: 683 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 684 685 const Identifier& m_ident; 686 }; 687 688 class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData { 689 public: 690 DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 691 692 private: 693 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 694 695 ExpressionNode* m_base; 696 ExpressionNode* m_subscript; 697 }; 698 699 class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData { 700 public: 701 DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 702 703 private: 704 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 705 706 ExpressionNode* m_base; 707 const Identifier& m_ident; 708 }; 709 710 class DeleteValueNode : public ExpressionNode { 711 public: 712 DeleteValueNode(const JSTokenLocation&, ExpressionNode*); 713 714 private: 715 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 716 717 ExpressionNode* m_expr; 718 }; 719 720 class VoidNode : public ExpressionNode { 721 public: 722 VoidNode(const JSTokenLocation&, ExpressionNode*); 723 724 private: 725 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 726 727 ExpressionNode* m_expr; 728 }; 729 730 class TypeOfResolveNode : public ExpressionNode { 731 public: 732 TypeOfResolveNode(const JSTokenLocation&, const Identifier&); 733 734 const Identifier& identifier() const { return m_ident; } 735 736 private: 737 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 738 739 const Identifier& m_ident; 740 }; 741 742 class TypeOfValueNode : public ExpressionNode { 743 public: 744 TypeOfValueNode(const JSTokenLocation&, ExpressionNode*); 745 746 private: 747 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 748 749 ExpressionNode* m_expr; 750 }; 751 752 class PrefixNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData { 753 public: 754 PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 755 756 protected: 757 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 758 virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0); 759 virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0); 760 virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0); 761 762 ExpressionNode* m_expr; 763 Operator m_operator; 764 }; 765 766 class PostfixNode : public PrefixNode { 767 public: 768 PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 769 770 private: 771 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 772 virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0) override; 773 virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0) override; 774 virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0) override; 775 }; 776 777 class UnaryOpNode : public ExpressionNode { 778 public: 779 UnaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode*, OpcodeID); 780 781 protected: 782 ExpressionNode* expr() { return m_expr; } 783 const ExpressionNode* expr() const { return m_expr; } 784 785 private: 786 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 787 788 OpcodeID opcodeID() const { return m_opcodeID; } 789 790 ExpressionNode* m_expr; 791 OpcodeID m_opcodeID; 792 }; 793 794 class UnaryPlusNode : public UnaryOpNode { 795 public: 796 UnaryPlusNode(const JSTokenLocation&, ExpressionNode*); 797 798 private: 799 virtual ExpressionNode* stripUnaryPlus() override { return expr(); } 800 }; 801 802 class NegateNode : public UnaryOpNode { 803 public: 804 NegateNode(const JSTokenLocation&, ExpressionNode*); 805 }; 806 807 class BitwiseNotNode : public ExpressionNode { 808 public: 809 BitwiseNotNode(const JSTokenLocation&, ExpressionNode*); 810 811 protected: 812 ExpressionNode* expr() { return m_expr; } 813 const ExpressionNode* expr() const { return m_expr; } 814 815 private: 816 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 817 818 ExpressionNode* m_expr; 819 }; 820 821 class LogicalNotNode : public UnaryOpNode { 822 public: 823 LogicalNotNode(const JSTokenLocation&, ExpressionNode*); 824 private: 825 virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override; 826 }; 827 828 class BinaryOpNode : public ExpressionNode { 829 public: 830 BinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); 831 BinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); 832 833 RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0); 834 virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override; 835 836 ExpressionNode* lhs() { return m_expr1; }; 837 ExpressionNode* rhs() { return m_expr2; }; 838 839 private: 840 void tryFoldToBranch(BytecodeGenerator&, TriState& branchCondition, ExpressionNode*& branchExpression); 841 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 842 843 protected: 844 OpcodeID opcodeID() const { return m_opcodeID; } 845 846 protected: 847 ExpressionNode* m_expr1; 848 ExpressionNode* m_expr2; 849 private: 850 OpcodeID m_opcodeID; 851 protected: 852 bool m_rightHasAssignments; 853 }; 854 855 class MultNode : public BinaryOpNode { 856 public: 857 MultNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 858 }; 859 860 class DivNode : public BinaryOpNode { 861 public: 862 DivNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 863 }; 864 865 class ModNode : public BinaryOpNode { 866 public: 867 ModNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 868 }; 869 870 class AddNode : public BinaryOpNode { 871 public: 872 AddNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 873 874 virtual bool isAdd() const override { return true; } 875 }; 876 877 class SubNode : public BinaryOpNode { 878 public: 879 SubNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 880 881 virtual bool isSubtract() const override { return true; } 882 }; 883 884 class LeftShiftNode : public BinaryOpNode { 885 public: 886 LeftShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 887 }; 888 889 class RightShiftNode : public BinaryOpNode { 890 public: 891 RightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 892 }; 893 894 class UnsignedRightShiftNode : public BinaryOpNode { 895 public: 896 UnsignedRightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 897 }; 898 899 class LessNode : public BinaryOpNode { 900 public: 901 LessNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 902 }; 903 904 class GreaterNode : public BinaryOpNode { 905 public: 906 GreaterNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 907 }; 908 909 class LessEqNode : public BinaryOpNode { 910 public: 911 LessEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 912 }; 913 914 class GreaterEqNode : public BinaryOpNode { 915 public: 916 GreaterEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 917 }; 918 919 class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData { 920 public: 921 ThrowableBinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); 922 ThrowableBinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); 923 924 private: 925 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 926 }; 927 928 class InstanceOfNode : public ThrowableBinaryOpNode { 929 public: 930 InstanceOfNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 931 932 private: 933 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 934 }; 935 936 class InNode : public ThrowableBinaryOpNode { 937 public: 938 InNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 939 }; 940 941 class EqualNode : public BinaryOpNode { 942 public: 943 EqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 944 945 private: 946 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 947 }; 948 949 class NotEqualNode : public BinaryOpNode { 950 public: 951 NotEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 952 }; 953 954 class StrictEqualNode : public BinaryOpNode { 955 public: 956 StrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 957 958 private: 959 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 960 }; 961 962 class NotStrictEqualNode : public BinaryOpNode { 963 public: 964 NotStrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 965 }; 966 967 class BitAndNode : public BinaryOpNode { 968 public: 969 BitAndNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 970 }; 971 972 class BitOrNode : public BinaryOpNode { 973 public: 974 BitOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 975 }; 976 977 class BitXOrNode : public BinaryOpNode { 978 public: 979 BitXOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); 980 }; 981 982 // m_expr1 && m_expr2, m_expr1 || m_expr2 983 class LogicalOpNode : public ExpressionNode { 984 public: 985 LogicalOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator); 986 987 private: 988 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 989 virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override; 990 991 ExpressionNode* m_expr1; 992 ExpressionNode* m_expr2; 993 LogicalOperator m_operator; 994 }; 995 996 // The ternary operator, "m_logical ? m_expr1 : m_expr2" 997 class ConditionalNode : public ExpressionNode { 998 public: 999 ConditionalNode(const JSTokenLocation&, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2); 1000 1001 private: 1002 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1003 1004 ExpressionNode* m_logical; 1005 ExpressionNode* m_expr1; 1006 ExpressionNode* m_expr2; 1007 }; 1008 1009 class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData { 1010 public: 1011 ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 1012 1013 private: 1014 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1015 1016 const Identifier& m_ident; 1017 ExpressionNode* m_right; 1018 Operator m_operator; 1019 bool m_rightHasAssignments; 1020 }; 1021 1022 class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData { 1023 public: 1024 AssignResolveNode(const JSTokenLocation&, const Identifier&, ExpressionNode* right); 1025 1026 private: 1027 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1028 1029 const Identifier& m_ident; 1030 ExpressionNode* m_right; 1031 }; 1032 1033 class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData { 1034 public: 1035 ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 1036 1037 private: 1038 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1039 1040 ExpressionNode* m_base; 1041 ExpressionNode* m_subscript; 1042 ExpressionNode* m_right; 1043 unsigned m_operator : 30; 1044 bool m_subscriptHasAssignments : 1; 1045 bool m_rightHasAssignments : 1; 1046 }; 1047 1048 class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData { 1049 public: 1050 AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 1051 1052 private: 1053 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1054 1055 ExpressionNode* m_base; 1056 ExpressionNode* m_subscript; 1057 ExpressionNode* m_right; 1058 bool m_subscriptHasAssignments : 1; 1059 bool m_rightHasAssignments : 1; 1060 }; 1061 1062 class AssignDotNode : public ExpressionNode, public ThrowableExpressionData { 1063 public: 1064 AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 1065 1066 private: 1067 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1068 1069 ExpressionNode* m_base; 1070 const Identifier& m_ident; 1071 ExpressionNode* m_right; 1072 bool m_rightHasAssignments; 1073 }; 1074 1075 class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData { 1076 public: 1077 ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 1078 1079 private: 1080 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1081 1082 ExpressionNode* m_base; 1083 const Identifier& m_ident; 1084 ExpressionNode* m_right; 1085 unsigned m_operator : 31; 1086 bool m_rightHasAssignments : 1; 1087 }; 1088 1089 class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData { 1090 public: 1091 AssignErrorNode(const JSTokenLocation&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 1092 1093 private: 1094 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1095 }; 1096 1097 typedef Vector<ExpressionNode*, 8> ExpressionVector; 1098 1099 class CommaNode : public ExpressionNode, public ParserArenaDeletable { 1100 public: 1101 CommaNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2); 1102 1103 using ParserArenaDeletable::operator new; 1104 1105 void append(ExpressionNode* expr) { ASSERT(expr); m_expressions.append(expr); } 1106 1107 private: 1108 virtual bool isCommaNode() const override { return true; } 1109 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1110 1111 ExpressionVector m_expressions; 1112 }; 1113 1114 class ConstDeclNode : public ExpressionNode { 1115 public: 1116 ConstDeclNode(const JSTokenLocation&, const Identifier&, ExpressionNode*); 1117 1118 bool hasInitializer() const { return m_init; } 1119 const Identifier& ident() { return m_ident; } 1120 1121 private: 1122 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1123 virtual RegisterID* emitCodeSingle(BytecodeGenerator&); 1124 1125 const Identifier& m_ident; 1126 1127 public: 1128 ConstDeclNode* m_next; 1129 1130 private: 1131 ExpressionNode* m_init; 1132 }; 1133 1134 class ConstStatementNode : public StatementNode { 1135 public: 1136 ConstStatementNode(const JSTokenLocation&, ConstDeclNode* next); 1137 1138 private: 1139 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1140 1141 ConstDeclNode* m_next; 1142 }; 1143 1144 class SourceElements : public ParserArenaDeletable { 1145 public: 1146 SourceElements(); 1147 1148 void append(StatementNode*); 1149 1150 StatementNode* singleStatement() const; 1151 StatementNode* lastStatement() const; 1152 1153 void emitBytecode(BytecodeGenerator&, RegisterID* destination); 1154 1155 private: 1156 Vector<StatementNode*> m_statements; 1157 }; 1158 1159 class BlockNode : public StatementNode { 1160 public: 1161 BlockNode(const JSTokenLocation&, SourceElements* = 0); 1162 1163 StatementNode* singleStatement() const; 1164 StatementNode* lastStatement() const; 1165 1166 private: 1167 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1168 1169 virtual bool isBlock() const override { return true; } 1170 1171 SourceElements* m_statements; 1172 }; 1173 1174 class EmptyStatementNode : public StatementNode { 1175 public: 1176 EmptyStatementNode(const JSTokenLocation&); 1177 1178 private: 1179 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1180 1181 virtual bool isEmptyStatement() const override { return true; } 1182 }; 1183 1184 class DebuggerStatementNode : public StatementNode { 1185 public: 1186 DebuggerStatementNode(const JSTokenLocation&); 1187 1188 private: 1189 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1190 }; 1191 1192 class ExprStatementNode : public StatementNode { 1193 public: 1194 ExprStatementNode(const JSTokenLocation&, ExpressionNode*); 1195 1196 ExpressionNode* expr() const { return m_expr; } 1197 1198 private: 1199 virtual bool isExprStatement() const override { return true; } 1200 1201 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1202 1203 ExpressionNode* m_expr; 1204 }; 1205 1206 class VarStatementNode : public StatementNode { 1207 public: 1208 VarStatementNode(const JSTokenLocation&, ExpressionNode*); 1209 private: 1210 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1211 1212 ExpressionNode* m_expr; 1213 }; 1214 1215 class IfElseNode : public StatementNode { 1216 public: 1217 IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock); 1218 1219 private: 1220 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1221 bool tryFoldBreakAndContinue(BytecodeGenerator&, StatementNode* ifBlock, 1222 Label*& trueTarget, FallThroughMode&); 1223 1224 ExpressionNode* m_condition; 1225 StatementNode* m_ifBlock; 1226 StatementNode* m_elseBlock; 1227 }; 1228 1229 class DoWhileNode : public StatementNode { 1230 public: 1231 DoWhileNode(const JSTokenLocation&, StatementNode*, ExpressionNode*); 1232 1233 private: 1234 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1235 1236 StatementNode* m_statement; 1237 ExpressionNode* m_expr; 1238 }; 1239 1240 class WhileNode : public StatementNode { 1241 public: 1242 WhileNode(const JSTokenLocation&, ExpressionNode*, StatementNode*); 1243 1244 private: 1245 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1246 1247 ExpressionNode* m_expr; 1248 StatementNode* m_statement; 1249 }; 1250 1251 class ForNode : public StatementNode { 1252 public: 1253 ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*); 1254 1255 private: 1256 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1257 1258 ExpressionNode* m_expr1; 1259 ExpressionNode* m_expr2; 1260 ExpressionNode* m_expr3; 1261 StatementNode* m_statement; 1262 }; 1263 1264 class DeconstructionPatternNode; 1265 1266 class EnumerationNode : public StatementNode, public ThrowableExpressionData { 1267 public: 1268 EnumerationNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*); 1269 EnumerationNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*); 1270 1271 protected: 1272 ExpressionNode* m_lexpr; 1273 ExpressionNode* m_expr; 1274 StatementNode* m_statement; 1275 }; 1276 1277 class ForInNode : public EnumerationNode { 1278 public: 1279 ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*); 1280 ForInNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*); 1281 1282 private: 1283 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1284 }; 1285 1286 class ForOfNode : public EnumerationNode { 1287 public: 1288 ForOfNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*); 1289 ForOfNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*); 1290 1291 private: 1292 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1293 }; 1294 1295 class ContinueNode : public StatementNode, public ThrowableExpressionData { 1296 public: 1297 ContinueNode(VM*, const JSTokenLocation&); 1298 ContinueNode(const JSTokenLocation&, const Identifier&); 1299 Label* trivialTarget(BytecodeGenerator&); 1300 1301 private: 1302 virtual bool isContinue() const override { return true; } 1303 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1304 1305 const Identifier& m_ident; 1306 }; 1307 1308 class BreakNode : public StatementNode, public ThrowableExpressionData { 1309 public: 1310 BreakNode(VM*, const JSTokenLocation&); 1311 BreakNode(const JSTokenLocation&, const Identifier&); 1312 Label* trivialTarget(BytecodeGenerator&); 1313 1314 private: 1315 virtual bool isBreak() const override { return true; } 1316 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1317 1318 const Identifier& m_ident; 1319 }; 1320 1321 class ReturnNode : public StatementNode, public ThrowableExpressionData { 1322 public: 1323 ReturnNode(const JSTokenLocation&, ExpressionNode* value); 1324 1325 ExpressionNode* value() { return m_value; } 1326 1327 private: 1328 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1329 1330 virtual bool isReturnNode() const override { return true; } 1331 1332 ExpressionNode* m_value; 1333 }; 1334 1335 class WithNode : public StatementNode { 1336 public: 1337 WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, const JSTextPosition& divot, uint32_t expressionLength); 1338 1339 private: 1340 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1341 1342 ExpressionNode* m_expr; 1343 StatementNode* m_statement; 1344 JSTextPosition m_divot; 1345 uint32_t m_expressionLength; 1346 }; 1347 1348 class LabelNode : public StatementNode, public ThrowableExpressionData { 1349 public: 1350 LabelNode(const JSTokenLocation&, const Identifier& name, StatementNode*); 1351 1352 private: 1353 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1354 1355 const Identifier& m_name; 1356 StatementNode* m_statement; 1357 }; 1358 1359 class ThrowNode : public StatementNode, public ThrowableExpressionData { 1360 public: 1361 ThrowNode(const JSTokenLocation&, ExpressionNode*); 1362 1363 private: 1364 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1365 1366 ExpressionNode* m_expr; 1367 }; 1368 1369 class TryNode : public StatementNode { 1370 public: 1371 TryNode(const JSTokenLocation&, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock); 1372 1373 private: 1374 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1375 1376 StatementNode* m_tryBlock; 1377 const Identifier& m_exceptionIdent; 1378 StatementNode* m_catchBlock; 1379 StatementNode* m_finallyBlock; 1380 }; 1381 1382 class ParameterNode : public ParserArenaDeletable { 1383 public: 1384 ParameterNode(PassRefPtr<DeconstructionPatternNode>); 1385 ParameterNode(ParameterNode*, PassRefPtr<DeconstructionPatternNode>); 1386 1387 DeconstructionPatternNode* pattern() const { return m_pattern.get(); } 1388 ParameterNode* nextParam() const { return m_next; } 1389 1390 private: 1391 RefPtr<DeconstructionPatternNode> m_pattern; 1392 ParameterNode* m_next; 1393 }; 1394 1395 class ScopeNode : public StatementNode, public ParserArenaRefCounted { 1396 public: 1397 typedef DeclarationStacks::VarStack VarStack; 1398 typedef DeclarationStacks::FunctionStack FunctionStack; 1399 1400 ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext); 1401 ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants); 1402 1403 using ParserArenaRefCounted::operator new; 1404 1405 void destroyData() 1406 { 1407 m_arena.reset(); 1408 m_varStack.clear(); 1409 m_functionStack.clear(); 1410 m_statements = 0; 1411 m_capturedVariables.clear(); 1412 } 1413 1414 const SourceCode& source() const { return m_source; } 1415 const String& sourceURL() const { return m_source.provider()->url(); } 1416 intptr_t sourceID() const { return m_source.providerID(); } 1417 1418 int startLine() const { return m_startLineNumber; } 1419 int startStartOffset() const { return m_startStartOffset; } 1420 int startLineStartOffset() const { return m_startLineStartOffset; } 1421 1422 void setFeatures(CodeFeatures features) { m_features = features; } 1423 CodeFeatures features() { return m_features; } 1424 1425 bool usesEval() const { return m_features & EvalFeature; } 1426 bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); } 1427 bool modifiesParameter() const { return m_features & ModifiedParameterFeature; } 1428 bool isStrictMode() const { return m_features & StrictModeFeature; } 1429 void setUsesArguments() { m_features |= ArgumentsFeature; } 1430 bool usesThis() const { return m_features & ThisFeature; } 1431 bool needsActivationForMoreThanVariables() const { return m_features & (EvalFeature | WithFeature | CatchFeature); } 1432 bool needsActivation() const { return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); } 1433 bool hasCapturedVariables() const { return !!m_capturedVariables.size(); } 1434 size_t capturedVariableCount() const { return m_capturedVariables.size(); } 1435 const IdentifierSet& capturedVariables() const { return m_capturedVariables; } 1436 bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); } 1437 1438 VarStack& varStack() { return m_varStack; } 1439 FunctionStack& functionStack() { return m_functionStack; } 1440 1441 int neededConstants() 1442 { 1443 // We may need 2 more constants than the count given by the parser, 1444 // because of the various uses of jsUndefined() and jsNull(). 1445 return m_numConstants + 2; 1446 } 1447 1448 StatementNode* singleStatement() const; 1449 1450 void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination); 1451 1452 void setClosedVariables(Vector<RefPtr<StringImpl>>&&) { } 1453 1454 protected: 1455 void setSource(const SourceCode& source) { m_source = source; } 1456 ParserArena m_arena; 1457 1458 int m_startLineNumber; 1459 unsigned m_startStartOffset; 1460 unsigned m_startLineStartOffset; 1461 1462 private: 1463 CodeFeatures m_features; 1464 SourceCode m_source; 1465 VarStack m_varStack; 1466 FunctionStack m_functionStack; 1467 int m_numConstants; 1468 SourceElements* m_statements; 1469 IdentifierSet m_capturedVariables; 1470 }; 1471 1472 class ProgramNode : public ScopeNode { 1473 public: 1474 static const bool isFunctionNode = false; 1475 static PassRefPtr<ProgramNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1476 1477 unsigned startColumn() const { return m_startColumn; } 1478 unsigned endColumn() const { return m_endColumn; } 1479 1480 static const bool scopeIsFunction = false; 1481 1482 void setClosedVariables(Vector<RefPtr<StringImpl>>&&); 1483 const Vector<RefPtr<StringImpl>>& closedVariables() const { return m_closedVariables; } 1484 private: 1485 ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1486 1487 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1488 Vector<RefPtr<StringImpl>> m_closedVariables; 1489 unsigned m_startColumn; 1490 unsigned m_endColumn; 1491 }; 1492 1493 class EvalNode : public ScopeNode { 1494 public: 1495 static const bool isFunctionNode = false; 1496 static PassRefPtr<EvalNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1497 1498 ALWAYS_INLINE unsigned startColumn() const { return 0; } 1499 unsigned endColumn() const { return m_endColumn; } 1500 1501 static const bool scopeIsFunction = false; 1502 1503 private: 1504 EvalNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1505 1506 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1507 1508 unsigned m_endColumn; 1509 }; 1510 1511 class FunctionParameters : public RefCounted<FunctionParameters> { 1512 WTF_MAKE_FAST_ALLOCATED; 1513 WTF_MAKE_NONCOPYABLE(FunctionParameters); 1514 public: 1515 static PassRefPtr<FunctionParameters> create(ParameterNode*); 1516 ~FunctionParameters(); 1517 1518 unsigned size() const { return m_size; } 1519 DeconstructionPatternNode* at(unsigned index) { ASSERT(index < m_size); return patterns()[index]; } 1520 1521 private: 1522 FunctionParameters(ParameterNode*, unsigned size); 1523 1524 DeconstructionPatternNode** patterns() { return &m_storage; } 1525 1526 unsigned m_size; 1527 DeconstructionPatternNode* m_storage; 1528 }; 1529 1530 class FunctionBodyNode : public ScopeNode { 1531 public: 1532 static const bool isFunctionNode = true; 1533 static FunctionBodyNode* create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, bool isStrictMode); 1534 static PassRefPtr<FunctionBodyNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1535 1536 FunctionParameters* parameters() const { return m_parameters.get(); } 1537 size_t parameterCount() const { return m_parameters->size(); } 1538 1539 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1540 1541 void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionMode); 1542 void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionMode); 1543 1544 void overrideName(const Identifier& ident) { m_ident = ident; } 1545 const Identifier& ident() { return m_ident; } 1546 void setInferredName(const Identifier& inferredName) { ASSERT(!inferredName.isNull()); m_inferredName = inferredName; } 1547 const Identifier& inferredName() { return m_inferredName.isEmpty() ? m_ident : m_inferredName; } 1548 1549 FunctionMode functionMode() { return m_functionMode; } 1550 1551 void setFunctionNameStart(int functionNameStart) { m_functionNameStart = functionNameStart; } 1552 int functionNameStart() const { return m_functionNameStart; } 1553 unsigned startColumn() const { return m_startColumn; } 1554 unsigned endColumn() const { return m_endColumn; } 1555 1556 void setEndPosition(JSTextPosition); 1557 1558 static const bool scopeIsFunction = true; 1559 1560 private: 1561 FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, bool inStrictContext); 1562 FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1563 1564 Identifier m_ident; 1565 Identifier m_inferredName; 1566 FunctionMode m_functionMode; 1567 RefPtr<FunctionParameters> m_parameters; 1568 int m_functionNameStart; 1569 unsigned m_startColumn; 1570 unsigned m_endColumn; 1571 }; 1572 1573 class FuncExprNode : public ExpressionNode { 1574 public: 1575 FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0); 1576 1577 FunctionBodyNode* body() { return m_body; } 1578 1579 private: 1580 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1581 1582 virtual bool isFuncExprNode() const override { return true; } 1583 1584 FunctionBodyNode* m_body; 1585 }; 1586 1587 class DeconstructionPatternNode : public RefCounted<DeconstructionPatternNode> { 1588 WTF_MAKE_NONCOPYABLE(DeconstructionPatternNode); 1589 WTF_MAKE_FAST_ALLOCATED; 1590 1591 public: 1592 virtual void collectBoundIdentifiers(Vector<Identifier>&) const = 0; 1593 virtual void bindValue(BytecodeGenerator&, RegisterID* source) const = 0; 1594 virtual void toString(StringBuilder&) const = 0; 1595 1596 virtual bool isBindingNode() const { return false; } 1597 virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID*, ExpressionNode*) { return 0; } 1598 1599 virtual ~DeconstructionPatternNode() = 0; 1600 1601 protected: 1602 DeconstructionPatternNode(VM*); 1603 }; 1604 1605 class ArrayPatternNode : public DeconstructionPatternNode { 1606 public: 1607 static PassRefPtr<ArrayPatternNode> create(VM*); 1608 void appendIndex(const JSTokenLocation&, DeconstructionPatternNode* node) 1609 { 1610 m_targetPatterns.append(node); 1611 } 1612 1613 private: 1614 ArrayPatternNode(VM*); 1615 virtual void collectBoundIdentifiers(Vector<Identifier>&) const override; 1616 virtual void bindValue(BytecodeGenerator&, RegisterID*) const override; 1617 virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID* dst, ExpressionNode*) override; 1618 virtual void toString(StringBuilder&) const override; 1619 1620 Vector<RefPtr<DeconstructionPatternNode>> m_targetPatterns; 1621 }; 1622 1623 class ObjectPatternNode : public DeconstructionPatternNode { 1624 public: 1625 static PassRefPtr<ObjectPatternNode> create(VM*); 1626 void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DeconstructionPatternNode* pattern) 1627 { 1628 m_targetPatterns.append(Entry(identifier, wasString, pattern)); 1629 } 1630 1631 private: 1632 ObjectPatternNode(VM*); 1633 virtual void collectBoundIdentifiers(Vector<Identifier>&) const override; 1634 virtual void bindValue(BytecodeGenerator&, RegisterID*) const override; 1635 virtual void toString(StringBuilder&) const override; 1636 struct Entry { 1637 Entry(const Identifier& propertyName, bool wasString, DeconstructionPatternNode* pattern) 1638 : propertyName(propertyName) 1639 , wasString(wasString) 1640 , pattern(pattern) 1641 { 1642 } 1643 Identifier propertyName; 1644 bool wasString; 1645 RefPtr<DeconstructionPatternNode> pattern; 1646 }; 1647 Vector<Entry> m_targetPatterns; 1648 }; 1649 1650 class BindingNode : public DeconstructionPatternNode { 1651 public: 1652 static PassRefPtr<BindingNode> create(VM*, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end); 1653 const Identifier& boundProperty() const { return m_boundProperty; } 1654 1655 const JSTextPosition& divotStart() const { return m_divotStart; } 1656 const JSTextPosition& divotEnd() const { return m_divotEnd; } 1657 1658 private: 1659 BindingNode(VM*, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end); 1660 1661 virtual void collectBoundIdentifiers(Vector<Identifier>&) const override; 1662 virtual void bindValue(BytecodeGenerator&, RegisterID*) const override; 1663 virtual void toString(StringBuilder&) const override; 1664 1665 virtual bool isBindingNode() const override { return true; } 1666 1667 JSTextPosition m_divotStart; 1668 JSTextPosition m_divotEnd; 1669 Identifier m_boundProperty; 1670 }; 1671 1672 class DeconstructingAssignmentNode : public ExpressionNode, public ParserArenaDeletable { 1673 public: 1674 DeconstructingAssignmentNode(const JSTokenLocation&, PassRefPtr<DeconstructionPatternNode>, ExpressionNode*); 1675 DeconstructionPatternNode* bindings() { return m_bindings.get(); } 1676 1677 using ParserArenaDeletable::operator new; 1678 1679 private: 1680 virtual bool isAssignmentLocation() const override { return true; } 1681 virtual bool isDeconstructionNode() const override { return true; } 1682 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1683 1684 RefPtr<DeconstructionPatternNode> m_bindings; 1685 ExpressionNode* m_initializer; 1686 }; 1687 1688 class FuncDeclNode : public StatementNode { 1689 public: 1690 FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0); 1691 1692 FunctionBodyNode* body() { return m_body; } 1693 1694 private: 1695 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1696 1697 FunctionBodyNode* m_body; 1698 }; 1699 1700 class CaseClauseNode : public ParserArenaFreeable { 1701 public: 1702 CaseClauseNode(ExpressionNode*, SourceElements* = 0); 1703 1704 ExpressionNode* expr() const { return m_expr; } 1705 1706 void emitBytecode(BytecodeGenerator&, RegisterID* destination); 1707 1708 private: 1709 ExpressionNode* m_expr; 1710 SourceElements* m_statements; 1711 }; 1712 1713 class ClauseListNode : public ParserArenaFreeable { 1714 public: 1715 ClauseListNode(CaseClauseNode*); 1716 ClauseListNode(ClauseListNode*, CaseClauseNode*); 1717 1718 CaseClauseNode* getClause() const { return m_clause; } 1719 ClauseListNode* getNext() const { return m_next; } 1720 1721 private: 1722 CaseClauseNode* m_clause; 1723 ClauseListNode* m_next; 1724 }; 1725 1726 class CaseBlockNode : public ParserArenaFreeable { 1727 public: 1728 CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2); 1729 1730 void emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination); 1731 1732 private: 1733 SwitchInfo::SwitchType tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num); 1734 static const size_t s_tableSwitchMinimum = 3; 1735 ClauseListNode* m_list1; 1736 CaseClauseNode* m_defaultClause; 1737 ClauseListNode* m_list2; 1738 }; 1739 1740 class SwitchNode : public StatementNode { 1741 public: 1742 SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*); 1743 1744 private: 1745 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1746 1747 ExpressionNode* m_expr; 1748 CaseBlockNode* m_block; 1749 }; 1750 1751 struct ElementList { 1752 ElementNode* head; 1753 ElementNode* tail; 1754 }; 1755 1756 struct PropertyList { 1757 PropertyListNode* head; 1758 PropertyListNode* tail; 1759 }; 1760 1761 struct ArgumentList { 1762 ArgumentListNode* head; 1763 ArgumentListNode* tail; 1764 }; 1765 1766 struct ConstDeclList { 1767 ConstDeclNode* head; 1768 ConstDeclNode* tail; 1769 }; 1770 1771 struct ParameterList { 1772 ParameterNode* head; 1773 ParameterNode* tail; 1774 }; 1775 1776 struct ClauseList { 1777 ClauseListNode* head; 1778 ClauseListNode* tail; 1779 }; 1780 1781} // namespace JSC 1782 1783#endif // Nodes_h 1784