Changeset 10148 in webkit for trunk/JavaScriptCore/kjs/nodes.cpp
- Timestamp:
- Aug 12, 2005, 12:36:00 AM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/nodes.cpp
r10135 r10148 172 172 } 173 173 174 ValueImp *Node::throwError(ExecState *exec, ErrorType e, const char *msg, ValueImp *v, Node *e1, Node *e2) 175 { 176 char *vStr = strdup(v->toString(exec).ascii()); 177 char *e1Str = strdup(e1->toString().ascii()); 178 char *e2Str = strdup(e2->toString().ascii()); 179 180 int length = strlen(msg) - 6 /* three %s */ + strlen(vStr) + strlen(e1Str) + strlen(e2Str) + 1 /* null terminator */; 181 char *str = new char[length]; 182 sprintf(str, msg, vStr, e1Str, e2Str); 183 free(vStr); 184 free(e1Str); 185 free(e2Str); 186 187 ValueImp *result = throwError(exec, e, str); 188 delete [] str; 189 190 return result; 191 } 192 193 ValueImp *Node::throwError(ExecState *exec, ErrorType e, const char *msg, ValueImp *v, Node *expr, Identifier label) 194 { 195 char *vStr = strdup(v->toString(exec).ascii()); 196 char *exprStr = strdup(expr->toString().ascii()); 197 const char *l = label.ascii(); 198 int length = strlen(msg) - 6 /* three %s */ + strlen(vStr) + strlen(exprStr) + strlen(l) + 1 /* null terminator */; 199 char *message = new char[length]; 200 sprintf(message, msg, vStr, exprStr, l); 201 free(vStr); 202 free(exprStr); 203 204 ValueImp *result = throwError(exec, e, message); 205 delete [] message; 206 207 return result; 208 } 209 210 ValueImp *Node::throwError(ExecState *exec, ErrorType e, const char *msg, ValueImp *v, Identifier label) 211 { 212 char *vStr = strdup(v->toString(exec).ascii()); 213 const char *l = label.ascii(); 214 int length = strlen(msg) - 4 /* two %s */ + strlen(vStr) + strlen(l) + 1 /* null terminator */; 215 char *message = new char[length]; 216 sprintf(message, msg, vStr, l); 217 free(vStr); 218 219 ValueImp *result = throwError(exec, e, message); 220 delete [] message; 221 222 return result; 223 } 224 225 174 226 void Node::setExceptionDetailsIfNeeded(ExecState *exec) 175 227 { … … 706 758 } 707 759 708 // ------------------------------ FunctionCallNode ----------------------------- 709 710 void FunctionCallNode::ref() 711 { 712 Node::ref(); 713 if ( expr ) 760 void FunctionCallValueNode::ref() 761 { 762 Node::ref(); 763 if (expr) 714 764 expr->ref(); 715 if ( args)765 if (args) 716 766 args->ref(); 717 767 } 718 768 719 bool FunctionCall Node::deref()720 { 721 if ( expr && expr->deref())769 bool FunctionCallValueNode::deref() 770 { 771 if (expr && expr->deref()) 722 772 delete expr; 723 if ( args && args->deref())773 if (args && args->deref()) 724 774 delete args; 725 775 return Node::deref(); … … 727 777 728 778 // ECMA 11.2.3 729 ValueImp *FunctionCallNode::evaluate(ExecState *exec) 730 { 731 Reference ref = expr->evaluateReference(exec); 732 KJS_CHECKEXCEPTIONVALUE 733 734 List argList = args->evaluateList(exec); 735 KJS_CHECKEXCEPTIONVALUE 736 737 ValueImp *v = ref.getValue(exec); 738 KJS_CHECKEXCEPTIONVALUE 739 779 ValueImp *FunctionCallValueNode::evaluate(ExecState *exec) 780 { 781 ValueImp *v = expr->evaluate(exec); 782 KJS_CHECKEXCEPTIONVALUE 783 740 784 if (!v->isObject()) { 741 785 return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, expr); … … 748 792 } 749 793 750 ObjectImp *thisObjImp = 0; 751 ValueImp *thisValImp = ref.baseIfMutable(); 752 if (thisValImp && thisValImp->isObject() && !static_cast<ObjectImp *>(thisValImp)->inherits(&ActivationImp::info)) 753 thisObjImp = static_cast<ObjectImp *>(thisValImp); 754 755 if (!thisObjImp) { 756 // ECMA 11.2.3 says that in this situation the this value should be null. 757 // However, section 10.2.3 says that in the case where the value provided 758 // by the caller is null, the global object should be used. It also says 759 // that the section does not apply to interal functions, but for simplicity 760 // of implementation we use the global object anyway here. This guarantees 761 // that in host objects you always get a valid object for this. 762 thisObjImp = exec->dynamicInterpreter()->globalObject(); 763 } 764 765 ObjectImp *thisObj(thisObjImp); 794 List argList = args->evaluateList(exec); 795 KJS_CHECKEXCEPTIONVALUE 796 797 ObjectImp *thisObj = exec->dynamicInterpreter()->globalObject(); 798 799 return func->call(exec, thisObj, argList); 800 } 801 802 803 void FunctionCallResolveNode::ref() 804 { 805 Node::ref(); 806 if (args) 807 args->ref(); 808 } 809 810 bool FunctionCallResolveNode::deref() 811 { 812 if (args && args->deref()) 813 delete args; 814 return Node::deref(); 815 } 816 817 // ECMA 11.2.3 818 ValueImp *FunctionCallResolveNode::evaluate(ExecState *exec) 819 { 820 ScopeChain chain = exec->context().imp()->scopeChain(); 821 822 assert(!chain.isEmpty()); 823 824 PropertySlot slot; 825 ObjectImp *base; 826 do { 827 base = chain.top(); 828 if (base->getPropertySlot(exec, ident, slot)) { 829 ValueImp *v = slot.getValue(exec, ident); 830 KJS_CHECKEXCEPTIONVALUE 831 832 if (!v->isObject()) { 833 return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, ident); 834 } 835 836 ObjectImp *func = static_cast<ObjectImp*>(v); 837 838 if (!func->implementsCall()) { 839 return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, ident); 840 } 841 842 List argList = args->evaluateList(exec); 843 KJS_CHECKEXCEPTIONVALUE 844 845 ObjectImp *thisObj = base; 846 // ECMA 11.2.3 says that in this situation the this value should be null. 847 // However, section 10.2.3 says that in the case where the value provided 848 // by the caller is null, the global object should be used. It also says 849 // that the section does not apply to interal functions, but for simplicity 850 // of implementation we use the global object anyway here. This guarantees 851 // that in host objects you always get a valid object for this. 852 if (thisObj->isActivation()) 853 thisObj = exec->dynamicInterpreter()->globalObject(); 854 855 return func->call(exec, thisObj, argList); 856 } 857 chain.pop(); 858 } while (!chain.isEmpty()); 859 860 return undefinedVariableError(exec, ident); 861 } 862 863 void FunctionCallBracketNode::ref() 864 { 865 Node::ref(); 866 if (base) 867 base->ref(); 868 if (subscript) 869 base->ref(); 870 if (args) 871 args->ref(); 872 } 873 874 bool FunctionCallBracketNode::deref() 875 { 876 if (base && base->deref()) 877 delete base; 878 if (subscript && subscript->deref()) 879 delete subscript; 880 if (args && args->deref()) 881 delete args; 882 return Node::deref(); 883 } 884 885 // ECMA 11.2.3 886 ValueImp *FunctionCallBracketNode::evaluate(ExecState *exec) 887 { 888 ValueImp *baseVal = base->evaluate(exec); 889 KJS_CHECKEXCEPTIONVALUE 890 891 ValueImp *subscriptVal = subscript->evaluate(exec); 892 893 ObjectImp *baseObj = baseVal->toObject(exec); 894 uint32_t i; 895 PropertySlot slot; 896 897 ValueImp *funcVal; 898 if (subscriptVal->getUInt32(i)) { 899 if (baseObj->getPropertySlot(exec, i, slot)) 900 funcVal = slot.getValue(exec, i); 901 else 902 funcVal = Undefined(); 903 } else { 904 Identifier ident(subscriptVal->toString(exec)); 905 if (baseObj->getPropertySlot(exec, ident, slot)) 906 funcVal = baseObj->get(exec, ident); 907 else 908 funcVal = Undefined(); 909 } 910 911 KJS_CHECKEXCEPTIONVALUE 912 913 if (!funcVal->isObject()) { 914 return throwError(exec, TypeError, "Value %s (result of expression %s[%s]) is not object.", funcVal, base, subscript); 915 } 916 917 ObjectImp *func = static_cast<ObjectImp*>(funcVal); 918 919 if (!func->implementsCall()) { 920 return throwError(exec, TypeError, "Object %s (result of expression %s[%s]) does not allow calls.", funcVal, base, subscript); 921 } 922 923 List argList = args->evaluateList(exec); 924 KJS_CHECKEXCEPTIONVALUE 925 926 ObjectImp *thisObj = baseObj; 927 assert(thisObj); 928 assert(thisObj->isObject()); 929 assert(!thisObj->isActivation()); 930 931 return func->call(exec, thisObj, argList); 932 } 933 934 935 void FunctionCallDotNode::ref() 936 { 937 Node::ref(); 938 if (base) 939 base->ref(); 940 if (args) 941 args->ref(); 942 } 943 944 bool FunctionCallDotNode::deref() 945 { 946 if (base && base->deref()) 947 delete base; 948 if (args && args->deref()) 949 delete args; 950 return Node::deref(); 951 } 952 953 static const char *dotExprNotAnObjectString() 954 { 955 return "Value %s (result of expression %s.%s) is not object."; 956 } 957 958 static const char *dotExprDoesNotAllowCallsString() 959 { 960 return "Object %s (result of expression %s.%s) does not allow calls."; 961 } 962 963 // ECMA 11.2.3 964 ValueImp *FunctionCallDotNode::evaluate(ExecState *exec) 965 { 966 ValueImp *baseVal = base->evaluate(exec); 967 968 ObjectImp *baseObj = baseVal->toObject(exec); 969 PropertySlot slot; 970 ValueImp *funcVal = baseObj->getPropertySlot(exec, ident, slot) ? slot.getValue(exec, ident) : Undefined(); 971 KJS_CHECKEXCEPTIONVALUE 972 973 if (!funcVal->isObject()) 974 return throwError(exec, TypeError, dotExprNotAnObjectString(), funcVal, base, ident); 975 976 ObjectImp *func = static_cast<ObjectImp*>(funcVal); 977 978 if (!func->implementsCall()) 979 return throwError(exec, TypeError, dotExprDoesNotAllowCallsString(), funcVal, base, ident); 980 981 List argList = args->evaluateList(exec); 982 KJS_CHECKEXCEPTIONVALUE 983 984 ObjectImp *thisObj = baseObj; 985 assert(thisObj); 986 assert(thisObj->isObject()); 987 assert(!thisObj->isActivation()); 988 766 989 return func->call(exec, thisObj, argList); 767 990 }
Note:
See TracChangeset
for help on using the changeset viewer.