Changeset 29836 in webkit for trunk/JavaScriptCore/kjs/nodes.cpp
- Timestamp:
- Jan 28, 2008, 12:50:45 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note:
See TracChangeset
for help on using the changeset viewer.