Changeset 29836 in webkit for trunk/JavaScriptCore
- Timestamp:
- Jan 28, 2008, 12:50:45 PM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r29825 r29836 1 2008-01-28 Sam Weinig <[email protected]> 2 3 Rubber-stamped by Darin Adler. 4 5 - Fix whitespace in nodes.h/cpp and nodes2string.cpp. 6 7 (NOTE: Specific changed functions elided for space and clarity) 8 * kjs/nodes.cpp: 9 * kjs/nodes.h: 10 * kjs/nodes2string.cpp: 11 1 12 2008-01-27 Sam Weinig <[email protected]> 2 13 -
trunk/JavaScriptCore/kjs/nodes.cpp
r29825 r29836 1 1 /* 2 3 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007Apple Inc. All rights reserved.5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 2 * Copyright (C) 1999-2002 Harri Porten ([email protected]) 3 * Copyright (C) 2001 Peter Kelly ([email protected]) 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 5 * Copyright (C) 2007 Cameron Zwarich ([email protected]) 6 * Copyright (C) 2007 Maks Orlovich 7 * Copyright (C) 2007 Eric Seidel <[email protected]> 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 25 26 26 #include "config.h" … … 45 45 namespace KJS { 46 46 47 48 49 50 51 47 class FunctionBodyNodeWithDebuggerHooks : public FunctionBodyNode { 48 public: 49 FunctionBodyNodeWithDebuggerHooks(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 50 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 51 }; 52 52 53 53 #define KJS_CHECKEXCEPTION \ 54 54 if (exec->hadException()) \ 55 55 return rethrowException(exec); 56 56 57 57 #define KJS_CHECKEXCEPTIONVALUE \ 58 58 if (exec->hadException()) { \ 59 59 handleException(exec); \ 60 60 return jsUndefined(); \ 61 61 } 62 62 63 63 #define KJS_CHECKEXCEPTIONNUMBER \ 64 64 if (exec->hadException()) { \ 65 65 handleException(exec); \ 66 66 return 0; \ 67 67 } 68 68 69 69 #define KJS_CHECKEXCEPTIONBOOLEAN \ 70 70 if (exec->hadException()) { \ 71 71 handleException(exec); \ 72 72 return false; \ 73 73 } 74 74 75 75 #define KJS_CHECKEXCEPTIONVOID \ 76 76 if (exec->hadException()) { \ 77 77 handleException(exec); \ 78 78 return; \ 79 79 } 80 80 81 81 #if !ASSERT_DISABLED 82 82 static inline bool canSkipLookup(ExecState* exec, const Identifier& ident) 83 83 { 84 // Static lookup in EvalCode is impossible because variables aren't DontDelete. 84 // Static lookup in EvalCode is impossible because variables aren't DontDelete. 85 85 // Static lookup in GlobalCode may be possible, but we haven't implemented support for it yet. 86 86 if (exec->codeType() != FunctionCode) … … 94 94 if (!exec->variableObject()->symbolTable().contains(ident.ustring().rep())) 95 95 return false; 96 96 97 97 return true; 98 98 } … … 113 113 static WTFLogChannel LogKJSNodeLeaks = { 0x00000000, "", WTFLogChannelOn }; 114 114 115 struct ParserRefCountedCounter { 116 static unsigned count; 117 ParserRefCountedCounter() 118 { 119 if (count) 120 LOG(KJSNodeLeaks, "LEAK: %u KJS::Node\n", count); 115 struct ParserRefCountedCounter { 116 static unsigned count; 117 ParserRefCountedCounter() 118 { 119 if (count) 120 LOG(KJSNodeLeaks, "LEAK: %u KJS::Node\n", count); 121 121 } 122 122 }; … … 133 133 ++ParserRefCountedCounter::count; 134 134 #endif 135 if (!newTrackedObjects)136 newTrackedObjects = new HashSet<ParserRefCounted*>;137 newTrackedObjects->add(this);138 ASSERT(newTrackedObjects->contains(this));135 if (!newTrackedObjects) 136 newTrackedObjects = new HashSet<ParserRefCounted*>; 137 newTrackedObjects->add(this); 138 ASSERT(newTrackedObjects->contains(this)); 139 139 } 140 140 … … 156 156 return; 157 157 } 158 } 158 } 159 159 160 160 ASSERT(!newTrackedObjects || !newTrackedObjects->contains(this)); 161 161 162 162 if (!trackedObjectExtraRefCounts) 163 163 trackedObjectExtraRefCounts = new HashCountedSet<ParserRefCounted*>; … … 168 168 { 169 169 ASSERT(!newTrackedObjects || !newTrackedObjects->contains(this)); 170 170 171 171 if (!trackedObjectExtraRefCounts) { 172 172 delete this; … … 187 187 return 0; 188 188 } 189 189 190 190 ASSERT(!newTrackedObjects || !newTrackedObjects->contains(this)); 191 191 … … 251 251 } 252 252 253 static void substitute(UString &string, const UString &substring) KJS_FAST_CALL;254 static void substitute(UString &string, const UString &substring)253 static void substitute(UString& string, const UString& substring) KJS_FAST_CALL; 254 static void substitute(UString& string, const UString& substring) 255 255 { 256 256 int position = string.find("%s"); … … 286 286 } 287 287 288 JSValue *Node::throwError(ExecState* exec, ErrorType e, const char *msg)288 JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg) 289 289 { 290 290 return KJS::throwError(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec)); 291 291 } 292 292 293 JSValue *Node::throwError(ExecState* exec, ErrorType e, const char* msg, const char* string)293 JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, const char* string) 294 294 { 295 295 UString message = msg; … … 298 298 } 299 299 300 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, JSValue *v, Node *expr)300 JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* expr) 301 301 { 302 302 UString message = msg; … … 306 306 } 307 307 308 309 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, const Identifier &label) 308 JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, const Identifier& label) 310 309 { 311 310 UString message = msg; … … 314 313 } 315 314 316 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, JSValue *v, Node *e1, Node *e2)315 JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* e1, Node* e2) 317 316 { 318 317 UString message = msg; … … 323 322 } 324 323 325 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, JSValue *v, Node *expr, const Identifier &label)324 JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* expr, const Identifier& label) 326 325 { 327 326 UString message = msg; … … 332 331 } 333 332 334 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, JSValue *v, const Identifier &label)333 JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue* v, const Identifier& label) 335 334 { 336 335 UString message = msg; … … 340 339 } 341 340 342 JSValue *Node::throwUndefinedVariableError(ExecState *exec, const Identifier &ident)341 JSValue* Node::throwUndefinedVariableError(ExecState* exec, const Identifier& ident) 343 342 { 344 343 return throwError(exec, ReferenceError, "Can't find variable: %s", ident); … … 377 376 // ------------------------------ StatementNode -------------------------------- 378 377 379 StatementNode::StatementNode() 378 StatementNode::StatementNode() 380 379 : m_lastLine(-1) 381 380 { … … 430 429 // ------------------------------ NullNode ------------------------------------- 431 430 432 JSValue *NullNode::evaluate(ExecState *)433 { 434 return jsNull();431 JSValue* NullNode::evaluate(ExecState* ) 432 { 433 return jsNull(); 435 434 } 436 435 … … 456 455 return jsNumberCell(m_double); 457 456 } 458 457 459 458 double NumberNode::evaluateToNumber(ExecState*) 460 459 { … … 502 501 JSValue* StringNode::evaluate(ExecState*) 503 502 { 504 return jsOwnedString(m_value);503 return jsOwnedString(m_value); 505 504 } 506 505 … … 514 513 return !m_value.isEmpty(); 515 514 } 516 515 517 516 // ------------------------------ RegExpNode ----------------------------------- 518 517 … … 525 524 526 525 // ECMA 11.1.1 527 JSValue *ThisNode::evaluate(ExecState *exec)528 { 529 return exec->thisValue();526 JSValue* ThisNode::evaluate(ExecState* exec) 527 { 528 return exec->thisValue(); 530 529 } 531 530 … … 535 534 JSValue* ResolveNode::inlineEvaluate(ExecState* exec) 536 535 { 537 // Check for missed optimization opportunity.538 ASSERT(!canSkipLookup(exec, m_ident));539 540 const ScopeChain& chain = exec->scopeChain();541 ScopeChainIterator iter = chain.begin();542 ScopeChainIterator end = chain.end();543 544 // we must always have something in the scope chain545 ASSERT(iter != end);546 547 PropertySlot slot;548 do {549 JSObject *o = *iter;550 551 if (o->getPropertySlot(exec, m_ident, slot))552 return slot.getValue(exec, o, m_ident);553 554 ++iter;555 } while (iter != end);556 557 return throwUndefinedVariableError(exec, m_ident);536 // Check for missed optimization opportunity. 537 ASSERT(!canSkipLookup(exec, m_ident)); 538 539 const ScopeChain& chain = exec->scopeChain(); 540 ScopeChainIterator iter = chain.begin(); 541 ScopeChainIterator end = chain.end(); 542 543 // we must always have something in the scope chain 544 ASSERT(iter != end); 545 546 PropertySlot slot; 547 do { 548 JSObject* o = *iter; 549 550 if (o->getPropertySlot(exec, m_ident, slot)) 551 return slot.getValue(exec, o, m_ident); 552 553 ++iter; 554 } while (iter != end); 555 556 return throwUndefinedVariableError(exec, m_ident); 558 557 } 559 558 … … 640 639 641 640 // ECMA 11.1.4 642 JSValue *ElementNode::evaluate(ExecState *exec)643 { 644 JSObject* array = exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList());645 int length = 0;646 for (ElementNode *n = this; n; n = n->m_next.get()) {647 JSValue *val = n->m_node->evaluate(exec);648 KJS_CHECKEXCEPTIONVALUE649 length += n->m_elision;650 array->put(exec, length++, val);651 }652 return array;641 JSValue* ElementNode::evaluate(ExecState* exec) 642 { 643 JSObject* array = exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList()); 644 int length = 0; 645 for (ElementNode* n = this; n; n = n->m_next.get()) { 646 JSValue* val = n->m_node->evaluate(exec); 647 KJS_CHECKEXCEPTIONVALUE 648 length += n->m_elision; 649 array->put(exec, length++, val); 650 } 651 return array; 653 652 } 654 653 … … 661 660 } 662 661 663 664 662 // ECMA 11.1.4 665 JSValue *ArrayNode::evaluate(ExecState *exec)666 { 667 JSObject *array;668 int length;669 670 if (m_element) {671 array = static_cast<JSObject*>(m_element->evaluate(exec));672 KJS_CHECKEXCEPTIONVALUE673 length = m_opt? array->get(exec, exec->propertyNames().length)->toInt32(exec) : 0;674 } else {675 JSValue* newArr = exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList());676 array = static_cast<JSObject*>(newArr);677 length = 0;678 }679 680 if (m_opt)681 array->put(exec, exec->propertyNames().length, jsNumber(m_elision + length), DontEnum | DontDelete);682 683 return array;663 JSValue* ArrayNode::evaluate(ExecState* exec) 664 { 665 JSObject* array; 666 int length; 667 668 if (m_element) { 669 array = static_cast<JSObject*>(m_element->evaluate(exec)); 670 KJS_CHECKEXCEPTIONVALUE 671 length = m_optional ? array->get(exec, exec->propertyNames().length)->toInt32(exec) : 0; 672 } else { 673 JSValue* newArr = exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList()); 674 array = static_cast<JSObject*>(newArr); 675 length = 0; 676 } 677 678 if (m_optional) 679 array->put(exec, exec->propertyNames().length, jsNumber(m_elision + length), DontEnum | DontDelete); 680 681 return array; 684 682 } 685 683 … … 693 691 694 692 // ECMA 11.1.5 695 JSValue *ObjectLiteralNode::evaluate(ExecState *exec)696 { 697 if (m_list)698 return m_list->evaluate(exec);699 700 return exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());693 JSValue* ObjectLiteralNode::evaluate(ExecState* exec) 694 { 695 if (m_list) 696 return m_list->evaluate(exec); 697 698 return exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList()); 701 699 } 702 700 … … 711 709 712 710 // ECMA 11.1.5 713 JSValue *PropertyListNode::evaluate(ExecState *exec)714 { 715 JSObject* obj = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());716 717 for (PropertyListNode *p = this; p; p = p->m_next.get()) {718 JSValue *v = p->m_node->m_assign->evaluate(exec);719 KJS_CHECKEXCEPTIONVALUE720 721 switch (p->m_node->m_type) {722 case PropertyNode::Getter:723 ASSERT(v->isObject());724 obj->defineGetter(exec, p->m_node->name(), static_cast<JSObject *>(v));725 break;726 case PropertyNode::Setter:727 ASSERT(v->isObject());728 obj->defineSetter(exec, p->m_node->name(), static_cast<JSObject *>(v));729 break;730 case PropertyNode::Constant:731 obj->put(exec, p->m_node->name(), v);732 break;733 }734 }735 736 return obj;711 JSValue* PropertyListNode::evaluate(ExecState* exec) 712 { 713 JSObject* obj = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList()); 714 715 for (PropertyListNode* p = this; p; p = p->m_next.get()) { 716 JSValue* v = p->m_node->m_assign->evaluate(exec); 717 KJS_CHECKEXCEPTIONVALUE 718 719 switch (p->m_node->m_type) { 720 case PropertyNode::Getter: 721 ASSERT(v->isObject()); 722 obj->defineGetter(exec, p->m_node->name(), static_cast<JSObject* >(v)); 723 break; 724 case PropertyNode::Setter: 725 ASSERT(v->isObject()); 726 obj->defineSetter(exec, p->m_node->name(), static_cast<JSObject* >(v)); 727 break; 728 case PropertyNode::Constant: 729 obj->put(exec, p->m_node->name(), v); 730 break; 731 } 732 } 733 734 return obj; 737 735 } 738 736 … … 745 743 746 744 // ECMA 11.1.5 747 JSValue *PropertyNode::evaluate(ExecState*)748 { 749 ASSERT(false);750 return jsNull();745 JSValue* PropertyNode::evaluate(ExecState*) 746 { 747 ASSERT(false); 748 return jsNull(); 751 749 } 752 750 … … 762 760 JSValue* BracketAccessorNode::inlineEvaluate(ExecState* exec) 763 761 { 764 JSValue* v1 = m_base->evaluate(exec);765 KJS_CHECKEXCEPTIONVALUE766 JSValue* v2 = m_subscript->evaluate(exec);767 KJS_CHECKEXCEPTIONVALUE768 JSObject* o = v1->toObject(exec);769 uint32_t i;770 if (v2->getUInt32(i))771 return o->get(exec, i);772 return o->get(exec, Identifier(v2->toString(exec)));762 JSValue* v1 = m_base->evaluate(exec); 763 KJS_CHECKEXCEPTIONVALUE 764 JSValue* v2 = m_subscript->evaluate(exec); 765 KJS_CHECKEXCEPTIONVALUE 766 JSObject* o = v1->toObject(exec); 767 uint32_t i; 768 if (v2->getUInt32(i)) 769 return o->get(exec, i); 770 return o->get(exec, Identifier(v2->toString(exec))); 773 771 } 774 772 … … 804 802 KJS_CHECKEXCEPTIONNUMBER 805 803 return v->toUInt32(exec); 806 } 804 } 807 805 808 806 // ------------------------------ DotAccessorNode -------------------------------- … … 852 850 KJS_CHECKEXCEPTIONNUMBER 853 851 return v->toUInt32(exec); 854 } 852 } 855 853 856 854 // ------------------------------ ArgumentListNode ----------------------------- … … 867 865 void ArgumentListNode::evaluateList(ExecState* exec, List& list) 868 866 { 869 for (ArgumentListNode *n = this; n; n = n->m_next.get()) {870 JSValue *v = n->m_expr->evaluate(exec);871 KJS_CHECKEXCEPTIONVOID872 list.append(v);873 }867 for (ArgumentListNode* n = this; n; n = n->m_next.get()) { 868 JSValue* v = n->m_expr->evaluate(exec); 869 KJS_CHECKEXCEPTIONVOID 870 list.append(v); 871 } 874 872 } 875 873 … … 895 893 JSValue* NewExprNode::inlineEvaluate(ExecState* exec) 896 894 { 897 JSValue* v = m_expr->evaluate(exec);898 KJS_CHECKEXCEPTIONVALUE899 900 List argList;901 if (m_args) {902 m_args->evaluateList(exec, argList);903 KJS_CHECKEXCEPTIONVALUE904 }905 906 if (!v->isObject())907 return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, m_expr.get());908 909 JSObject *constr = static_cast<JSObject*>(v);910 if (!constr->implementsConstruct())911 return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, m_expr.get());912 913 return constr->construct(exec, argList);895 JSValue* v = m_expr->evaluate(exec); 896 KJS_CHECKEXCEPTIONVALUE 897 898 List argList; 899 if (m_args) { 900 m_args->evaluateList(exec, argList); 901 KJS_CHECKEXCEPTIONVALUE 902 } 903 904 if (!v->isObject()) 905 return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, m_expr.get()); 906 907 JSObject* constr = static_cast<JSObject*>(v); 908 if (!constr->implementsConstruct()) 909 return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, m_expr.get()); 910 911 return constr->construct(exec, argList); 914 912 } 915 913 … … 945 943 KJS_CHECKEXCEPTIONNUMBER 946 944 return v->toUInt32(exec); 947 } 945 } 948 946 949 947 void FunctionCallValueNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack) … … 954 952 955 953 // ECMA 11.2.3 956 JSValue *FunctionCallValueNode::evaluate(ExecState *exec)957 { 958 JSValue *v = m_expr->evaluate(exec);959 KJS_CHECKEXCEPTIONVALUE960 961 if (!v->isObject()) {962 return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_expr.get());963 }964 965 JSObject *func = static_cast<JSObject*>(v);966 967 if (!func->implementsCall()) {968 return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_expr.get());969 }970 971 List argList;972 m_args->evaluateList(exec, argList);973 KJS_CHECKEXCEPTIONVALUE974 975 JSObject *thisObj = exec->dynamicGlobalObject();976 977 return func->call(exec, thisObj, argList);954 JSValue* FunctionCallValueNode::evaluate(ExecState* exec) 955 { 956 JSValue* v = m_expr->evaluate(exec); 957 KJS_CHECKEXCEPTIONVALUE 958 959 if (!v->isObject()) { 960 return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_expr.get()); 961 } 962 963 JSObject* func = static_cast<JSObject*>(v); 964 965 if (!func->implementsCall()) { 966 return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_expr.get()); 967 } 968 969 List argList; 970 m_args->evaluateList(exec, argList); 971 KJS_CHECKEXCEPTIONVALUE 972 973 JSObject* thisObj = exec->dynamicGlobalObject(); 974 975 return func->call(exec, thisObj, argList); 978 976 } 979 977 … … 990 988 JSValue* FunctionCallResolveNode::inlineEvaluate(ExecState* exec) 991 989 { 992 // Check for missed optimization opportunity.993 ASSERT(!canSkipLookup(exec, m_ident));994 995 const ScopeChain& chain = exec->scopeChain();996 ScopeChainIterator iter = chain.begin();997 ScopeChainIterator end = chain.end();998 999 // we must always have something in the scope chain1000 ASSERT(iter != end);1001 1002 PropertySlot slot;1003 JSObject* base;1004 do {1005 base = *iter;1006 if (base->getPropertySlot(exec, m_ident, slot)) {1007 JSValue* v = slot.getValue(exec, base, m_ident);1008 KJS_CHECKEXCEPTIONVALUE1009 1010 if (!v->isObject())1011 return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_ident);1012 1013 JSObject *func = static_cast<JSObject*>(v);1014 1015 if (!func->implementsCall())1016 return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_ident);1017 1018 List argList;1019 m_args->evaluateList(exec, argList);1020 KJS_CHECKEXCEPTIONVALUE1021 1022 JSObject* thisObj = base;1023 // ECMA 11.2.3 says that in this situation the this value should be null.1024 // However, section 10.2.3 says that in the case where the value provided1025 // by the caller is null, the global object should be used. It also says1026 // that the section does not apply to internal functions, but for simplicity1027 // of implementation we use the global object anyway here. This guarantees1028 // that in host objects you always get a valid object for this.1029 if (thisObj->isActivationObject())1030 thisObj = exec->dynamicGlobalObject();1031 1032 return func->call(exec, thisObj, argList);1033 }1034 ++iter;1035 } while (iter != end);1036 1037 return throwUndefinedVariableError(exec, m_ident);990 // Check for missed optimization opportunity. 991 ASSERT(!canSkipLookup(exec, m_ident)); 992 993 const ScopeChain& chain = exec->scopeChain(); 994 ScopeChainIterator iter = chain.begin(); 995 ScopeChainIterator end = chain.end(); 996 997 // we must always have something in the scope chain 998 ASSERT(iter != end); 999 1000 PropertySlot slot; 1001 JSObject* base; 1002 do { 1003 base = *iter; 1004 if (base->getPropertySlot(exec, m_ident, slot)) { 1005 JSValue* v = slot.getValue(exec, base, m_ident); 1006 KJS_CHECKEXCEPTIONVALUE 1007 1008 if (!v->isObject()) 1009 return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_ident); 1010 1011 JSObject* func = static_cast<JSObject*>(v); 1012 1013 if (!func->implementsCall()) 1014 return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_ident); 1015 1016 List argList; 1017 m_args->evaluateList(exec, argList); 1018 KJS_CHECKEXCEPTIONVALUE 1019 1020 JSObject* thisObj = base; 1021 // ECMA 11.2.3 says that in this situation the this value should be null. 1022 // However, section 10.2.3 says that in the case where the value provided 1023 // by the caller is null, the global object should be used. It also says 1024 // that the section does not apply to internal functions, but for simplicity 1025 // of implementation we use the global object anyway here. This guarantees 1026 // that in host objects you always get a valid object for this. 1027 if (thisObj->isActivationObject()) 1028 thisObj = exec->dynamicGlobalObject(); 1029 1030 return func->call(exec, thisObj, argList); 1031 } 1032 ++iter; 1033 } while (iter != end); 1034 1035 return throwUndefinedVariableError(exec, m_ident); 1038 1036 } 1039 1037 … … 1079 1077 if (!v->isObject()) 1080 1078 return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_ident); 1081 1079 1082 1080 JSObject* func = static_cast<JSObject*>(v); 1083 1081 if (!func->implementsCall()) 1084 1082 return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_ident); 1085 1083 1086 1084 List argList; 1087 1085 m_args->evaluateList(exec, argList); … … 1132 1130 1133 1131 // ECMA 11.2.3 1134 JSValue *FunctionCallBracketNode::evaluate(ExecState *exec) 1135 { 1136 JSValue *baseVal = m_base->evaluate(exec); 1137 KJS_CHECKEXCEPTIONVALUE 1138 1139 JSValue *subscriptVal = m_subscript->evaluate(exec); 1140 1141 JSObject *baseObj = baseVal->toObject(exec); 1142 uint32_t i; 1143 PropertySlot slot; 1144 1145 JSValue *funcVal; 1146 if (subscriptVal->getUInt32(i)) { 1147 if (baseObj->getPropertySlot(exec, i, slot)) 1148 funcVal = slot.getValue(exec, baseObj, i); 1149 else 1150 funcVal = jsUndefined(); 1151 } else { 1152 Identifier ident(subscriptVal->toString(exec)); 1153 if (baseObj->getPropertySlot(exec, ident, slot)) 1154 funcVal = baseObj->get(exec, ident); 1155 else 1156 funcVal = jsUndefined(); 1157 } 1158 1159 KJS_CHECKEXCEPTIONVALUE 1160 1161 if (!funcVal->isObject()) { 1162 return throwError(exec, TypeError, "Value %s (result of expression %s[%s]) is not object.", funcVal, m_base.get(), m_subscript.get()); 1163 } 1164 1165 JSObject *func = static_cast<JSObject*>(funcVal); 1166 1167 if (!func->implementsCall()) { 1168 return throwError(exec, TypeError, "Object %s (result of expression %s[%s]) does not allow calls.", funcVal, m_base.get(), m_subscript.get()); 1169 } 1170 1171 List argList; 1172 m_args->evaluateList(exec, argList); 1173 KJS_CHECKEXCEPTIONVALUE 1174 1175 JSObject *thisObj = baseObj; 1176 ASSERT(thisObj); 1177 ASSERT(thisObj->isObject()); 1178 ASSERT(!thisObj->isActivationObject()); 1179 1180 return func->call(exec, thisObj, argList); 1181 } 1182 1183 static const char *dotExprNotAnObjectString() KJS_FAST_CALL; 1184 static const char *dotExprNotAnObjectString() 1185 { 1186 return "Value %s (result of expression %s.%s) is not object."; 1187 } 1188 1189 static const char *dotExprDoesNotAllowCallsString() KJS_FAST_CALL; 1190 static const char *dotExprDoesNotAllowCallsString() 1191 { 1192 return "Object %s (result of expression %s.%s) does not allow calls."; 1132 JSValue* FunctionCallBracketNode::evaluate(ExecState* exec) 1133 { 1134 JSValue* baseVal = m_base->evaluate(exec); 1135 KJS_CHECKEXCEPTIONVALUE 1136 1137 JSValue* subscriptVal = m_subscript->evaluate(exec); 1138 1139 JSObject* baseObj = baseVal->toObject(exec); 1140 uint32_t i; 1141 PropertySlot slot; 1142 1143 JSValue* funcVal; 1144 if (subscriptVal->getUInt32(i)) { 1145 if (baseObj->getPropertySlot(exec, i, slot)) 1146 funcVal = slot.getValue(exec, baseObj, i); 1147 else 1148 funcVal = jsUndefined(); 1149 } else { 1150 Identifier ident(subscriptVal->toString(exec)); 1151 if (baseObj->getPropertySlot(exec, ident, slot)) 1152 funcVal = baseObj->get(exec, ident); 1153 else 1154 funcVal = jsUndefined(); 1155 } 1156 1157 KJS_CHECKEXCEPTIONVALUE 1158 1159 if (!funcVal->isObject()) 1160 return throwError(exec, TypeError, "Value %s (result of expression %s[%s]) is not object.", funcVal, m_base.get(), m_subscript.get()); 1161 1162 JSObject* func = static_cast<JSObject*>(funcVal); 1163 1164 if (!func->implementsCall()) 1165 return throwError(exec, TypeError, "Object %s (result of expression %s[%s]) does not allow calls.", funcVal, m_base.get(), m_subscript.get()); 1166 1167 List argList; 1168 m_args->evaluateList(exec, argList); 1169 KJS_CHECKEXCEPTIONVALUE 1170 1171 JSObject* thisObj = baseObj; 1172 ASSERT(thisObj); 1173 ASSERT(thisObj->isObject()); 1174 ASSERT(!thisObj->isActivationObject()); 1175 1176 return func->call(exec, thisObj, argList); 1177 } 1178 1179 static const char* dotExprNotAnObjectString() KJS_FAST_CALL; 1180 static const char* dotExprNotAnObjectString() 1181 { 1182 return "Value %s (result of expression %s.%s) is not object."; 1183 } 1184 1185 static const char* dotExprDoesNotAllowCallsString() KJS_FAST_CALL; 1186 static const char* dotExprDoesNotAllowCallsString() 1187 { 1188 return "Object %s (result of expression %s.%s) does not allow calls."; 1193 1189 } 1194 1190 … … 1202 1198 JSValue* FunctionCallDotNode::inlineEvaluate(ExecState* exec) 1203 1199 { 1204 JSValue *baseVal = m_base->evaluate(exec);1205 KJS_CHECKEXCEPTIONVALUE1206 1207 JSObject *baseObj = baseVal->toObject(exec);1208 PropertySlot slot;1209 JSValue *funcVal = baseObj->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, baseObj, m_ident) : jsUndefined();1210 KJS_CHECKEXCEPTIONVALUE1211 1212 if (!funcVal->isObject())1213 return throwError(exec, TypeError, dotExprNotAnObjectString(), funcVal, m_base.get(), m_ident);1214 1215 JSObject *func = static_cast<JSObject*>(funcVal);1216 1217 if (!func->implementsCall())1218 return throwError(exec, TypeError, dotExprDoesNotAllowCallsString(), funcVal, m_base.get(), m_ident);1219 1220 List argList;1221 m_args->evaluateList(exec, argList);1222 KJS_CHECKEXCEPTIONVALUE1223 1224 JSObject *thisObj = baseObj;1225 ASSERT(thisObj);1226 ASSERT(thisObj->isObject());1227 ASSERT(!thisObj->isActivationObject());1228 1229 return func->call(exec, thisObj, argList);1200 JSValue* baseVal = m_base->evaluate(exec); 1201 KJS_CHECKEXCEPTIONVALUE 1202 1203 JSObject* baseObj = baseVal->toObject(exec); 1204 PropertySlot slot; 1205 JSValue* funcVal = baseObj->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, baseObj, m_ident) : jsUndefined(); 1206 KJS_CHECKEXCEPTIONVALUE 1207 1208 if (!funcVal->isObject()) 1209 return throwError(exec, TypeError, dotExprNotAnObjectString(), funcVal, m_base.get(), m_ident); 1210 1211 JSObject* func = static_cast<JSObject*>(funcVal); 1212 1213 if (!func->implementsCall()) 1214 return throwError(exec, TypeError, dotExprDoesNotAllowCallsString(), funcVal, m_base.get(), m_ident); 1215 1216 List argList; 1217 m_args->evaluateList(exec, argList); 1218 KJS_CHECKEXCEPTIONVALUE 1219 1220 JSObject* thisObj = baseObj; 1221 ASSERT(thisObj); 1222 ASSERT(thisObj->isObject()); 1223 ASSERT(!thisObj->isActivationObject()); 1224 1225 return func->call(exec, thisObj, argList); 1230 1226 } 1231 1227 … … 1279 1275 } 1280 1276 1281 JSValue *PostIncResolveNode::evaluate(ExecState *exec)1282 { 1283 // Check for missed optimization opportunity.1284 ASSERT(!canSkipLookup(exec, m_ident));1285 1286 const ScopeChain& chain = exec->scopeChain();1287 ScopeChainIterator iter = chain.begin();1288 ScopeChainIterator end = chain.end();1289 1290 // we must always have something in the scope chain1291 ASSERT(iter != end);1292 1293 PropertySlot slot;1294 do {1295 if ((*iter)->getPropertySlot(exec, m_ident, slot)) {1296 // See the comment in PostIncResolveNode::evaluate().1297 1298 JSObject* base = *iter;1299 JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);1300 base->put(exec, m_ident, jsNumber(v->toNumber(exec) + 1));1301 return v;1302 }1303 1304 ++iter;1305 } while (iter != end);1306 1307 return throwUndefinedVariableError(exec, m_ident);1277 JSValue* PostIncResolveNode::evaluate(ExecState* exec) 1278 { 1279 // Check for missed optimization opportunity. 1280 ASSERT(!canSkipLookup(exec, m_ident)); 1281 1282 const ScopeChain& chain = exec->scopeChain(); 1283 ScopeChainIterator iter = chain.begin(); 1284 ScopeChainIterator end = chain.end(); 1285 1286 // we must always have something in the scope chain 1287 ASSERT(iter != end); 1288 1289 PropertySlot slot; 1290 do { 1291 if ((*iter)->getPropertySlot(exec, m_ident, slot)) { 1292 // See the comment in PostIncResolveNode::evaluate(). 1293 1294 JSObject* base = *iter; 1295 JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec); 1296 base->put(exec, m_ident, jsNumber(v->toNumber(exec) + 1)); 1297 return v; 1298 } 1299 1300 ++iter; 1301 } while (iter != end); 1302 1303 return throwUndefinedVariableError(exec, m_ident); 1308 1304 } 1309 1305 … … 1312 1308 new (this) PreIncResolveNode(PlacementNewAdopt); 1313 1309 } 1314 1310 1315 1311 JSValue* PostIncLocalVarNode::evaluate(ExecState* exec) 1316 1312 { … … 1327 1323 new (this) PreIncLocalVarNode(m_index); 1328 1324 } 1329 1330 1325 1331 1326 // Decrement … … 1341 1336 } 1342 1337 1343 JSValue *PostDecResolveNode::evaluate(ExecState *exec)1344 { 1345 // Check for missed optimization opportunity.1346 ASSERT(!canSkipLookup(exec, m_ident));1347 1348 const ScopeChain& chain = exec->scopeChain();1349 ScopeChainIterator iter = chain.begin();1350 ScopeChainIterator end = chain.end();1351 1352 // we must always have something in the scope chain1353 ASSERT(iter != end);1354 1355 PropertySlot slot;1356 do {1357 if ((*iter)->getPropertySlot(exec, m_ident, slot)) {1358 // See the comment in PostIncResolveNode::evaluate().1359 1360 JSObject* base = *iter;1361 JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);1362 base->put(exec, m_ident, jsNumber(v->toNumber(exec) - 1));1363 return v;1364 }1365 1366 ++iter;1367 } while (iter != end);1368 1369 return throwUndefinedVariableError(exec, m_ident);1370 } 1371 1338 JSValue* PostDecResolveNode::evaluate(ExecState* exec) 1339 { 1340 // Check for missed optimization opportunity. 1341 ASSERT(!canSkipLookup(exec, m_ident)); 1342 1343 const ScopeChain& chain = exec->scopeChain(); 1344 ScopeChainIterator iter = chain.begin(); 1345 ScopeChainIterator end = chain.end(); 1346 1347 // we must always have something in the scope chain 1348 ASSERT(iter != end); 1349 1350 PropertySlot slot; 1351 do { 1352 if ((*iter)->getPropertySlot(exec, m_ident, slot)) { 1353 // See the comment in PostIncResolveNode::evaluate(). 1354 1355 JSObject* base = *iter; 1356 JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec); 1357 base->put(exec, m_ident, jsNumber(v->toNumber(exec) - 1)); 1358 return v; 1359 } 1360 1361 ++iter; 1362 } while (iter != end); 1363 1364 return throwUndefinedVariableError(exec, m_ident); 1365 } 1366 1372 1367 void PostDecResolveNode::optimizeForUnnecessaryResult() 1373 1368 { 1374 1369 new (this) PreDecResolveNode(PlacementNewAdopt); 1375 1370 } 1376 1371 1377 1372 JSValue* PostDecLocalVarNode::evaluate(ExecState* exec) 1378 1373 { … … 1388 1383 { 1389 1384 ASSERT(exec->variableObject() == exec->scopeChain().top()); 1390 1385 1391 1386 JSValue** slot = &exec->localStorage()[m_index].value; 1392 1387 double n = (*slot)->toNumber(exec); … … 1419 1414 new (this) PreDecLocalVarNode(m_index); 1420 1415 } 1421 1416 1422 1417 // ------------------------------ PostfixBracketNode ---------------------------------- 1423 1418 … … 1428 1423 } 1429 1424 1430 JSValue *PostIncBracketNode::evaluate(ExecState *exec) 1431 { 1432 JSValue *baseValue = m_base->evaluate(exec); 1433 KJS_CHECKEXCEPTIONVALUE 1434 JSValue *subscript = m_subscript->evaluate(exec); 1435 KJS_CHECKEXCEPTIONVALUE 1436 1437 JSObject *base = baseValue->toObject(exec); 1438 1439 uint32_t propertyIndex; 1440 if (subscript->getUInt32(propertyIndex)) { 1425 JSValue* PostIncBracketNode::evaluate(ExecState* exec) 1426 { 1427 JSValue* baseValue = m_base->evaluate(exec); 1428 KJS_CHECKEXCEPTIONVALUE 1429 JSValue* subscript = m_subscript->evaluate(exec); 1430 KJS_CHECKEXCEPTIONVALUE 1431 1432 JSObject* base = baseValue->toObject(exec); 1433 1434 uint32_t propertyIndex; 1435 if (subscript->getUInt32(propertyIndex)) { 1436 PropertySlot slot; 1437 JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined(); 1438 KJS_CHECKEXCEPTIONVALUE 1439 1440 JSValue* v2 = v->toJSNumber(exec); 1441 base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) + 1)); 1442 1443 return v2; 1444 } 1445 1446 Identifier propertyName(subscript->toString(exec)); 1441 1447 PropertySlot slot; 1442 JSValue *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();1448 JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined(); 1443 1449 KJS_CHECKEXCEPTIONVALUE 1444 1450 1445 1451 JSValue* v2 = v->toJSNumber(exec); 1446 base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) + 1)); 1447 1452 base->put(exec, propertyName, jsNumber(v2->toNumber(exec) + 1)); 1448 1453 return v2; 1449 1450 1451 Identifier propertyName(subscript->toString(exec)); 1452 PropertySlot slot; 1453 JSValue *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();1454 KJS_CHECKEXCEPTIONVALUE1455 1456 JSValue* v2 = v->toJSNumber(exec);1457 base->put(exec, propertyName, jsNumber(v2->toNumber(exec) + 1)); 1458 return v2;1459 } 1460 1461 JSValue *PostDecBracketNode::evaluate(ExecState *exec) 1462 { 1463 JSValue *baseValue = m_base->evaluate(exec);1464 KJS_CHECKEXCEPTIONVALUE1465 JSValue *subscript = m_subscript->evaluate(exec); 1466 KJS_CHECKEXCEPTIONVALUE1467 1468 JSObject *base = baseValue->toObject(exec);1469 1470 uint32_t propertyIndex; 1471 if (subscript->getUInt32(propertyIndex)) {1454 } 1455 1456 JSValue* PostDecBracketNode::evaluate(ExecState* exec) 1457 { 1458 JSValue* baseValue = m_base->evaluate(exec); 1459 KJS_CHECKEXCEPTIONVALUE 1460 JSValue* subscript = m_subscript->evaluate(exec); 1461 KJS_CHECKEXCEPTIONVALUE 1462 1463 JSObject* base = baseValue->toObject(exec); 1464 1465 uint32_t propertyIndex; 1466 if (subscript->getUInt32(propertyIndex)) { 1467 PropertySlot slot; 1468 JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined(); 1469 KJS_CHECKEXCEPTIONVALUE 1470 1471 JSValue* v2 = v->toJSNumber(exec); 1472 base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) - 1)); 1473 return v2; 1474 } 1475 1476 Identifier propertyName(subscript->toString(exec)); 1472 1477 PropertySlot slot; 1473 JSValue *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();1478 JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined(); 1474 1479 KJS_CHECKEXCEPTIONVALUE 1475 1480 1476 1481 JSValue* v2 = v->toJSNumber(exec); 1477 base->put(exec, property Index, jsNumber(v2->toNumber(exec) - 1));1482 base->put(exec, propertyName, jsNumber(v2->toNumber(exec) - 1)); 1478 1483 return v2; 1479 }1480 1481 Identifier propertyName(subscript->toString(exec));1482 PropertySlot slot;1483 JSValue *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();1484 KJS_CHECKEXCEPTIONVALUE1485 1486 JSValue* v2 = v->toJSNumber(exec);1487 base->put(exec, propertyName, jsNumber(v2->toNumber(exec) - 1));1488 return v2;1489 1484 } 1490 1485 … … 1496 1491 } 1497 1492 1498 JSValue *PostIncDotNode::evaluate(ExecState *exec)1499 { 1500 JSValue *baseValue = m_base->evaluate(exec);1501 KJS_CHECKEXCEPTIONVALUE1502 JSObject *base = baseValue->toObject(exec);1503 1504 PropertySlot slot;1505 JSValue *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();1506 KJS_CHECKEXCEPTIONVALUE1507 1508 JSValue* v2 = v->toJSNumber(exec);1509 base->put(exec, m_ident, jsNumber(v2->toNumber(exec) + 1));1510 return v2;1511 } 1512 1513 JSValue *PostDecDotNode::evaluate(ExecState *exec)1514 { 1515 JSValue *baseValue = m_base->evaluate(exec);1516 KJS_CHECKEXCEPTIONVALUE1517 JSObject *base = baseValue->toObject(exec);1518 1519 PropertySlot slot;1520 JSValue *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();1521 KJS_CHECKEXCEPTIONVALUE1522 1523 JSValue* v2 = v->toJSNumber(exec);1524 base->put(exec, m_ident, jsNumber(v2->toNumber(exec) - 1));1525 return v2;1493 JSValue* PostIncDotNode::evaluate(ExecState* exec) 1494 { 1495 JSValue* baseValue = m_base->evaluate(exec); 1496 KJS_CHECKEXCEPTIONVALUE 1497 JSObject* base = baseValue->toObject(exec); 1498 1499 PropertySlot slot; 1500 JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined(); 1501 KJS_CHECKEXCEPTIONVALUE 1502 1503 JSValue* v2 = v->toJSNumber(exec); 1504 base->put(exec, m_ident, jsNumber(v2->toNumber(exec) + 1)); 1505 return v2; 1506 } 1507 1508 JSValue* PostDecDotNode::evaluate(ExecState* exec) 1509 { 1510 JSValue* baseValue = m_base->evaluate(exec); 1511 KJS_CHECKEXCEPTIONVALUE 1512 JSObject* base = baseValue->toObject(exec); 1513 1514 PropertySlot slot; 1515 JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined(); 1516 KJS_CHECKEXCEPTIONVALUE 1517 1518 JSValue* v2 = v->toJSNumber(exec); 1519 base->put(exec, m_ident, jsNumber(v2->toNumber(exec) - 1)); 1520 return v2; 1526 1521 } 1527 1522 … … 1531 1526 { 1532 1527 throwError(exec, ReferenceError, "Postfix %s operator applied to value that is not a reference.", 1533 m_oper == OpPlusPlus ? "++" : "--");1528 m_operator == OpPlusPlus ? "++" : "--"); 1534 1529 handleException(exec); 1535 1530 return jsUndefined(); … … 1547 1542 // ECMA 11.4.1 1548 1543 1549 JSValue *DeleteResolveNode::evaluate(ExecState *exec) 1550 { 1551 // Check for missed optimization opportunity. 1552 ASSERT(!canSkipLookup(exec, m_ident)); 1553 1554 const ScopeChain& chain = exec->scopeChain(); 1555 ScopeChainIterator iter = chain.begin(); 1556 ScopeChainIterator end = chain.end(); 1557 1558 // we must always have something in the scope chain 1559 ASSERT(iter != end); 1560 1561 PropertySlot slot; 1562 JSObject *base; 1563 do { 1564 base = *iter; 1565 if (base->getPropertySlot(exec, m_ident, slot)) { 1566 return jsBoolean(base->deleteProperty(exec, m_ident)); 1567 } 1568 1569 ++iter; 1570 } while (iter != end); 1571 1572 return jsBoolean(true); 1544 JSValue* DeleteResolveNode::evaluate(ExecState* exec) 1545 { 1546 // Check for missed optimization opportunity. 1547 ASSERT(!canSkipLookup(exec, m_ident)); 1548 1549 const ScopeChain& chain = exec->scopeChain(); 1550 ScopeChainIterator iter = chain.begin(); 1551 ScopeChainIterator end = chain.end(); 1552 1553 // We must always have something in the scope chain 1554 ASSERT(iter != end); 1555 1556 PropertySlot slot; 1557 JSObject* base; 1558 do { 1559 base = *iter; 1560 if (base->getPropertySlot(exec, m_ident, slot)) 1561 return jsBoolean(base->deleteProperty(exec, m_ident)); 1562 1563 ++iter; 1564 } while (iter != end); 1565 1566 return jsBoolean(true); 1573 1567 } 1574 1568 … … 1586 1580 } 1587 1581 1588 JSValue *DeleteBracketNode::evaluate(ExecState *exec)1589 { 1590 JSValue *baseValue = m_base->evaluate(exec);1591 KJS_CHECKEXCEPTIONVALUE1592 JSValue *subscript = m_subscript->evaluate(exec);1593 KJS_CHECKEXCEPTIONVALUE1594 1595 JSObject *base = baseValue->toObject(exec);1596 1597 uint32_t propertyIndex;1598 if (subscript->getUInt32(propertyIndex))1599 return jsBoolean(base->deleteProperty(exec, propertyIndex));1600 1601 Identifier propertyName(subscript->toString(exec));1602 return jsBoolean(base->deleteProperty(exec, propertyName));1582 JSValue* DeleteBracketNode::evaluate(ExecState* exec) 1583 { 1584 JSValue* baseValue = m_base->evaluate(exec); 1585 KJS_CHECKEXCEPTIONVALUE 1586 JSValue* subscript = m_subscript->evaluate(exec); 1587 KJS_CHECKEXCEPTIONVALUE 1588 1589 JSObject* base = baseValue->toObject(exec); 1590 1591 uint32_t propertyIndex; 1592 if (subscript->getUInt32(propertyIndex)) 1593 return jsBoolean(base->deleteProperty(exec, propertyIndex)); 1594 1595 Identifier propertyName(subscript->toString(exec)); 1596 return jsBoolean(base->deleteProperty(exec, propertyName)); 1603 1597 } 1604 1598 … … 1610 1604 } 1611 1605 1612 JSValue *DeleteDotNode::evaluate(ExecState *exec)1613 { 1614 JSValue *baseValue = m_base->evaluate(exec);1615 JSObject *base = baseValue->toObject(exec);1616 KJS_CHECKEXCEPTIONVALUE1617 1618 return jsBoolean(base->deleteProperty(exec, m_ident));1606 JSValue* DeleteDotNode::evaluate(ExecState* exec) 1607 { 1608 JSValue* baseValue = m_base->evaluate(exec); 1609 JSObject* base = baseValue->toObject(exec); 1610 KJS_CHECKEXCEPTIONVALUE 1611 1612 return jsBoolean(base->deleteProperty(exec, m_ident)); 1619 1613 } 1620 1614 … … 1626 1620 } 1627 1621 1628 JSValue *DeleteValueNode::evaluate(ExecState *exec)1629 { 1630 m_expr->evaluate(exec);1631 KJS_CHECKEXCEPTIONVALUE1632 1633 // delete on a non-location expression ignores the value and returns true1634 return jsBoolean(true);1622 JSValue* DeleteValueNode::evaluate(ExecState* exec) 1623 { 1624 m_expr->evaluate(exec); 1625 KJS_CHECKEXCEPTIONVALUE 1626 1627 // delete on a non-location expression ignores the value and returns true 1628 return jsBoolean(true); 1635 1629 } 1636 1630 … … 1643 1637 1644 1638 // ECMA 11.4.2 1645 JSValue *VoidNode::evaluate(ExecState *exec)1646 { 1647 m_expr->evaluate(exec);1648 KJS_CHECKEXCEPTIONVALUE1649 1650 return jsUndefined();1639 JSValue* VoidNode::evaluate(ExecState* exec) 1640 { 1641 m_expr->evaluate(exec); 1642 KJS_CHECKEXCEPTIONVALUE 1643 1644 return jsUndefined(); 1651 1645 } 1652 1646 … … 1660 1654 } 1661 1655 1662 static JSValue *typeStringForValue(JSValue *v) KJS_FAST_CALL;1663 static JSValue *typeStringForValue(JSValue *v)1656 static JSValue* typeStringForValue(JSValue* v) KJS_FAST_CALL; 1657 static JSValue* typeStringForValue(JSValue* v) 1664 1658 { 1665 1659 switch (v->type()) { 1666 case UndefinedType:1667 return jsString("undefined");1668 case NullType:1669 return jsString("object");1670 case BooleanType:1671 return jsString("boolean");1672 case NumberType:1673 return jsString("number");1674 case StringType:1675 return jsString("string");1676 default:1677 if (v->isObject()) {1678 // Return "undefined" for objects that should be treated1679 // as null when doing comparisons.1680 if (static_cast<JSObject*>(v)->masqueradeAsUndefined())1681 return jsString("undefined");1682 else if (static_cast<JSObject*>(v)->implementsCall())1683 return jsString("function");1684 }1685 1686 return jsString("object");1660 case UndefinedType: 1661 return jsString("undefined"); 1662 case NullType: 1663 return jsString("object"); 1664 case BooleanType: 1665 return jsString("boolean"); 1666 case NumberType: 1667 return jsString("number"); 1668 case StringType: 1669 return jsString("string"); 1670 default: 1671 if (v->isObject()) { 1672 // Return "undefined" for objects that should be treated 1673 // as null when doing comparisons. 1674 if (static_cast<JSObject*>(v)->masqueradeAsUndefined()) 1675 return jsString("undefined"); 1676 else if (static_cast<JSObject*>(v)->implementsCall()) 1677 return jsString("function"); 1678 } 1679 1680 return jsString("object"); 1687 1681 } 1688 1682 } … … 1702 1696 } 1703 1697 1704 JSValue *TypeOfResolveNode::evaluate(ExecState *exec)1705 { 1706 const ScopeChain& chain = exec->scopeChain();1707 ScopeChainIterator iter = chain.begin();1708 ScopeChainIterator end = chain.end();1709 1710 // we must always have something in the scope chain1711 ASSERT(iter != end);1712 1713 PropertySlot slot;1714 JSObject *base;1715 do {1716 base = *iter;1717 if (base->getPropertySlot(exec, m_ident, slot)) {1718 JSValue *v = slot.getValue(exec, base, m_ident);1719 return typeStringForValue(v);1720 }1721 1722 ++iter;1723 } while (iter != end);1724 1725 return jsString("undefined");1698 JSValue* TypeOfResolveNode::evaluate(ExecState* exec) 1699 { 1700 const ScopeChain& chain = exec->scopeChain(); 1701 ScopeChainIterator iter = chain.begin(); 1702 ScopeChainIterator end = chain.end(); 1703 1704 // We must always have something in the scope chain 1705 ASSERT(iter != end); 1706 1707 PropertySlot slot; 1708 JSObject* base; 1709 do { 1710 base = *iter; 1711 if (base->getPropertySlot(exec, m_ident, slot)) { 1712 JSValue* v = slot.getValue(exec, base, m_ident); 1713 return typeStringForValue(v); 1714 } 1715 1716 ++iter; 1717 } while (iter != end); 1718 1719 return jsString("undefined"); 1726 1720 } 1727 1721 1728 1722 // ------------------------------ TypeOfValueNode ----------------------------------- 1729 1723 1730 JSValue *TypeOfValueNode::evaluate(ExecState *exec)1731 { 1732 JSValue *v = m_expr->evaluate(exec);1733 KJS_CHECKEXCEPTIONVALUE1734 1735 return typeStringForValue(v);1724 JSValue* TypeOfValueNode::evaluate(ExecState* exec) 1725 { 1726 JSValue* v = m_expr->evaluate(exec); 1727 KJS_CHECKEXCEPTIONVALUE 1728 1729 return typeStringForValue(v); 1736 1730 } 1737 1731 … … 1762 1756 } 1763 1757 1764 JSValue *PreIncResolveNode::evaluate(ExecState *exec)1765 { 1766 const ScopeChain& chain = exec->scopeChain();1767 ScopeChainIterator iter = chain.begin();1768 ScopeChainIterator end = chain.end();1769 1770 // we must always have something in the scope chain1771 ASSERT(iter != end);1772 1773 PropertySlot slot;1774 do {1775 if ((*iter)->getPropertySlot(exec, m_ident, slot)) {1776 // See the comment in PostIncResolveNode::evaluate().1777 1778 JSObject* base = *iter;1779 JSValue *v = slot.getValue(exec, base, m_ident);1780 1781 double n = v->toNumber(exec);1782 JSValue *n2 = jsNumber(n + 1);1783 base->put(exec, m_ident, n2);1784 1785 return n2;1786 }1787 1788 ++iter;1789 } while (iter != end);1790 1791 return throwUndefinedVariableError(exec, m_ident);1758 JSValue* PreIncResolveNode::evaluate(ExecState* exec) 1759 { 1760 const ScopeChain& chain = exec->scopeChain(); 1761 ScopeChainIterator iter = chain.begin(); 1762 ScopeChainIterator end = chain.end(); 1763 1764 // we must always have something in the scope chain 1765 ASSERT(iter != end); 1766 1767 PropertySlot slot; 1768 do { 1769 if ((*iter)->getPropertySlot(exec, m_ident, slot)) { 1770 // See the comment in PostIncResolveNode::evaluate(). 1771 1772 JSObject* base = *iter; 1773 JSValue* v = slot.getValue(exec, base, m_ident); 1774 1775 double n = v->toNumber(exec); 1776 JSValue* n2 = jsNumber(n + 1); 1777 base->put(exec, m_ident, n2); 1778 1779 return n2; 1780 } 1781 1782 ++iter; 1783 } while (iter != end); 1784 1785 return throwUndefinedVariableError(exec, m_ident); 1792 1786 } 1793 1787 … … 1814 1808 } 1815 1809 1816 JSValue *PreDecResolveNode::evaluate(ExecState *exec)1817 { 1818 const ScopeChain& chain = exec->scopeChain();1819 ScopeChainIterator iter = chain.begin();1820 ScopeChainIterator end = chain.end();1821 1822 // we must always have something in the scope chain1823 ASSERT(iter != end);1824 1825 PropertySlot slot;1826 do {1827 if ((*iter)->getPropertySlot(exec, m_ident, slot)) {1828 // See the comment in PostIncResolveNode::evaluate().1829 1830 JSObject* base = *iter;1831 JSValue *v = slot.getValue(exec, base, m_ident);1832 1833 double n = v->toNumber(exec);1834 JSValue *n2 = jsNumber(n - 1);1835 base->put(exec, m_ident, n2);1836 1837 return n2;1838 }1839 1840 ++iter;1841 } while (iter != end);1842 1843 return throwUndefinedVariableError(exec, m_ident);1810 JSValue* PreDecResolveNode::evaluate(ExecState* exec) 1811 { 1812 const ScopeChain& chain = exec->scopeChain(); 1813 ScopeChainIterator iter = chain.begin(); 1814 ScopeChainIterator end = chain.end(); 1815 1816 // we must always have something in the scope chain 1817 ASSERT(iter != end); 1818 1819 PropertySlot slot; 1820 do { 1821 if ((*iter)->getPropertySlot(exec, m_ident, slot)) { 1822 // See the comment in PostIncResolveNode::evaluate(). 1823 1824 JSObject* base = *iter; 1825 JSValue* v = slot.getValue(exec, base, m_ident); 1826 1827 double n = v->toNumber(exec); 1828 JSValue* n2 = jsNumber(n - 1); 1829 base->put(exec, m_ident, n2); 1830 1831 return n2; 1832 } 1833 1834 ++iter; 1835 } while (iter != end); 1836 1837 return throwUndefinedVariableError(exec, m_ident); 1844 1838 } 1845 1839 … … 1884 1878 } 1885 1879 1886 JSValue *PreIncBracketNode::evaluate(ExecState *exec) 1887 { 1888 JSValue *baseValue = m_base->evaluate(exec); 1889 KJS_CHECKEXCEPTIONVALUE 1890 JSValue *subscript = m_subscript->evaluate(exec); 1891 KJS_CHECKEXCEPTIONVALUE 1892 1893 JSObject *base = baseValue->toObject(exec); 1894 1895 uint32_t propertyIndex; 1896 if (subscript->getUInt32(propertyIndex)) { 1880 JSValue* PreIncBracketNode::evaluate(ExecState* exec) 1881 { 1882 JSValue* baseValue = m_base->evaluate(exec); 1883 KJS_CHECKEXCEPTIONVALUE 1884 JSValue* subscript = m_subscript->evaluate(exec); 1885 KJS_CHECKEXCEPTIONVALUE 1886 1887 JSObject* base = baseValue->toObject(exec); 1888 1889 uint32_t propertyIndex; 1890 if (subscript->getUInt32(propertyIndex)) { 1891 PropertySlot slot; 1892 JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined(); 1893 KJS_CHECKEXCEPTIONVALUE 1894 1895 JSValue* n2 = jsNumber(v->toNumber(exec) + 1); 1896 base->put(exec, propertyIndex, n2); 1897 1898 return n2; 1899 } 1900 1901 Identifier propertyName(subscript->toString(exec)); 1897 1902 PropertySlot slot; 1898 JSValue *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();1899 KJS_CHECKEXCEPTIONVALUE 1900 1901 JSValue *n2 = jsNumber(v->toNumber(exec) + 1);1902 base->put(exec, property Index, n2);1903 JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined(); 1904 KJS_CHECKEXCEPTIONVALUE 1905 1906 JSValue* n2 = jsNumber(v->toNumber(exec) + 1); 1907 base->put(exec, propertyName, n2); 1903 1908 1904 1909 return n2; 1905 1906 1907 Identifier propertyName(subscript->toString(exec)); 1908 PropertySlot slot; 1909 JSValue *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();1910 KJS_CHECKEXCEPTIONVALUE1911 1912 JSValue *n2 = jsNumber(v->toNumber(exec) + 1);1913 base->put(exec, propertyName, n2); 1914 1915 return n2; 1916 } 1917 1918 JSValue *PreDecBracketNode::evaluate(ExecState *exec) 1919 { 1920 JSValue *baseValue = m_base->evaluate(exec);1921 KJS_CHECKEXCEPTIONVALUE 1922 JSValue *subscript = m_subscript->evaluate(exec);1923 KJS_CHECKEXCEPTIONVALUE1924 1925 JSObject *base = baseValue->toObject(exec);1926 1927 uint32_t propertyIndex; 1928 if (subscript->getUInt32(propertyIndex)) {1910 } 1911 1912 JSValue* PreDecBracketNode::evaluate(ExecState* exec) 1913 { 1914 JSValue* baseValue = m_base->evaluate(exec); 1915 KJS_CHECKEXCEPTIONVALUE 1916 JSValue* subscript = m_subscript->evaluate(exec); 1917 KJS_CHECKEXCEPTIONVALUE 1918 1919 JSObject* base = baseValue->toObject(exec); 1920 1921 uint32_t propertyIndex; 1922 if (subscript->getUInt32(propertyIndex)) { 1923 PropertySlot slot; 1924 JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined(); 1925 KJS_CHECKEXCEPTIONVALUE 1926 1927 JSValue* n2 = jsNumber(v->toNumber(exec) - 1); 1928 base->put(exec, propertyIndex, n2); 1929 1930 return n2; 1931 } 1932 1933 Identifier propertyName(subscript->toString(exec)); 1929 1934 PropertySlot slot; 1930 JSValue *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();1931 KJS_CHECKEXCEPTIONVALUE 1932 1933 JSValue *n2 = jsNumber(v->toNumber(exec) - 1);1934 base->put(exec, property Index, n2);1935 JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined(); 1936 KJS_CHECKEXCEPTIONVALUE 1937 1938 JSValue* n2 = jsNumber(v->toNumber(exec) - 1); 1939 base->put(exec, propertyName, n2); 1935 1940 1936 1941 return n2; 1937 }1938 1939 Identifier propertyName(subscript->toString(exec));1940 PropertySlot slot;1941 JSValue *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();1942 KJS_CHECKEXCEPTIONVALUE1943 1944 JSValue *n2 = jsNumber(v->toNumber(exec) - 1);1945 base->put(exec, propertyName, n2);1946 1947 return n2;1948 1942 } 1949 1943 … … 1955 1949 } 1956 1950 1957 JSValue *PreIncDotNode::evaluate(ExecState *exec)1958 { 1959 JSValue *baseValue = m_base->evaluate(exec);1960 KJS_CHECKEXCEPTIONVALUE1961 JSObject *base = baseValue->toObject(exec);1962 1963 PropertySlot slot;1964 JSValue *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();1965 KJS_CHECKEXCEPTIONVALUE1966 1967 double n = v->toNumber(exec);1968 JSValue *n2 = jsNumber(n + 1);1969 base->put(exec, m_ident, n2);1970 1971 return n2;1972 } 1973 1974 JSValue *PreDecDotNode::evaluate(ExecState *exec)1975 { 1976 JSValue *baseValue = m_base->evaluate(exec);1977 KJS_CHECKEXCEPTIONVALUE1978 JSObject *base = baseValue->toObject(exec);1979 1980 PropertySlot slot;1981 JSValue *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();1982 KJS_CHECKEXCEPTIONVALUE1983 1984 double n = v->toNumber(exec);1985 JSValue *n2 = jsNumber(n - 1);1986 base->put(exec, m_ident, n2);1987 1988 return n2;1951 JSValue* PreIncDotNode::evaluate(ExecState* exec) 1952 { 1953 JSValue* baseValue = m_base->evaluate(exec); 1954 KJS_CHECKEXCEPTIONVALUE 1955 JSObject* base = baseValue->toObject(exec); 1956 1957 PropertySlot slot; 1958 JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined(); 1959 KJS_CHECKEXCEPTIONVALUE 1960 1961 double n = v->toNumber(exec); 1962 JSValue* n2 = jsNumber(n + 1); 1963 base->put(exec, m_ident, n2); 1964 1965 return n2; 1966 } 1967 1968 JSValue* PreDecDotNode::evaluate(ExecState* exec) 1969 { 1970 JSValue* baseValue = m_base->evaluate(exec); 1971 KJS_CHECKEXCEPTIONVALUE 1972 JSObject* base = baseValue->toObject(exec); 1973 1974 PropertySlot slot; 1975 JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined(); 1976 KJS_CHECKEXCEPTIONVALUE 1977 1978 double n = v->toNumber(exec); 1979 JSValue* n2 = jsNumber(n - 1); 1980 base->put(exec, m_ident, n2); 1981 1982 return n2; 1989 1983 } 1990 1984 … … 1994 1988 { 1995 1989 throwError(exec, ReferenceError, "Prefix %s operator applied to value that is not a reference.", 1996 m_oper == OpPlusPlus ? "++" : "--");1990 m_operator == OpPlusPlus ? "++" : "--"); 1997 1991 handleException(exec); 1998 1992 return jsUndefined(); … … 2009 2003 JSValue* UnaryPlusNode::evaluate(ExecState* exec) 2010 2004 { 2011 JSValue *v = m_expr->evaluate(exec);2005 JSValue* v = m_expr->evaluate(exec); 2012 2006 KJS_CHECKEXCEPTIONVALUE 2013 2007 return v->toJSNumber(exec); … … 2127 2121 } 2128 2122 2129 JSValue *MultNode::evaluate(ExecState* exec)2123 JSValue* MultNode::evaluate(ExecState* exec) 2130 2124 { 2131 2125 return jsNumber(inlineEvaluateToNumber(exec)); 2132 2126 } 2133 2127 2134 2128 double MultNode::evaluateToNumber(ExecState* exec) 2135 2129 { … … 2241 2235 exec->setException(error); 2242 2236 return 0.0; 2243 } 2237 } 2244 2238 2245 2239 // ECMA 11.6 … … 2247 2241 { 2248 2242 // exception for the Date exception in defaultValue() 2249 JSValue *p1 = v1->toPrimitive(exec, UnspecifiedType);2250 JSValue *p2 = v2->toPrimitive(exec, UnspecifiedType);2251 2243 JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType); 2244 JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType); 2245 2252 2246 if (p1->isString() || p2->isString()) { 2253 2247 UString value = p1->toString(exec) + p2->toString(exec); … … 2256 2250 return jsString(value); 2257 2251 } 2258 2252 2259 2253 return jsNumber(p1->toNumber(exec) + p2->toNumber(exec)); 2260 2254 } … … 2263 2257 { 2264 2258 // exception for the Date exception in defaultValue() 2265 JSValue *p1 = v1->toPrimitive(exec, UnspecifiedType);2266 JSValue *p2 = v2->toPrimitive(exec, UnspecifiedType);2267 2259 JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType); 2260 JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType); 2261 2268 2262 if (p1->isString() || p2->isString()) { 2269 2263 UString value = p1->toString(exec) + p2->toString(exec); … … 2272 2266 return value.toDouble(); 2273 2267 } 2274 2268 2275 2269 return p1->toNumber(exec) + p2->toNumber(exec); 2276 2270 } … … 2286 2280 // 1 Add case: 3 5 2287 2281 2288 static inline JSValue* add(ExecState* exec, JSValue* v1, JSValue *v2)2282 static inline JSValue* add(ExecState* exec, JSValue* v1, JSValue* v2) 2289 2283 { 2290 2284 JSType t1 = v1->type(); 2291 2285 JSType t2 = v2->type(); 2292 2286 const unsigned bothTypes = (t1 << 3) | t2; 2293 2287 2294 2288 if (bothTypes == ((NumberType << 3) | NumberType)) 2295 2289 return jsNumber(v1->toNumber(exec) + v2->toNumber(exec)); … … 2300 2294 return jsString(value); 2301 2295 } 2302 2296 2303 2297 // All other cases are pretty uncommon 2304 2298 return addSlowCase(exec, v1, v2); 2305 2299 } 2306 2300 2307 static inline double addToNumber(ExecState* exec, JSValue* v1, JSValue *v2)2301 static inline double addToNumber(ExecState* exec, JSValue* v1, JSValue* v2) 2308 2302 { 2309 2303 JSType t1 = v1->type(); 2310 2304 JSType t2 = v2->type(); 2311 2305 const unsigned bothTypes = (t1 << 3) | t2; 2312 2306 2313 2307 if (bothTypes == ((NumberType << 3) | NumberType)) 2314 2308 return v1->toNumber(exec) + v2->toNumber(exec); … … 2319 2313 return value.toDouble(); 2320 2314 } 2321 2315 2322 2316 // All other cases are pretty uncommon 2323 2317 return addSlowCaseToNumber(exec, v1, v2); … … 2333 2327 JSValue* AddNode::evaluate(ExecState* exec) 2334 2328 { 2335 JSValue* v1 = m_term1->evaluate(exec);2336 KJS_CHECKEXCEPTIONVALUE2337 2338 JSValue* v2 = m_term2->evaluate(exec);2339 KJS_CHECKEXCEPTIONVALUE2340 2341 return add(exec, v1, v2);2329 JSValue* v1 = m_term1->evaluate(exec); 2330 KJS_CHECKEXCEPTIONVALUE 2331 2332 JSValue* v2 = m_term2->evaluate(exec); 2333 KJS_CHECKEXCEPTIONVALUE 2334 2335 return add(exec, v1, v2); 2342 2336 } 2343 2337 … … 2346 2340 JSValue* v1 = m_term1->evaluate(exec); 2347 2341 KJS_CHECKEXCEPTIONNUMBER 2348 2342 2349 2343 JSValue* v2 = m_term2->evaluate(exec); 2350 2344 KJS_CHECKEXCEPTIONNUMBER 2351 2345 2352 2346 return addToNumber(exec, v1, v2); 2353 2347 } … … 2366 2360 { 2367 2361 return JSValue::toUInt32(inlineEvaluateToNumber(exec)); 2368 } 2362 } 2369 2363 2370 2364 double AddNumbersNode::inlineEvaluateToNumber(ExecState* exec) … … 2400 2394 JSValue* v1 = m_term1->evaluate(exec); 2401 2395 KJS_CHECKEXCEPTIONVALUE 2402 2396 2403 2397 JSValue* v2 = m_term2->evaluate(exec); 2404 2398 KJS_CHECKEXCEPTIONVALUE 2405 2399 2406 2400 return jsString(static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value()); 2407 2401 } … … 2411 2405 JSValue* v1 = m_term1->evaluate(exec); 2412 2406 KJS_CHECKEXCEPTIONVALUE 2413 2407 2414 2408 JSValue* v2 = m_term2->evaluate(exec); 2415 2409 KJS_CHECKEXCEPTIONVALUE 2416 2410 2417 2411 JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType); 2418 2412 return jsString(static_cast<StringImp*>(v1)->value() + p2->toString(exec)); … … 2423 2417 JSValue* v1 = m_term1->evaluate(exec); 2424 2418 KJS_CHECKEXCEPTIONVALUE 2425 2419 2426 2420 JSValue* v2 = m_term2->evaluate(exec); 2427 2421 KJS_CHECKEXCEPTIONVALUE 2428 2422 2429 2423 JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType); 2430 2424 return jsString(p1->toString(exec) + static_cast<StringImp*>(v2)->value()); … … 2464 2458 { 2465 2459 return JSValue::toUInt32(inlineEvaluateToNumber(exec)); 2466 } 2460 } 2467 2461 2468 2462 // ------------------------------ Shift Nodes ------------------------------------ … … 2575 2569 // ------------------------------ Relational Nodes ------------------------------- 2576 2570 2577 static inline bool lessThan(ExecState *exec, JSValue* v1, JSValue* v2)2571 static inline bool lessThan(ExecState* exec, JSValue* v1, JSValue* v2) 2578 2572 { 2579 2573 double n1; … … 2583 2577 bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1); 2584 2578 bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2); 2585 2579 2586 2580 if (wasNotString1 | wasNotString2) 2587 2581 return n1 < n2; … … 2590 2584 } 2591 2585 2592 static inline bool lessThanEq(ExecState *exec, JSValue* v1, JSValue* v2)2586 static inline bool lessThanEq(ExecState* exec, JSValue* v1, JSValue* v2) 2593 2587 { 2594 2588 double n1; … … 2598 2592 bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1); 2599 2593 bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2); 2600 2594 2601 2595 if (wasNotString1 | wasNotString2) 2602 2596 return n1 <= n2; … … 2674 2668 2675 2669 // ECMA 11.8.2 2676 bool GreaterNode::inlineEvaluateToBoolean(ExecState *exec)2670 bool GreaterNode::inlineEvaluateToBoolean(ExecState* exec) 2677 2671 { 2678 2672 JSValue* v1 = m_expr1->evaluate(exec); … … 2688 2682 } 2689 2683 2690 bool GreaterNode::evaluateToBoolean(ExecState *exec)2684 bool GreaterNode::evaluateToBoolean(ExecState* exec) 2691 2685 { 2692 2686 return inlineEvaluateToBoolean(exec); … … 2805 2799 2806 2800 // ECMA 11.8.7 2807 JSValue* InNode::evaluate(ExecState *exec)2801 JSValue* InNode::evaluate(ExecState* exec) 2808 2802 { 2809 2803 JSValue* v1 = m_expr1->evaluate(exec); … … 2818 2812 } 2819 2813 2820 bool InNode::evaluateToBoolean(ExecState *exec)2814 bool InNode::evaluateToBoolean(ExecState* exec) 2821 2815 { 2822 2816 JSValue* v1 = m_expr1->evaluate(exec); … … 2848 2842 JSValue* v2 = m_expr2->evaluate(exec); 2849 2843 KJS_CHECKEXCEPTIONBOOLEAN 2850 2844 2851 2845 return equal(exec, v1, v2); 2852 2846 } … … 2953 2947 // ECMA 11.10 2954 2948 JSValue* BitAndNode::evaluate(ExecState* exec) 2955 { 2956 JSValue *v1 = m_expr1->evaluate(exec);2957 KJS_CHECKEXCEPTIONVALUE 2958 JSValue *v2 = m_expr2->evaluate(exec);2949 { 2950 JSValue* v1 = m_expr1->evaluate(exec); 2951 KJS_CHECKEXCEPTIONVALUE 2952 JSValue* v2 = m_expr2->evaluate(exec); 2959 2953 KJS_CHECKEXCEPTIONVALUE 2960 2954 … … 3169 3163 static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(ExecState* exec, JSValue* current, ExpressionNode* right, Operator oper) 3170 3164 { 3171 JSValue *v;3172 int i1;3173 int i2;3174 unsigned int ui;3175 switch (oper) {3176 case OpMultEq:3177 v = jsNumber(current->toNumber(exec) * right->evaluateToNumber(exec));3178 break;3179 case OpDivEq:3180 v = jsNumber(current->toNumber(exec) / right->evaluateToNumber(exec));3181 break;3182 case OpPlusEq:3183 v = add(exec, current, right->evaluate(exec));3184 break;3185 case OpMinusEq:3186 v = jsNumber(current->toNumber(exec) - right->evaluateToNumber(exec));3187 break;3188 case OpLShift:3189 i1 = current->toInt32(exec);3190 i2 = right->evaluateToInt32(exec);3191 v = jsNumber(i1 << i2);3192 break;3193 case OpRShift:3194 i1 = current->toInt32(exec);3195 i2 = right->evaluateToInt32(exec);3196 v = jsNumber(i1 >> i2);3197 break;3198 case OpURShift:3199 ui = current->toUInt32(exec);3200 i2 = right->evaluateToInt32(exec);3201 v = jsNumber(ui >> i2);3202 break;3203 case OpAndEq:3204 i1 = current->toInt32(exec);3205 i2 = right->evaluateToInt32(exec);3206 v = jsNumber(i1 & i2);3207 break;3208 case OpXOrEq:3209 i1 = current->toInt32(exec);3210 i2 = right->evaluateToInt32(exec);3211 v = jsNumber(i1 ^ i2);3212 break;3213 case OpOrEq:3214 i1 = current->toInt32(exec);3215 i2 = right->evaluateToInt32(exec);3216 v = jsNumber(i1 | i2);3217 break;3218 case OpModEq: {3219 double d1 = current->toNumber(exec);3220 double d2 = right->evaluateToNumber(exec);3221 v = jsNumber(fmod(d1, d2));3222 }3223 break;3224 default:3225 ASSERT_NOT_REACHED();3226 v = jsUndefined();3227 }3228 3229 return v;3165 JSValue* v; 3166 int i1; 3167 int i2; 3168 unsigned int ui; 3169 switch (oper) { 3170 case OpMultEq: 3171 v = jsNumber(current->toNumber(exec) * right->evaluateToNumber(exec)); 3172 break; 3173 case OpDivEq: 3174 v = jsNumber(current->toNumber(exec) / right->evaluateToNumber(exec)); 3175 break; 3176 case OpPlusEq: 3177 v = add(exec, current, right->evaluate(exec)); 3178 break; 3179 case OpMinusEq: 3180 v = jsNumber(current->toNumber(exec) - right->evaluateToNumber(exec)); 3181 break; 3182 case OpLShift: 3183 i1 = current->toInt32(exec); 3184 i2 = right->evaluateToInt32(exec); 3185 v = jsNumber(i1 << i2); 3186 break; 3187 case OpRShift: 3188 i1 = current->toInt32(exec); 3189 i2 = right->evaluateToInt32(exec); 3190 v = jsNumber(i1 >> i2); 3191 break; 3192 case OpURShift: 3193 ui = current->toUInt32(exec); 3194 i2 = right->evaluateToInt32(exec); 3195 v = jsNumber(ui >> i2); 3196 break; 3197 case OpAndEq: 3198 i1 = current->toInt32(exec); 3199 i2 = right->evaluateToInt32(exec); 3200 v = jsNumber(i1 & i2); 3201 break; 3202 case OpXOrEq: 3203 i1 = current->toInt32(exec); 3204 i2 = right->evaluateToInt32(exec); 3205 v = jsNumber(i1 ^ i2); 3206 break; 3207 case OpOrEq: 3208 i1 = current->toInt32(exec); 3209 i2 = right->evaluateToInt32(exec); 3210 v = jsNumber(i1 | i2); 3211 break; 3212 case OpModEq: { 3213 double d1 = current->toNumber(exec); 3214 double d2 = right->evaluateToNumber(exec); 3215 v = jsNumber(fmod(d1, d2)); 3216 } 3217 break; 3218 default: 3219 ASSERT_NOT_REACHED(); 3220 v = jsUndefined(); 3221 } 3222 3223 return v; 3230 3224 } 3231 3225 … … 3265 3259 JSValue** slot = &exec->localStorage()[m_index].value; 3266 3260 3267 ASSERT(m_oper != OpEqual); 3268 JSValue* v = valueForReadModifyAssignment(exec, *slot, m_right.get(), m_oper); 3269 3270 KJS_CHECKEXCEPTIONVALUE 3271 3261 ASSERT(m_operator != OpEqual); 3262 JSValue* v = valueForReadModifyAssignment(exec, *slot, m_right.get(), m_operator); 3263 3264 KJS_CHECKEXCEPTIONVALUE 3272 3265 *slot = v; 3273 3266 return v; … … 3284 3277 3285 3278 exec->localStorage()[m_index].value = v; 3286 3279 3287 3280 return v; 3288 3281 } … … 3294 3287 ASSERT(exec->variableObject() == exec->scopeChain().top()); 3295 3288 JSValue* left = exec->localStorage()[m_index].value; 3296 ASSERT(m_oper != OpEqual);3297 JSValue* result = valueForReadModifyAssignment(exec, left, m_right.get(), m_oper );3289 ASSERT(m_operator != OpEqual); 3290 JSValue* result = valueForReadModifyAssignment(exec, left, m_right.get(), m_operator); 3298 3291 KJS_CHECKEXCEPTIONVALUE 3299 3292 return result; … … 3307 3300 } 3308 3301 3309 JSValue *ReadModifyResolveNode::evaluate(ExecState *exec) 3310 { 3311 const ScopeChain& chain = exec->scopeChain(); 3312 ScopeChainIterator iter = chain.begin(); 3313 ScopeChainIterator end = chain.end(); 3314 3315 // we must always have something in the scope chain 3316 ASSERT(iter != end); 3317 3318 PropertySlot slot; 3319 JSObject *base; 3320 do { 3321 base = *iter; 3322 if (base->getPropertySlot(exec, m_ident, slot)) { 3323 // See the comment in PostIncResolveNode::evaluate(). 3324 3325 base = *iter; 3326 goto found; 3327 } 3328 3329 ++iter; 3330 } while (iter != end); 3331 3332 ASSERT(m_oper != OpEqual); 3333 return throwUndefinedVariableError(exec, m_ident); 3334 3335 found: 3336 JSValue *v; 3337 3338 3339 ASSERT(m_oper != OpEqual); 3340 JSValue *v1 = slot.getValue(exec, base, m_ident); 3341 KJS_CHECKEXCEPTIONVALUE 3342 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_oper); 3343 3344 KJS_CHECKEXCEPTIONVALUE 3345 3346 base->put(exec, m_ident, v); 3347 return v; 3348 } 3349 3350 JSValue *AssignResolveNode::evaluate(ExecState *exec) 3351 { 3352 const ScopeChain& chain = exec->scopeChain(); 3353 ScopeChainIterator iter = chain.begin(); 3354 ScopeChainIterator end = chain.end(); 3355 3356 // we must always have something in the scope chain 3357 ASSERT(iter != end); 3358 3359 PropertySlot slot; 3360 JSObject *base; 3361 do { 3362 base = *iter; 3363 if (base->getPropertySlot(exec, m_ident, slot)) { 3364 // See the comment in PostIncResolveNode::evaluate(). 3365 3366 base = *iter; 3367 goto found; 3368 } 3369 3370 ++iter; 3371 } while (iter != end); 3372 3373 found: 3374 JSValue *v = m_right->evaluate(exec); 3375 3376 KJS_CHECKEXCEPTIONVALUE 3377 3378 base->put(exec, m_ident, v); 3379 return v; 3302 JSValue* ReadModifyResolveNode::evaluate(ExecState* exec) 3303 { 3304 const ScopeChain& chain = exec->scopeChain(); 3305 ScopeChainIterator iter = chain.begin(); 3306 ScopeChainIterator end = chain.end(); 3307 3308 // We must always have something in the scope chain 3309 ASSERT(iter != end); 3310 3311 PropertySlot slot; 3312 JSObject* base; 3313 do { 3314 base = *iter; 3315 if (base->getPropertySlot(exec, m_ident, slot)) { 3316 // See the comment in PostIncResolveNode::evaluate(). 3317 3318 base = *iter; 3319 goto found; 3320 } 3321 3322 ++iter; 3323 } while (iter != end); 3324 3325 ASSERT(m_operator != OpEqual); 3326 return throwUndefinedVariableError(exec, m_ident); 3327 3328 found: 3329 JSValue* v; 3330 3331 ASSERT(m_operator != OpEqual); 3332 JSValue* v1 = slot.getValue(exec, base, m_ident); 3333 KJS_CHECKEXCEPTIONVALUE 3334 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator); 3335 3336 KJS_CHECKEXCEPTIONVALUE 3337 3338 base->put(exec, m_ident, v); 3339 return v; 3340 } 3341 3342 JSValue* AssignResolveNode::evaluate(ExecState* exec) 3343 { 3344 const ScopeChain& chain = exec->scopeChain(); 3345 ScopeChainIterator iter = chain.begin(); 3346 ScopeChainIterator end = chain.end(); 3347 3348 // we must always have something in the scope chain 3349 ASSERT(iter != end); 3350 3351 PropertySlot slot; 3352 JSObject* base; 3353 do { 3354 base = *iter; 3355 if (base->getPropertySlot(exec, m_ident, slot)) { 3356 // See the comment in PostIncResolveNode::evaluate(). 3357 3358 base = *iter; 3359 goto found; 3360 } 3361 3362 ++iter; 3363 } while (iter != end); 3364 3365 found: 3366 JSValue* v = m_right->evaluate(exec); 3367 3368 KJS_CHECKEXCEPTIONVALUE 3369 3370 base->put(exec, m_ident, v); 3371 return v; 3380 3372 } 3381 3373 … … 3388 3380 } 3389 3381 3390 JSValue *AssignDotNode::evaluate(ExecState *exec)3391 { 3392 JSValue *baseValue = m_base->evaluate(exec);3393 KJS_CHECKEXCEPTIONVALUE3394 JSObject *base = baseValue->toObject(exec);3395 3396 JSValue *v = m_right->evaluate(exec);3397 3398 KJS_CHECKEXCEPTIONVALUE3399 3400 base->put(exec, m_ident, v);3401 return v;3382 JSValue* AssignDotNode::evaluate(ExecState* exec) 3383 { 3384 JSValue* baseValue = m_base->evaluate(exec); 3385 KJS_CHECKEXCEPTIONVALUE 3386 JSObject* base = baseValue->toObject(exec); 3387 3388 JSValue* v = m_right->evaluate(exec); 3389 3390 KJS_CHECKEXCEPTIONVALUE 3391 3392 base->put(exec, m_ident, v); 3393 return v; 3402 3394 } 3403 3395 … … 3408 3400 } 3409 3401 3410 JSValue *ReadModifyDotNode::evaluate(ExecState *exec)3411 { 3412 JSValue *baseValue = m_base->evaluate(exec);3413 KJS_CHECKEXCEPTIONVALUE3414 JSObject *base = baseValue->toObject(exec);3415 3416 JSValue *v;3417 3418 ASSERT(m_oper != OpEqual);3419 PropertySlot slot;3420 JSValue *v1 = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();3421 KJS_CHECKEXCEPTIONVALUE3422 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_oper);3423 3424 KJS_CHECKEXCEPTIONVALUE3425 3426 base->put(exec, m_ident, v);3427 return v;3402 JSValue* ReadModifyDotNode::evaluate(ExecState* exec) 3403 { 3404 JSValue* baseValue = m_base->evaluate(exec); 3405 KJS_CHECKEXCEPTIONVALUE 3406 JSObject* base = baseValue->toObject(exec); 3407 3408 JSValue* v; 3409 3410 ASSERT(m_operator != OpEqual); 3411 PropertySlot slot; 3412 JSValue* v1 = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined(); 3413 KJS_CHECKEXCEPTIONVALUE 3414 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator); 3415 3416 KJS_CHECKEXCEPTIONVALUE 3417 3418 base->put(exec, m_ident, v); 3419 return v; 3428 3420 } 3429 3421 … … 3446 3438 } 3447 3439 3448 JSValue *AssignBracketNode::evaluate(ExecState *exec) 3449 { 3450 JSValue *baseValue = m_base->evaluate(exec); 3451 KJS_CHECKEXCEPTIONVALUE 3452 JSValue *subscript = m_subscript->evaluate(exec); 3453 KJS_CHECKEXCEPTIONVALUE 3454 3455 JSObject *base = baseValue->toObject(exec); 3456 3457 uint32_t propertyIndex; 3458 if (subscript->getUInt32(propertyIndex)) { 3459 JSValue *v = m_right->evaluate(exec); 3460 KJS_CHECKEXCEPTIONVALUE 3461 3462 base->put(exec, propertyIndex, v); 3440 JSValue* AssignBracketNode::evaluate(ExecState* exec) 3441 { 3442 JSValue* baseValue = m_base->evaluate(exec); 3443 KJS_CHECKEXCEPTIONVALUE 3444 JSValue* subscript = m_subscript->evaluate(exec); 3445 KJS_CHECKEXCEPTIONVALUE 3446 3447 JSObject* base = baseValue->toObject(exec); 3448 3449 uint32_t propertyIndex; 3450 if (subscript->getUInt32(propertyIndex)) { 3451 JSValue* v = m_right->evaluate(exec); 3452 KJS_CHECKEXCEPTIONVALUE 3453 3454 base->put(exec, propertyIndex, v); 3455 return v; 3456 } 3457 3458 Identifier propertyName(subscript->toString(exec)); 3459 JSValue* v = m_right->evaluate(exec); 3460 KJS_CHECKEXCEPTIONVALUE 3461 3462 base->put(exec, propertyName, v); 3463 3463 return v; 3464 }3465 3466 Identifier propertyName(subscript->toString(exec));3467 JSValue *v = m_right->evaluate(exec);3468 KJS_CHECKEXCEPTIONVALUE3469 3470 base->put(exec, propertyName, v);3471 return v;3472 3464 } 3473 3465 void ReadModifyBracketNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack) … … 3478 3470 } 3479 3471 3480 JSValue *ReadModifyBracketNode::evaluate(ExecState *exec) 3481 { 3482 JSValue *baseValue = m_base->evaluate(exec); 3483 KJS_CHECKEXCEPTIONVALUE 3484 JSValue *subscript = m_subscript->evaluate(exec); 3485 KJS_CHECKEXCEPTIONVALUE 3486 3487 JSObject *base = baseValue->toObject(exec); 3488 3489 uint32_t propertyIndex; 3490 if (subscript->getUInt32(propertyIndex)) { 3491 JSValue *v; 3492 ASSERT(m_oper != OpEqual); 3472 JSValue* ReadModifyBracketNode::evaluate(ExecState* exec) 3473 { 3474 JSValue* baseValue = m_base->evaluate(exec); 3475 KJS_CHECKEXCEPTIONVALUE 3476 JSValue* subscript = m_subscript->evaluate(exec); 3477 KJS_CHECKEXCEPTIONVALUE 3478 3479 JSObject* base = baseValue->toObject(exec); 3480 3481 uint32_t propertyIndex; 3482 if (subscript->getUInt32(propertyIndex)) { 3483 JSValue* v; 3484 ASSERT(m_operator != OpEqual); 3485 PropertySlot slot; 3486 JSValue* v1 = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined(); 3487 KJS_CHECKEXCEPTIONVALUE 3488 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator); 3489 3490 KJS_CHECKEXCEPTIONVALUE 3491 3492 base->put(exec, propertyIndex, v); 3493 return v; 3494 } 3495 3496 Identifier propertyName(subscript->toString(exec)); 3497 JSValue* v; 3498 3499 ASSERT(m_operator != OpEqual); 3493 3500 PropertySlot slot; 3494 JSValue *v1 = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();3495 KJS_CHECKEXCEPTIONVALUE 3496 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_oper );3497 3498 KJS_CHECKEXCEPTIONVALUE 3499 3500 base->put(exec, property Index, v);3501 JSValue* v1 = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined(); 3502 KJS_CHECKEXCEPTIONVALUE 3503 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator); 3504 3505 KJS_CHECKEXCEPTIONVALUE 3506 3507 base->put(exec, propertyName, v); 3501 3508 return v; 3502 }3503 3504 Identifier propertyName(subscript->toString(exec));3505 JSValue *v;3506 3507 ASSERT(m_oper != OpEqual);3508 PropertySlot slot;3509 JSValue *v1 = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();3510 KJS_CHECKEXCEPTIONVALUE3511 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_oper);3512 3513 KJS_CHECKEXCEPTIONVALUE3514 3515 base->put(exec, propertyName, v);3516 return v;3517 3509 } 3518 3510 … … 3526 3518 3527 3519 // ECMA 11.14 3528 JSValue* CommaNode::evaluate(ExecState *exec)3520 JSValue* CommaNode::evaluate(ExecState* exec) 3529 3521 { 3530 3522 m_expr1->evaluate(exec); … … 3553 3545 ScopeChainIterator iter = chain.begin(); 3554 3546 ScopeChainIterator end = chain.end(); 3555 3556 // we must always have something in the scope chain3547 3548 // We must always have something in the scope chain 3557 3549 ASSERT(iter != end); 3558 3550 3559 3551 PropertySlot slot; 3560 3552 JSObject* base; 3561 3553 3562 3554 do { 3563 3555 base = *iter; 3564 3556 if (base->getPropertySlot(exec, m_ident, slot)) 3565 3557 break; 3566 3558 3567 3559 ++iter; 3568 3560 } while (iter != end); 3569 3561 3570 3562 unsigned flags = 0; 3571 3563 base->getPropertyAttributes(m_ident, flags); 3572 3564 flags |= ReadOnly; 3573 3565 3574 3566 base->put(exec, m_ident, val, flags); 3575 3567 } … … 3599 3591 3600 3592 // if the variable object is the top of the scope chain, then that must 3601 // be where this variable is declared, processVarDecls would have put 3593 // be where this variable is declared, processVarDecls would have put 3602 3594 // it there. Don't search the scope chain, to optimize this very common case. 3603 3595 if (chain.top() != variableObject) … … 3607 3599 variableObject->getPropertyAttributes(m_ident, flags); 3608 3600 flags |= ReadOnly; 3609 3601 3610 3602 variableObject->put(exec, m_ident, val, flags); 3611 3603 } … … 3658 3650 static inline Node* statementListInitializeVariableAccessStack(StatementVector& statements, DeclarationStacks::NodeStack& stack) 3659 3651 { 3660 if ( !statements.size())3652 if (statements.isEmpty()) 3661 3653 return 0; 3662 3654 … … 3664 3656 StatementVector::iterator begin = statements.begin(); 3665 3657 StatementVector::iterator beginPlusOne = begin + 1; 3666 3658 3667 3659 while (it != beginPlusOne) { 3668 3660 --it; … … 3780 3772 if (b) 3781 3773 return m_ifBlock->execute(exec); 3782 3783 3774 return m_elseBlock->execute(exec); 3784 3775 } … … 3816 3807 } 3817 3808 3818 continueDoWhileLoop:3809 continueDoWhileLoop: 3819 3810 bool b = m_expr->evaluateToBoolean(exec); 3820 3811 KJS_CHECKEXCEPTION … … 3851 3842 if (exec->dynamicGlobalObject()->timedOut()) 3852 3843 return exec->setInterruptedCompletion(); 3853 3844 3854 3845 if (statementValue) 3855 3846 value = statementValue; … … 3878 3869 3879 3870 // ECMA 12.6.3 3880 JSValue* ForNode::execute(ExecState *exec)3871 JSValue* ForNode::execute(ExecState* exec) 3881 3872 { 3882 3873 JSValue* value = 0; … … 3908 3899 } 3909 3900 3910 continueForLoop:3901 continueForLoop: 3911 3902 m_expr3->evaluate(exec); 3912 3903 KJS_CHECKEXCEPTION 3913 3904 } 3914 3905 3915 3906 return exec->setNormalCompletion(value); 3916 3907 } … … 3934 3925 , m_identIsVarDecl(true) 3935 3926 { 3936 if (in)3937 m_init = new AssignResolveNode(ident, in);3938 // for( var foo = bar in baz )3927 if (in) 3928 m_init = new AssignResolveNode(ident, in); 3929 // for( var foo = bar in baz ) 3939 3930 } 3940 3931 … … 3951 3942 JSValue* ForInNode::execute(ExecState* exec) 3952 3943 { 3953 JSValue* value = 0; 3954 3955 if (m_init) { 3956 m_init->evaluate(exec); 3944 JSValue* value = 0; 3945 3946 if (m_init) { 3947 m_init->evaluate(exec); 3948 KJS_CHECKEXCEPTION 3949 } 3950 3951 JSValue* e = m_expr->evaluate(exec); 3957 3952 KJS_CHECKEXCEPTION 3958 } 3959 3960 JSValue* e = m_expr->evaluate(exec); 3961 KJS_CHECKEXCEPTION 3962 3963 // For Null and Undefined, we want to make sure not to go through 3964 // the loop at all, because toObject will throw an exception. 3965 if (e->isUndefinedOrNull()) 3966 return exec->setNormalCompletion(); 3967 3968 JSObject* v = e->toObject(exec); 3969 PropertyNameArray propertyNames; 3970 v->getPropertyNames(exec, propertyNames); 3971 3972 PropertyNameArray::const_iterator end = propertyNames.end(); 3973 for (PropertyNameArray::const_iterator it = propertyNames.begin(); it != end; ++it) { 3974 const Identifier& name = *it; 3975 if (!v->hasProperty(exec, name)) 3976 continue; 3977 3978 JSValue *str = jsOwnedString(name.ustring()); 3979 3980 if (m_lexpr->isResolveNode()) { 3981 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr.get())->identifier(); 3982 3983 const ScopeChain& chain = exec->scopeChain(); 3984 ScopeChainIterator iter = chain.begin(); 3985 ScopeChainIterator end = chain.end(); 3986 3987 // we must always have something in the scope chain 3988 ASSERT(iter != end); 3989 3990 PropertySlot slot; 3991 JSObject *o; 3992 do { 3993 o = *iter; 3994 if (o->getPropertySlot(exec, ident, slot)) { 3953 3954 // For Null and Undefined, we want to make sure not to go through 3955 // the loop at all, because toObject will throw an exception. 3956 if (e->isUndefinedOrNull()) 3957 return exec->setNormalCompletion(); 3958 3959 JSObject* v = e->toObject(exec); 3960 PropertyNameArray propertyNames; 3961 v->getPropertyNames(exec, propertyNames); 3962 3963 PropertyNameArray::const_iterator end = propertyNames.end(); 3964 for (PropertyNameArray::const_iterator it = propertyNames.begin(); it != end; ++it) { 3965 const Identifier& name = *it; 3966 if (!v->hasProperty(exec, name)) 3967 continue; 3968 3969 JSValue* str = jsOwnedString(name.ustring()); 3970 3971 if (m_lexpr->isResolveNode()) { 3972 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr.get())->identifier(); 3973 3974 const ScopeChain& chain = exec->scopeChain(); 3975 ScopeChainIterator iter = chain.begin(); 3976 ScopeChainIterator end = chain.end(); 3977 3978 // we must always have something in the scope chain 3979 ASSERT(iter != end); 3980 3981 PropertySlot slot; 3982 JSObject* o; 3983 do { 3984 o = *iter; 3985 if (o->getPropertySlot(exec, ident, slot)) { 3986 o->put(exec, ident, str); 3987 break; 3988 } 3989 ++iter; 3990 } while (iter != end); 3991 3992 if (iter == end) 3995 3993 o->put(exec, ident, str); 3994 } else if (m_lexpr->isDotAccessorNode()) { 3995 const Identifier& ident = static_cast<DotAccessorNode*>(m_lexpr.get())->identifier(); 3996 JSValue* v = static_cast<DotAccessorNode*>(m_lexpr.get())->base()->evaluate(exec); 3997 KJS_CHECKEXCEPTION 3998 JSObject* o = v->toObject(exec); 3999 4000 o->put(exec, ident, str); 4001 } else { 4002 ASSERT(m_lexpr->isBracketAccessorNode()); 4003 JSValue* v = static_cast<BracketAccessorNode*>(m_lexpr.get())->base()->evaluate(exec); 4004 KJS_CHECKEXCEPTION 4005 JSValue* v2 = static_cast<BracketAccessorNode*>(m_lexpr.get())->subscript()->evaluate(exec); 4006 KJS_CHECKEXCEPTION 4007 JSObject* o = v->toObject(exec); 4008 4009 uint32_t i; 4010 if (v2->getUInt32(i)) 4011 o->put(exec, i, str); 4012 o->put(exec, Identifier(v2->toString(exec)), str); 4013 } 4014 4015 KJS_CHECKEXCEPTION 4016 4017 exec->pushIteration(); 4018 JSValue* statementValue = m_statement->execute(exec); 4019 exec->popIteration(); 4020 if (statementValue) 4021 value = statementValue; 4022 4023 if (exec->completionType() != Normal) { 4024 if (exec->completionType() == Continue && m_labelStack.contains(exec->breakOrContinueTarget())) 4025 continue; 4026 if (exec->completionType() == Break && m_labelStack.contains(exec->breakOrContinueTarget())) 3996 4027 break; 3997 } 3998 ++iter; 3999 } while (iter != end); 4000 4001 if (iter == end) 4002 o->put(exec, ident, str); 4003 } else if (m_lexpr->isDotAccessorNode()) { 4004 const Identifier& ident = static_cast<DotAccessorNode*>(m_lexpr.get())->identifier(); 4005 JSValue* v = static_cast<DotAccessorNode*>(m_lexpr.get())->base()->evaluate(exec); 4006 KJS_CHECKEXCEPTION 4007 JSObject *o = v->toObject(exec); 4008 4009 o->put(exec, ident, str); 4010 } else { 4011 ASSERT(m_lexpr->isBracketAccessorNode()); 4012 JSValue* v = static_cast<BracketAccessorNode*>(m_lexpr.get())->base()->evaluate(exec); 4013 KJS_CHECKEXCEPTION 4014 JSValue* v2 = static_cast<BracketAccessorNode*>(m_lexpr.get())->subscript()->evaluate(exec); 4015 KJS_CHECKEXCEPTION 4016 JSObject *o = v->toObject(exec); 4017 4018 uint32_t i; 4019 if (v2->getUInt32(i)) 4020 o->put(exec, i, str); 4021 o->put(exec, Identifier(v2->toString(exec)), str); 4022 } 4023 4024 KJS_CHECKEXCEPTION 4025 4026 exec->pushIteration(); 4027 JSValue* statementValue = m_statement->execute(exec); 4028 exec->popIteration(); 4029 if (statementValue) 4030 value = statementValue; 4031 4032 if (exec->completionType() != Normal) { 4033 if (exec->completionType() == Continue && m_labelStack.contains(exec->breakOrContinueTarget())) 4034 continue; 4035 if (exec->completionType() == Break && m_labelStack.contains(exec->breakOrContinueTarget())) 4036 break; 4037 return statementValue; 4038 } 4039 } 4040 4041 return exec->setNormalCompletion(value); 4028 return statementValue; 4029 } 4030 } 4031 4032 return exec->setNormalCompletion(value); 4042 4033 } 4043 4034 … … 4047 4038 JSValue* ContinueNode::execute(ExecState* exec) 4048 4039 { 4049 if (m_ident.isEmpty() && !exec->inIteration())4050 return setErrorCompletion(exec, SyntaxError, "Invalid continue statement.");4051 if (!m_ident.isEmpty() && !exec->seenLabels().contains(m_ident))4052 return setErrorCompletion(exec, SyntaxError, "Label %s not found.", m_ident);4053 return exec->setContinueCompletion(&m_ident);4040 if (m_ident.isEmpty() && !exec->inIteration()) 4041 return setErrorCompletion(exec, SyntaxError, "Invalid continue statement."); 4042 if (!m_ident.isEmpty() && !exec->seenLabels().contains(m_ident)) 4043 return setErrorCompletion(exec, SyntaxError, "Label %s not found.", m_ident); 4044 return exec->setContinueCompletion(&m_ident); 4054 4045 } 4055 4046 … … 4057 4048 4058 4049 // ECMA 12.8 4059 JSValue* BreakNode::execute(ExecState *exec)4060 { 4061 if (m_ident.isEmpty() && !exec->inIteration() && !exec->inSwitch())4062 return setErrorCompletion(exec, SyntaxError, "Invalid break statement.");4063 if (!m_ident.isEmpty() && !exec->seenLabels().contains(m_ident))4064 return setErrorCompletion(exec, SyntaxError, "Label %s not found.");4065 return exec->setBreakCompletion(&m_ident);4050 JSValue* BreakNode::execute(ExecState* exec) 4051 { 4052 if (m_ident.isEmpty() && !exec->inIteration() && !exec->inSwitch()) 4053 return setErrorCompletion(exec, SyntaxError, "Invalid break statement."); 4054 if (!m_ident.isEmpty() && !exec->seenLabels().contains(m_ident)) 4055 return setErrorCompletion(exec, SyntaxError, "Label %s not found."); 4056 return exec->setBreakCompletion(&m_ident); 4066 4057 } 4067 4058 … … 4077 4068 JSValue* ReturnNode::execute(ExecState* exec) 4078 4069 { 4079 CodeType codeType = exec->codeType();4080 if (codeType != FunctionCode)4081 return setErrorCompletion(exec, SyntaxError, "Invalid return statement.");4082 4083 if (!m_value)4084 return exec->setReturnValueCompletion(jsUndefined());4085 4086 JSValue* v = m_value->evaluate(exec);4087 KJS_CHECKEXCEPTION4088 4089 return exec->setReturnValueCompletion(v);4070 CodeType codeType = exec->codeType(); 4071 if (codeType != FunctionCode) 4072 return setErrorCompletion(exec, SyntaxError, "Invalid return statement."); 4073 4074 if (!m_value) 4075 return exec->setReturnValueCompletion(jsUndefined()); 4076 4077 JSValue* v = m_value->evaluate(exec); 4078 KJS_CHECKEXCEPTION 4079 4080 return exec->setReturnValueCompletion(v); 4090 4081 } 4091 4082 … … 4099 4090 4100 4091 // ECMA 12.10 4101 JSValue* WithNode::execute(ExecState *exec)4102 { 4103 JSValue *v = m_expr->evaluate(exec);4104 KJS_CHECKEXCEPTION4105 JSObject *o = v->toObject(exec);4106 KJS_CHECKEXCEPTION4107 exec->dynamicGlobalObject()->tearOffActivation(exec);4108 exec->pushScope(o);4109 JSValue* value = m_statement->execute(exec);4110 exec->popScope();4111 4112 return value;4113 } 4114 4092 JSValue* WithNode::execute(ExecState* exec) 4093 { 4094 JSValue* v = m_expr->evaluate(exec); 4095 KJS_CHECKEXCEPTION 4096 JSObject* o = v->toObject(exec); 4097 KJS_CHECKEXCEPTION 4098 exec->dynamicGlobalObject()->tearOffActivation(exec); 4099 exec->pushScope(o); 4100 JSValue* value = m_statement->execute(exec); 4101 exec->popScope(); 4102 4103 return value; 4104 } 4105 4115 4106 // ------------------------------ CaseClauseNode ------------------------------- 4116 4107 … … 4123 4114 4124 4115 // ECMA 12.11 4125 JSValue *CaseClauseNode::evaluate(ExecState *exec)4126 { 4127 JSValue *v = m_expr->evaluate(exec);4128 KJS_CHECKEXCEPTIONVALUE4129 4130 return v;4116 JSValue* CaseClauseNode::evaluate(ExecState* exec) 4117 { 4118 JSValue* v = m_expr->evaluate(exec); 4119 KJS_CHECKEXCEPTIONVALUE 4120 4121 return v; 4131 4122 } 4132 4123 … … 4154 4145 { 4155 4146 } 4156 4147 4157 4148 void CaseBlockNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack) 4158 4149 { … … 4168 4159 JSValue* CaseBlockNode::executeBlock(ExecState* exec, JSValue* input) 4169 4160 { 4170 ClauseListNode* a = m_list1.get();4161 ClauseListNode* a = m_list1.get(); 4171 4162 while (a) { 4172 CaseClauseNode* clause = a->getClause(); 4173 a = a->getNext(); 4174 JSValue* v = clause->evaluate(exec); 4175 KJS_CHECKEXCEPTION 4176 if (strictEqual(exec, input, v)) { 4163 CaseClauseNode* clause = a->getClause(); 4164 a = a->getNext(); 4165 JSValue* v = clause->evaluate(exec); 4166 KJS_CHECKEXCEPTION 4167 if (strictEqual(exec, input, v)) { 4168 JSValue* res = clause->executeStatements(exec); 4169 if (exec->completionType() != Normal) 4170 return res; 4171 for (; a; a = a->getNext()) { 4172 JSValue* res = a->getClause()->executeStatements(exec); 4173 if (exec->completionType() != Normal) 4174 return res; 4175 } 4176 break; 4177 } 4178 } 4179 4180 ClauseListNode* b = m_list2.get(); 4181 while (b) { 4182 CaseClauseNode* clause = b->getClause(); 4183 b = b->getNext(); 4184 JSValue* v = clause->evaluate(exec); 4185 KJS_CHECKEXCEPTION 4186 if (strictEqual(exec, input, v)) { 4187 JSValue* res = clause->executeStatements(exec); 4188 if (exec->completionType() != Normal) 4189 return res; 4190 goto step18; 4191 } 4192 } 4193 4194 // default clause 4195 if (m_defaultClause) { 4196 JSValue* res = m_defaultClause->executeStatements(exec); 4197 if (exec->completionType() != Normal) 4198 return res; 4199 } 4200 b = m_list2.get(); 4201 step18: 4202 while (b) { 4203 CaseClauseNode* clause = b->getClause(); 4177 4204 JSValue* res = clause->executeStatements(exec); 4178 4205 if (exec->completionType() != Normal) 4179 return res;4180 for (; a; a = a->getNext()) {4181 JSValue* res = a->getClause()->executeStatements(exec);4182 if (exec->completionType() != Normal)4183 4206 return res; 4184 } 4185 break; 4186 } 4187 } 4188 4189 ClauseListNode* b = m_list2.get(); 4190 while (b) { 4191 CaseClauseNode* clause = b->getClause(); 4192 b = b->getNext(); 4193 JSValue* v = clause->evaluate(exec); 4207 b = b->getNext(); 4208 } 4209 4210 // bail out on error 4194 4211 KJS_CHECKEXCEPTION 4195 if (strictEqual(exec, input, v)) { 4196 JSValue* res = clause->executeStatements(exec); 4197 if (exec->completionType() != Normal) 4198 return res; 4199 goto step18; 4200 } 4201 } 4202 4203 // default clause 4204 if (m_defaultClause) { 4205 JSValue* res = m_defaultClause->executeStatements(exec); 4206 if (exec->completionType() != Normal) 4207 return res; 4208 } 4209 b = m_list2.get(); 4210 step18: 4211 while (b) { 4212 CaseClauseNode* clause = b->getClause(); 4213 JSValue* res = clause->executeStatements(exec); 4214 if (exec->completionType() != Normal) 4215 return res; 4216 b = b->getNext(); 4217 } 4218 4219 // bail out on error 4220 KJS_CHECKEXCEPTION 4221 4222 return exec->setNormalCompletion(); 4212 4213 return exec->setNormalCompletion(); 4223 4214 } 4224 4215 … … 4234 4225 JSValue* SwitchNode::execute(ExecState* exec) 4235 4226 { 4236 JSValue *v = m_expr->evaluate(exec);4237 KJS_CHECKEXCEPTION4238 4239 exec->pushSwitch();4240 JSValue* result = m_block->executeBlock(exec, v);4241 exec->popSwitch();4242 4243 if (exec->completionType() == Break && m_labelStack.contains(exec->breakOrContinueTarget()))4244 exec->setCompletionType(Normal);4245 return result;4227 JSValue* v = m_expr->evaluate(exec); 4228 KJS_CHECKEXCEPTION 4229 4230 exec->pushSwitch(); 4231 JSValue* result = m_block->executeBlock(exec, v); 4232 exec->popSwitch(); 4233 4234 if (exec->completionType() == Break && m_labelStack.contains(exec->breakOrContinueTarget())) 4235 exec->setCompletionType(Normal); 4236 return result; 4246 4237 } 4247 4238 … … 4256 4247 JSValue* LabelNode::execute(ExecState* exec) 4257 4248 { 4258 if (!exec->seenLabels().push(m_label))4259 return setErrorCompletion(exec, SyntaxError, "Duplicated label %s found.", m_label);4260 JSValue* result = m_statement->execute(exec);4261 exec->seenLabels().pop();4262 4263 if (exec->completionType() == Break && exec->breakOrContinueTarget() == m_label)4264 exec->setCompletionType(Normal);4265 return result;4249 if (!exec->seenLabels().push(m_label)) 4250 return setErrorCompletion(exec, SyntaxError, "Duplicated label %s found.", m_label); 4251 JSValue* result = m_statement->execute(exec); 4252 exec->seenLabels().pop(); 4253 4254 if (exec->completionType() == Break && exec->breakOrContinueTarget() == m_label) 4255 exec->setCompletionType(Normal); 4256 return result; 4266 4257 } 4267 4258 … … 4276 4267 JSValue* ThrowNode::execute(ExecState* exec) 4277 4268 { 4278 JSValue *v = m_expr->evaluate(exec);4279 KJS_CHECKEXCEPTION4280 4281 handleException(exec, v);4282 return exec->setThrowCompletion(v);4269 JSValue* v = m_expr->evaluate(exec); 4270 KJS_CHECKEXCEPTION 4271 4272 handleException(exec, v); 4273 return exec->setThrowCompletion(v); 4283 4274 } 4284 4275 … … 4296 4287 JSValue* TryNode::execute(ExecState* exec) 4297 4288 { 4298 JSValue* result = m_tryBlock->execute(exec);4299 4300 if (Collector::isOutOfMemory())4301 return result; // don't try to catch an out of memory exception thrown by the collector4302 4303 if (m_catchBlock && exec->completionType() == Throw) {4304 JSObject* obj = new JSObject;4305 obj->put(exec, m_exceptionIdent, result, DontDelete);4306 exec->dynamicGlobalObject()->tearOffActivation(exec);4307 exec->pushScope(obj);4308 result = m_catchBlock->execute(exec);4309 exec->popScope();4310 }4311 4312 if (m_finallyBlock) {4313 ComplType savedCompletionType = exec->completionType();4314 JSValue* finallyResult = m_finallyBlock->execute(exec);4315 if (exec->completionType() != Normal)4316 result = finallyResult;4317 else4318 exec->setCompletionType(savedCompletionType);4319 }4320 4321 return result;4289 JSValue* result = m_tryBlock->execute(exec); 4290 4291 if (Collector::isOutOfMemory()) 4292 return result; // don't try to catch an out of memory exception thrown by the collector 4293 4294 if (m_catchBlock && exec->completionType() == Throw) { 4295 JSObject* obj = new JSObject; 4296 obj->put(exec, m_exceptionIdent, result, DontDelete); 4297 exec->dynamicGlobalObject()->tearOffActivation(exec); 4298 exec->pushScope(obj); 4299 result = m_catchBlock->execute(exec); 4300 exec->popScope(); 4301 } 4302 4303 if (m_finallyBlock) { 4304 ComplType savedCompletionType = exec->completionType(); 4305 JSValue* finallyResult = m_finallyBlock->execute(exec); 4306 if (exec->completionType() != Normal) 4307 result = finallyResult; 4308 else 4309 exec->setCompletionType(savedCompletionType); 4310 } 4311 4312 return result; 4322 4313 } 4323 4314 … … 4377 4368 { 4378 4369 SymbolTable& symbolTable = exec->variableObject()->symbolTable(); 4379 ASSERT( !symbolTable.size());4370 ASSERT(symbolTable.isEmpty()); 4380 4371 4381 4372 size_t localStorageIndex = 0; … … 4408 4399 // FunctionBodyNode::initializeSymbolTable, which knows that no bindings 4409 4400 // have yet been made. 4410 4401 4411 4402 JSVariableObject* variableObject = exec->variableObject(); 4412 4403 SymbolTable& symbolTable = variableObject->symbolTable(); … … 4416 4407 4417 4408 // Order must match the order in processDeclarations. 4418 4409 4419 4410 size = m_functionStack.size(); 4420 4411 m_functionIndexes.resize(size); … … 4454 4445 if (!node) 4455 4446 return; 4456 4447 4457 4448 const SymbolTable& symbolTable = exec->variableObject()->symbolTable(); 4458 4449 const LocalStorage& localStorage = exec->variableObject()->localStorage(); 4459 4450 while (true) { 4460 4451 node->optimizeVariableAccess(symbolTable, localStorage, nodeStack); 4461 4452 4462 4453 size_t size = nodeStack.size(); 4463 4454 if (!size) … … 4474 4465 initializeSymbolTable(exec); 4475 4466 4476 if ( m_functionStack.size() != 0)4467 if (!m_functionStack.isEmpty()) 4477 4468 exec->dynamicGlobalObject()->tearOffActivation(exec); 4478 4469 4479 4470 LocalStorage& localStorage = exec->variableObject()->localStorage(); 4480 4471 4481 4472 // We can't just resize localStorage here because that would temporarily 4482 4473 // leave uninitialized entries, which would crash GC during the mark phase. … … 4484 4475 if (totalSize > localStorage.capacity()) // Doing this check inline avoids function call overhead. 4485 4476 localStorage.reserveCapacity(totalSize); 4486 4477 4487 4478 int minAttributes = Internal | DontDelete; 4488 4489 // In order for our localStorage indexes to be correct, we must match the 4479 4480 // In order for our localStorage indexes to be correct, we must match the 4490 4481 // order of addition in initializeSymbolTable(). 4491 4482 … … 4507 4498 4508 4499 if (!m_initialized) { 4509 optimizeVariableAccess(exec); 4500 optimizeVariableAccess(exec); 4510 4501 m_initialized = true; 4511 4502 } … … 4523 4514 // increase in L2 cache misses. FIXME: <rdar://problem/5657439> WTF? 4524 4515 gccIsCrazy(); 4525 4516 4526 4517 initializeSymbolTable(exec); 4527 4518 … … 4559 4550 attributes |= ReadOnly; 4560 4551 LocalStorageEntry entry = LocalStorageEntry(jsUndefined(), attributes); 4561 4552 4562 4553 ASSERT(index == localStorage.size()); 4563 4554 localStorage.uncheckedAppend(entry); … … 4572 4563 // reports that to be a net loss. 4573 4564 4574 size_t i, size; 4565 size_t i; 4566 size_t size; 4575 4567 4576 4568 JSVariableObject* variableObject = exec->variableObject(); 4577 4569 4578 4570 int minAttributes = Internal; 4579 4571 … … 4596 4588 UString FunctionBodyNode::paramString() const 4597 4589 { 4598 UString s("");4599 size_t count = m_parameters.size();4600 for (size_t pos = 0; pos < count; ++pos) {4601 if (!s.isEmpty())4602 s += ", ";4603 s += m_parameters[pos].ustring();4604 }4605 4606 return s;4590 UString s(""); 4591 size_t count = m_parameters.size(); 4592 for (size_t pos = 0; pos < count; ++pos) { 4593 if (!s.isEmpty()) 4594 s += ", "; 4595 s += m_parameters[pos].ustring(); 4596 } 4597 4598 return s; 4607 4599 } 4608 4600 … … 4627 4619 // ------------------------------ FunctionBodyNodeWithDebuggerHooks --------------------------------- 4628 4620 4629 FunctionBodyNodeWithDebuggerHooks::FunctionBodyNodeWithDebuggerHooks(SourceElements* children, 4630 DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack) 4621 FunctionBodyNodeWithDebuggerHooks::FunctionBodyNodeWithDebuggerHooks(SourceElements* children, DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack) 4631 4622 : FunctionBodyNode(children, varStack, funcStack) 4632 4623 { … … 4658 4649 // ------------------------------ FuncDeclNode --------------------------------- 4659 4650 4660 void FuncDeclNode::addParams() 4661 { 4662 for (ParameterNode *p = m_parameter.get(); p != 0L; p = p->nextParam())4663 m_body->parameters().append(p->ident());4651 void FuncDeclNode::addParams() 4652 { 4653 for (ParameterNode* p = m_parameter.get(); p; p = p->nextParam()) 4654 m_body->parameters().append(p->ident()); 4664 4655 } 4665 4656 4666 4657 FunctionImp* FuncDeclNode::makeFunction(ExecState* exec) 4667 4658 { 4668 FunctionImp *func = new FunctionImp(exec, m_ident, m_body.get(), exec->scopeChain());4669 4670 JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());4671 proto->put(exec, exec->propertyNames().constructor, func, ReadOnly | DontDelete | DontEnum);4672 func->put(exec, exec->propertyNames().prototype, proto, Internal|DontDelete);4673 4674 func->put(exec, exec->propertyNames().length, jsNumber(m_body->parameters().size()), ReadOnly|DontDelete|DontEnum);4675 return func;4659 FunctionImp* func = new FunctionImp(exec, m_ident, m_body.get(), exec->scopeChain()); 4660 4661 JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList()); 4662 proto->put(exec, exec->propertyNames().constructor, func, ReadOnly | DontDelete | DontEnum); 4663 func->put(exec, exec->propertyNames().prototype, proto, Internal|DontDelete); 4664 4665 func->put(exec, exec->propertyNames().length, jsNumber(m_body->parameters().size()), ReadOnly|DontDelete|DontEnum); 4666 return func; 4676 4667 } 4677 4668 … … 4686 4677 void FuncExprNode::addParams() 4687 4678 { 4688 for (ParameterNode* p = m_parameter.get(); p != 0L; p = p->nextParam())4689 m_body->parameters().append(p->ident());4690 } 4691 4692 JSValue *FuncExprNode::evaluate(ExecState *exec)4693 { 4694 exec->dynamicGlobalObject()->tearOffActivation(exec);4695 4696 bool named = !m_ident.isNull();4697 JSObject *functionScopeObject = 0;4698 4699 if (named) {4700 // named FunctionExpressions can recursively call themselves,4701 // but they won't register with the current scope chain and should4702 // be contained as single property in an anonymous object.4703 functionScopeObject = new JSObject;4704 exec->pushScope(functionScopeObject);4705 }4706 4707 FunctionImp* func = new FunctionImp(exec, m_ident, m_body.get(), exec->scopeChain());4708 JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());4709 proto->put(exec, exec->propertyNames().constructor, func, ReadOnly | DontDelete | DontEnum);4710 func->put(exec, exec->propertyNames().prototype, proto, Internal | DontDelete);4711 4712 if (named) {4713 functionScopeObject->put(exec, m_ident, func, Internal | ReadOnly | (exec->codeType() == EvalCode ? 0 : DontDelete));4714 exec->popScope();4715 }4716 4717 return func;4679 for (ParameterNode* p = m_parameter.get(); p; p = p->nextParam()) 4680 m_body->parameters().append(p->ident()); 4681 } 4682 4683 JSValue* FuncExprNode::evaluate(ExecState* exec) 4684 { 4685 exec->dynamicGlobalObject()->tearOffActivation(exec); 4686 4687 bool named = !m_ident.isNull(); 4688 JSObject* functionScopeObject = 0; 4689 4690 if (named) { 4691 // named FunctionExpressions can recursively call themselves, 4692 // but they won't register with the current scope chain and should 4693 // be contained as single property in an anonymous object. 4694 functionScopeObject = new JSObject; 4695 exec->pushScope(functionScopeObject); 4696 } 4697 4698 FunctionImp* func = new FunctionImp(exec, m_ident, m_body.get(), exec->scopeChain()); 4699 JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList()); 4700 proto->put(exec, exec->propertyNames().constructor, func, ReadOnly | DontDelete | DontEnum); 4701 func->put(exec, exec->propertyNames().prototype, proto, Internal | DontDelete); 4702 4703 if (named) { 4704 functionScopeObject->put(exec, m_ident, func, Internal | ReadOnly | (exec->codeType() == EvalCode ? 0 : DontDelete)); 4705 exec->popScope(); 4706 } 4707 4708 return func; 4718 4709 } 4719 4710 -
trunk/JavaScriptCore/kjs/nodes.h
r29825 r29836 2 2 * Copyright (C) 1999-2000 Harri Porten ([email protected]) 3 3 * Copyright (C) 2001 Peter Kelly ([email protected]) 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 5 5 * Copyright (C) 2007 Cameron Zwarich ([email protected]) 6 6 * Copyright (C) 2007 Maks Orlovich … … 43 43 namespace KJS { 44 44 45 class ConstDeclNode; 45 46 class FuncDeclNode; 46 47 class Node; 47 48 class PropertyListNode; 48 49 class SourceStream; 49 class ConstDeclNode;50 50 51 51 enum Operator { … … 87 87 PrecExpression 88 88 }; 89 90 struct DeclarationStacks { 91 typedef Vector<Node*, 16> NodeStack; 92 enum { IsConstant = 1, HasInitializer = 2 } VarAttrs; 93 typedef Vector<std::pair<Identifier, unsigned>, 16> VarStack; 94 typedef Vector<FuncDeclNode*, 16> FunctionStack; 95 96 DeclarationStacks(ExecState* e, NodeStack& n, VarStack& v, FunctionStack& f) 97 : exec(e) 98 , nodeStack(n) 99 , varStack(v) 100 , functionStack(f) 101 { 102 } 103 104 ExecState* exec; 105 NodeStack& nodeStack; 106 VarStack& varStack; 107 FunctionStack& functionStack; 108 }; 109 110 class ParserRefCounted : Noncopyable { 111 protected: 112 ParserRefCounted() KJS_FAST_CALL; 113 ParserRefCounted(PlacementNewAdoptType) KJS_FAST_CALL { } 114 115 public: 116 void ref() KJS_FAST_CALL; 117 void deref() KJS_FAST_CALL; 118 unsigned refcount() KJS_FAST_CALL; 119 120 static void deleteNewObjects() KJS_FAST_CALL; 121 122 virtual ~ParserRefCounted(); 123 }; 124 125 class Node : public ParserRefCounted { 126 public: 127 typedef DeclarationStacks::NodeStack NodeStack; 128 typedef DeclarationStacks::VarStack VarStack; 129 typedef DeclarationStacks::FunctionStack FunctionStack; 130 131 Node() KJS_FAST_CALL; 132 Node(PlacementNewAdoptType placementAdopt) KJS_FAST_CALL 133 : ParserRefCounted(placementAdopt) { } 134 135 UString toString() const KJS_FAST_CALL; 136 int lineNo() const KJS_FAST_CALL { return m_line; } 137 138 // Serialization. 139 virtual void streamTo(SourceStream&) const KJS_FAST_CALL = 0; 140 virtual Precedence precedence() const = 0; 141 virtual bool needsParensIfLeftmost() const { return false; } 142 143 // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries. 144 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL { } 145 146 protected: 147 Node(JSType) KJS_FAST_CALL; // used by ExpressionNode 148 149 // for use in execute() 150 JSValue* setErrorCompletion(ExecState*, ErrorType, const char* msg) KJS_FAST_CALL; 151 JSValue* setErrorCompletion(ExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL; 152 153 // for use in evaluate() 154 JSValue* throwError(ExecState*, ErrorType, const char* msg) KJS_FAST_CALL; 155 JSValue* throwError(ExecState*, ErrorType, const char* msg, const char*) KJS_FAST_CALL; 156 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*) KJS_FAST_CALL; 157 JSValue* throwError(ExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL; 158 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, const Identifier&) KJS_FAST_CALL; 159 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, Node*) KJS_FAST_CALL; 160 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, const Identifier&) KJS_FAST_CALL; 161 162 JSValue* throwUndefinedVariableError(ExecState*, const Identifier&) KJS_FAST_CALL; 163 164 void handleException(ExecState*) KJS_FAST_CALL; 165 void handleException(ExecState*, JSValue*) KJS_FAST_CALL; 166 167 // for use in execute() 168 JSValue* rethrowException(ExecState*) KJS_FAST_CALL; 169 170 int m_line : 28; 171 unsigned m_expectedReturnType : 3; // JSType 172 }; 173 89 90 struct DeclarationStacks { 91 typedef Vector<Node*, 16> NodeStack; 92 enum { IsConstant = 1, HasInitializer = 2 } VarAttrs; 93 typedef Vector<std::pair<Identifier, unsigned>, 16> VarStack; 94 typedef Vector<FuncDeclNode*, 16> FunctionStack; 95 96 DeclarationStacks(ExecState* e, NodeStack& n, VarStack& v, FunctionStack& f) 97 : exec(e) 98 , nodeStack(n) 99 , varStack(v) 100 , functionStack(f) 101 { 102 } 103 104 ExecState* exec; 105 NodeStack& nodeStack; 106 VarStack& varStack; 107 FunctionStack& functionStack; 108 }; 109 110 class ParserRefCounted : Noncopyable { 111 protected: 112 ParserRefCounted() KJS_FAST_CALL; 113 ParserRefCounted(PlacementNewAdoptType) KJS_FAST_CALL 114 { 115 } 116 117 public: 118 void ref() KJS_FAST_CALL; 119 void deref() KJS_FAST_CALL; 120 unsigned refcount() KJS_FAST_CALL; 121 122 static void deleteNewObjects() KJS_FAST_CALL; 123 124 virtual ~ParserRefCounted(); 125 }; 126 127 class Node : public ParserRefCounted { 128 public: 129 typedef DeclarationStacks::NodeStack NodeStack; 130 typedef DeclarationStacks::VarStack VarStack; 131 typedef DeclarationStacks::FunctionStack FunctionStack; 132 133 Node() KJS_FAST_CALL; 134 Node(PlacementNewAdoptType placementAdopt) KJS_FAST_CALL 135 : ParserRefCounted(placementAdopt) 136 { 137 } 138 139 UString toString() const KJS_FAST_CALL; 140 int lineNo() const KJS_FAST_CALL { return m_line; } 141 142 // Serialization. 143 virtual void streamTo(SourceStream&) const KJS_FAST_CALL = 0; 144 virtual Precedence precedence() const = 0; 145 virtual bool needsParensIfLeftmost() const { return false; } 146 147 // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries. 148 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL { } 149 150 protected: 151 Node(JSType) KJS_FAST_CALL; // used by ExpressionNode 152 153 // for use in execute() 154 JSValue* setErrorCompletion(ExecState*, ErrorType, const char* msg) KJS_FAST_CALL; 155 JSValue* setErrorCompletion(ExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL; 156 157 // for use in evaluate() 158 JSValue* throwError(ExecState*, ErrorType, const char* msg) KJS_FAST_CALL; 159 JSValue* throwError(ExecState*, ErrorType, const char* msg, const char*) KJS_FAST_CALL; 160 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*) KJS_FAST_CALL; 161 JSValue* throwError(ExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL; 162 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, const Identifier&) KJS_FAST_CALL; 163 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, Node*) KJS_FAST_CALL; 164 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, const Identifier&) KJS_FAST_CALL; 165 166 JSValue* throwUndefinedVariableError(ExecState*, const Identifier&) KJS_FAST_CALL; 167 168 void handleException(ExecState*) KJS_FAST_CALL; 169 void handleException(ExecState*, JSValue*) KJS_FAST_CALL; 170 171 // for use in execute() 172 JSValue* rethrowException(ExecState*) KJS_FAST_CALL; 173 174 int m_line : 28; 175 unsigned m_expectedReturnType : 3; // JSType 176 }; 177 174 178 class ExpressionNode : public Node { 175 179 public: 176 180 ExpressionNode() KJS_FAST_CALL : Node() {} 177 181 ExpressionNode(JSType expectedReturn) KJS_FAST_CALL 178 : Node(expectedReturn) {} 179 182 : Node(expectedReturn) 183 { 184 } 185 180 186 // Special constructor for cases where we overwrite an object in place. 181 187 ExpressionNode(PlacementNewAdoptType) KJS_FAST_CALL 182 : Node(PlacementNewAdopt) {} 183 188 : Node(PlacementNewAdopt) 189 { 190 } 191 184 192 virtual bool isNumber() const KJS_FAST_CALL { return false; } 185 193 virtual bool isLocation() const KJS_FAST_CALL { return false; } … … 187 195 virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return false; } 188 196 virtual bool isDotAccessorNode() const KJS_FAST_CALL { return false; } 189 197 190 198 JSType expectedReturnType() const KJS_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); } 191 199 192 200 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL = 0; 193 201 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; … … 198 206 // Used to optimize those nodes that do extra work when returning a result, even if the result has no semantic relevance 199 207 virtual void optimizeForUnnecessaryResult() { } 200 }; 201 202 class StatementNode : public Node { 203 public: 204 StatementNode() KJS_FAST_CALL; 205 void setLoc(int line0, int line1) KJS_FAST_CALL; 206 int firstLine() const KJS_FAST_CALL { return lineNo(); } 207 int lastLine() const KJS_FAST_CALL { return m_lastLine; } 208 virtual JSValue* execute(ExecState *exec) KJS_FAST_CALL = 0; 209 void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_labelStack.push(ident); } 210 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 211 virtual bool isEmptyStatement() const KJS_FAST_CALL { return false; } 212 protected: 213 LabelStack m_labelStack; 214 private: 215 int m_lastLine; 216 }; 217 218 class NullNode : public ExpressionNode { 219 public: 220 NullNode() KJS_FAST_CALL : ExpressionNode(NullType) {} 221 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 222 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 223 virtual Precedence precedence() const { return PrecPrimary; } 224 }; 225 226 class FalseNode : public ExpressionNode { 227 public: 228 FalseNode() KJS_FAST_CALL : ExpressionNode(BooleanType) {} 229 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 230 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return false; } 231 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 232 virtual Precedence precedence() const { return PrecPrimary; } 233 }; 234 235 class TrueNode : public ExpressionNode { 236 public: 237 TrueNode() KJS_FAST_CALL : ExpressionNode(BooleanType) {} 238 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 239 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return true; } 240 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 241 virtual Precedence precedence() const { return PrecPrimary; } 242 }; 243 244 class PlaceholderTrueNode : public TrueNode { 245 public: 246 // Like TrueNode, but does not serialize as "true". 247 PlaceholderTrueNode() KJS_FAST_CALL : TrueNode() { } 248 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 249 }; 250 251 class NumberNode : public ExpressionNode { 252 public: 253 NumberNode(double v) KJS_FAST_CALL : ExpressionNode(NumberType), m_double(v) {} 254 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 255 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 256 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 257 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 258 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 259 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 260 virtual Precedence precedence() const { return signbit(m_double) ? PrecUnary : PrecPrimary; } 261 262 virtual bool isNumber() const KJS_FAST_CALL { return true; } 263 double value() const KJS_FAST_CALL { return m_double; } 264 virtual void setValue(double d) KJS_FAST_CALL { m_double = d; } 265 266 protected: 267 double m_double; 268 }; 269 270 class ImmediateNumberNode : public NumberNode { 271 public: 272 ImmediateNumberNode(JSValue* v, double d) KJS_FAST_CALL : NumberNode(d), m_value(v) { ASSERT(v == JSImmediate::from(d)); } 273 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 274 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 275 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 276 277 virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); } 278 private: 279 JSValue* m_value; // This is never a JSCell, only JSImmediate, thus no ProtectedPtr 280 }; 281 282 class StringNode : public ExpressionNode { 283 public: 284 StringNode(const UString* v) KJS_FAST_CALL : ExpressionNode(StringType), m_value(*v) {} 285 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 286 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 287 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 288 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 289 virtual Precedence precedence() const { return PrecPrimary; } 290 291 private: 292 UString m_value; 293 }; 294 295 class RegExpNode : public ExpressionNode { 296 public: 297 RegExpNode(const UString& pattern, const UString& flags) KJS_FAST_CALL 298 : m_regExp(new RegExp(pattern, flags)) 299 { 300 } 301 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 302 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 303 virtual Precedence precedence() const { return PrecPrimary; } 304 private: 305 RefPtr<RegExp> m_regExp; 306 }; 307 308 class ThisNode : public ExpressionNode { 309 public: 310 ThisNode() KJS_FAST_CALL {} 311 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 312 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 313 virtual Precedence precedence() const { return PrecPrimary; } 314 }; 315 316 class ResolveNode : public ExpressionNode { 317 public: 318 ResolveNode(const Identifier& ident) KJS_FAST_CALL 319 : m_ident(ident) 320 { 321 } 322 323 // Special constructor for cases where we overwrite an object in place. 324 ResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 325 : ExpressionNode(PlacementNewAdopt) 326 , m_ident(PlacementNewAdopt) 327 { 328 } 329 330 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 331 332 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 333 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 334 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 335 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 336 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 337 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 338 virtual Precedence precedence() const { return PrecPrimary; } 339 340 virtual bool isLocation() const KJS_FAST_CALL { return true; } 341 virtual bool isResolveNode() const KJS_FAST_CALL { return true; } 342 const Identifier& identifier() const KJS_FAST_CALL { return m_ident; } 343 344 protected: 345 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 346 Identifier m_ident; 347 size_t m_index; // Used by LocalVarAccessNode. 348 }; 349 350 class LocalVarAccessNode : public ResolveNode { 351 public: 352 // Overwrites a ResolveNode in place. 353 LocalVarAccessNode(size_t i) KJS_FAST_CALL 354 : ResolveNode(PlacementNewAdopt) 355 { 356 ASSERT(i != missingSymbolMarker()); 357 m_index = i; 358 } 359 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 360 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 361 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 362 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 363 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 364 private: 365 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 366 }; 367 368 class ElementNode : public Node { 369 public: 370 ElementNode(int elision, ExpressionNode* node) KJS_FAST_CALL 371 : m_elision(elision), m_node(node) { } 372 ElementNode(ElementNode* l, int elision, ExpressionNode* node) KJS_FAST_CALL 373 : m_elision(elision), m_node(node) { l->m_next = this; } 374 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 375 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 376 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 377 378 PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return m_next.release(); } 379 380 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 381 382 private: 383 friend class ArrayNode; 384 ListRefPtr<ElementNode> m_next; 385 int m_elision; 386 RefPtr<ExpressionNode> m_node; 387 }; 388 389 class ArrayNode : public ExpressionNode { 390 public: 391 ArrayNode(int e) KJS_FAST_CALL 392 : m_elision(e), m_opt(true) { } 393 ArrayNode(ElementNode* element) KJS_FAST_CALL 394 : m_element(element), m_elision(0), m_opt(false) { } 395 ArrayNode(int elision, ElementNode* element) KJS_FAST_CALL 396 : m_element(element), m_elision(elision), m_opt(true) { } 397 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 398 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 399 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 400 virtual Precedence precedence() const { return PrecPrimary; } 401 private: 402 RefPtr<ElementNode> m_element; 403 int m_elision; 404 bool m_opt; 405 }; 406 407 class PropertyNode : public Node { 408 public: 409 enum Type { Constant, Getter, Setter }; 410 PropertyNode(const Identifier& n, ExpressionNode* a, Type t) KJS_FAST_CALL 411 : m_name(n), m_assign(a), m_type(t) { } 412 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 413 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 414 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 415 416 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 417 const Identifier& name() const { return m_name; } 418 419 private: 420 friend class PropertyListNode; 421 Identifier m_name; 422 RefPtr<ExpressionNode> m_assign; 423 Type m_type; 424 }; 425 426 class PropertyListNode : public Node { 427 public: 428 PropertyListNode(PropertyNode* node) KJS_FAST_CALL 429 : m_node(node) { } 430 PropertyListNode(PropertyNode* node, PropertyListNode* list) KJS_FAST_CALL 431 : m_node(node) { list->m_next = this; } 432 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 433 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 434 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 435 436 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 437 PassRefPtr<PropertyListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); } 438 439 private: 440 friend class ObjectLiteralNode; 441 RefPtr<PropertyNode> m_node; 442 ListRefPtr<PropertyListNode> m_next; 443 }; 444 445 class ObjectLiteralNode : public ExpressionNode { 446 public: 447 ObjectLiteralNode() KJS_FAST_CALL { } 448 ObjectLiteralNode(PropertyListNode* list) KJS_FAST_CALL : m_list(list) { } 449 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 450 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 451 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 452 virtual Precedence precedence() const { return PrecPrimary; } 453 virtual bool needsParensIfLeftmost() const { return true; } 454 private: 455 RefPtr<PropertyListNode> m_list; 456 }; 457 458 class BracketAccessorNode : public ExpressionNode { 459 public: 460 BracketAccessorNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 461 : m_base(base), m_subscript(subscript) { } 462 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 463 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 464 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 465 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 466 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 467 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 468 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 469 virtual Precedence precedence() const { return PrecMember; } 470 471 virtual bool isLocation() const KJS_FAST_CALL { return true; } 472 virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return true; } 473 ExpressionNode* base() KJS_FAST_CALL { return m_base.get(); } 474 ExpressionNode* subscript() KJS_FAST_CALL { return m_subscript.get(); } 475 476 private: 477 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 478 RefPtr<ExpressionNode> m_base; 479 RefPtr<ExpressionNode> m_subscript; 480 }; 481 482 class DotAccessorNode : public ExpressionNode { 483 public: 484 DotAccessorNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL : m_base(base), m_ident(ident) { } 485 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 486 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 487 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 488 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 489 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 490 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 491 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 492 virtual Precedence precedence() const { return PrecMember; } 493 494 virtual bool isLocation() const KJS_FAST_CALL { return true; } 495 virtual bool isDotAccessorNode() const KJS_FAST_CALL { return true; } 496 ExpressionNode* base() const KJS_FAST_CALL { return m_base.get(); } 497 const Identifier& identifier() const KJS_FAST_CALL { return m_ident; } 498 499 private: 500 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 501 RefPtr<ExpressionNode> m_base; 502 Identifier m_ident; 503 }; 504 505 class ArgumentListNode : public Node { 506 public: 507 ArgumentListNode(ExpressionNode* expr) KJS_FAST_CALL 508 : m_expr(expr) { } 509 ArgumentListNode(ArgumentListNode* listNode, ExpressionNode* expr) KJS_FAST_CALL 510 : m_expr(expr) { listNode->m_next = this; } 511 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 512 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 513 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 514 515 void evaluateList(ExecState*, List&) KJS_FAST_CALL; 516 PassRefPtr<ArgumentListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); } 517 518 private: 519 friend class ArgumentsNode; 520 ListRefPtr<ArgumentListNode> m_next; 521 RefPtr<ExpressionNode> m_expr; 522 }; 523 524 class ArgumentsNode : public Node { 525 public: 526 ArgumentsNode() KJS_FAST_CALL { } 527 ArgumentsNode(ArgumentListNode* listNode) KJS_FAST_CALL 528 : m_listNode(listNode) { } 529 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 530 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 531 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 532 533 void evaluateList(ExecState* exec, List& list) KJS_FAST_CALL { if (m_listNode) m_listNode->evaluateList(exec, list); } 534 535 private: 536 RefPtr<ArgumentListNode> m_listNode; 537 }; 538 539 class NewExprNode : public ExpressionNode { 540 public: 541 NewExprNode(ExpressionNode* expr) KJS_FAST_CALL 542 : m_expr(expr) { } 543 NewExprNode(ExpressionNode* expr, ArgumentsNode* args) KJS_FAST_CALL 544 : m_expr(expr), m_args(args) { } 545 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 546 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 547 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 548 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 549 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 550 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 551 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 552 virtual Precedence precedence() const { return PrecLeftHandSide; } 553 private: 554 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 555 RefPtr<ExpressionNode> m_expr; 556 RefPtr<ArgumentsNode> m_args; 557 }; 558 559 class FunctionCallValueNode : public ExpressionNode { 560 public: 561 FunctionCallValueNode(ExpressionNode* expr, ArgumentsNode* args) KJS_FAST_CALL 562 : m_expr(expr), m_args(args) { } 563 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 564 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 565 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 566 virtual Precedence precedence() const { return PrecCall; } 567 private: 568 RefPtr<ExpressionNode> m_expr; 569 RefPtr<ArgumentsNode> m_args; 570 }; 571 572 class FunctionCallResolveNode : public ExpressionNode { 573 public: 574 FunctionCallResolveNode(const Identifier& ident, ArgumentsNode* args) KJS_FAST_CALL 575 : m_ident(ident) 576 , m_args(args) 577 { 578 } 579 580 FunctionCallResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 581 : ExpressionNode(PlacementNewAdopt) 582 , m_ident(PlacementNewAdopt) 583 , m_args(PlacementNewAdopt) 584 { 585 } 586 587 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 588 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 589 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 590 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 591 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 592 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 593 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 594 virtual Precedence precedence() const { return PrecCall; } 595 596 protected: 597 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 598 Identifier m_ident; 599 RefPtr<ArgumentsNode> m_args; 600 size_t m_index; // Used by LocalVarFunctionCallNode. 601 }; 602 603 class LocalVarFunctionCallNode : public FunctionCallResolveNode { 604 public: 605 LocalVarFunctionCallNode(size_t i) KJS_FAST_CALL 606 : FunctionCallResolveNode(PlacementNewAdopt) 607 { 608 ASSERT(i != missingSymbolMarker()); 609 m_index = i; 610 } 611 612 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 613 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 614 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 615 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 616 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 617 private: 618 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 619 }; 620 621 class FunctionCallBracketNode : public ExpressionNode { 622 public: 623 FunctionCallBracketNode(ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args) KJS_FAST_CALL 624 : m_base(base), m_subscript(subscript), m_args(args) { } 625 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 626 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 627 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 628 virtual Precedence precedence() const { return PrecCall; } 629 protected: 630 RefPtr<ExpressionNode> m_base; 631 RefPtr<ExpressionNode> m_subscript; 632 RefPtr<ArgumentsNode> m_args; 633 }; 634 635 class FunctionCallDotNode : public ExpressionNode { 636 public: 637 FunctionCallDotNode(ExpressionNode* base, const Identifier& ident, ArgumentsNode* args) KJS_FAST_CALL 638 : m_base(base), m_ident(ident), m_args(args) { } 639 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 640 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 641 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 642 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 643 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 644 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 645 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 646 virtual Precedence precedence() const { return PrecCall; } 647 private: 648 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 649 RefPtr<ExpressionNode> m_base; 650 Identifier m_ident; 651 RefPtr<ArgumentsNode> m_args; 652 }; 653 654 class PrePostResolveNode : public ExpressionNode { 655 public: 656 PrePostResolveNode(const Identifier& i) KJS_FAST_CALL : ExpressionNode(NumberType), m_ident(i) {} 657 658 PrePostResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 659 : ExpressionNode(PlacementNewAdopt) 660 , m_ident(PlacementNewAdopt) 661 { 662 } 663 664 protected: 665 Identifier m_ident; 666 size_t m_index; // Used by LocalVarPostfixNode. 667 }; 668 669 class PostIncResolveNode : public PrePostResolveNode { 670 public: 671 PostIncResolveNode(const Identifier& i) KJS_FAST_CALL : PrePostResolveNode(i) {} 672 673 PostIncResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 674 : PrePostResolveNode(PlacementNewAdopt) 675 { 676 } 677 678 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 679 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 680 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 681 virtual Precedence precedence() const { return PrecPostfix; } 682 virtual void optimizeForUnnecessaryResult(); 683 }; 684 685 class PostIncLocalVarNode : public PostIncResolveNode { 686 public: 687 PostIncLocalVarNode(size_t i) KJS_FAST_CALL 688 : PostIncResolveNode(PlacementNewAdopt) 689 { 690 ASSERT(i != missingSymbolMarker()); 691 m_index = i; 692 } 693 694 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 695 virtual void optimizeForUnnecessaryResult(); 696 }; 697 698 class PostIncConstNode : public PostIncResolveNode { 699 public: 700 PostIncConstNode(size_t i) KJS_FAST_CALL 701 : PostIncResolveNode(PlacementNewAdopt) 702 { 703 ASSERT(i != missingSymbolMarker()); 704 m_index = i; 705 } 706 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 707 }; 708 709 class PostDecResolveNode : public PrePostResolveNode { 710 public: 711 PostDecResolveNode(const Identifier& i) KJS_FAST_CALL : PrePostResolveNode(i) {} 712 713 PostDecResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 714 : PrePostResolveNode(PlacementNewAdopt) 715 { 716 } 717 718 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 719 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 720 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 721 virtual Precedence precedence() const { return PrecPostfix; } 722 virtual void optimizeForUnnecessaryResult(); 723 }; 724 725 class PostDecLocalVarNode : public PostDecResolveNode { 726 public: 727 PostDecLocalVarNode(size_t i) KJS_FAST_CALL 728 : PostDecResolveNode(PlacementNewAdopt) 729 { 730 ASSERT(i != missingSymbolMarker()); 731 m_index = i; 732 } 733 734 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 735 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 736 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 737 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 738 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 739 virtual void optimizeForUnnecessaryResult(); 740 private: 741 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 742 }; 743 744 class PostDecConstNode : public PostDecResolveNode { 745 public: 746 PostDecConstNode(size_t i) KJS_FAST_CALL 747 : PostDecResolveNode(PlacementNewAdopt) 748 { 749 ASSERT(i != missingSymbolMarker()); 750 m_index = i; 751 } 752 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 753 }; 754 755 class PostfixBracketNode : public ExpressionNode { 756 public: 757 PostfixBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 758 : m_base(base), m_subscript(subscript) { } 759 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 760 virtual Precedence precedence() const { return PrecPostfix; } 761 protected: 762 RefPtr<ExpressionNode> m_base; 763 RefPtr<ExpressionNode> m_subscript; 764 }; 765 766 class PostIncBracketNode : public PostfixBracketNode { 767 public: 768 PostIncBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 769 : PostfixBracketNode(base, subscript) { } 770 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 771 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 772 }; 773 774 class PostDecBracketNode : public PostfixBracketNode { 775 public: 776 PostDecBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 777 : PostfixBracketNode(base, subscript) { } 778 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 779 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 780 }; 781 782 class PostfixDotNode : public ExpressionNode { 783 public: 784 PostfixDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 785 : m_base(base), m_ident(ident) { } 786 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 787 virtual Precedence precedence() const { return PrecPostfix; } 788 protected: 789 RefPtr<ExpressionNode> m_base; 790 Identifier m_ident; 791 }; 792 793 class PostIncDotNode : public PostfixDotNode { 794 public: 795 PostIncDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 796 : PostfixDotNode(base, ident) { } 797 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 798 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 799 }; 800 801 class PostDecDotNode : public PostfixDotNode { 802 public: 803 PostDecDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 804 : PostfixDotNode(base, ident) { } 805 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 806 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 807 }; 808 809 class PostfixErrorNode : public ExpressionNode { 810 public: 811 PostfixErrorNode(ExpressionNode* expr, Operator oper) KJS_FAST_CALL 812 : m_expr(expr), m_oper(oper) { } 813 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 814 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 815 virtual Precedence precedence() const { return PrecPostfix; } 816 private: 817 RefPtr<ExpressionNode> m_expr; 818 Operator m_oper; 819 }; 820 821 class DeleteResolveNode : public ExpressionNode { 822 public: 823 DeleteResolveNode(const Identifier& ident) KJS_FAST_CALL 824 : m_ident(ident) 825 { 826 } 827 DeleteResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 828 : ExpressionNode(PlacementNewAdopt) 829 , m_ident(PlacementNewAdopt) 830 { 831 } 832 833 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 834 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 835 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 836 virtual Precedence precedence() const { return PrecUnary; } 837 private: 838 Identifier m_ident; 839 }; 840 841 class LocalVarDeleteNode : public DeleteResolveNode { 842 public: 843 LocalVarDeleteNode() KJS_FAST_CALL 844 : DeleteResolveNode(PlacementNewAdopt) 845 { 846 } 847 848 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 849 }; 850 851 class DeleteBracketNode : public ExpressionNode { 852 public: 853 DeleteBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 854 : m_base(base), m_subscript(subscript) { } 855 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 856 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 857 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 858 virtual Precedence precedence() const { return PrecUnary; } 859 private: 860 RefPtr<ExpressionNode> m_base; 861 RefPtr<ExpressionNode> m_subscript; 862 }; 863 864 class DeleteDotNode : public ExpressionNode { 865 public: 866 DeleteDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 867 : m_base(base), m_ident(ident) { } 868 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 869 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 870 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 871 virtual Precedence precedence() const { return PrecUnary; } 872 private: 873 RefPtr<ExpressionNode> m_base; 874 Identifier m_ident; 875 }; 876 877 class DeleteValueNode : public ExpressionNode { 878 public: 879 DeleteValueNode(ExpressionNode* expr) KJS_FAST_CALL 880 : m_expr(expr) { } 881 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 882 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 883 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 884 virtual Precedence precedence() const { return PrecUnary; } 885 private: 886 RefPtr<ExpressionNode> m_expr; 887 }; 888 889 class VoidNode : public ExpressionNode { 890 public: 891 VoidNode(ExpressionNode* expr) KJS_FAST_CALL 892 : m_expr(expr) { } 893 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 894 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 895 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 896 virtual Precedence precedence() const { return PrecUnary; } 897 private: 898 RefPtr<ExpressionNode> m_expr; 899 }; 900 901 class TypeOfResolveNode : public ExpressionNode { 902 public: 903 TypeOfResolveNode(const Identifier& ident) KJS_FAST_CALL 904 : ExpressionNode(StringType) 905 , m_ident(ident) 906 { 907 } 908 909 TypeOfResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 910 : ExpressionNode(PlacementNewAdopt) 911 , m_ident(PlacementNewAdopt) 912 { 913 m_expectedReturnType = StringType; 914 } 915 916 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 917 918 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 919 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 920 virtual Precedence precedence() const { return PrecUnary; } 921 922 const Identifier& identifier() const KJS_FAST_CALL { return m_ident; } 923 924 protected: 925 Identifier m_ident; 926 size_t m_index; // Used by LocalTypeOfNode. 927 }; 928 929 class LocalVarTypeOfNode : public TypeOfResolveNode { 930 public: 931 LocalVarTypeOfNode(size_t i) KJS_FAST_CALL 932 : TypeOfResolveNode(PlacementNewAdopt) 933 { 934 m_expectedReturnType = StringType; 935 ASSERT(i != missingSymbolMarker()); 936 m_index = i; 937 } 938 939 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 940 }; 941 942 class TypeOfValueNode : public ExpressionNode { 943 public: 944 TypeOfValueNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(StringType), m_expr(e) {} 945 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 946 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 947 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 948 virtual Precedence precedence() const { return PrecUnary; } 949 private: 950 RefPtr<ExpressionNode> m_expr; 951 }; 952 953 class PreIncResolveNode : public PrePostResolveNode { 954 public: 955 PreIncResolveNode(const Identifier& ident) KJS_FAST_CALL 956 : PrePostResolveNode(ident) 957 { 958 } 959 960 PreIncResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 961 : PrePostResolveNode(PlacementNewAdopt) 962 { 963 } 964 965 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 966 967 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 968 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 969 virtual Precedence precedence() const { return PrecUnary; } 970 }; 971 972 class PreIncLocalVarNode : public PreIncResolveNode { 973 public: 974 PreIncLocalVarNode(size_t i) KJS_FAST_CALL 975 : PreIncResolveNode(PlacementNewAdopt) 976 { 977 ASSERT(i != missingSymbolMarker()); 978 m_index = i; 979 } 980 981 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 982 }; 983 984 class PreIncConstNode : public PreIncResolveNode { 985 public: 986 PreIncConstNode(size_t i) KJS_FAST_CALL 987 : PreIncResolveNode(PlacementNewAdopt) 988 { 989 ASSERT(i != missingSymbolMarker()); 990 m_index = i; 991 } 992 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 993 }; 994 995 class PreDecResolveNode : public PrePostResolveNode { 996 public: 997 PreDecResolveNode(const Identifier& ident) KJS_FAST_CALL 998 : PrePostResolveNode(ident) 999 { 1000 } 1001 1002 PreDecResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 1003 : PrePostResolveNode(PlacementNewAdopt) 1004 { 1005 } 1006 1007 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1008 1009 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1010 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1011 virtual Precedence precedence() const { return PrecUnary; } 1012 }; 1013 1014 class PreDecLocalVarNode : public PreDecResolveNode { 1015 public: 1016 PreDecLocalVarNode(size_t i) KJS_FAST_CALL 1017 : PreDecResolveNode(PlacementNewAdopt) 1018 { 1019 ASSERT(i != missingSymbolMarker()); 1020 m_index = i; 1021 } 1022 1023 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1024 }; 1025 1026 class PreDecConstNode : public PreDecResolveNode { 1027 public: 1028 PreDecConstNode(size_t i) KJS_FAST_CALL 1029 : PreDecResolveNode(PlacementNewAdopt) 1030 { 1031 ASSERT(i != missingSymbolMarker()); 1032 m_index = i; 1033 } 1034 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1035 }; 1036 1037 class PrefixBracketNode : public ExpressionNode { 1038 public: 1039 PrefixBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 1040 : m_base(base), m_subscript(subscript) { } 1041 1042 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1043 virtual Precedence precedence() const { return PrecUnary; } 1044 protected: 1045 RefPtr<ExpressionNode> m_base; 1046 RefPtr<ExpressionNode> m_subscript; 1047 }; 1048 1049 class PreIncBracketNode : public PrefixBracketNode { 1050 public: 1051 PreIncBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 1052 : PrefixBracketNode(base, subscript) { } 1053 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1054 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1055 }; 1056 1057 class PreDecBracketNode : public PrefixBracketNode { 1058 public: 1059 PreDecBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 1060 : PrefixBracketNode(base, subscript) { } 1061 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1062 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1063 }; 1064 1065 class PrefixDotNode : public ExpressionNode { 1066 public: 1067 PrefixDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 1068 : m_base(base), m_ident(ident) { } 1069 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1070 virtual Precedence precedence() const { return PrecPostfix; } 1071 protected: 1072 RefPtr<ExpressionNode> m_base; 1073 Identifier m_ident; 1074 }; 1075 1076 class PreIncDotNode : public PrefixDotNode { 1077 public: 1078 PreIncDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 1079 : PrefixDotNode(base, ident) { } 1080 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1081 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1082 }; 1083 1084 class PreDecDotNode : public PrefixDotNode { 1085 public: 1086 PreDecDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 1087 : PrefixDotNode(base, ident) { } 1088 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1089 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1090 }; 1091 1092 class PrefixErrorNode : public ExpressionNode { 1093 public: 1094 PrefixErrorNode(ExpressionNode* expr, Operator oper) KJS_FAST_CALL 1095 : m_expr(expr), m_oper(oper) { } 1096 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1097 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1098 virtual Precedence precedence() const { return PrecUnary; } 1099 private: 1100 RefPtr<ExpressionNode> m_expr; 1101 Operator m_oper; 1102 }; 1103 1104 class UnaryPlusNode : public ExpressionNode { 1105 public: 1106 UnaryPlusNode(ExpressionNode* expr) KJS_FAST_CALL 1107 : ExpressionNode(NumberType), m_expr(expr) { } 1108 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1109 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1110 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1111 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1112 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1113 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1114 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1115 virtual Precedence precedence() const { return PrecUnary; } 1116 private: 1117 RefPtr<ExpressionNode> m_expr; 1118 }; 1119 1120 class NegateNode : public ExpressionNode { 1121 public: 1122 NegateNode(ExpressionNode* expr) KJS_FAST_CALL 1123 : ExpressionNode(NumberType), m_expr(expr) { } 1124 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1125 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1126 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1127 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1128 virtual Precedence precedence() const { return PrecUnary; } 1129 private: 1130 RefPtr<ExpressionNode> m_expr; 1131 }; 1132 1133 class BitwiseNotNode : public ExpressionNode { 1134 public: 1135 BitwiseNotNode(ExpressionNode* expr) KJS_FAST_CALL 1136 : ExpressionNode(NumberType), m_expr(expr) { } 1137 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1138 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1139 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1140 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1141 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1142 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1143 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1144 virtual Precedence precedence() const { return PrecUnary; } 1145 private: 1146 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*); 1147 RefPtr<ExpressionNode> m_expr; 1148 }; 1149 1150 class LogicalNotNode : public ExpressionNode { 1151 public: 1152 LogicalNotNode(ExpressionNode* expr) KJS_FAST_CALL 1153 : ExpressionNode(BooleanType), m_expr(expr) { } 1154 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1155 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1156 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1157 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1158 virtual Precedence precedence() const { return PrecUnary; } 1159 private: 1160 RefPtr<ExpressionNode> m_expr; 1161 }; 1162 1163 class MultNode : public ExpressionNode { 1164 public: 1165 MultNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1166 : ExpressionNode(NumberType), m_term1(term1), m_term2(term2) { } 1167 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1168 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1169 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1170 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1171 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1172 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1173 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1174 virtual Precedence precedence() const { return PrecMultiplicitave; } 1175 private: 1176 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 1177 RefPtr<ExpressionNode> m_term1; 1178 RefPtr<ExpressionNode> m_term2; 1179 }; 1180 1181 class DivNode : public ExpressionNode { 1182 public: 1183 DivNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1184 : ExpressionNode(NumberType), m_term1(term1), m_term2(term2) { } 1185 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1186 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1187 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1188 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1189 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1190 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1191 virtual Precedence precedence() const { return PrecMultiplicitave; } 1192 private: 1193 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 1194 RefPtr<ExpressionNode> m_term1; 1195 RefPtr<ExpressionNode> m_term2; 1196 }; 1197 1198 class ModNode : public ExpressionNode { 1199 public: 1200 ModNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1201 : ExpressionNode(NumberType), m_term1(term1), m_term2(term2) { } 1202 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1203 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1204 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1205 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1206 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1207 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1208 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1209 virtual Precedence precedence() const { return PrecMultiplicitave; } 1210 private: 1211 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 1212 RefPtr<ExpressionNode> m_term1; 1213 RefPtr<ExpressionNode> m_term2; 1214 }; 1215 1216 class AddNode : public ExpressionNode { 1217 public: 1218 AddNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1219 : m_term1(term1), m_term2(term2) { } 1220 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1221 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1222 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1223 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1224 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1225 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1226 virtual Precedence precedence() const { return PrecAdditive; } 1227 protected: 1228 AddNode(ExpressionNode* term1, ExpressionNode* term2, JSType expectedReturn) KJS_FAST_CALL 1229 : ExpressionNode(expectedReturn), m_term1(term1), m_term2(term2) { } 1230 RefPtr<ExpressionNode> m_term1; 1231 RefPtr<ExpressionNode> m_term2; 1232 private: 1233 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 1234 }; 1235 1236 class AddNumbersNode : public AddNode { 1237 public: 1238 AddNumbersNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1239 : AddNode(term1, term2, NumberType) { } 1240 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 208 }; 209 210 class StatementNode : public Node { 211 public: 212 StatementNode() KJS_FAST_CALL; 213 void setLoc(int line0, int line1) KJS_FAST_CALL; 214 int firstLine() const KJS_FAST_CALL { return lineNo(); } 215 int lastLine() const KJS_FAST_CALL { return m_lastLine; } 216 virtual JSValue* execute(ExecState *exec) KJS_FAST_CALL = 0; 217 void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_labelStack.push(ident); } 218 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 219 virtual bool isEmptyStatement() const KJS_FAST_CALL { return false; } 220 221 protected: 222 LabelStack m_labelStack; 223 224 private: 225 int m_lastLine; 226 }; 227 228 class NullNode : public ExpressionNode { 229 public: 230 NullNode() KJS_FAST_CALL : ExpressionNode(NullType) {} 231 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 232 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 233 virtual Precedence precedence() const { return PrecPrimary; } 234 }; 235 236 class FalseNode : public ExpressionNode { 237 public: 238 FalseNode() KJS_FAST_CALL 239 : ExpressionNode(BooleanType) 240 { 241 } 242 243 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 244 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return false; } 245 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 246 virtual Precedence precedence() const { return PrecPrimary; } 247 }; 248 249 class TrueNode : public ExpressionNode { 250 public: 251 TrueNode() KJS_FAST_CALL 252 : ExpressionNode(BooleanType) 253 { 254 } 255 256 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 257 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return true; } 258 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 259 virtual Precedence precedence() const { return PrecPrimary; } 260 }; 261 262 class PlaceholderTrueNode : public TrueNode { 263 public: 264 // Like TrueNode, but does not serialize as "true". 265 PlaceholderTrueNode() KJS_FAST_CALL 266 : TrueNode() 267 { 268 } 269 270 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 271 }; 272 273 class NumberNode : public ExpressionNode { 274 public: 275 NumberNode(double v) KJS_FAST_CALL 276 : ExpressionNode(NumberType) 277 , m_double(v) 278 { 279 } 280 281 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 282 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 283 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 284 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 285 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 286 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 287 virtual Precedence precedence() const { return signbit(m_double) ? PrecUnary : PrecPrimary; } 288 289 virtual bool isNumber() const KJS_FAST_CALL { return true; } 290 double value() const KJS_FAST_CALL { return m_double; } 291 virtual void setValue(double d) KJS_FAST_CALL { m_double = d; } 292 293 protected: 294 double m_double; 295 }; 296 297 class ImmediateNumberNode : public NumberNode { 298 public: 299 ImmediateNumberNode(JSValue* v, double d) KJS_FAST_CALL 300 : NumberNode(d) 301 , m_value(v) 302 { 303 ASSERT(v == JSImmediate::from(d)); 304 } 305 306 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 307 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 308 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 309 310 virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); } 311 312 private: 313 JSValue* m_value; // This is never a JSCell, only JSImmediate, thus no ProtectedPtr 314 }; 315 316 class StringNode : public ExpressionNode { 317 public: 318 StringNode(const UString* v) KJS_FAST_CALL 319 : ExpressionNode(StringType) 320 , m_value(*v) 321 { 322 } 323 324 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 325 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 326 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 327 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 328 virtual Precedence precedence() const { return PrecPrimary; } 329 330 private: 331 UString m_value; 332 }; 333 334 class RegExpNode : public ExpressionNode { 335 public: 336 RegExpNode(const UString& pattern, const UString& flags) KJS_FAST_CALL 337 : m_regExp(new RegExp(pattern, flags)) 338 { 339 } 340 341 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 342 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 343 virtual Precedence precedence() const { return PrecPrimary; } 344 345 private: 346 RefPtr<RegExp> m_regExp; 347 }; 348 349 class ThisNode : public ExpressionNode { 350 public: 351 ThisNode() KJS_FAST_CALL 352 { 353 } 354 355 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 356 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 357 virtual Precedence precedence() const { return PrecPrimary; } 358 }; 359 360 class ResolveNode : public ExpressionNode { 361 public: 362 ResolveNode(const Identifier& ident) KJS_FAST_CALL 363 : m_ident(ident) 364 { 365 } 366 367 // Special constructor for cases where we overwrite an object in place. 368 ResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 369 : ExpressionNode(PlacementNewAdopt) 370 , m_ident(PlacementNewAdopt) 371 { 372 } 373 374 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 375 376 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 377 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1241 378 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1242 379 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1243 380 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 381 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 382 virtual Precedence precedence() const { return PrecPrimary; } 383 384 virtual bool isLocation() const KJS_FAST_CALL { return true; } 385 virtual bool isResolveNode() const KJS_FAST_CALL { return true; } 386 const Identifier& identifier() const KJS_FAST_CALL { return m_ident; } 387 388 protected: 389 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 390 Identifier m_ident; 391 size_t m_index; // Used by LocalVarAccessNode. 392 }; 393 394 class LocalVarAccessNode : public ResolveNode { 395 public: 396 // Overwrites a ResolveNode in place. 397 LocalVarAccessNode(size_t i) KJS_FAST_CALL 398 : ResolveNode(PlacementNewAdopt) 399 { 400 ASSERT(i != missingSymbolMarker()); 401 m_index = i; 402 } 403 404 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 405 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 406 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 407 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 408 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 409 410 private: 411 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 412 }; 413 414 class ElementNode : public Node { 415 public: 416 ElementNode(int elision, ExpressionNode* node) KJS_FAST_CALL 417 : m_elision(elision) 418 , m_node(node) 419 { 420 } 421 422 ElementNode(ElementNode* l, int elision, ExpressionNode* node) KJS_FAST_CALL 423 : m_elision(elision) 424 , m_node(node) 425 { 426 l->m_next = this; 427 } 428 429 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 430 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 431 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 432 433 PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return m_next.release(); } 434 435 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 436 437 private: 438 friend class ArrayNode; 439 ListRefPtr<ElementNode> m_next; 440 int m_elision; 441 RefPtr<ExpressionNode> m_node; 442 }; 443 444 class ArrayNode : public ExpressionNode { 445 public: 446 ArrayNode(int elision) KJS_FAST_CALL 447 : m_elision(elision) 448 , m_optional(true) 449 { 450 } 451 452 ArrayNode(ElementNode* element) KJS_FAST_CALL 453 : m_element(element) 454 , m_elision(0) 455 , m_optional(false) 456 { 457 } 458 459 ArrayNode(int elision, ElementNode* element) KJS_FAST_CALL 460 : m_element(element) 461 , m_elision(elision) 462 , m_optional(true) 463 { 464 } 465 466 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 467 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 468 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 469 virtual Precedence precedence() const { return PrecPrimary; } 470 471 private: 472 RefPtr<ElementNode> m_element; 473 int m_elision; 474 bool m_optional; 475 }; 476 477 class PropertyNode : public Node { 478 public: 479 enum Type { Constant, Getter, Setter }; 480 481 PropertyNode(const Identifier& name, ExpressionNode* assign, Type type) KJS_FAST_CALL 482 : m_name(name) 483 , m_assign(assign) 484 , m_type(type) 485 { 486 } 487 488 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 489 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 490 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 491 492 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 493 const Identifier& name() const { return m_name; } 494 495 private: 496 friend class PropertyListNode; 497 Identifier m_name; 498 RefPtr<ExpressionNode> m_assign; 499 Type m_type; 500 }; 501 502 class PropertyListNode : public Node { 503 public: 504 PropertyListNode(PropertyNode* node) KJS_FAST_CALL 505 : m_node(node) 506 { 507 } 508 509 PropertyListNode(PropertyNode* node, PropertyListNode* list) KJS_FAST_CALL 510 : m_node(node) 511 { 512 list->m_next = this; 513 } 514 515 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 516 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 517 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 518 519 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 520 PassRefPtr<PropertyListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); } 521 522 private: 523 friend class ObjectLiteralNode; 524 RefPtr<PropertyNode> m_node; 525 ListRefPtr<PropertyListNode> m_next; 526 }; 527 528 class ObjectLiteralNode : public ExpressionNode { 529 public: 530 ObjectLiteralNode() KJS_FAST_CALL 531 { 532 } 533 534 ObjectLiteralNode(PropertyListNode* list) KJS_FAST_CALL 535 : m_list(list) 536 { 537 } 538 539 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 540 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 541 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 542 virtual Precedence precedence() const { return PrecPrimary; } 543 virtual bool needsParensIfLeftmost() const { return true; } 544 545 private: 546 RefPtr<PropertyListNode> m_list; 547 }; 548 549 class BracketAccessorNode : public ExpressionNode { 550 public: 551 BracketAccessorNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 552 : m_base(base) 553 , m_subscript(subscript) 554 { 555 } 556 557 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 558 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 559 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 560 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 561 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 562 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 563 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 564 virtual Precedence precedence() const { return PrecMember; } 565 566 virtual bool isLocation() const KJS_FAST_CALL { return true; } 567 virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return true; } 568 ExpressionNode* base() KJS_FAST_CALL { return m_base.get(); } 569 ExpressionNode* subscript() KJS_FAST_CALL { return m_subscript.get(); } 570 571 private: 572 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 573 574 RefPtr<ExpressionNode> m_base; 575 RefPtr<ExpressionNode> m_subscript; 576 }; 577 578 class DotAccessorNode : public ExpressionNode { 579 public: 580 DotAccessorNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 581 : m_base(base) 582 , m_ident(ident) 583 { 584 } 585 586 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 587 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 588 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 589 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 590 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 591 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 592 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 593 virtual Precedence precedence() const { return PrecMember; } 594 595 virtual bool isLocation() const KJS_FAST_CALL { return true; } 596 virtual bool isDotAccessorNode() const KJS_FAST_CALL { return true; } 597 ExpressionNode* base() const KJS_FAST_CALL { return m_base.get(); } 598 const Identifier& identifier() const KJS_FAST_CALL { return m_ident; } 599 600 private: 601 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 602 603 RefPtr<ExpressionNode> m_base; 604 Identifier m_ident; 605 }; 606 607 class ArgumentListNode : public Node { 608 public: 609 ArgumentListNode(ExpressionNode* expr) KJS_FAST_CALL 610 : m_expr(expr) 611 { 612 } 613 614 ArgumentListNode(ArgumentListNode* listNode, ExpressionNode* expr) KJS_FAST_CALL 615 : m_expr(expr) 616 { 617 listNode->m_next = this; 618 } 619 620 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 621 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 622 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 623 624 void evaluateList(ExecState*, List&) KJS_FAST_CALL; 625 PassRefPtr<ArgumentListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); } 626 627 private: 628 friend class ArgumentsNode; 629 ListRefPtr<ArgumentListNode> m_next; 630 RefPtr<ExpressionNode> m_expr; 631 }; 632 633 class ArgumentsNode : public Node { 634 public: 635 ArgumentsNode() KJS_FAST_CALL 636 { 637 } 638 639 ArgumentsNode(ArgumentListNode* listNode) KJS_FAST_CALL 640 : m_listNode(listNode) 641 { 642 } 643 644 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 645 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 646 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 647 648 void evaluateList(ExecState* exec, List& list) KJS_FAST_CALL { if (m_listNode) m_listNode->evaluateList(exec, list); } 649 650 private: 651 RefPtr<ArgumentListNode> m_listNode; 652 }; 653 654 class NewExprNode : public ExpressionNode { 655 public: 656 NewExprNode(ExpressionNode* expr) KJS_FAST_CALL 657 : m_expr(expr) 658 { 659 } 660 661 NewExprNode(ExpressionNode* expr, ArgumentsNode* args) KJS_FAST_CALL 662 : m_expr(expr) 663 , m_args(args) 664 { 665 } 666 667 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 668 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 669 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 670 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 671 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 672 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 673 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 674 virtual Precedence precedence() const { return PrecLeftHandSide; } 675 676 private: 677 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 678 679 RefPtr<ExpressionNode> m_expr; 680 RefPtr<ArgumentsNode> m_args; 681 }; 682 683 class FunctionCallValueNode : public ExpressionNode { 684 public: 685 FunctionCallValueNode(ExpressionNode* expr, ArgumentsNode* args) KJS_FAST_CALL 686 : m_expr(expr) 687 , m_args(args) 688 { 689 } 690 691 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 692 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 693 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 694 virtual Precedence precedence() const { return PrecCall; } 695 696 private: 697 RefPtr<ExpressionNode> m_expr; 698 RefPtr<ArgumentsNode> m_args; 699 }; 700 701 class FunctionCallResolveNode : public ExpressionNode { 702 public: 703 FunctionCallResolveNode(const Identifier& ident, ArgumentsNode* args) KJS_FAST_CALL 704 : m_ident(ident) 705 , m_args(args) 706 { 707 } 708 709 FunctionCallResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 710 : ExpressionNode(PlacementNewAdopt) 711 , m_ident(PlacementNewAdopt) 712 , m_args(PlacementNewAdopt) 713 { 714 } 715 716 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 717 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 718 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 719 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 720 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 721 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 722 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 723 virtual Precedence precedence() const { return PrecCall; } 724 725 protected: 726 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 727 728 Identifier m_ident; 729 RefPtr<ArgumentsNode> m_args; 730 size_t m_index; // Used by LocalVarFunctionCallNode. 731 }; 732 733 class LocalVarFunctionCallNode : public FunctionCallResolveNode { 734 public: 735 LocalVarFunctionCallNode(size_t i) KJS_FAST_CALL 736 : FunctionCallResolveNode(PlacementNewAdopt) 737 { 738 ASSERT(i != missingSymbolMarker()); 739 m_index = i; 740 } 741 742 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 743 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 744 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 745 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 746 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 747 748 private: 749 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 750 }; 751 752 class FunctionCallBracketNode : public ExpressionNode { 753 public: 754 FunctionCallBracketNode(ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args) KJS_FAST_CALL 755 : m_base(base) 756 , m_subscript(subscript) 757 , m_args(args) 758 { 759 } 760 761 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 762 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 763 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 764 virtual Precedence precedence() const { return PrecCall; } 765 766 protected: 767 RefPtr<ExpressionNode> m_base; 768 RefPtr<ExpressionNode> m_subscript; 769 RefPtr<ArgumentsNode> m_args; 770 }; 771 772 class FunctionCallDotNode : public ExpressionNode { 773 public: 774 FunctionCallDotNode(ExpressionNode* base, const Identifier& ident, ArgumentsNode* args) KJS_FAST_CALL 775 : m_base(base) 776 , m_ident(ident) 777 , m_args(args) 778 { 779 } 780 781 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 782 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 783 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 784 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 785 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 786 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 787 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 788 virtual Precedence precedence() const { return PrecCall; } 789 790 private: 791 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 792 793 RefPtr<ExpressionNode> m_base; 794 Identifier m_ident; 795 RefPtr<ArgumentsNode> m_args; 796 }; 797 798 class PrePostResolveNode : public ExpressionNode { 799 public: 800 PrePostResolveNode(const Identifier& ident) KJS_FAST_CALL 801 : ExpressionNode(NumberType) 802 , m_ident(ident) 803 { 804 } 805 806 PrePostResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 807 : ExpressionNode(PlacementNewAdopt) 808 , m_ident(PlacementNewAdopt) 809 { 810 } 811 812 protected: 813 Identifier m_ident; 814 size_t m_index; // Used by LocalVarPostfixNode. 815 }; 816 817 class PostIncResolveNode : public PrePostResolveNode { 818 public: 819 PostIncResolveNode(const Identifier& ident) KJS_FAST_CALL 820 : PrePostResolveNode(ident) 821 { 822 } 823 824 PostIncResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 825 : PrePostResolveNode(PlacementNewAdopt) 826 { 827 } 828 829 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 830 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 831 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 832 virtual Precedence precedence() const { return PrecPostfix; } 833 virtual void optimizeForUnnecessaryResult(); 834 }; 835 836 class PostIncLocalVarNode : public PostIncResolveNode { 837 public: 838 PostIncLocalVarNode(size_t i) KJS_FAST_CALL 839 : PostIncResolveNode(PlacementNewAdopt) 840 { 841 ASSERT(i != missingSymbolMarker()); 842 m_index = i; 843 } 844 845 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 846 virtual void optimizeForUnnecessaryResult(); 847 }; 848 849 class PostIncConstNode : public PostIncResolveNode { 850 public: 851 PostIncConstNode(size_t i) KJS_FAST_CALL 852 : PostIncResolveNode(PlacementNewAdopt) 853 { 854 ASSERT(i != missingSymbolMarker()); 855 m_index = i; 856 } 857 858 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 859 }; 860 861 class PostDecResolveNode : public PrePostResolveNode { 862 public: 863 PostDecResolveNode(const Identifier& ident) KJS_FAST_CALL 864 : PrePostResolveNode(ident) 865 { 866 } 867 868 PostDecResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 869 : PrePostResolveNode(PlacementNewAdopt) 870 { 871 } 872 873 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 874 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 875 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 876 virtual Precedence precedence() const { return PrecPostfix; } 877 virtual void optimizeForUnnecessaryResult(); 878 }; 879 880 class PostDecLocalVarNode : public PostDecResolveNode { 881 public: 882 PostDecLocalVarNode(size_t i) KJS_FAST_CALL 883 : PostDecResolveNode(PlacementNewAdopt) 884 { 885 ASSERT(i != missingSymbolMarker()); 886 m_index = i; 887 } 888 889 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 890 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 891 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 892 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 893 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 894 virtual void optimizeForUnnecessaryResult(); 895 896 private: 897 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 898 }; 899 900 class PostDecConstNode : public PostDecResolveNode { 901 public: 902 PostDecConstNode(size_t i) KJS_FAST_CALL 903 : PostDecResolveNode(PlacementNewAdopt) 904 { 905 ASSERT(i != missingSymbolMarker()); 906 m_index = i; 907 } 908 909 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 910 }; 911 912 class PostfixBracketNode : public ExpressionNode { 913 public: 914 PostfixBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 915 : m_base(base) 916 , m_subscript(subscript) 917 { 918 } 919 920 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 921 virtual Precedence precedence() const { return PrecPostfix; } 922 923 protected: 924 RefPtr<ExpressionNode> m_base; 925 RefPtr<ExpressionNode> m_subscript; 926 }; 927 928 class PostIncBracketNode : public PostfixBracketNode { 929 public: 930 PostIncBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 931 : PostfixBracketNode(base, subscript) 932 { 933 } 934 935 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 936 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 937 }; 938 939 class PostDecBracketNode : public PostfixBracketNode { 940 public: 941 PostDecBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 942 : PostfixBracketNode(base, subscript) 943 { 944 } 945 946 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 947 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 948 }; 949 950 class PostfixDotNode : public ExpressionNode { 951 public: 952 PostfixDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 953 : m_base(base) 954 , m_ident(ident) 955 { 956 } 957 958 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 959 virtual Precedence precedence() const { return PrecPostfix; } 960 961 protected: 962 RefPtr<ExpressionNode> m_base; 963 Identifier m_ident; 964 }; 965 966 class PostIncDotNode : public PostfixDotNode { 967 public: 968 PostIncDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 969 : PostfixDotNode(base, ident) 970 { 971 } 972 973 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 974 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 975 }; 976 977 class PostDecDotNode : public PostfixDotNode { 978 public: 979 PostDecDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 980 : PostfixDotNode(base, ident) 981 { 982 } 983 984 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 985 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 986 }; 987 988 class PostfixErrorNode : public ExpressionNode { 989 public: 990 PostfixErrorNode(ExpressionNode* expr, Operator oper) KJS_FAST_CALL 991 : m_expr(expr) 992 , m_operator(oper) 993 { 994 } 995 996 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 997 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 998 virtual Precedence precedence() const { return PrecPostfix; } 999 1000 private: 1001 RefPtr<ExpressionNode> m_expr; 1002 Operator m_operator; 1003 }; 1004 1005 class DeleteResolveNode : public ExpressionNode { 1006 public: 1007 DeleteResolveNode(const Identifier& ident) KJS_FAST_CALL 1008 : m_ident(ident) 1009 { 1010 } 1011 1012 DeleteResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 1013 : ExpressionNode(PlacementNewAdopt) 1014 , m_ident(PlacementNewAdopt) 1015 { 1016 } 1017 1018 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1019 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1020 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1021 virtual Precedence precedence() const { return PrecUnary; } 1022 1023 private: 1024 Identifier m_ident; 1025 }; 1026 1027 class LocalVarDeleteNode : public DeleteResolveNode { 1028 public: 1029 LocalVarDeleteNode() KJS_FAST_CALL 1030 : DeleteResolveNode(PlacementNewAdopt) 1031 { 1032 } 1033 1034 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1035 }; 1036 1037 class DeleteBracketNode : public ExpressionNode { 1038 public: 1039 DeleteBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 1040 : m_base(base) 1041 , m_subscript(subscript) 1042 { 1043 } 1044 1045 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1046 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1047 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1048 virtual Precedence precedence() const { return PrecUnary; } 1049 1050 private: 1051 RefPtr<ExpressionNode> m_base; 1052 RefPtr<ExpressionNode> m_subscript; 1053 }; 1054 1055 class DeleteDotNode : public ExpressionNode { 1056 public: 1057 DeleteDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 1058 : m_base(base) 1059 , m_ident(ident) 1060 { 1061 } 1062 1063 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1064 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1065 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1066 virtual Precedence precedence() const { return PrecUnary; } 1067 1068 private: 1069 RefPtr<ExpressionNode> m_base; 1070 Identifier m_ident; 1071 }; 1072 1073 class DeleteValueNode : public ExpressionNode { 1074 public: 1075 DeleteValueNode(ExpressionNode* expr) KJS_FAST_CALL 1076 : m_expr(expr) 1077 { 1078 } 1079 1080 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1081 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1082 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1083 virtual Precedence precedence() const { return PrecUnary; } 1084 1085 private: 1086 RefPtr<ExpressionNode> m_expr; 1087 }; 1088 1089 class VoidNode : public ExpressionNode { 1090 public: 1091 VoidNode(ExpressionNode* expr) KJS_FAST_CALL 1092 : m_expr(expr) 1093 { 1094 } 1095 1096 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1097 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1098 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1099 virtual Precedence precedence() const { return PrecUnary; } 1100 1101 private: 1102 RefPtr<ExpressionNode> m_expr; 1103 }; 1104 1105 class TypeOfResolveNode : public ExpressionNode { 1106 public: 1107 TypeOfResolveNode(const Identifier& ident) KJS_FAST_CALL 1108 : ExpressionNode(StringType) 1109 , m_ident(ident) 1110 { 1111 } 1112 1113 TypeOfResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 1114 : ExpressionNode(PlacementNewAdopt) 1115 , m_ident(PlacementNewAdopt) 1116 { 1117 m_expectedReturnType = StringType; 1118 } 1119 1120 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1121 1122 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1123 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1124 virtual Precedence precedence() const { return PrecUnary; } 1125 1126 const Identifier& identifier() const KJS_FAST_CALL { return m_ident; } 1127 1128 protected: 1129 Identifier m_ident; 1130 size_t m_index; // Used by LocalTypeOfNode. 1131 }; 1132 1133 class LocalVarTypeOfNode : public TypeOfResolveNode { 1134 public: 1135 LocalVarTypeOfNode(size_t i) KJS_FAST_CALL 1136 : TypeOfResolveNode(PlacementNewAdopt) 1137 { 1138 m_expectedReturnType = StringType; 1139 ASSERT(i != missingSymbolMarker()); 1140 m_index = i; 1141 } 1142 1143 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1144 }; 1145 1146 class TypeOfValueNode : public ExpressionNode { 1147 public: 1148 TypeOfValueNode(ExpressionNode* expr) KJS_FAST_CALL 1149 : ExpressionNode(StringType) 1150 , m_expr(expr) 1151 { 1152 } 1153 1154 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1155 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1156 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1157 virtual Precedence precedence() const { return PrecUnary; } 1158 1159 private: 1160 RefPtr<ExpressionNode> m_expr; 1161 }; 1162 1163 class PreIncResolveNode : public PrePostResolveNode { 1164 public: 1165 PreIncResolveNode(const Identifier& ident) KJS_FAST_CALL 1166 : PrePostResolveNode(ident) 1167 { 1168 } 1169 1170 PreIncResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 1171 : PrePostResolveNode(PlacementNewAdopt) 1172 { 1173 } 1174 1175 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1176 1177 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1178 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1179 virtual Precedence precedence() const { return PrecUnary; } 1180 }; 1181 1182 class PreIncLocalVarNode : public PreIncResolveNode { 1183 public: 1184 PreIncLocalVarNode(size_t i) KJS_FAST_CALL 1185 : PreIncResolveNode(PlacementNewAdopt) 1186 { 1187 ASSERT(i != missingSymbolMarker()); 1188 m_index = i; 1189 } 1190 1191 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1192 }; 1193 1194 class PreIncConstNode : public PreIncResolveNode { 1195 public: 1196 PreIncConstNode(size_t i) KJS_FAST_CALL 1197 : PreIncResolveNode(PlacementNewAdopt) 1198 { 1199 ASSERT(i != missingSymbolMarker()); 1200 m_index = i; 1201 } 1202 1203 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1204 }; 1205 1206 class PreDecResolveNode : public PrePostResolveNode { 1207 public: 1208 PreDecResolveNode(const Identifier& ident) KJS_FAST_CALL 1209 : PrePostResolveNode(ident) 1210 { 1211 } 1212 1213 PreDecResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 1214 : PrePostResolveNode(PlacementNewAdopt) 1215 { 1216 } 1217 1218 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1219 1220 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1221 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1222 virtual Precedence precedence() const { return PrecUnary; } 1223 }; 1224 1225 class PreDecLocalVarNode : public PreDecResolveNode { 1226 public: 1227 PreDecLocalVarNode(size_t i) KJS_FAST_CALL 1228 : PreDecResolveNode(PlacementNewAdopt) 1229 { 1230 ASSERT(i != missingSymbolMarker()); 1231 m_index = i; 1232 } 1233 1234 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1235 }; 1236 1237 class PreDecConstNode : public PreDecResolveNode { 1238 public: 1239 PreDecConstNode(size_t i) KJS_FAST_CALL 1240 : PreDecResolveNode(PlacementNewAdopt) 1241 { 1242 ASSERT(i != missingSymbolMarker()); 1243 m_index = i; 1244 } 1245 1246 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1247 }; 1248 1249 class PrefixBracketNode : public ExpressionNode { 1250 public: 1251 PrefixBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 1252 : m_base(base) 1253 , m_subscript(subscript) 1254 { 1255 } 1256 1257 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1258 virtual Precedence precedence() const { return PrecUnary; } 1259 1260 protected: 1261 RefPtr<ExpressionNode> m_base; 1262 RefPtr<ExpressionNode> m_subscript; 1263 }; 1264 1265 class PreIncBracketNode : public PrefixBracketNode { 1266 public: 1267 PreIncBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 1268 : PrefixBracketNode(base, subscript) 1269 { 1270 } 1271 1272 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1273 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1274 }; 1275 1276 class PreDecBracketNode : public PrefixBracketNode { 1277 public: 1278 PreDecBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL 1279 : PrefixBracketNode(base, subscript) 1280 { 1281 } 1282 1283 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1284 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1285 }; 1286 1287 class PrefixDotNode : public ExpressionNode { 1288 public: 1289 PrefixDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 1290 : m_base(base) 1291 , m_ident(ident) 1292 { 1293 } 1294 1295 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1296 virtual Precedence precedence() const { return PrecPostfix; } 1297 1298 protected: 1299 RefPtr<ExpressionNode> m_base; 1300 Identifier m_ident; 1301 }; 1302 1303 class PreIncDotNode : public PrefixDotNode { 1304 public: 1305 PreIncDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 1306 : PrefixDotNode(base, ident) 1307 { 1308 } 1309 1310 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1311 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1312 }; 1313 1314 class PreDecDotNode : public PrefixDotNode { 1315 public: 1316 PreDecDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL 1317 : PrefixDotNode(base, ident) 1318 { 1319 } 1320 1321 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1322 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1323 }; 1324 1325 class PrefixErrorNode : public ExpressionNode { 1326 public: 1327 PrefixErrorNode(ExpressionNode* expr, Operator oper) KJS_FAST_CALL 1328 : m_expr(expr) 1329 , m_operator(oper) 1330 { 1331 } 1332 1333 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1334 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1335 virtual Precedence precedence() const { return PrecUnary; } 1336 1337 private: 1338 RefPtr<ExpressionNode> m_expr; 1339 Operator m_operator; 1340 }; 1341 1342 class UnaryPlusNode : public ExpressionNode { 1343 public: 1344 UnaryPlusNode(ExpressionNode* expr) KJS_FAST_CALL 1345 : ExpressionNode(NumberType) 1346 , m_expr(expr) 1347 { 1348 } 1349 1350 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1351 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1352 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1353 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1354 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1355 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1356 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1357 virtual Precedence precedence() const { return PrecUnary; } 1358 1359 private: 1360 RefPtr<ExpressionNode> m_expr; 1361 }; 1362 1363 class NegateNode : public ExpressionNode { 1364 public: 1365 NegateNode(ExpressionNode* expr) KJS_FAST_CALL 1366 : ExpressionNode(NumberType) 1367 , m_expr(expr) 1368 { 1369 } 1370 1371 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1372 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1373 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1374 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1375 virtual Precedence precedence() const { return PrecUnary; } 1376 1377 private: 1378 RefPtr<ExpressionNode> m_expr; 1379 }; 1380 1381 class BitwiseNotNode : public ExpressionNode { 1382 public: 1383 BitwiseNotNode(ExpressionNode* expr) KJS_FAST_CALL 1384 : ExpressionNode(NumberType) 1385 , m_expr(expr) 1386 { 1387 } 1388 1389 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1390 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1391 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1392 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1393 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1394 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1395 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1396 virtual Precedence precedence() const { return PrecUnary; } 1397 1398 private: 1399 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*); 1400 1401 RefPtr<ExpressionNode> m_expr; 1402 }; 1403 1404 class LogicalNotNode : public ExpressionNode { 1405 public: 1406 LogicalNotNode(ExpressionNode* expr) KJS_FAST_CALL 1407 : ExpressionNode(BooleanType) 1408 , m_expr(expr) 1409 { 1410 } 1411 1412 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1413 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1414 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1415 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1416 virtual Precedence precedence() const { return PrecUnary; } 1417 1418 private: 1419 RefPtr<ExpressionNode> m_expr; 1420 }; 1421 1422 class MultNode : public ExpressionNode { 1423 public: 1424 MultNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1425 : ExpressionNode(NumberType) 1426 , m_term1(term1) 1427 , m_term2(term2) 1428 { 1429 } 1430 1431 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1432 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1433 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1434 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1435 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1436 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1437 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1438 virtual Precedence precedence() const { return PrecMultiplicitave; } 1439 1440 private: 1441 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 1442 1443 RefPtr<ExpressionNode> m_term1; 1444 RefPtr<ExpressionNode> m_term2; 1445 }; 1446 1447 class DivNode : public ExpressionNode { 1448 public: 1449 DivNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1450 : ExpressionNode(NumberType) 1451 , m_term1(term1) 1452 , m_term2(term2) 1453 { 1454 } 1455 1456 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1457 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1458 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1459 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1460 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1461 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1462 virtual Precedence precedence() const { return PrecMultiplicitave; } 1463 1464 private: 1465 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 1466 1467 RefPtr<ExpressionNode> m_term1; 1468 RefPtr<ExpressionNode> m_term2; 1469 }; 1470 1471 class ModNode : public ExpressionNode { 1472 public: 1473 ModNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1474 : ExpressionNode(NumberType) 1475 , m_term1(term1) 1476 , m_term2(term2) 1477 { 1478 } 1479 1480 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1481 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1482 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1483 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1484 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1485 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1486 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1487 virtual Precedence precedence() const { return PrecMultiplicitave; } 1488 1489 private: 1490 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 1491 1492 RefPtr<ExpressionNode> m_term1; 1493 RefPtr<ExpressionNode> m_term2; 1494 }; 1495 1496 class AddNode : public ExpressionNode { 1497 public: 1498 AddNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1499 : m_term1(term1) 1500 , m_term2(term2) 1501 { 1502 } 1503 1504 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1505 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1506 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1507 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1508 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1509 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1510 virtual Precedence precedence() const { return PrecAdditive; } 1511 1512 protected: 1513 AddNode(ExpressionNode* term1, ExpressionNode* term2, JSType expectedReturn) KJS_FAST_CALL 1514 : ExpressionNode(expectedReturn) 1515 , m_term1(term1) 1516 , m_term2(term2) 1517 { 1518 } 1519 1520 RefPtr<ExpressionNode> m_term1; 1521 RefPtr<ExpressionNode> m_term2; 1522 1523 private: 1524 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 1525 }; 1526 1527 class AddNumbersNode : public AddNode { 1528 public: 1529 AddNumbersNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1530 : AddNode(term1, term2, NumberType) 1531 { 1532 } 1533 1534 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1535 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1536 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1537 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1538 1244 1539 private: 1245 1540 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*) KJS_FAST_CALL; … … 1249 1544 public: 1250 1545 AddStringLeftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1251 : AddNode(term1, term2, StringType) { } 1546 : AddNode(term1, term2, StringType) 1547 { 1548 } 1549 1252 1550 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1253 1551 }; … … 1256 1554 public: 1257 1555 AddStringRightNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1258 : AddNode(term1, term2, StringType) { } 1556 : AddNode(term1, term2, StringType) 1557 { 1558 } 1559 1259 1560 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1260 1561 }; … … 1263 1564 public: 1264 1565 AddStringsNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1265 : AddNode(term1, term2, StringType) { } 1266 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1267 }; 1268 1269 class SubNode : public ExpressionNode { 1270 public: 1271 SubNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1272 : ExpressionNode(NumberType), m_term1(term1), m_term2(term2) { } 1273 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1274 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1275 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1276 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1277 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1278 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1279 virtual Precedence precedence() const { return PrecAdditive; } 1280 private: 1281 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 1282 RefPtr<ExpressionNode> m_term1; 1283 RefPtr<ExpressionNode> m_term2; 1284 }; 1285 1286 class LeftShiftNode : public ExpressionNode { 1287 public: 1288 LeftShiftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1289 : ExpressionNode(NumberType), m_term1(term1), m_term2(term2) { } 1290 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1291 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1292 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1293 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1294 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1295 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1296 virtual Precedence precedence() const { return PrecShift; } 1297 private: 1298 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*); 1299 RefPtr<ExpressionNode> m_term1; 1300 RefPtr<ExpressionNode> m_term2; 1301 }; 1302 1303 class RightShiftNode : public ExpressionNode { 1304 public: 1305 RightShiftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1306 : ExpressionNode(NumberType), m_term1(term1), m_term2(term2) { } 1307 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1308 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1309 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1310 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1311 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1312 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1313 virtual Precedence precedence() const { return PrecShift; } 1314 private: 1315 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*); 1316 RefPtr<ExpressionNode> m_term1; 1317 RefPtr<ExpressionNode> m_term2; 1318 }; 1319 1320 class UnsignedRightShiftNode : public ExpressionNode { 1321 public: 1322 UnsignedRightShiftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1323 : ExpressionNode(NumberType), m_term1(term1), m_term2(term2) { } 1324 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1325 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1326 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1327 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1328 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1329 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1330 virtual Precedence precedence() const { return PrecShift; } 1331 private: 1332 ALWAYS_INLINE uint32_t inlineEvaluateToUInt32(ExecState*); 1333 RefPtr<ExpressionNode> m_term1; 1334 RefPtr<ExpressionNode> m_term2; 1335 }; 1336 1337 class LessNode : public ExpressionNode { 1338 public: 1339 LessNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1340 : ExpressionNode(BooleanType), m_expr1(expr1), m_expr2(expr2) {} 1341 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1342 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1343 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1344 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1345 virtual Precedence precedence() const { return PrecRelational; } 1346 private: 1347 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1348 protected: 1349 RefPtr<ExpressionNode> m_expr1; 1350 RefPtr<ExpressionNode> m_expr2; 1351 }; 1566 : AddNode(term1, term2, StringType) 1567 { 1568 } 1569 1570 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1571 }; 1572 1573 class SubNode : public ExpressionNode { 1574 public: 1575 SubNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1576 : ExpressionNode(NumberType) 1577 , m_term1(term1) 1578 , m_term2(term2) 1579 { 1580 } 1581 1582 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1583 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1584 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1585 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1586 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1587 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1588 virtual Precedence precedence() const { return PrecAdditive; } 1589 1590 private: 1591 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 1592 1593 RefPtr<ExpressionNode> m_term1; 1594 RefPtr<ExpressionNode> m_term2; 1595 }; 1596 1597 class LeftShiftNode : public ExpressionNode { 1598 public: 1599 LeftShiftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1600 : ExpressionNode(NumberType) 1601 , m_term1(term1) 1602 , m_term2(term2) 1603 { 1604 } 1605 1606 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1607 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1608 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1609 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1610 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1611 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1612 virtual Precedence precedence() const { return PrecShift; } 1613 1614 private: 1615 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*); 1616 1617 RefPtr<ExpressionNode> m_term1; 1618 RefPtr<ExpressionNode> m_term2; 1619 }; 1620 1621 class RightShiftNode : public ExpressionNode { 1622 public: 1623 RightShiftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1624 : ExpressionNode(NumberType) 1625 , m_term1(term1) 1626 , m_term2(term2) 1627 { 1628 } 1629 1630 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1631 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1632 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1633 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1634 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1635 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1636 virtual Precedence precedence() const { return PrecShift; } 1637 1638 private: 1639 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*); 1640 1641 RefPtr<ExpressionNode> m_term1; 1642 RefPtr<ExpressionNode> m_term2; 1643 }; 1644 1645 class UnsignedRightShiftNode : public ExpressionNode { 1646 public: 1647 UnsignedRightShiftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL 1648 : ExpressionNode(NumberType) 1649 , m_term1(term1) 1650 , m_term2(term2) 1651 { 1652 } 1653 1654 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1655 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1656 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1657 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1658 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1659 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1660 virtual Precedence precedence() const { return PrecShift; } 1661 private: 1662 ALWAYS_INLINE uint32_t inlineEvaluateToUInt32(ExecState*); 1663 1664 RefPtr<ExpressionNode> m_term1; 1665 RefPtr<ExpressionNode> m_term2; 1666 }; 1667 1668 class LessNode : public ExpressionNode { 1669 public: 1670 LessNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1671 : ExpressionNode(BooleanType) 1672 , m_expr1(expr1) 1673 , m_expr2(expr2) 1674 { 1675 } 1676 1677 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1678 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1679 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1680 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1681 virtual Precedence precedence() const { return PrecRelational; } 1682 1683 private: 1684 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1685 1686 protected: 1687 RefPtr<ExpressionNode> m_expr1; 1688 RefPtr<ExpressionNode> m_expr2; 1689 }; 1352 1690 1353 1691 class LessNumbersNode : public LessNode { 1354 1692 public: 1355 1693 LessNumbersNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1356 : LessNode(expr1, expr2) { } 1357 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1358 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1694 : LessNode(expr1, expr2) 1695 { 1696 } 1697 1698 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1699 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1700 1359 1701 private: 1360 1702 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); … … 1364 1706 public: 1365 1707 LessStringsNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1366 : LessNode(expr1, expr2) { } 1367 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1368 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1708 : LessNode(expr1, expr2) 1709 { 1710 } 1711 1712 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1713 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1714 1369 1715 private: 1370 1716 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1371 1717 }; 1372 1718 1373 class GreaterNode : public ExpressionNode { 1374 public: 1375 GreaterNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL : 1376 m_expr1(e1), m_expr2(e2) {} 1377 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1378 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1379 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1380 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1381 virtual Precedence precedence() const { return PrecRelational; } 1382 private: 1383 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1384 RefPtr<ExpressionNode> m_expr1; 1385 RefPtr<ExpressionNode> m_expr2; 1386 }; 1387 1388 class LessEqNode : public ExpressionNode { 1389 public: 1390 LessEqNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1391 : m_expr1(expr1), m_expr2(expr2) { } 1392 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1393 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1394 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1395 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1396 virtual Precedence precedence() const { return PrecRelational; } 1397 private: 1398 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1399 RefPtr<ExpressionNode> m_expr1; 1400 RefPtr<ExpressionNode> m_expr2; 1401 }; 1402 1403 class GreaterEqNode : public ExpressionNode { 1404 public: 1405 GreaterEqNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1406 : m_expr1(expr1), m_expr2(expr2) { } 1407 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1408 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1409 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1410 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1411 virtual Precedence precedence() const { return PrecRelational; } 1412 private: 1413 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1414 RefPtr<ExpressionNode> m_expr1; 1415 RefPtr<ExpressionNode> m_expr2; 1416 }; 1719 class GreaterNode : public ExpressionNode { 1720 public: 1721 GreaterNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1722 : m_expr1(expr1) 1723 , m_expr2(expr2) 1724 { 1725 } 1726 1727 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1728 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1729 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1730 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1731 virtual Precedence precedence() const { return PrecRelational; } 1732 1733 private: 1734 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1735 1736 RefPtr<ExpressionNode> m_expr1; 1737 RefPtr<ExpressionNode> m_expr2; 1738 }; 1739 1740 class LessEqNode : public ExpressionNode { 1741 public: 1742 LessEqNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1743 : m_expr1(expr1) 1744 , m_expr2(expr2) 1745 { 1746 } 1747 1748 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1749 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1750 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1751 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1752 virtual Precedence precedence() const { return PrecRelational; } 1753 1754 private: 1755 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1756 1757 RefPtr<ExpressionNode> m_expr1; 1758 RefPtr<ExpressionNode> m_expr2; 1759 }; 1760 1761 class GreaterEqNode : public ExpressionNode { 1762 public: 1763 GreaterEqNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1764 : m_expr1(expr1) 1765 , m_expr2(expr2) 1766 { 1767 } 1768 1769 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1770 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1771 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1772 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1773 virtual Precedence precedence() const { return PrecRelational; } 1774 1775 private: 1776 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1777 1778 RefPtr<ExpressionNode> m_expr1; 1779 RefPtr<ExpressionNode> m_expr2; 1780 }; 1417 1781 1418 1782 class InstanceOfNode : public ExpressionNode { 1419 public: 1420 InstanceOfNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1421 : ExpressionNode(BooleanType), m_expr1(expr1), m_expr2(expr2) { } 1422 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1423 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1424 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1425 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1426 virtual Precedence precedence() const { return PrecRelational; } 1427 private: 1428 RefPtr<ExpressionNode> m_expr1; 1429 RefPtr<ExpressionNode> m_expr2; 1430 }; 1783 public: 1784 InstanceOfNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1785 : ExpressionNode(BooleanType) 1786 , m_expr1(expr1) 1787 , m_expr2(expr2) 1788 { 1789 } 1790 1791 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1792 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1793 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1794 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1795 virtual Precedence precedence() const { return PrecRelational; } 1796 1797 private: 1798 RefPtr<ExpressionNode> m_expr1; 1799 RefPtr<ExpressionNode> m_expr2; 1800 }; 1431 1801 1432 1802 class InNode : public ExpressionNode { 1433 public: 1434 InNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1435 : m_expr1(expr1), m_expr2(expr2) { } 1436 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1437 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1438 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1439 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1440 virtual Precedence precedence() const { return PrecRelational; } 1441 private: 1442 RefPtr<ExpressionNode> m_expr1; 1443 RefPtr<ExpressionNode> m_expr2; 1444 }; 1803 public: 1804 InNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1805 : m_expr1(expr1) 1806 , m_expr2(expr2) 1807 { 1808 } 1809 1810 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1811 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1812 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1813 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1814 virtual Precedence precedence() const { return PrecRelational; } 1815 1816 private: 1817 RefPtr<ExpressionNode> m_expr1; 1818 RefPtr<ExpressionNode> m_expr2; 1819 }; 1445 1820 1446 1821 class EqualNode : public ExpressionNode { 1447 public: 1448 EqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1449 : ExpressionNode(BooleanType), m_expr1(expr1), m_expr2(expr2) { } 1450 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1451 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1452 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1453 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1454 virtual Precedence precedence() const { return PrecEquality; } 1455 private: 1456 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1457 RefPtr<ExpressionNode> m_expr1; 1458 RefPtr<ExpressionNode> m_expr2; 1459 }; 1822 public: 1823 EqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1824 : ExpressionNode(BooleanType) 1825 , m_expr1(expr1) 1826 , m_expr2(expr2) 1827 { 1828 } 1829 1830 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1831 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1832 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1833 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1834 virtual Precedence precedence() const { return PrecEquality; } 1835 1836 private: 1837 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1838 1839 RefPtr<ExpressionNode> m_expr1; 1840 RefPtr<ExpressionNode> m_expr2; 1841 }; 1460 1842 1461 1843 class NotEqualNode : public ExpressionNode { 1462 public: 1463 NotEqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1464 : ExpressionNode(BooleanType), m_expr1(expr1), m_expr2(expr2) { } 1465 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1466 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1467 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1468 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1469 virtual Precedence precedence() const { return PrecEquality; } 1470 private: 1471 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1472 RefPtr<ExpressionNode> m_expr1; 1473 RefPtr<ExpressionNode> m_expr2; 1474 }; 1844 public: 1845 NotEqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1846 : ExpressionNode(BooleanType) 1847 , m_expr1(expr1) 1848 , m_expr2(expr2) 1849 { 1850 } 1851 1852 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1853 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1854 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1855 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1856 virtual Precedence precedence() const { return PrecEquality; } 1857 1858 private: 1859 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1860 1861 RefPtr<ExpressionNode> m_expr1; 1862 RefPtr<ExpressionNode> m_expr2; 1863 }; 1475 1864 1476 1865 class StrictEqualNode : public ExpressionNode { 1477 public: 1478 StrictEqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1479 : ExpressionNode(BooleanType), m_expr1(expr1), m_expr2(expr2) { } 1480 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1481 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1482 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1483 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1484 virtual Precedence precedence() const { return PrecEquality; } 1485 private: 1486 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1487 RefPtr<ExpressionNode> m_expr1; 1488 RefPtr<ExpressionNode> m_expr2; 1489 }; 1866 public: 1867 StrictEqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1868 : ExpressionNode(BooleanType) 1869 , m_expr1(expr1) 1870 , m_expr2(expr2) 1871 { 1872 } 1873 1874 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1875 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1876 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1877 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1878 virtual Precedence precedence() const { return PrecEquality; } 1879 1880 private: 1881 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1882 1883 RefPtr<ExpressionNode> m_expr1; 1884 RefPtr<ExpressionNode> m_expr2; 1885 }; 1490 1886 1491 1887 class NotStrictEqualNode : public ExpressionNode { 1492 public: 1493 NotStrictEqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1494 : ExpressionNode(BooleanType), m_expr1(expr1), m_expr2(expr2) { } 1495 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1496 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1497 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1498 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1499 virtual Precedence precedence() const { return PrecEquality; } 1500 private: 1501 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1502 RefPtr<ExpressionNode> m_expr1; 1503 RefPtr<ExpressionNode> m_expr2; 1504 }; 1888 public: 1889 NotStrictEqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1890 : ExpressionNode(BooleanType) 1891 , m_expr1(expr1) 1892 , m_expr2(expr2) 1893 { 1894 } 1895 1896 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1897 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1898 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1899 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1900 virtual Precedence precedence() const { return PrecEquality; } 1901 1902 private: 1903 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1904 1905 RefPtr<ExpressionNode> m_expr1; 1906 RefPtr<ExpressionNode> m_expr2; 1907 }; 1505 1908 1506 1909 class BitAndNode : public ExpressionNode { 1507 public: 1508 BitAndNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1509 : ExpressionNode(NumberType), m_expr1(expr1), m_expr2(expr2) { } 1510 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1511 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1512 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1513 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1514 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1515 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1516 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1517 virtual Precedence precedence() const { return PrecBitwiseAnd; } 1518 private: 1519 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*); 1520 RefPtr<ExpressionNode> m_expr1; 1521 RefPtr<ExpressionNode> m_expr2; 1522 }; 1910 public: 1911 BitAndNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1912 : ExpressionNode(NumberType) 1913 , m_expr1(expr1) 1914 , m_expr2(expr2) 1915 { 1916 } 1917 1918 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1919 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1920 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1921 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1922 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1923 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1924 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1925 virtual Precedence precedence() const { return PrecBitwiseAnd; } 1926 1927 private: 1928 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*); 1929 1930 RefPtr<ExpressionNode> m_expr1; 1931 RefPtr<ExpressionNode> m_expr2; 1932 }; 1523 1933 1524 1934 class BitOrNode : public ExpressionNode { 1525 public: 1526 BitOrNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1527 : ExpressionNode(NumberType), m_expr1(expr1), m_expr2(expr2) { } 1528 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1529 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1530 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1531 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1532 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1533 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1534 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1535 virtual Precedence precedence() const { return PrecBitwiseOr; } 1536 private: 1537 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*); 1538 RefPtr<ExpressionNode> m_expr1; 1539 RefPtr<ExpressionNode> m_expr2; 1540 }; 1541 1542 class BitXOrNode : public ExpressionNode { 1543 public: 1544 BitXOrNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1545 : ExpressionNode(NumberType), m_expr1(expr1), m_expr2(expr2) { } 1546 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1547 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1548 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1549 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1550 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1551 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1552 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1553 virtual Precedence precedence() const { return PrecBitwiseXor; } 1554 private: 1555 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*); 1556 RefPtr<ExpressionNode> m_expr1; 1557 RefPtr<ExpressionNode> m_expr2; 1558 }; 1559 1560 /** 1561 * m_expr1 && m_expr2, m_expr1 || m_expr2 1562 */ 1935 public: 1936 BitOrNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1937 : ExpressionNode(NumberType) 1938 , m_expr1(expr1) 1939 , m_expr2(expr2) 1940 { 1941 } 1942 1943 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1944 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1945 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1946 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1947 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1948 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1949 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1950 virtual Precedence precedence() const { return PrecBitwiseOr; } 1951 1952 private: 1953 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*); 1954 1955 RefPtr<ExpressionNode> m_expr1; 1956 RefPtr<ExpressionNode> m_expr2; 1957 }; 1958 1959 class BitXOrNode : public ExpressionNode { 1960 public: 1961 BitXOrNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1962 : ExpressionNode(NumberType) 1963 , m_expr1(expr1) 1964 , m_expr2(expr2) 1965 { 1966 } 1967 1968 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1969 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1970 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1971 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1972 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1973 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1974 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1975 virtual Precedence precedence() const { return PrecBitwiseXor; } 1976 1977 private: 1978 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*); 1979 1980 RefPtr<ExpressionNode> m_expr1; 1981 RefPtr<ExpressionNode> m_expr2; 1982 }; 1983 1984 /** 1985 * m_expr1 && m_expr2, m_expr1 || m_expr2 1986 */ 1563 1987 class LogicalAndNode : public ExpressionNode { 1564 public: 1565 LogicalAndNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1566 : ExpressionNode(BooleanType), m_expr1(expr1), m_expr2(expr2) { } 1567 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1568 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1569 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1570 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1571 virtual Precedence precedence() const { return PrecLogicalAnd; } 1572 private: 1573 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1574 RefPtr<ExpressionNode> m_expr1; 1575 RefPtr<ExpressionNode> m_expr2; 1576 }; 1577 1988 public: 1989 LogicalAndNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1990 : ExpressionNode(BooleanType) 1991 , m_expr1(expr1) 1992 , m_expr2(expr2) 1993 { 1994 } 1995 1996 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1997 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1998 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1999 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2000 virtual Precedence precedence() const { return PrecLogicalAnd; } 2001 2002 private: 2003 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 2004 2005 RefPtr<ExpressionNode> m_expr1; 2006 RefPtr<ExpressionNode> m_expr2; 2007 }; 2008 1578 2009 class LogicalOrNode : public ExpressionNode { 1579 public: 1580 LogicalOrNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1581 : ExpressionNode(BooleanType), m_expr1(expr1), m_expr2(expr2) { } 1582 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1583 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1584 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1585 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1586 virtual Precedence precedence() const { return PrecLogicalOr; } 1587 private: 1588 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 1589 RefPtr<ExpressionNode> m_expr1; 1590 RefPtr<ExpressionNode> m_expr2; 1591 }; 1592 1593 /** 1594 * The ternary operator, "m_logical ? m_expr1 : m_expr2" 1595 */ 1596 class ConditionalNode : public ExpressionNode { 1597 public: 1598 ConditionalNode(ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 1599 : m_logical(logical), m_expr1(expr1), m_expr2(expr2) { } 1600 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1601 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1602 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 1603 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1604 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 1605 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 1606 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1607 virtual Precedence precedence() const { return PrecConditional; } 1608 private: 1609 RefPtr<ExpressionNode> m_logical; 1610 RefPtr<ExpressionNode> m_expr1; 1611 RefPtr<ExpressionNode> m_expr2; 1612 }; 1613 1614 class ReadModifyResolveNode : public ExpressionNode { 1615 public: 1616 ReadModifyResolveNode(const Identifier& ident, Operator oper, ExpressionNode* right) KJS_FAST_CALL 1617 : m_ident(ident) 1618 , m_oper(oper) 1619 , m_right(right) 2010 public: 2011 LogicalOrNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 2012 : ExpressionNode(BooleanType) 2013 , m_expr1(expr1) 2014 , m_expr2(expr2) 2015 { 2016 } 2017 2018 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2019 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2020 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 2021 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2022 virtual Precedence precedence() const { return PrecLogicalOr; } 2023 2024 private: 2025 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*); 2026 2027 RefPtr<ExpressionNode> m_expr1; 2028 RefPtr<ExpressionNode> m_expr2; 2029 }; 2030 2031 /** 2032 * The ternary operator, "m_logical ? m_expr1 : m_expr2" 2033 */ 2034 class ConditionalNode : public ExpressionNode { 2035 public: 2036 ConditionalNode(ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 2037 : m_logical(logical) 2038 , m_expr1(expr1) 2039 , m_expr2(expr2) 2040 { 2041 } 2042 2043 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2044 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2045 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL; 2046 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 2047 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL; 2048 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL; 2049 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2050 virtual Precedence precedence() const { return PrecConditional; } 2051 2052 private: 2053 RefPtr<ExpressionNode> m_logical; 2054 RefPtr<ExpressionNode> m_expr1; 2055 RefPtr<ExpressionNode> m_expr2; 2056 }; 2057 2058 class ReadModifyResolveNode : public ExpressionNode { 2059 public: 2060 ReadModifyResolveNode(const Identifier& ident, Operator oper, ExpressionNode* right) KJS_FAST_CALL 2061 : m_ident(ident) 2062 , m_operator(oper) 2063 , m_right(right) 2064 { 2065 } 2066 2067 ReadModifyResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 2068 : ExpressionNode(PlacementNewAdopt) 2069 , m_ident(PlacementNewAdopt) 2070 , m_right(PlacementNewAdopt) 2071 { 2072 } 2073 2074 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2075 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2076 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2077 virtual Precedence precedence() const { return PrecAssignment; } 2078 2079 protected: 2080 Identifier m_ident; 2081 Operator m_operator; 2082 RefPtr<ExpressionNode> m_right; 2083 size_t m_index; // Used by ReadModifyLocalVarNode. 2084 }; 2085 2086 class ReadModifyLocalVarNode : public ReadModifyResolveNode { 2087 public: 2088 ReadModifyLocalVarNode(size_t i) KJS_FAST_CALL 2089 : ReadModifyResolveNode(PlacementNewAdopt) 2090 { 2091 ASSERT(i != missingSymbolMarker()); 2092 m_index = i; 2093 } 2094 2095 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2096 }; 2097 2098 class ReadModifyConstNode : public ReadModifyResolveNode { 2099 public: 2100 ReadModifyConstNode(size_t i) KJS_FAST_CALL 2101 : ReadModifyResolveNode(PlacementNewAdopt) 2102 { 2103 ASSERT(i != missingSymbolMarker()); 2104 m_index = i; 2105 } 2106 2107 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2108 }; 2109 2110 class AssignResolveNode : public ExpressionNode { 2111 public: 2112 AssignResolveNode(const Identifier& ident, ExpressionNode* right) KJS_FAST_CALL 2113 : m_ident(ident) 2114 , m_right(right) 2115 { 2116 } 2117 2118 AssignResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 2119 : ExpressionNode(PlacementNewAdopt) 2120 , m_ident(PlacementNewAdopt) 2121 , m_right(PlacementNewAdopt) 2122 { 2123 } 2124 2125 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2126 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2127 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2128 virtual Precedence precedence() const { return PrecAssignment; } 2129 2130 protected: 2131 Identifier m_ident; 2132 RefPtr<ExpressionNode> m_right; 2133 size_t m_index; // Used by ReadModifyLocalVarNode. 2134 }; 2135 2136 class AssignLocalVarNode : public AssignResolveNode { 2137 public: 2138 AssignLocalVarNode(size_t i) KJS_FAST_CALL 2139 : AssignResolveNode(PlacementNewAdopt) 2140 { 2141 ASSERT(i != missingSymbolMarker()); 2142 m_index = i; 2143 } 2144 2145 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2146 }; 2147 2148 class AssignConstNode : public AssignResolveNode { 2149 public: 2150 AssignConstNode() KJS_FAST_CALL 2151 : AssignResolveNode(PlacementNewAdopt) 2152 { 2153 } 2154 2155 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2156 }; 2157 2158 class ReadModifyBracketNode : public ExpressionNode { 2159 public: 2160 ReadModifyBracketNode(ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right) KJS_FAST_CALL 2161 : m_base(base) 2162 , m_subscript(subscript) 2163 , m_operator(oper) 2164 , m_right(right) 2165 { 2166 } 2167 2168 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2169 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2170 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2171 virtual Precedence precedence() const { return PrecAssignment; } 2172 2173 protected: 2174 RefPtr<ExpressionNode> m_base; 2175 RefPtr<ExpressionNode> m_subscript; 2176 Operator m_operator; 2177 RefPtr<ExpressionNode> m_right; 2178 }; 2179 2180 class AssignBracketNode : public ExpressionNode { 2181 public: 2182 AssignBracketNode(ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right) KJS_FAST_CALL 2183 : m_base(base) 2184 , m_subscript(subscript) 2185 , m_right(right) 2186 { 2187 } 2188 2189 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2190 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2191 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2192 virtual Precedence precedence() const { return PrecAssignment; } 2193 2194 protected: 2195 RefPtr<ExpressionNode> m_base; 2196 RefPtr<ExpressionNode> m_subscript; 2197 RefPtr<ExpressionNode> m_right; 2198 }; 2199 2200 class AssignDotNode : public ExpressionNode { 2201 public: 2202 AssignDotNode(ExpressionNode* base, const Identifier& ident, ExpressionNode* right) KJS_FAST_CALL 2203 : m_base(base) 2204 , m_ident(ident) 2205 , m_right(right) 2206 { 2207 } 2208 2209 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2210 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2211 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2212 virtual Precedence precedence() const { return PrecAssignment; } 2213 2214 protected: 2215 RefPtr<ExpressionNode> m_base; 2216 Identifier m_ident; 2217 RefPtr<ExpressionNode> m_right; 2218 }; 2219 2220 class ReadModifyDotNode : public ExpressionNode { 2221 public: 2222 ReadModifyDotNode(ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right) KJS_FAST_CALL 2223 : m_base(base) 2224 , m_ident(ident) 2225 , m_operator(oper) 2226 , m_right(right) 2227 { 2228 } 2229 2230 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2231 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2232 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2233 virtual Precedence precedence() const { return PrecAssignment; } 2234 2235 protected: 2236 RefPtr<ExpressionNode> m_base; 2237 Identifier m_ident; 2238 Operator m_operator; 2239 RefPtr<ExpressionNode> m_right; 2240 }; 2241 2242 class AssignErrorNode : public ExpressionNode { 2243 public: 2244 AssignErrorNode(ExpressionNode* left, Operator oper, ExpressionNode* right) KJS_FAST_CALL 2245 : m_left(left) 2246 , m_operator(oper) 2247 , m_right(right) 2248 { 2249 } 2250 2251 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2252 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2253 virtual Precedence precedence() const { return PrecAssignment; } 2254 2255 protected: 2256 RefPtr<ExpressionNode> m_left; 2257 Operator m_operator; 2258 RefPtr<ExpressionNode> m_right; 2259 }; 2260 2261 class CommaNode : public ExpressionNode { 2262 public: 2263 CommaNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL 2264 : m_expr1(expr1) 2265 , m_expr2(expr2) 2266 { 2267 m_expr1->optimizeForUnnecessaryResult(); 2268 } 2269 2270 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2271 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2272 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2273 virtual Precedence precedence() const { return PrecExpression; } 2274 2275 private: 2276 RefPtr<ExpressionNode> m_expr1; 2277 RefPtr<ExpressionNode> m_expr2; 2278 }; 2279 2280 class ConstDeclNode : public ExpressionNode { 2281 public: 2282 ConstDeclNode(const Identifier& ident, ExpressionNode* in) KJS_FAST_CALL; 2283 2284 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2285 virtual KJS::JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2286 void evaluateSingle(ExecState*) KJS_FAST_CALL; 2287 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2288 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 2289 PassRefPtr<ConstDeclNode> releaseNext() KJS_FAST_CALL { return m_next.release(); } 2290 2291 Identifier m_ident; 2292 ListRefPtr<ConstDeclNode> m_next; 2293 RefPtr<ExpressionNode> m_init; 2294 2295 private: 2296 void handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL NEVER_INLINE; 2297 }; 2298 2299 class ConstStatementNode : public StatementNode { 2300 public: 2301 ConstStatementNode(ConstDeclNode* next) KJS_FAST_CALL 2302 : m_next(next) 2303 { 2304 } 2305 2306 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2307 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2308 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2309 2310 private: 2311 RefPtr<ConstDeclNode> m_next; 2312 }; 2313 2314 typedef Vector<RefPtr<StatementNode> > StatementVector; 2315 2316 class SourceElements : public ParserRefCounted { 2317 public: 2318 void append(PassRefPtr<StatementNode>); 2319 void releaseContentsIntoVector(StatementVector& destination) 2320 { 2321 ASSERT(destination.isEmpty()); 2322 m_statements.swap(destination); 2323 } 2324 2325 private: 2326 StatementVector m_statements; 2327 }; 2328 2329 class BlockNode : public StatementNode { 2330 public: 2331 BlockNode(SourceElements* children) KJS_FAST_CALL; 2332 2333 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2334 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2335 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2336 2337 protected: 2338 StatementVector m_children; 2339 }; 2340 2341 class EmptyStatementNode : public StatementNode { 2342 public: 2343 EmptyStatementNode() KJS_FAST_CALL // debug 2344 { 2345 } 2346 2347 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2348 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2349 virtual bool isEmptyStatement() const KJS_FAST_CALL { return true; } 2350 }; 2351 2352 class ExprStatementNode : public StatementNode { 2353 public: 2354 ExprStatementNode(ExpressionNode* expr) KJS_FAST_CALL 2355 : m_expr(expr) 2356 { 2357 } 2358 2359 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2360 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2361 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2362 2363 private: 2364 RefPtr<ExpressionNode> m_expr; 2365 }; 2366 2367 class VarStatementNode : public StatementNode { 2368 public: 2369 VarStatementNode(ExpressionNode* expr) KJS_FAST_CALL 2370 : m_expr(expr) 2371 { 2372 } 2373 2374 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2375 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2376 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2377 2378 private: 2379 RefPtr<ExpressionNode> m_expr; 2380 }; 2381 2382 class IfNode : public StatementNode { 2383 public: 2384 IfNode(ExpressionNode* condition, StatementNode* ifBlock) KJS_FAST_CALL 2385 : m_condition(condition) 2386 , m_ifBlock(ifBlock) 2387 { 2388 } 2389 2390 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2391 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2392 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2393 2394 protected: 2395 RefPtr<ExpressionNode> m_condition; 2396 RefPtr<StatementNode> m_ifBlock; 2397 }; 2398 2399 class IfElseNode : public IfNode { 2400 public: 2401 IfElseNode(ExpressionNode* condtion, StatementNode* ifBlock, StatementNode* elseBlock) KJS_FAST_CALL 2402 : IfNode(condtion, ifBlock) 2403 , m_elseBlock(elseBlock) 2404 { 2405 } 2406 2407 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2408 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2409 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2410 2411 private: 2412 RefPtr<StatementNode> m_elseBlock; 2413 }; 2414 2415 class DoWhileNode : public StatementNode { 2416 public: 2417 DoWhileNode(StatementNode* statement, ExpressionNode* expr) KJS_FAST_CALL 2418 : m_statement(statement) 2419 , m_expr(expr) 2420 { 2421 } 2422 2423 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2424 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2425 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2426 2427 private: 2428 RefPtr<StatementNode> m_statement; 2429 RefPtr<ExpressionNode> m_expr; 2430 }; 2431 2432 class WhileNode : public StatementNode { 2433 public: 2434 WhileNode(ExpressionNode* expr, StatementNode* statement) KJS_FAST_CALL 2435 : m_expr(expr) 2436 , m_statement(statement) 2437 { 2438 } 2439 2440 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2441 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2442 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2443 2444 private: 2445 RefPtr<ExpressionNode> m_expr; 2446 RefPtr<StatementNode> m_statement; 2447 }; 2448 2449 class ForNode : public StatementNode { 2450 public: 2451 ForNode(ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl) KJS_FAST_CALL 2452 : m_expr1(expr1 ? expr1 : new PlaceholderTrueNode) 2453 , m_expr2(expr2 ? expr2 : new PlaceholderTrueNode) 2454 , m_expr3(expr3 ? expr3 : new PlaceholderTrueNode) 2455 , m_statement(statement) 2456 , m_expr1WasVarDecl(expr1 && expr1WasVarDecl) 2457 { 2458 ASSERT(m_expr1); 2459 ASSERT(m_expr2); 2460 ASSERT(m_expr3); 2461 ASSERT(statement); 2462 2463 m_expr1->optimizeForUnnecessaryResult(); 2464 m_expr3->optimizeForUnnecessaryResult(); 2465 } 2466 2467 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2468 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2469 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2470 2471 private: 2472 RefPtr<ExpressionNode> m_expr1; 2473 RefPtr<ExpressionNode> m_expr2; 2474 RefPtr<ExpressionNode> m_expr3; 2475 RefPtr<StatementNode> m_statement; 2476 bool m_expr1WasVarDecl; 2477 }; 2478 2479 class ForInNode : public StatementNode { 2480 public: 2481 ForInNode(ExpressionNode*, ExpressionNode*, StatementNode*) KJS_FAST_CALL; 2482 ForInNode(const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*) KJS_FAST_CALL; 2483 2484 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2485 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2486 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2487 2488 private: 2489 Identifier m_ident; 2490 RefPtr<ExpressionNode> m_init; 2491 RefPtr<ExpressionNode> m_lexpr; 2492 RefPtr<ExpressionNode> m_expr; 2493 RefPtr<StatementNode> m_statement; 2494 bool m_identIsVarDecl; 2495 }; 2496 2497 class ContinueNode : public StatementNode { 2498 public: 2499 ContinueNode() KJS_FAST_CALL 2500 { 2501 } 2502 2503 ContinueNode(const Identifier& ident) KJS_FAST_CALL 2504 : m_ident(ident) 2505 { 2506 } 2507 2508 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2509 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2510 2511 private: 2512 Identifier m_ident; 2513 }; 2514 2515 class BreakNode : public StatementNode { 2516 public: 2517 BreakNode() KJS_FAST_CALL 2518 { 2519 } 2520 2521 BreakNode(const Identifier& ident) KJS_FAST_CALL 2522 : m_ident(ident) 2523 { 2524 } 2525 2526 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2527 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2528 2529 private: 2530 Identifier m_ident; 2531 }; 2532 2533 class ReturnNode : public StatementNode { 2534 public: 2535 ReturnNode(ExpressionNode* value) KJS_FAST_CALL 2536 : m_value(value) 2537 { 2538 } 2539 2540 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2541 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2542 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2543 2544 private: 2545 RefPtr<ExpressionNode> m_value; 2546 }; 2547 2548 class WithNode : public StatementNode { 2549 public: 2550 WithNode(ExpressionNode* expr, StatementNode* statement) KJS_FAST_CALL 2551 : m_expr(expr) 2552 , m_statement(statement) 2553 { 2554 } 2555 2556 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2557 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2558 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2559 2560 private: 2561 RefPtr<ExpressionNode> m_expr; 2562 RefPtr<StatementNode> m_statement; 2563 }; 2564 2565 class LabelNode : public StatementNode { 2566 public: 2567 LabelNode(const Identifier& label, StatementNode* statement) KJS_FAST_CALL 2568 : m_label(label) 2569 , m_statement(statement) 1620 2570 { 1621 2571 } 1622 2572 1623 ReadModifyResolveNode(PlacementNewAdoptType) KJS_FAST_CALL1624 : ExpressionNode(PlacementNewAdopt)1625 , m_ident(PlacementNewAdopt)1626 , m_right(PlacementNewAdopt)1627 {1628 }1629 1630 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1631 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;1632 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1633 virtual Precedence precedence() const { return PrecAssignment; }1634 protected:1635 Identifier m_ident;1636 Operator m_oper;1637 RefPtr<ExpressionNode> m_right;1638 size_t m_index; // Used by ReadModifyLocalVarNode.1639 };1640 1641 class ReadModifyLocalVarNode : public ReadModifyResolveNode {1642 public:1643 ReadModifyLocalVarNode(size_t i) KJS_FAST_CALL1644 : ReadModifyResolveNode(PlacementNewAdopt)1645 {1646 ASSERT(i != missingSymbolMarker());1647 m_index = i;1648 }1649 1650 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;1651 };1652 1653 class ReadModifyConstNode : public ReadModifyResolveNode {1654 public:1655 ReadModifyConstNode(size_t i) KJS_FAST_CALL1656 : ReadModifyResolveNode(PlacementNewAdopt)1657 {1658 ASSERT(i != missingSymbolMarker());1659 m_index = i;1660 }1661 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;1662 };1663 1664 class AssignResolveNode : public ExpressionNode {1665 public:1666 AssignResolveNode(const Identifier& ident, ExpressionNode* right) KJS_FAST_CALL1667 : m_ident(ident)1668 , m_right(right)1669 {1670 }1671 1672 AssignResolveNode(PlacementNewAdoptType) KJS_FAST_CALL1673 : ExpressionNode(PlacementNewAdopt)1674 , m_ident(PlacementNewAdopt)1675 , m_right(PlacementNewAdopt)1676 {1677 }1678 1679 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1680 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;1681 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1682 virtual Precedence precedence() const { return PrecAssignment; }1683 protected:1684 Identifier m_ident;1685 RefPtr<ExpressionNode> m_right;1686 size_t m_index; // Used by ReadModifyLocalVarNode.1687 };1688 1689 class AssignLocalVarNode : public AssignResolveNode {1690 public:1691 AssignLocalVarNode(size_t i) KJS_FAST_CALL1692 : AssignResolveNode(PlacementNewAdopt)1693 {1694 ASSERT(i != missingSymbolMarker());1695 m_index = i;1696 }1697 1698 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;1699 };1700 1701 class AssignConstNode : public AssignResolveNode {1702 public:1703 AssignConstNode() KJS_FAST_CALL1704 : AssignResolveNode(PlacementNewAdopt)1705 {1706 }1707 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;1708 };1709 1710 class ReadModifyBracketNode : public ExpressionNode {1711 public:1712 ReadModifyBracketNode(ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right) KJS_FAST_CALL1713 : m_base(base), m_subscript(subscript), m_oper(oper), m_right(right) { }1714 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1715 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;1716 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1717 virtual Precedence precedence() const { return PrecAssignment; }1718 protected:1719 RefPtr<ExpressionNode> m_base;1720 RefPtr<ExpressionNode> m_subscript;1721 Operator m_oper;1722 RefPtr<ExpressionNode> m_right;1723 };1724 1725 class AssignBracketNode : public ExpressionNode {1726 public:1727 AssignBracketNode(ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right) KJS_FAST_CALL1728 : m_base(base), m_subscript(subscript), m_right(right) { }1729 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1730 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;1731 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1732 virtual Precedence precedence() const { return PrecAssignment; }1733 protected:1734 RefPtr<ExpressionNode> m_base;1735 RefPtr<ExpressionNode> m_subscript;1736 RefPtr<ExpressionNode> m_right;1737 };1738 1739 class AssignDotNode : public ExpressionNode {1740 public:1741 AssignDotNode(ExpressionNode* base, const Identifier& ident, ExpressionNode* right) KJS_FAST_CALL1742 : m_base(base), m_ident(ident), m_right(right) { }1743 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1744 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;1745 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1746 virtual Precedence precedence() const { return PrecAssignment; }1747 protected:1748 RefPtr<ExpressionNode> m_base;1749 Identifier m_ident;1750 RefPtr<ExpressionNode> m_right;1751 };1752 1753 class ReadModifyDotNode : public ExpressionNode {1754 public:1755 ReadModifyDotNode(ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right) KJS_FAST_CALL1756 : m_base(base), m_ident(ident), m_oper(oper), m_right(right) { }1757 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1758 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;1759 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1760 virtual Precedence precedence() const { return PrecAssignment; }1761 protected:1762 RefPtr<ExpressionNode> m_base;1763 Identifier m_ident;1764 Operator m_oper;1765 RefPtr<ExpressionNode> m_right;1766 };1767 1768 class AssignErrorNode : public ExpressionNode {1769 public:1770 AssignErrorNode(ExpressionNode* left, Operator oper, ExpressionNode* right) KJS_FAST_CALL1771 : m_left(left), m_oper(oper), m_right(right) { }1772 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;1773 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1774 virtual Precedence precedence() const { return PrecAssignment; }1775 protected:1776 RefPtr<ExpressionNode> m_left;1777 Operator m_oper;1778 RefPtr<ExpressionNode> m_right;1779 };1780 1781 class CommaNode : public ExpressionNode {1782 public:1783 CommaNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL1784 : m_expr1(expr1)1785 , m_expr2(expr2)1786 {1787 m_expr1->optimizeForUnnecessaryResult();1788 }1789 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1790 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;1791 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1792 virtual Precedence precedence() const { return PrecExpression; }1793 private:1794 RefPtr<ExpressionNode> m_expr1;1795 RefPtr<ExpressionNode> m_expr2;1796 };1797 1798 class ConstDeclNode : public ExpressionNode {1799 public:1800 ConstDeclNode(const Identifier& ident, ExpressionNode* in) KJS_FAST_CALL;1801 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1802 virtual KJS::JSValue* evaluate(ExecState*) KJS_FAST_CALL;1803 void evaluateSingle(ExecState*) KJS_FAST_CALL;1804 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1805 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }1806 PassRefPtr<ConstDeclNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }1807 1808 Identifier m_ident;1809 ListRefPtr<ConstDeclNode> m_next;1810 RefPtr<ExpressionNode> m_init;1811 private:1812 void handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL NEVER_INLINE;1813 };1814 1815 class ConstStatementNode : public StatementNode {1816 public:1817 ConstStatementNode(ConstDeclNode* next) KJS_FAST_CALL1818 : m_next(next) { }1819 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1820 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;1821 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1822 private:1823 RefPtr<ConstDeclNode> m_next;1824 };1825 1826 typedef Vector<RefPtr<StatementNode> > StatementVector;1827 1828 class SourceElements : public ParserRefCounted {1829 public:1830 void append(PassRefPtr<StatementNode>);1831 void releaseContentsIntoVector(StatementVector& destination)1832 {1833 ASSERT(destination.isEmpty());1834 m_statements.swap(destination);1835 }1836 private:1837 StatementVector m_statements;1838 };1839 1840 class BlockNode : public StatementNode {1841 public:1842 BlockNode(SourceElements* children) KJS_FAST_CALL;1843 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1844 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;1845 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1846 protected:1847 StatementVector m_children;1848 };1849 1850 class EmptyStatementNode : public StatementNode {1851 public:1852 EmptyStatementNode() KJS_FAST_CALL { } // debug1853 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;1854 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1855 virtual bool isEmptyStatement() const KJS_FAST_CALL { return true; }1856 };1857 1858 class ExprStatementNode : public StatementNode {1859 public:1860 ExprStatementNode(ExpressionNode* expr) KJS_FAST_CALL1861 : m_expr(expr) { }1862 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1863 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;1864 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1865 private:1866 RefPtr<ExpressionNode> m_expr;1867 };1868 1869 class VarStatementNode : public StatementNode {1870 public:1871 VarStatementNode(ExpressionNode* e) KJS_FAST_CALL : m_expr(e) { }1872 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1873 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;1874 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1875 private:1876 RefPtr<ExpressionNode> m_expr;1877 };1878 1879 class IfNode : public StatementNode {1880 public:1881 IfNode(ExpressionNode* condition, StatementNode* ifBlock) KJS_FAST_CALL1882 : m_condition(condition), m_ifBlock(ifBlock) { }1883 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1884 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;1885 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;1886 protected:1887 RefPtr<ExpressionNode> m_condition;1888 RefPtr<StatementNode> m_ifBlock;1889 };1890 1891 class IfElseNode : public IfNode {1892 public:1893 IfElseNode(ExpressionNode* condtion, StatementNode* ifBlock, StatementNode* elseBlock) KJS_FAST_CALL1894 : IfNode(condtion, ifBlock), m_elseBlock(elseBlock) { }1895 2573 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1896 2574 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 1897 2575 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1898 private: 1899 RefPtr<StatementNode> m_elseBlock; 1900 }; 1901 1902 class DoWhileNode : public StatementNode { 1903 public: 1904 DoWhileNode(StatementNode* statement, ExpressionNode* expr) KJS_FAST_CALL 1905 : m_statement(statement), m_expr(expr) { } 1906 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1907 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 1908 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1909 private: 1910 RefPtr<StatementNode> m_statement; 1911 RefPtr<ExpressionNode> m_expr; 1912 }; 1913 1914 class WhileNode : public StatementNode { 1915 public: 1916 WhileNode(ExpressionNode* expr, StatementNode* statement) KJS_FAST_CALL 1917 : m_expr(expr), m_statement(statement) { } 1918 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1919 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 1920 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1921 private: 1922 RefPtr<ExpressionNode> m_expr; 1923 RefPtr<StatementNode> m_statement; 1924 }; 1925 1926 class ForNode : public StatementNode { 1927 public: 1928 ForNode(ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl) KJS_FAST_CALL 1929 : m_expr1(expr1 ? expr1 : new PlaceholderTrueNode) 1930 , m_expr2(expr2 ? expr2 : new PlaceholderTrueNode) 1931 , m_expr3(expr3 ? expr3 : new PlaceholderTrueNode) 1932 , m_statement(statement) 1933 , m_expr1WasVarDecl(expr1 && expr1WasVarDecl) 1934 { 1935 ASSERT(m_expr1); 1936 ASSERT(m_expr2); 1937 ASSERT(m_expr3); 1938 ASSERT(statement); 1939 1940 m_expr1->optimizeForUnnecessaryResult(); 1941 m_expr3->optimizeForUnnecessaryResult(); 1942 } 1943 1944 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1945 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 1946 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1947 private: 1948 RefPtr<ExpressionNode> m_expr1; 1949 RefPtr<ExpressionNode> m_expr2; 1950 RefPtr<ExpressionNode> m_expr3; 1951 RefPtr<StatementNode> m_statement; 1952 bool m_expr1WasVarDecl; 1953 }; 1954 1955 class ForInNode : public StatementNode { 1956 public: 1957 ForInNode(ExpressionNode*, ExpressionNode*, StatementNode*) KJS_FAST_CALL; 1958 ForInNode(const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*) KJS_FAST_CALL; 1959 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1960 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 1961 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1962 private: 1963 Identifier m_ident; 1964 RefPtr<ExpressionNode> m_init; 1965 RefPtr<ExpressionNode> m_lexpr; 1966 RefPtr<ExpressionNode> m_expr; 1967 RefPtr<StatementNode> m_statement; 1968 bool m_identIsVarDecl; 1969 }; 1970 1971 class ContinueNode : public StatementNode { 1972 public: 1973 ContinueNode() KJS_FAST_CALL { } 1974 ContinueNode(const Identifier& ident) KJS_FAST_CALL 1975 : m_ident(ident) { } 1976 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 1977 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1978 private: 1979 Identifier m_ident; 1980 }; 1981 1982 class BreakNode : public StatementNode { 1983 public: 1984 BreakNode() KJS_FAST_CALL { } 1985 BreakNode(const Identifier& ident) KJS_FAST_CALL 1986 : m_ident(ident) { } 1987 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 1988 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1989 private: 1990 Identifier m_ident; 1991 }; 1992 1993 class ReturnNode : public StatementNode { 1994 public: 1995 ReturnNode(ExpressionNode* value) KJS_FAST_CALL 1996 : m_value(value) { } 1997 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 1998 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 1999 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2000 private: 2001 RefPtr<ExpressionNode> m_value; 2002 }; 2003 2004 class WithNode : public StatementNode { 2005 public: 2006 WithNode(ExpressionNode* expr, StatementNode* statement) KJS_FAST_CALL 2007 : m_expr(expr), m_statement(statement) { } 2008 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2009 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2010 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2011 private: 2012 RefPtr<ExpressionNode> m_expr; 2013 RefPtr<StatementNode> m_statement; 2014 }; 2015 2016 class LabelNode : public StatementNode { 2017 public: 2018 LabelNode(const Identifier& label, StatementNode* statement) KJS_FAST_CALL 2019 : m_label(label), m_statement(statement) { } 2020 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2021 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2022 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2023 private: 2024 Identifier m_label; 2025 RefPtr<StatementNode> m_statement; 2026 }; 2027 2028 class ThrowNode : public StatementNode { 2029 public: 2030 ThrowNode(ExpressionNode* expr) KJS_FAST_CALL 2031 : m_expr(expr) { } 2032 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2033 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2034 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2035 private: 2036 RefPtr<ExpressionNode> m_expr; 2037 }; 2038 2039 class TryNode : public StatementNode { 2040 public: 2041 TryNode(StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock) KJS_FAST_CALL 2042 : m_tryBlock(tryBlock), m_exceptionIdent(exceptionIdent), m_catchBlock(catchBlock), m_finallyBlock(finallyBlock) { } 2043 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2044 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2045 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2046 private: 2047 RefPtr<StatementNode> m_tryBlock; 2048 Identifier m_exceptionIdent; 2049 RefPtr<StatementNode> m_catchBlock; 2050 RefPtr<StatementNode> m_finallyBlock; 2051 }; 2052 2053 class ParameterNode : public Node { 2054 public: 2055 ParameterNode(const Identifier& ident) KJS_FAST_CALL 2056 : m_ident(ident) { } 2057 ParameterNode(ParameterNode* l, const Identifier& ident) KJS_FAST_CALL 2058 : m_ident(ident) { l->m_next = this; } 2059 Identifier ident() KJS_FAST_CALL { return m_ident; } 2060 ParameterNode *nextParam() KJS_FAST_CALL { return m_next.get(); } 2061 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2062 PassRefPtr<ParameterNode> releaseNext() KJS_FAST_CALL { return m_next.release(); } 2063 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 2064 private: 2065 friend class FuncDeclNode; 2066 friend class FuncExprNode; 2067 Identifier m_ident; 2068 ListRefPtr<ParameterNode> m_next; 2069 }; 2070 2071 class ScopeNode : public BlockNode { 2072 public: 2073 ScopeNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 2074 2075 int sourceId() const KJS_FAST_CALL { return m_sourceId; } 2076 const UString& sourceURL() const KJS_FAST_CALL { return m_sourceURL; } 2077 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2078 2079 protected: 2080 void optimizeVariableAccess(ExecState*) KJS_FAST_CALL; 2081 2082 VarStack m_varStack; 2083 FunctionStack m_functionStack; 2084 2085 private: 2086 UString m_sourceURL; 2087 int m_sourceId; 2088 }; 2089 2090 class ProgramNode : public ScopeNode { 2091 public: 2092 static ProgramNode* create(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 2093 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2094 2095 private: 2096 ProgramNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 2097 void initializeSymbolTable(ExecState*) KJS_FAST_CALL; 2098 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL; 2099 2100 Vector<size_t> m_varIndexes; // Storage indexes belonging to the nodes in m_varStack. (Recorded to avoid double lookup.) 2101 Vector<size_t> m_functionIndexes; // Storage indexes belonging to the nodes in m_functionStack. (Recorded to avoid double lookup.) 2102 }; 2103 2104 class EvalNode : public ScopeNode { 2105 public: 2106 static EvalNode* create(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 2107 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2108 2109 private: 2110 EvalNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 2111 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL; 2112 }; 2113 2114 class FunctionBodyNode : public ScopeNode { 2115 public: 2116 static FunctionBodyNode* create(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 2117 2118 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2119 2120 SymbolTable& symbolTable() KJS_FAST_CALL { return m_symbolTable; } 2121 2122 Vector<Identifier>& parameters() KJS_FAST_CALL { return m_parameters; } 2123 UString paramString() const KJS_FAST_CALL; 2124 2125 protected: 2126 FunctionBodyNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 2127 2128 private: 2129 void initializeSymbolTable(ExecState*) KJS_FAST_CALL; 2130 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL; 2131 2132 bool m_initialized; 2133 Vector<Identifier> m_parameters; 2134 SymbolTable m_symbolTable; 2135 }; 2136 2137 class FuncExprNode : public ExpressionNode { 2138 public: 2139 FuncExprNode(const Identifier& ident, FunctionBodyNode* body, ParameterNode* parameter = 0) KJS_FAST_CALL 2140 : m_ident(ident), m_parameter(parameter), m_body(body) { addParams(); } 2141 virtual JSValue *evaluate(ExecState*) KJS_FAST_CALL; 2142 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2143 virtual Precedence precedence() const { return PrecMember; } 2144 virtual bool needsParensIfLeftmost() const { return true; } 2145 private: 2146 void addParams() KJS_FAST_CALL; 2147 // Used for streamTo 2148 friend class PropertyNode; 2149 Identifier m_ident; 2150 RefPtr<ParameterNode> m_parameter; 2151 RefPtr<FunctionBodyNode> m_body; 2152 }; 2153 2154 class FuncDeclNode : public StatementNode { 2155 public: 2156 FuncDeclNode(const Identifier& ident, FunctionBodyNode* body) KJS_FAST_CALL 2157 : m_ident(ident), m_body(body) { addParams(); } 2158 FuncDeclNode(const Identifier& ident, ParameterNode* parameter, FunctionBodyNode* body) KJS_FAST_CALL 2159 : m_ident(ident), m_parameter(parameter), m_body(body) { addParams(); } 2160 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2161 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2162 ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL; 2163 Identifier m_ident; 2164 private: 2165 void addParams() KJS_FAST_CALL; 2166 RefPtr<ParameterNode> m_parameter; 2167 RefPtr<FunctionBodyNode> m_body; 2168 }; 2169 2170 class CaseClauseNode : public Node { 2171 public: 2172 CaseClauseNode(ExpressionNode* e) KJS_FAST_CALL 2173 : m_expr(e) { } 2174 CaseClauseNode(ExpressionNode* e, SourceElements* children) KJS_FAST_CALL 2175 : m_expr(e) { if (children) children->releaseContentsIntoVector(m_children); } 2176 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2177 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2178 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 2179 2180 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2181 JSValue* executeStatements(ExecState*) KJS_FAST_CALL; 2182 2183 private: 2184 RefPtr<ExpressionNode> m_expr; 2185 StatementVector m_children; 2186 }; 2187 2188 class ClauseListNode : public Node { 2189 public: 2190 ClauseListNode(CaseClauseNode* clause) KJS_FAST_CALL 2191 : m_clause(clause) { } 2192 ClauseListNode(ClauseListNode* clauseList, CaseClauseNode* clause) KJS_FAST_CALL 2193 : m_clause(clause) { clauseList->m_next = this; } 2194 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2195 CaseClauseNode* getClause() const KJS_FAST_CALL { return m_clause.get(); } 2196 ClauseListNode* getNext() const KJS_FAST_CALL { return m_next.get(); } 2197 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2198 PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); } 2199 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 2200 private: 2201 friend class CaseBlockNode; 2202 RefPtr<CaseClauseNode> m_clause; 2203 ListRefPtr<ClauseListNode> m_next; 2204 }; 2205 2206 class CaseBlockNode : public Node { 2207 public: 2208 CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2) KJS_FAST_CALL; 2209 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2210 JSValue* executeBlock(ExecState*, JSValue *input) KJS_FAST_CALL; 2211 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2212 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 2213 private: 2214 RefPtr<ClauseListNode> m_list1; 2215 RefPtr<CaseClauseNode> m_defaultClause; 2216 RefPtr<ClauseListNode> m_list2; 2217 }; 2218 2219 class SwitchNode : public StatementNode { 2220 public: 2221 SwitchNode(ExpressionNode* expr, CaseBlockNode* block) KJS_FAST_CALL 2222 : m_expr(expr), m_block(block) { } 2223 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2224 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2225 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2226 private: 2227 RefPtr<ExpressionNode> m_expr; 2228 RefPtr<CaseBlockNode> m_block; 2229 }; 2576 2577 private: 2578 Identifier m_label; 2579 RefPtr<StatementNode> m_statement; 2580 }; 2581 2582 class ThrowNode : public StatementNode { 2583 public: 2584 ThrowNode(ExpressionNode* expr) KJS_FAST_CALL 2585 : m_expr(expr) 2586 { 2587 } 2588 2589 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2590 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2591 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2592 2593 private: 2594 RefPtr<ExpressionNode> m_expr; 2595 }; 2596 2597 class TryNode : public StatementNode { 2598 public: 2599 TryNode(StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock) KJS_FAST_CALL 2600 : m_tryBlock(tryBlock) 2601 , m_exceptionIdent(exceptionIdent) 2602 , m_catchBlock(catchBlock) 2603 , m_finallyBlock(finallyBlock) 2604 { 2605 } 2606 2607 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2608 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2609 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2610 2611 private: 2612 RefPtr<StatementNode> m_tryBlock; 2613 Identifier m_exceptionIdent; 2614 RefPtr<StatementNode> m_catchBlock; 2615 RefPtr<StatementNode> m_finallyBlock; 2616 }; 2617 2618 class ParameterNode : public Node { 2619 public: 2620 ParameterNode(const Identifier& ident) KJS_FAST_CALL 2621 : m_ident(ident) 2622 { 2623 } 2624 2625 ParameterNode(ParameterNode* l, const Identifier& ident) KJS_FAST_CALL 2626 : m_ident(ident) 2627 { 2628 l->m_next = this; 2629 } 2630 2631 Identifier ident() KJS_FAST_CALL { return m_ident; } 2632 ParameterNode *nextParam() KJS_FAST_CALL { return m_next.get(); } 2633 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2634 PassRefPtr<ParameterNode> releaseNext() KJS_FAST_CALL { return m_next.release(); } 2635 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 2636 2637 private: 2638 friend class FuncDeclNode; 2639 friend class FuncExprNode; 2640 Identifier m_ident; 2641 ListRefPtr<ParameterNode> m_next; 2642 }; 2643 2644 class ScopeNode : public BlockNode { 2645 public: 2646 ScopeNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 2647 2648 int sourceId() const KJS_FAST_CALL { return m_sourceId; } 2649 const UString& sourceURL() const KJS_FAST_CALL { return m_sourceURL; } 2650 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2651 2652 protected: 2653 void optimizeVariableAccess(ExecState*) KJS_FAST_CALL; 2654 2655 VarStack m_varStack; 2656 FunctionStack m_functionStack; 2657 2658 private: 2659 UString m_sourceURL; 2660 int m_sourceId; 2661 }; 2662 2663 class ProgramNode : public ScopeNode { 2664 public: 2665 static ProgramNode* create(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 2666 2667 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2668 2669 private: 2670 ProgramNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 2671 2672 void initializeSymbolTable(ExecState*) KJS_FAST_CALL; 2673 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL; 2674 2675 Vector<size_t> m_varIndexes; // Storage indexes belonging to the nodes in m_varStack. (Recorded to avoid double lookup.) 2676 Vector<size_t> m_functionIndexes; // Storage indexes belonging to the nodes in m_functionStack. (Recorded to avoid double lookup.) 2677 }; 2678 2679 class EvalNode : public ScopeNode { 2680 public: 2681 static EvalNode* create(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 2682 2683 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2684 2685 private: 2686 EvalNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 2687 2688 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL; 2689 }; 2690 2691 class FunctionBodyNode : public ScopeNode { 2692 public: 2693 static FunctionBodyNode* create(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 2694 2695 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2696 2697 SymbolTable& symbolTable() KJS_FAST_CALL { return m_symbolTable; } 2698 2699 Vector<Identifier>& parameters() KJS_FAST_CALL { return m_parameters; } 2700 UString paramString() const KJS_FAST_CALL; 2701 2702 protected: 2703 FunctionBodyNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL; 2704 2705 private: 2706 void initializeSymbolTable(ExecState*) KJS_FAST_CALL; 2707 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL; 2708 2709 bool m_initialized; 2710 Vector<Identifier> m_parameters; 2711 SymbolTable m_symbolTable; 2712 }; 2713 2714 class FuncExprNode : public ExpressionNode { 2715 public: 2716 FuncExprNode(const Identifier& ident, FunctionBodyNode* body, ParameterNode* parameter = 0) KJS_FAST_CALL 2717 : m_ident(ident) 2718 , m_parameter(parameter) 2719 , m_body(body) 2720 { 2721 addParams(); 2722 } 2723 2724 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2725 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2726 virtual Precedence precedence() const { return PrecMember; } 2727 virtual bool needsParensIfLeftmost() const { return true; } 2728 2729 private: 2730 void addParams() KJS_FAST_CALL; 2731 2732 // Used for streamTo 2733 friend class PropertyNode; 2734 Identifier m_ident; 2735 RefPtr<ParameterNode> m_parameter; 2736 RefPtr<FunctionBodyNode> m_body; 2737 }; 2738 2739 class FuncDeclNode : public StatementNode { 2740 public: 2741 FuncDeclNode(const Identifier& ident, FunctionBodyNode* body) KJS_FAST_CALL 2742 : m_ident(ident) 2743 , m_body(body) 2744 { 2745 addParams(); 2746 } 2747 2748 FuncDeclNode(const Identifier& ident, ParameterNode* parameter, FunctionBodyNode* body) KJS_FAST_CALL 2749 : m_ident(ident) 2750 , m_parameter(parameter) 2751 , m_body(body) 2752 { 2753 addParams(); 2754 } 2755 2756 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2757 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2758 ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL; 2759 2760 Identifier m_ident; 2761 2762 private: 2763 void addParams() KJS_FAST_CALL; 2764 2765 RefPtr<ParameterNode> m_parameter; 2766 RefPtr<FunctionBodyNode> m_body; 2767 }; 2768 2769 class CaseClauseNode : public Node { 2770 public: 2771 CaseClauseNode(ExpressionNode* expr) KJS_FAST_CALL 2772 : m_expr(expr) 2773 { 2774 } 2775 2776 CaseClauseNode(ExpressionNode* expr, SourceElements* children) KJS_FAST_CALL 2777 : m_expr(expr) 2778 { 2779 if (children) 2780 children->releaseContentsIntoVector(m_children); 2781 } 2782 2783 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2784 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2785 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 2786 2787 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 2788 JSValue* executeStatements(ExecState*) KJS_FAST_CALL; 2789 2790 private: 2791 RefPtr<ExpressionNode> m_expr; 2792 StatementVector m_children; 2793 }; 2794 2795 class ClauseListNode : public Node { 2796 public: 2797 ClauseListNode(CaseClauseNode* clause) KJS_FAST_CALL 2798 : m_clause(clause) 2799 { 2800 } 2801 2802 ClauseListNode(ClauseListNode* clauseList, CaseClauseNode* clause) KJS_FAST_CALL 2803 : m_clause(clause) 2804 { 2805 clauseList->m_next = this; 2806 } 2807 2808 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2809 CaseClauseNode* getClause() const KJS_FAST_CALL { return m_clause.get(); } 2810 ClauseListNode* getNext() const KJS_FAST_CALL { return m_next.get(); } 2811 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2812 PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); } 2813 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 2814 2815 private: 2816 friend class CaseBlockNode; 2817 RefPtr<CaseClauseNode> m_clause; 2818 ListRefPtr<ClauseListNode> m_next; 2819 }; 2820 2821 class CaseBlockNode : public Node { 2822 public: 2823 CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2) KJS_FAST_CALL; 2824 2825 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2826 JSValue* executeBlock(ExecState*, JSValue *input) KJS_FAST_CALL; 2827 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2828 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 2829 2830 private: 2831 RefPtr<ClauseListNode> m_list1; 2832 RefPtr<CaseClauseNode> m_defaultClause; 2833 RefPtr<ClauseListNode> m_list2; 2834 }; 2835 2836 class SwitchNode : public StatementNode { 2837 public: 2838 SwitchNode(ExpressionNode* expr, CaseBlockNode* block) KJS_FAST_CALL 2839 : m_expr(expr) 2840 , m_block(block) 2841 { 2842 } 2843 2844 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2845 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2846 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2847 2848 private: 2849 RefPtr<ExpressionNode> m_expr; 2850 RefPtr<CaseBlockNode> m_block; 2851 }; 2230 2852 2231 2853 class BreakpointCheckStatement : public StatementNode { 2232 2854 public: 2233 2855 BreakpointCheckStatement(PassRefPtr<StatementNode>) KJS_FAST_CALL; 2856 2234 2857 virtual JSValue* execute(ExecState*) KJS_FAST_CALL; 2235 2858 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2236 2859 virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2860 2237 2861 private: 2238 2862 RefPtr<StatementNode> m_statement; 2239 2863 }; 2240 2864 2241 struct ElementList {2242 ElementNode* head;2243 ElementNode* tail;2244 };2245 2246 struct PropertyList {2247 PropertyListNode* head;2248 PropertyListNode* tail;2249 };2250 2251 struct ArgumentList {2252 ArgumentListNode* head;2253 ArgumentListNode* tail;2254 };2255 2256 struct ConstDeclList {2257 ConstDeclNode* head;2258 ConstDeclNode* tail;2259 };2260 2261 struct ParameterList {2262 ParameterNode* head;2263 ParameterNode* tail;2264 };2265 2266 struct ClauseList {2267 ClauseListNode* head;2268 ClauseListNode* tail;2269 };2865 struct ElementList { 2866 ElementNode* head; 2867 ElementNode* tail; 2868 }; 2869 2870 struct PropertyList { 2871 PropertyListNode* head; 2872 PropertyListNode* tail; 2873 }; 2874 2875 struct ArgumentList { 2876 ArgumentListNode* head; 2877 ArgumentListNode* tail; 2878 }; 2879 2880 struct ConstDeclList { 2881 ConstDeclNode* head; 2882 ConstDeclNode* tail; 2883 }; 2884 2885 struct ParameterList { 2886 ParameterNode* head; 2887 ParameterNode* tail; 2888 }; 2889 2890 struct ClauseList { 2891 ClauseListNode* head; 2892 ClauseListNode* tail; 2893 }; 2270 2894 2271 2895 } // namespace KJS -
trunk/JavaScriptCore/kjs/nodes2string.cpp
r29825 r29836 42 42 class SourceStream { 43 43 public: 44 SourceStream() : m_numberNeedsParens(false), m_atStartOfStatement(true), m_precedence(PrecExpression) { } 44 SourceStream() 45 : m_numberNeedsParens(false) 46 , m_atStartOfStatement(true) 47 , m_precedence(PrecExpression) 48 { 49 } 50 45 51 UString toString() const { return m_string; } 52 46 53 SourceStream& operator<<(const Identifier&); 47 54 SourceStream& operator<<(const UString&); … … 100 107 } 101 108 102 return escapedString; 109 return escapedString; 103 110 } 104 111 … … 315 322 316 323 void RegExpNode::streamTo(SourceStream& s) const 317 { 324 { 318 325 s << '/' << m_regExp->pattern() << '/' << m_regExp->flags(); 319 326 } … … 345 352 for (int i = 0; i < m_elision; i++) 346 353 s << ','; 347 // Parser consumes one elision comma if there's array elements 354 // Parser consumes one elision comma if there's array elements 348 355 // present in the expression. 349 if (m_opt && m_element)356 if (m_optional && m_element) 350 357 s << ','; 351 358 s << ']'; … … 383 390 const FuncExprNode* func = static_cast<const FuncExprNode*>(m_assign.get()); 384 391 if (m_type == Getter) 385 s << "get "; 392 s << "get "; 386 393 else 387 394 s << "set "; … … 479 486 { 480 487 s << PrecLeftHandSide << m_expr; 481 if (m_oper == OpPlusPlus)488 if (m_operator == OpPlusPlus) 482 489 s << "++"; 483 490 else … … 558 565 void PrefixErrorNode::streamTo(SourceStream& s) const 559 566 { 560 if (m_oper == OpPlusPlus)567 if (m_operator == OpPlusPlus) 561 568 s << "++" << PrecUnary << m_expr; 562 569 else … … 708 715 void ReadModifyResolveNode::streamTo(SourceStream& s) const 709 716 { 710 s << m_ident << ' ' << operatorString(m_oper ) << ' ' << PrecAssignment << m_right;717 s << m_ident << ' ' << operatorString(m_operator) << ' ' << PrecAssignment << m_right; 711 718 } 712 719 … … 719 726 { 720 727 bracketNodeStreamTo(s, m_base, m_subscript); 721 s << ' ' << operatorString(m_oper ) << ' ' << PrecAssignment << m_right;728 s << ' ' << operatorString(m_operator) << ' ' << PrecAssignment << m_right; 722 729 } 723 730 … … 731 738 { 732 739 dotNodeStreamTo(s, m_base, m_ident); 733 s << ' ' << operatorString(m_oper ) << ' ' << PrecAssignment << m_right;740 s << ' ' << operatorString(m_operator) << ' ' << PrecAssignment << m_right; 734 741 } 735 742 … … 743 750 { 744 751 s << PrecLeftHandSide << m_left << ' ' 745 << operatorString(m_oper ) << ' ' << PrecAssignment << m_right;752 << operatorString(m_operator) << ' ' << PrecAssignment << m_right; 746 753 } 747 754 … … 773 780 s << *ptr; 774 781 } 775 782 776 783 void BlockNode::streamTo(SourceStream& s) const 777 784 { 778 785 s << Endl << "{" << Indent; 779 statementListStreamTo(m_children, s); 786 statementListStreamTo(m_children, s); 780 787 s << Unindent << Endl << "}"; 781 788 } … … 799 806 s << ';'; 800 807 801 statementListStreamTo(m_children, s); 808 statementListStreamTo(m_children, s); 802 809 s << Unindent << Endl << "}"; 803 810 }
Note:
See TracChangeset
for help on using the changeset viewer.