Changeset 10084 in webkit for trunk/JavaScriptCore/kjs/nodes.cpp
- Timestamp:
- Aug 7, 2005, 9:07:46 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/nodes.cpp
r10076 r10084 25 25 #include "nodes.h" 26 26 27 //#include <iostream>28 27 #include <math.h> 29 28 #include <assert.h> … … 45 44 #include "operations.h" 46 45 #include "ustring.h" 46 #include "reference_list.h" 47 47 48 48 using namespace KJS; … … 117 117 Reference Node::evaluateReference(ExecState *exec) 118 118 { 119 Value 119 ValueImp *v = evaluate(exec); 120 120 KJS_CHECKEXCEPTIONREFERENCE 121 121 return Reference::makeValueReference(v); … … 134 134 #endif 135 135 136 Value 137 { 138 Object 136 ValueImp *Node::throwError(ExecState *exec, ErrorType e, const char *msg) 137 { 138 ObjectImp *err = Error::create(exec, e, msg, lineNo(), sourceId(), &sourceURL); 139 139 exec->setException(err); 140 140 return err; 141 141 } 142 142 143 Value Node::throwError(ExecState *exec, ErrorType e, const char *msg, Valuev, Node *expr)144 { 145 char *vStr = strdup(v .toString(exec).ascii());143 ValueImp *Node::throwError(ExecState *exec, ErrorType e, const char *msg, ValueImp *v, Node *expr) 144 { 145 char *vStr = strdup(v->toString(exec).ascii()); 146 146 char *exprStr = strdup(expr->toString().ascii()); 147 147 … … 152 152 free(exprStr); 153 153 154 Value 154 ValueImp *result = throwError(exec, e, str); 155 155 delete [] str; 156 156 … … 159 159 160 160 161 Value 161 ValueImp *Node::throwError(ExecState *exec, ErrorType e, const char *msg, Identifier label) 162 162 { 163 163 const char *l = label.ascii(); … … 166 166 sprintf(message, msg, l); 167 167 168 Value 168 ValueImp *result = throwError(exec, e, message); 169 169 delete [] message; 170 170 … … 175 175 { 176 176 if (exec->hadException()) { 177 Object exception = exec->exception().toObject(exec);178 if (!exception .hasProperty(exec, "line") &&179 !exception .hasProperty(exec, "sourceURL")) {180 exception .put(exec, "line", Number(line));181 exception .put(exec, "sourceURL", String(sourceURL));177 ObjectImp *exception = exec->exception()->toObject(exec); 178 if (!exception->hasProperty(exec, "line") && 179 !exception->hasProperty(exec, "sourceURL")) { 180 exception->put(exec, "line", Number(line)); 181 exception->put(exec, "sourceURL", String(sourceURL)); 182 182 } 183 183 } … … 223 223 // ------------------------------ NullNode ------------------------------------- 224 224 225 Value 225 ValueImp *NullNode::evaluate(ExecState */*exec*/) 226 226 { 227 227 return Null(); … … 230 230 // ------------------------------ BooleanNode ---------------------------------- 231 231 232 Value 233 { 234 return Value(value);232 ValueImp *BooleanNode::evaluate(ExecState */*exec*/) 233 { 234 return jsBoolean(value); 235 235 } 236 236 237 237 // ------------------------------ NumberNode ----------------------------------- 238 238 239 Value 240 { 241 return Value(value);239 ValueImp *NumberNode::evaluate(ExecState */*exec*/) 240 { 241 return jsNumber(value); 242 242 } 243 243 244 244 // ------------------------------ StringNode ----------------------------------- 245 245 246 Value 247 { 248 return value;246 ValueImp *StringNode::evaluate(ExecState */*exec*/) 247 { 248 return jsString(value); 249 249 } 250 250 251 251 // ------------------------------ RegExpNode ----------------------------------- 252 252 253 Value 253 ValueImp *RegExpNode::evaluate(ExecState *exec) 254 254 { 255 255 List list; 256 String p(pattern); 257 String f(flags); 258 list.append(p); 259 list.append(f); 260 261 Object reg = exec->lexicalInterpreter()->imp()->builtinRegExp(); 262 return reg.construct(exec,list); 256 list.append(jsString(pattern)); 257 list.append(jsString(flags)); 258 259 ObjectImp *reg = exec->lexicalInterpreter()->imp()->builtinRegExp(); 260 return reg->construct(exec,list); 263 261 } 264 262 … … 266 264 267 265 // ECMA 11.1.1 268 Value 266 ValueImp *ThisNode::evaluate(ExecState *exec) 269 267 { 270 268 return exec->context().imp()->thisValue(); … … 274 272 275 273 // ECMA 11.1.2 & 10.1.4 276 Value 274 ValueImp *ResolveNode::evaluate(ExecState *exec) 277 275 { 278 276 ScopeChain chain = exec->context().imp()->scopeChain(); … … 283 281 do { 284 282 ObjectImp *o = chain.top(); 283 285 284 if (o->getPropertySlot(exec, ident, slot)) 286 285 return slot.getValue(exec, ident); … … 289 288 } while (!chain.isEmpty()); 290 289 291 return Reference( Null(),ident).getValue(exec);290 return Reference(ident).getValue(exec); 292 291 } 293 292 … … 307 306 } while (!chain.isEmpty()); 308 307 309 return Reference(Null(), ident); 310 } 311 308 return Reference(ident); 309 } 312 310 313 311 // ------------------------------ GroupNode ------------------------------------ … … 328 326 329 327 // ECMA 11.1.6 330 Value 328 ValueImp *GroupNode::evaluate(ExecState *exec) 331 329 { 332 330 return group->evaluate(exec); … … 363 361 364 362 // ECMA 11.1.4 365 Value 366 { 367 Object array = exec->lexicalInterpreter()->builtinArray().construct(exec, List::empty());363 ValueImp *ElementNode::evaluate(ExecState *exec) 364 { 365 ObjectImp *array = exec->lexicalInterpreter()->builtinArray()->construct(exec, List::empty()); 368 366 int length = 0; 369 367 for (ElementNode *n = this; n; n = n->list) { 370 Value 368 ValueImp *val = n->node->evaluate(exec); 371 369 KJS_CHECKEXCEPTIONVALUE 372 370 length += n->elision; 373 array .put(exec, length++, val);371 array->put(exec, length++, val); 374 372 } 375 373 return array; … … 393 391 394 392 // ECMA 11.1.4 395 Value 396 { 397 Object 393 ValueImp *ArrayNode::evaluate(ExecState *exec) 394 { 395 ObjectImp *array; 398 396 int length; 399 397 400 398 if (element) { 401 array = Object(static_cast<ObjectImp*>(element->evaluate(exec).imp()));399 array = static_cast<ObjectImp*>(element->evaluate(exec)); 402 400 KJS_CHECKEXCEPTIONVALUE 403 length = opt ? array .get(exec,lengthPropertyName).toInt32(exec) : 0;401 length = opt ? array->get(exec,lengthPropertyName)->toInt32(exec) : 0; 404 402 } else { 405 Value newArr = exec->lexicalInterpreter()->builtinArray().construct(exec,List::empty());406 array = Object(static_cast<ObjectImp*>(newArr.imp()));403 ValueImp *newArr = exec->lexicalInterpreter()->builtinArray()->construct(exec,List::empty()); 404 array = static_cast<ObjectImp*>(newArr); 407 405 length = 0; 408 406 } 409 407 410 408 if (opt) 411 array .put(exec,lengthPropertyName, Value(elision + length), DontEnum | DontDelete);409 array->put(exec,lengthPropertyName, jsNumber(elision + length), DontEnum | DontDelete); 412 410 413 411 return array; … … 431 429 432 430 // ECMA 11.1.5 433 Value 431 ValueImp *ObjectLiteralNode::evaluate(ExecState *exec) 434 432 { 435 433 if (list) 436 434 return list->evaluate(exec); 437 435 438 return exec->lexicalInterpreter()->builtinObject() .construct(exec,List::empty());436 return exec->lexicalInterpreter()->builtinObject()->construct(exec,List::empty()); 439 437 } 440 438 … … 468 466 469 467 // ECMA 11.1.5 470 Value 471 { 472 Object obj = exec->lexicalInterpreter()->builtinObject().construct(exec, List::empty());468 ValueImp *PropertyValueNode::evaluate(ExecState *exec) 469 { 470 ObjectImp *obj = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty()); 473 471 474 472 for (PropertyValueNode *p = this; p; p = p->list) { 475 Value 473 ValueImp *n = p->name->evaluate(exec); 476 474 KJS_CHECKEXCEPTIONVALUE 477 Value 475 ValueImp *v = p->assign->evaluate(exec); 478 476 KJS_CHECKEXCEPTIONVALUE 479 477 480 obj .put(exec, Identifier(n.toString(exec)), v);478 obj->put(exec, Identifier(n->toString(exec)), v); 481 479 } 482 480 … … 487 485 488 486 // ECMA 11.1.5 489 Value 490 { 491 Value 487 ValueImp *PropertyNode::evaluate(ExecState */*exec*/) 488 { 489 ValueImp *s; 492 490 493 491 if (str.isNull()) { … … 521 519 522 520 // ECMA 11.2.1a 523 Value AccessorNode1::evaluate(ExecState *exec) 524 { 525 Value v1 = expr1->evaluate(exec); 526 KJS_CHECKEXCEPTIONVALUE 527 Value v2 = expr2->evaluate(exec); 528 KJS_CHECKEXCEPTIONVALUE 529 Object o = v1.toObject(exec); 530 unsigned i; 531 if (v2.toUInt32(i)) 532 return o.get(exec, i); 533 534 String s = v2.toString(exec); 535 return o.get(exec, Identifier(s.value())); 521 ValueImp *AccessorNode1::evaluate(ExecState *exec) 522 { 523 ValueImp *v1 = expr1->evaluate(exec); 524 KJS_CHECKEXCEPTIONVALUE 525 ValueImp *v2 = expr2->evaluate(exec); 526 KJS_CHECKEXCEPTIONVALUE 527 ObjectImp *o = v1->toObject(exec); 528 uint32_t i; 529 if (v2->getUInt32(i)) 530 return o->get(exec, i); 531 return o->get(exec, Identifier(v2->toString(exec))); 536 532 } 537 533 538 534 Reference AccessorNode1::evaluateReference(ExecState *exec) 539 535 { 540 Value 536 ValueImp *v1 = expr1->evaluate(exec); 541 537 KJS_CHECKEXCEPTIONREFERENCE 542 Value 538 ValueImp *v2 = expr2->evaluate(exec); 543 539 KJS_CHECKEXCEPTIONREFERENCE 544 Object o = v1.toObject(exec);545 u nsignedi;546 if (v2 .toUInt32(i))540 ObjectImp *o = v1->toObject(exec); 541 uint32_t i; 542 if (v2->getUInt32(i)) 547 543 return Reference(o, i); 548 String s = v2.toString(exec); 549 return Reference(o, Identifier(s.value())); 550 } 551 544 return Reference(o, Identifier(v2->toString(exec))); 545 } 552 546 553 547 // ------------------------------ AccessorNode2 -------------------------------- … … 568 562 569 563 // ECMA 11.2.1b 570 Value AccessorNode2::evaluate(ExecState *exec) 571 { 572 Value v = expr->evaluate(exec); 573 KJS_CHECKEXCEPTIONVALUE 574 Object o = v.toObject(exec); 575 return o.get(exec, ident); 564 ValueImp *AccessorNode2::evaluate(ExecState *exec) 565 { 566 ValueImp *v = expr->evaluate(exec); 567 KJS_CHECKEXCEPTIONVALUE 568 return v->toObject(exec)->get(exec, ident); 576 569 577 570 } … … 579 572 Reference AccessorNode2::evaluateReference(ExecState *exec) 580 573 { 581 Value 574 ValueImp *v = expr->evaluate(exec); 582 575 KJS_CHECKEXCEPTIONREFERENCE 583 Object o = v.toObject(exec);576 ObjectImp *o = v->toObject(exec); 584 577 return Reference(o, ident); 585 578 } … … 609 602 } 610 603 611 Value 604 ValueImp *ArgumentListNode::evaluate(ExecState */*exec*/) 612 605 { 613 606 assert(0); 614 return Value(); // dummy, see evaluateList()607 return NULL; // dummy, see evaluateList() 615 608 } 616 609 … … 621 614 622 615 for (ArgumentListNode *n = this; n; n = n->list) { 623 Value 616 ValueImp *v = n->expr->evaluate(exec); 624 617 KJS_CHECKEXCEPTIONLIST 625 618 l.append(v); … … 645 638 } 646 639 647 Value 640 ValueImp *ArgumentsNode::evaluate(ExecState */*exec*/) 648 641 { 649 642 assert(0); 650 return Value(); // dummy, see evaluateList()643 return NULL; // dummy, see evaluateList() 651 644 } 652 645 … … 682 675 } 683 676 684 Value 685 { 686 Value 677 ValueImp *NewExprNode::evaluate(ExecState *exec) 678 { 679 ValueImp *v = expr->evaluate(exec); 687 680 KJS_CHECKEXCEPTIONVALUE 688 681 … … 693 686 } 694 687 695 if ( v.type() != ObjectType) {688 if (!v->isObject()) { 696 689 return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, expr); 697 690 } 698 691 699 Object constr = Object(static_cast<ObjectImp*>(v.imp()));700 if (!constr .implementsConstruct()) {692 ObjectImp *constr = static_cast<ObjectImp*>(v); 693 if (!constr->implementsConstruct()) { 701 694 return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, expr); 702 695 } 703 696 704 Value res = constr.construct(exec,argList); 705 706 return res; 697 return constr->construct(exec, argList); 707 698 } 708 699 … … 728 719 729 720 // ECMA 11.2.3 730 Value 721 ValueImp *FunctionCallNode::evaluate(ExecState *exec) 731 722 { 732 723 Reference ref = expr->evaluateReference(exec); … … 736 727 KJS_CHECKEXCEPTIONVALUE 737 728 738 Value 739 KJS_CHECKEXCEPTIONVALUE 740 741 if ( v.type() != ObjectType) {729 ValueImp *v = ref.getValue(exec); 730 KJS_CHECKEXCEPTIONVALUE 731 732 if (!v->isObject()) { 742 733 return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, expr); 743 734 } 744 745 ObjectImp *func = static_cast<ObjectImp*>(v .imp());735 736 ObjectImp *func = static_cast<ObjectImp*>(v); 746 737 747 738 if (!func->implementsCall()) { … … 751 742 ObjectImp *thisObjImp = 0; 752 743 ValueImp *thisValImp = ref.baseIfMutable(); 753 if (thisValImp && thisValImp-> type() == ObjectType&& !static_cast<ObjectImp *>(thisValImp)->inherits(&ActivationImp::info))744 if (thisValImp && thisValImp->isObject() && !static_cast<ObjectImp *>(thisValImp)->inherits(&ActivationImp::info)) 754 745 thisObjImp = static_cast<ObjectImp *>(thisValImp); 755 746 … … 761 752 // of implementation we use the global object anyway here. This guarantees 762 753 // that in host objects you always get a valid object for this. 763 thisObjImp = exec->dynamicInterpreter()->globalObject() .imp();764 } 765 766 Object 754 thisObjImp = exec->dynamicInterpreter()->globalObject(); 755 } 756 757 ObjectImp *thisObj(thisObjImp); 767 758 return func->call(exec, thisObj, argList); 768 759 } … … 785 776 786 777 // ECMA 11.3 787 Value 778 ValueImp *PostfixNode::evaluate(ExecState *exec) 788 779 { 789 780 Reference ref = expr->evaluateReference(exec); 790 781 KJS_CHECKEXCEPTIONVALUE 791 Value 782 ValueImp *v = ref.getValue(exec); 792 783 793 784 bool knownToBeInteger; 794 double n = v .toNumber(exec, knownToBeInteger);785 double n = v->toNumber(exec, knownToBeInteger); 795 786 796 787 double newValue = (oper == OpPlusPlus) ? n + 1 : n - 1; 797 ref.putValue(exec, Value(newValue, knownToBeInteger));798 799 return Value(n, knownToBeInteger);788 ref.putValue(exec, jsNumber(newValue, knownToBeInteger)); 789 790 return jsNumber(n, knownToBeInteger); 800 791 } 801 792 … … 817 808 818 809 // ECMA 11.4.1 819 Value 810 ValueImp *DeleteNode::evaluate(ExecState *exec) 820 811 { 821 812 Reference ref = expr->evaluateReference(exec); 822 813 KJS_CHECKEXCEPTIONVALUE 823 return Value(ref.deleteValue(exec));814 return jsBoolean(ref.deleteValue(exec)); 824 815 } 825 816 … … 841 832 842 833 // ECMA 11.4.2 843 Value 844 { 845 Value dummy1 =expr->evaluate(exec);834 ValueImp *VoidNode::evaluate(ExecState *exec) 835 { 836 expr->evaluate(exec); 846 837 KJS_CHECKEXCEPTIONVALUE 847 838 … … 866 857 867 858 // ECMA 11.4.3 868 Value 859 ValueImp *TypeOfNode::evaluate(ExecState *exec) 869 860 { 870 861 const char *s = 0L; … … 872 863 KJS_CHECKEXCEPTIONVALUE 873 864 ValueImp *b = ref.baseIfMutable(); 874 if (b && b-> dispatchType() == NullType)875 return Value("undefined");876 Value 877 switch (v .type())865 if (b && b->isNull()) 866 return jsString("undefined"); 867 ValueImp *v = ref.getValue(exec); 868 switch (v->type()) 878 869 { 879 870 case UndefinedType: … … 893 884 break; 894 885 default: 895 if (v .type() == ObjectType && static_cast<ObjectImp*>(v.imp())->implementsCall())886 if (v->isObject() && static_cast<ObjectImp*>(v)->implementsCall()) 896 887 s = "function"; 897 888 else … … 900 891 } 901 892 902 return Value(s);893 return jsString(s); 903 894 } 904 895 … … 920 911 921 912 // ECMA 11.4.4 and 11.4.5 922 Value 913 ValueImp *PrefixNode::evaluate(ExecState *exec) 923 914 { 924 915 Reference ref = expr->evaluateReference(exec); 925 916 KJS_CHECKEXCEPTIONVALUE 926 Value 917 ValueImp *v = ref.getValue(exec); 927 918 928 919 bool knownToBeInteger; 929 double n = v .toNumber(exec, knownToBeInteger);920 double n = v->toNumber(exec, knownToBeInteger); 930 921 931 922 double newValue = (oper == OpPlusPlus) ? n + 1 : n - 1; 932 Value n2(newValue, knownToBeInteger);923 ValueImp *n2 = jsNumber(newValue, knownToBeInteger); 933 924 934 925 ref.putValue(exec, n2); … … 954 945 955 946 // ECMA 11.4.6 956 Value 957 { 958 Value 959 KJS_CHECKEXCEPTIONVALUE 960 961 return Value(v.toNumber(exec)); /* TODO: optimize */947 ValueImp *UnaryPlusNode::evaluate(ExecState *exec) 948 { 949 ValueImp *v = expr->evaluate(exec); 950 KJS_CHECKEXCEPTIONVALUE 951 952 return jsNumber(v->toNumber(exec)); /* TODO: optimize */ 962 953 } 963 954 … … 979 970 980 971 // ECMA 11.4.7 981 Value 982 { 983 Value 972 ValueImp *NegateNode::evaluate(ExecState *exec) 973 { 974 ValueImp *v = expr->evaluate(exec); 984 975 KJS_CHECKEXCEPTIONVALUE 985 976 986 977 bool knownToBeInteger; 987 double n = v .toNumber(exec, knownToBeInteger);988 return Value(-n, knownToBeInteger && n != 0);978 double n = v->toNumber(exec, knownToBeInteger); 979 return jsNumber(-n, knownToBeInteger && n != 0); 989 980 } 990 981 … … 1006 997 1007 998 // ECMA 11.4.8 1008 Value 1009 { 1010 Value 1011 KJS_CHECKEXCEPTIONVALUE 1012 return Value(~v.toInt32(exec));999 ValueImp *BitwiseNotNode::evaluate(ExecState *exec) 1000 { 1001 ValueImp *v = expr->evaluate(exec); 1002 KJS_CHECKEXCEPTIONVALUE 1003 return jsNumber(~v->toInt32(exec)); 1013 1004 } 1014 1005 … … 1030 1021 1031 1022 // ECMA 11.4.9 1032 Value 1033 { 1034 Value 1035 KJS_CHECKEXCEPTIONVALUE 1036 return Value(!v.toBoolean(exec));1023 ValueImp *LogicalNotNode::evaluate(ExecState *exec) 1024 { 1025 ValueImp *v = expr->evaluate(exec); 1026 KJS_CHECKEXCEPTIONVALUE 1027 return jsBoolean(!v->toBoolean(exec)); 1037 1028 } 1038 1029 … … 1058 1049 1059 1050 // ECMA 11.5 1060 Value 1061 { 1062 Value 1063 KJS_CHECKEXCEPTIONVALUE 1064 1065 Value 1051 ValueImp *MultNode::evaluate(ExecState *exec) 1052 { 1053 ValueImp *v1 = term1->evaluate(exec); 1054 KJS_CHECKEXCEPTIONVALUE 1055 1056 ValueImp *v2 = term2->evaluate(exec); 1066 1057 KJS_CHECKEXCEPTIONVALUE 1067 1058 … … 1090 1081 1091 1082 // ECMA 11.6 1092 Value 1093 { 1094 Value 1095 KJS_CHECKEXCEPTIONVALUE 1096 1097 Value 1083 ValueImp *AddNode::evaluate(ExecState *exec) 1084 { 1085 ValueImp *v1 = term1->evaluate(exec); 1086 KJS_CHECKEXCEPTIONVALUE 1087 1088 ValueImp *v2 = term2->evaluate(exec); 1098 1089 KJS_CHECKEXCEPTIONVALUE 1099 1090 … … 1122 1113 1123 1114 // ECMA 11.7 1124 Value 1125 { 1126 Value 1127 KJS_CHECKEXCEPTIONVALUE 1128 Value 1129 KJS_CHECKEXCEPTIONVALUE 1130 unsigned int i2 = v2 .toUInt32(exec);1115 ValueImp *ShiftNode::evaluate(ExecState *exec) 1116 { 1117 ValueImp *v1 = term1->evaluate(exec); 1118 KJS_CHECKEXCEPTIONVALUE 1119 ValueImp *v2 = term2->evaluate(exec); 1120 KJS_CHECKEXCEPTIONVALUE 1121 unsigned int i2 = v2->toUInt32(exec); 1131 1122 i2 &= 0x1f; 1132 1123 1133 1124 switch (oper) { 1134 1125 case OpLShift: 1135 return Value(v1.toInt32(exec) << i2);1126 return jsNumber(v1->toInt32(exec) << i2); 1136 1127 case OpRShift: 1137 return Value(v1.toInt32(exec) >> i2);1128 return jsNumber(v1->toInt32(exec) >> i2); 1138 1129 case OpURShift: 1139 return Value(v1.toUInt32(exec) >> i2);1130 return jsNumber(v1->toUInt32(exec) >> i2); 1140 1131 default: 1141 1132 assert(!"ShiftNode: unhandled switch case"); … … 1165 1156 1166 1157 // ECMA 11.8 1167 Value 1168 { 1169 Value 1170 KJS_CHECKEXCEPTIONVALUE 1171 Value 1158 ValueImp *RelationalNode::evaluate(ExecState *exec) 1159 { 1160 ValueImp *v1 = expr1->evaluate(exec); 1161 KJS_CHECKEXCEPTIONVALUE 1162 ValueImp *v2 = expr2->evaluate(exec); 1172 1163 KJS_CHECKEXCEPTIONVALUE 1173 1164 … … 1187 1178 } else if (oper == OpIn) { 1188 1179 // Is all of this OK for host objects? 1189 if ( v2.type() != ObjectType)1180 if (!v2->isObject()) 1190 1181 return throwError(exec, TypeError, 1191 1182 "Value %s (result of expression %s) is not an object. Cannot be used with IN expression.", v2, expr2); 1192 Object o2(static_cast<ObjectImp*>(v2.imp()));1193 b = o2 .hasProperty(exec, Identifier(v1.toString(exec)));1183 ObjectImp *o2(static_cast<ObjectImp*>(v2)); 1184 b = o2->hasProperty(exec, Identifier(v1->toString(exec))); 1194 1185 } else { 1195 if ( v2.type() != ObjectType)1186 if (!v2->isObject()) 1196 1187 return throwError(exec, TypeError, 1197 1188 "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, expr2); 1198 1189 1199 Object o2(static_cast<ObjectImp*>(v2.imp()));1200 if (!o2 .implementsHasInstance()) {1201 // According to the spec, only some types of objects "im lement" the [[HasInstance]] property.1190 ObjectImp *o2(static_cast<ObjectImp*>(v2)); 1191 if (!o2->implementsHasInstance()) { 1192 // According to the spec, only some types of objects "implement" the [[HasInstance]] property. 1202 1193 // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]] 1203 1194 // property. It seems that all object have the property, but not all implement it, so in this 1204 1195 // case we return false (consistent with mozilla) 1205 return Value(false);1196 return jsBoolean(false); 1206 1197 // return throwError(exec, TypeError, 1207 1198 // "Object does not implement the [[HasInstance]] method." ); 1208 1199 } 1209 return o2.hasInstance(exec, v1);1210 } 1211 1212 return Value(b);1200 return jsBoolean(o2->hasInstance(exec, v1)); 1201 } 1202 1203 return jsBoolean(b); 1213 1204 } 1214 1205 … … 1234 1225 1235 1226 // ECMA 11.9 1236 Value 1237 { 1238 Value 1239 KJS_CHECKEXCEPTIONVALUE 1240 Value 1227 ValueImp *EqualNode::evaluate(ExecState *exec) 1228 { 1229 ValueImp *v1 = expr1->evaluate(exec); 1230 KJS_CHECKEXCEPTIONVALUE 1231 ValueImp *v2 = expr2->evaluate(exec); 1241 1232 KJS_CHECKEXCEPTIONVALUE 1242 1233 … … 1251 1242 result = oper == OpStrEq ? eq : !eq; 1252 1243 } 1253 return Value(result);1244 return jsBoolean(result); 1254 1245 } 1255 1246 … … 1275 1266 1276 1267 // ECMA 11.10 1277 Value 1278 { 1279 Value 1280 KJS_CHECKEXCEPTIONVALUE 1281 Value 1282 KJS_CHECKEXCEPTIONVALUE 1283 int i1 = v1 .toInt32(exec);1284 int i2 = v2 .toInt32(exec);1268 ValueImp *BitOperNode::evaluate(ExecState *exec) 1269 { 1270 ValueImp *v1 = expr1->evaluate(exec); 1271 KJS_CHECKEXCEPTIONVALUE 1272 ValueImp *v2 = expr2->evaluate(exec); 1273 KJS_CHECKEXCEPTIONVALUE 1274 int i1 = v1->toInt32(exec); 1275 int i2 = v2->toInt32(exec); 1285 1276 int result; 1286 1277 if (oper == OpBitAnd) … … 1291 1282 result = i1 | i2; 1292 1283 1293 return Value(result);1284 return jsNumber(result); 1294 1285 } 1295 1286 … … 1315 1306 1316 1307 // ECMA 11.11 1317 Value 1318 { 1319 Value 1320 KJS_CHECKEXCEPTIONVALUE 1321 bool b1 = v1 .toBoolean(exec);1308 ValueImp *BinaryLogicalNode::evaluate(ExecState *exec) 1309 { 1310 ValueImp *v1 = expr1->evaluate(exec); 1311 KJS_CHECKEXCEPTIONVALUE 1312 bool b1 = v1->toBoolean(exec); 1322 1313 if ((!b1 && oper == OpAnd) || (b1 && oper == OpOr)) 1323 1314 return v1; 1324 1315 1325 Value 1316 ValueImp *v2 = expr2->evaluate(exec); 1326 1317 KJS_CHECKEXCEPTIONVALUE 1327 1318 … … 1354 1345 1355 1346 // ECMA 11.12 1356 Value 1357 { 1358 Value 1359 KJS_CHECKEXCEPTIONVALUE 1360 bool b = v .toBoolean(exec);1347 ValueImp *ConditionalNode::evaluate(ExecState *exec) 1348 { 1349 ValueImp *v = logical->evaluate(exec); 1350 KJS_CHECKEXCEPTIONVALUE 1351 bool b = v->toBoolean(exec); 1361 1352 1362 1353 if (b) … … 1390 1381 1391 1382 // ECMA 11.13 1392 Value 1383 ValueImp *AssignNode::evaluate(ExecState *exec) 1393 1384 { 1394 1385 Reference l = left->evaluateReference(exec); 1395 1386 KJS_CHECKEXCEPTIONVALUE 1396 Value e,v;1387 ValueImp *v; 1397 1388 if (oper == OpEqual) { 1398 1389 v = expr->evaluate(exec); 1399 1390 KJS_CHECKEXCEPTIONVALUE 1400 1391 } else { 1401 Value 1402 Value 1392 ValueImp *v1 = l.getValue(exec); 1393 ValueImp *v2 = expr->evaluate(exec); 1403 1394 KJS_CHECKEXCEPTIONVALUE 1404 1395 int i1; … … 1419 1410 break; 1420 1411 case OpLShift: 1421 i1 = v1 .toInt32(exec);1422 i2 = v2 .toInt32(exec);1423 v = Value(i1 << i2);1412 i1 = v1->toInt32(exec); 1413 i2 = v2->toInt32(exec); 1414 v = jsNumber(i1 << i2); 1424 1415 break; 1425 1416 case OpRShift: 1426 i1 = v1 .toInt32(exec);1427 i2 = v2 .toInt32(exec);1428 v = Value(i1 >> i2);1417 i1 = v1->toInt32(exec); 1418 i2 = v2->toInt32(exec); 1419 v = jsNumber(i1 >> i2); 1429 1420 break; 1430 1421 case OpURShift: 1431 ui = v1 .toUInt32(exec);1432 i2 = v2 .toInt32(exec);1433 v = Value(ui >> i2);1422 ui = v1->toUInt32(exec); 1423 i2 = v2->toInt32(exec); 1424 v = jsNumber(ui >> i2); 1434 1425 break; 1435 1426 case OpAndEq: 1436 i1 = v1 .toInt32(exec);1437 i2 = v2 .toInt32(exec);1438 v = Value(i1 & i2);1427 i1 = v1->toInt32(exec); 1428 i2 = v2->toInt32(exec); 1429 v = jsNumber(i1 & i2); 1439 1430 break; 1440 1431 case OpXOrEq: 1441 i1 = v1 .toInt32(exec);1442 i2 = v2 .toInt32(exec);1443 v = Value(i1 ^ i2);1432 i1 = v1->toInt32(exec); 1433 i2 = v2->toInt32(exec); 1434 v = jsNumber(i1 ^ i2); 1444 1435 break; 1445 1436 case OpOrEq: 1446 i1 = v1 .toInt32(exec);1447 i2 = v2 .toInt32(exec);1448 v = Value(i1 | i2);1437 i1 = v1->toInt32(exec); 1438 i2 = v2->toInt32(exec); 1439 v = jsNumber(i1 | i2); 1449 1440 break; 1450 1441 case OpModEq: { 1451 1442 bool d1KnownToBeInteger; 1452 double d1 = v1 .toNumber(exec, d1KnownToBeInteger);1443 double d1 = v1->toNumber(exec, d1KnownToBeInteger); 1453 1444 bool d2KnownToBeInteger; 1454 double d2 = v2 .toNumber(exec, d2KnownToBeInteger);1455 v = Value(fmod(d1, d2), d1KnownToBeInteger && d2KnownToBeInteger && d2 != 0);1445 double d2 = v2->toNumber(exec, d2KnownToBeInteger); 1446 v = jsNumber(fmod(d1, d2), d1KnownToBeInteger && d2KnownToBeInteger && d2 != 0); 1456 1447 } 1457 1448 break; … … 1488 1479 1489 1480 // ECMA 11.14 1490 Value 1491 { 1492 Value dummy =expr1->evaluate(exec);1493 KJS_CHECKEXCEPTIONVALUE 1494 Value 1481 ValueImp *CommaNode::evaluate(ExecState *exec) 1482 { 1483 expr1->evaluate(exec); 1484 KJS_CHECKEXCEPTIONVALUE 1485 ValueImp *v = expr2->evaluate(exec); 1495 1486 KJS_CHECKEXCEPTIONVALUE 1496 1487 … … 1541 1532 KJS_ABORTPOINT 1542 1533 if (exec->hadException()) { 1543 Value 1534 ValueImp *ex = exec->exception(); 1544 1535 exec->clearException(); 1545 1536 return Completion(Throw, ex); … … 1549 1540 return c; 1550 1541 1551 Value 1542 ValueImp *v = c.value(); 1552 1543 1553 1544 for (StatListNode *n = list; n; n = n->list) { … … 1558 1549 1559 1550 if (exec->hadException()) { 1560 Value 1551 ValueImp *ex = exec->exception(); 1561 1552 exec->clearException(); 1562 1553 return Completion(Throw, ex); … … 1594 1585 1595 1586 // ECMA 12.2 1596 Value 1587 ValueImp *AssignExprNode::evaluate(ExecState *exec) 1597 1588 { 1598 1589 return expr->evaluate(exec); … … 1622 1613 1623 1614 // ECMA 12.2 1624 Value 1625 { 1626 Object 1627 1628 Value 1615 ValueImp *VarDeclNode::evaluate(ExecState *exec) 1616 { 1617 ObjectImp *variable = exec->context().imp()->variableObject(); 1618 1619 ValueImp *val; 1629 1620 if (init) { 1630 1621 val = init->evaluate(exec); … … 1633 1624 // already declared? - check with getDirect so you can override 1634 1625 // built-in properties of the global object with var declarations. 1635 if ( variable.imp()->getDirect(ident))1636 return Value();1626 if (variable->getDirect(ident)) 1627 return NULL; 1637 1628 val = Undefined(); 1638 1629 } … … 1648 1639 if (varType == VarDeclNode::Constant) 1649 1640 flags |= ReadOnly; 1650 variable .put(exec, ident, val, flags);1651 1652 return ident.ustring();1641 variable->put(exec, ident, val, flags); 1642 1643 return jsString(ident.ustring()); 1653 1644 } 1654 1645 1655 1646 void VarDeclNode::processVarDecls(ExecState *exec) 1656 1647 { 1657 Object 1648 ObjectImp *variable = exec->context().imp()->variableObject(); 1658 1649 1659 1650 // If a variable by this name already exists, don't clobber it - 1660 1651 // it might be a function parameter 1661 if (!variable .hasProperty(exec, ident)) {1652 if (!variable->hasProperty(exec, ident)) { 1662 1653 int flags = Internal; 1663 1654 if (exec->context().imp()->codeType() != EvalCode) … … 1665 1656 if (varType == VarDeclNode::Constant) 1666 1657 flags |= ReadOnly; 1667 variable .put(exec, ident, Undefined(), flags);1658 variable->put(exec, ident, Undefined(), flags); 1668 1659 } 1669 1660 } … … 1695 1686 1696 1687 // ECMA 12.2 1697 Value 1688 ValueImp *VarDeclListNode::evaluate(ExecState *exec) 1698 1689 { 1699 1690 for (VarDeclListNode *n = this; n; n = n->list) { … … 1815 1806 KJS_BREAKPOINT; 1816 1807 1817 Value 1808 ValueImp *v = expr->evaluate(exec); 1818 1809 KJS_CHECKEXCEPTION 1819 1810 … … 1850 1841 KJS_BREAKPOINT; 1851 1842 1852 Value 1843 ValueImp *v = expr->evaluate(exec); 1853 1844 KJS_CHECKEXCEPTION 1854 bool b = v .toBoolean(exec);1845 bool b = v->toBoolean(exec); 1855 1846 1856 1847 // if ... then … … 1899 1890 KJS_BREAKPOINT; 1900 1891 1901 Value be,bv;1892 ValueImp *bv; 1902 1893 Completion c; 1903 Value value;1904 1894 1905 1895 do { … … 1912 1902 if (!((c.complType() == Continue) && ls.contains(c.target()))) { 1913 1903 if ((c.complType() == Break) && ls.contains(c.target())) 1914 return Completion(Normal, value);1904 return Completion(Normal, NULL); 1915 1905 if (c.complType() != Normal) 1916 1906 return c; … … 1918 1908 bv = expr->evaluate(exec); 1919 1909 KJS_CHECKEXCEPTION 1920 } while (bv .toBoolean(exec));1921 1922 return Completion(Normal, value);1910 } while (bv->toBoolean(exec)); 1911 1912 return Completion(Normal, NULL); 1923 1913 } 1924 1914 … … 1953 1943 KJS_BREAKPOINT; 1954 1944 1955 Value be,bv;1945 ValueImp *bv; 1956 1946 Completion c; 1957 1947 bool b(false); 1958 Value value;1948 ValueImp *value = NULL; 1959 1949 1960 1950 while (1) { 1961 1951 bv = expr->evaluate(exec); 1962 1952 KJS_CHECKEXCEPTION 1963 b = bv .toBoolean(exec);1953 b = bv->toBoolean(exec); 1964 1954 1965 1955 // bail out on error … … 2022 2012 Completion ForNode::execute(ExecState *exec) 2023 2013 { 2024 Value v, cval;2014 ValueImp *v, *cval = NULL; 2025 2015 2026 2016 if (expr1) { … … 2032 2022 v = expr2->evaluate(exec); 2033 2023 KJS_CHECKEXCEPTION 2034 if (!v .toBoolean(exec))2024 if (!v->toBoolean(exec)) 2035 2025 return Completion(Normal, cval); 2036 2026 } … … 2114 2104 Completion ForInNode::execute(ExecState *exec) 2115 2105 { 2116 Value e, retval; 2117 Object v; 2106 ValueImp *e; 2107 ValueImp *retval = NULL; 2108 ObjectImp *v; 2118 2109 Completion c; 2119 2110 ReferenceList propList; … … 2130 2121 // property list but will throw an exception if you attempt to 2131 2122 // access any property. 2132 if (e .type() == UndefinedType || e.type() == NullType) {2133 return Completion(Normal, retval);2123 if (e->isUndefinedOrNull()) { 2124 return Completion(Normal, NULL); 2134 2125 } 2135 2126 2136 2127 KJS_CHECKEXCEPTION 2137 v = e .toObject(exec);2138 propList = v .propList(exec);2128 v = e->toObject(exec); 2129 propList = v->propList(exec); 2139 2130 2140 2131 ReferenceListIterator propIt = propList.begin(); … … 2142 2133 while (propIt != propList.end()) { 2143 2134 Identifier name = propIt->getPropertyName(exec); 2144 if (!v .hasProperty(exec,name)) {2135 if (!v->hasProperty(exec,name)) { 2145 2136 propIt++; 2146 2137 continue; … … 2186 2177 KJS_BREAKPOINT; 2187 2178 2188 Value dummy;2189 2190 2179 if (ident.isEmpty() && !exec->context().imp()->seenLabels()->inIteration()) 2191 2180 return Completion(Throw, … … 2195 2184 throwError(exec, SyntaxError, "Label %s not found.", ident)); 2196 2185 else 2197 return Completion(Continue, dummy, ident);2186 return Completion(Continue, NULL, ident); 2198 2187 } 2199 2188 … … 2204 2193 { 2205 2194 KJS_BREAKPOINT; 2206 2207 Value dummy;2208 2195 2209 2196 if (ident.isEmpty() && !exec->context().imp()->seenLabels()->inIteration() && … … 2215 2202 throwError(exec, SyntaxError, "Label %s not found.", ident)); 2216 2203 else 2217 return Completion(Break, dummy, ident);2204 return Completion(Break, NULL, ident); 2218 2205 } 2219 2206 … … 2247 2234 return Completion(ReturnValue, Undefined()); 2248 2235 2249 Value 2236 ValueImp *v = value->evaluate(exec); 2250 2237 KJS_CHECKEXCEPTION 2251 2238 … … 2278 2265 KJS_BREAKPOINT; 2279 2266 2280 Value 2267 ValueImp *v = expr->evaluate(exec); 2281 2268 KJS_CHECKEXCEPTION 2282 Object o = v.toObject(exec);2269 ObjectImp *o = v->toObject(exec); 2283 2270 KJS_CHECKEXCEPTION 2284 2271 exec->context().imp()->pushScope(o); … … 2315 2302 2316 2303 // ECMA 12.11 2317 Value 2318 { 2319 Value 2304 ValueImp *CaseClauseNode::evaluate(ExecState *exec) 2305 { 2306 ValueImp *v = expr->evaluate(exec); 2320 2307 KJS_CHECKEXCEPTIONVALUE 2321 2308 … … 2362 2349 } 2363 2350 2364 Value 2351 ValueImp *ClauseListNode::evaluate(ExecState */*exec*/) 2365 2352 { 2366 2353 /* should never be called */ 2367 2354 assert(false); 2368 return Value();2355 return NULL; 2369 2356 } 2370 2357 … … 2421 2408 } 2422 2409 2423 Value 2410 ValueImp *CaseBlockNode::evaluate(ExecState */*exec*/) 2424 2411 { 2425 2412 /* should never be called */ 2426 2413 assert(false); 2427 return Value();2414 return NULL; 2428 2415 } 2429 2416 2430 2417 // ECMA 12.11 2431 Completion CaseBlockNode::evalBlock(ExecState *exec, const Value&input)2432 { 2433 Value 2418 Completion CaseBlockNode::evalBlock(ExecState *exec, ValueImp *input) 2419 { 2420 ValueImp *v; 2434 2421 Completion res; 2435 2422 ClauseListNode *a = list1, *b = list2; … … 2525 2512 KJS_BREAKPOINT; 2526 2513 2527 Value 2514 ValueImp *v = expr->evaluate(exec); 2528 2515 KJS_CHECKEXCEPTION 2529 2516 … … 2601 2588 KJS_BREAKPOINT; 2602 2589 2603 Value 2590 ValueImp *v = expr->evaluate(exec); 2604 2591 KJS_CHECKEXCEPTION 2605 2592 … … 2631 2618 2632 2619 // ECMA 12.14 2633 Completion CatchNode::execute(ExecState *exec, const Value &arg)2620 Completion CatchNode::execute(ExecState *exec, ValueImp *arg) 2634 2621 { 2635 2622 /* TODO: correct ? Not part of the spec */ … … 2637 2624 exec->clearException(); 2638 2625 2639 Object 2640 obj .put(exec, ident, arg, DontDelete);2626 ObjectImp *obj(new ObjectImp()); 2627 obj->put(exec, ident, arg, DontDelete); 2641 2628 exec->context().imp()->pushScope(obj); 2642 2629 Completion c = block->execute(exec); … … 2718 2705 2719 2706 if (!_catch) { 2720 Value 2707 ValueImp *lastException = exec->exception(); 2721 2708 exec->clearException(); 2722 2709 … … 2765 2752 2766 2753 // ECMA 13 2767 Value 2754 ValueImp *ParameterNode::evaluate(ExecState */*exec*/) 2768 2755 { 2769 2756 return Undefined(); … … 2808 2795 void FuncDeclNode::processFuncDecl(ExecState *exec) 2809 2796 { 2797 ContextImp *context = exec->context().imp(); 2798 2810 2799 // TODO: let this be an object with [[Class]] property "Function" 2811 FunctionImp *fimp = new DeclaredFunctionImp(exec, ident, body, exec->context().imp()->scopeChain()); 2812 Object func(fimp); // protect from GC 2813 2814 // Value proto = exec->lexicalInterpreter()->builtinObject().construct(exec,List::empty()); 2815 List empty; 2816 Object proto = exec->lexicalInterpreter()->builtinObject().construct(exec,empty); 2817 proto.put(exec, constructorPropertyName, func, ReadOnly|DontDelete|DontEnum); 2818 func.put(exec, prototypePropertyName, proto, Internal|DontDelete); 2800 FunctionImp *fimp = new DeclaredFunctionImp(exec, ident, body, context->scopeChain()); 2801 ObjectImp *func(fimp); // protect from GC 2802 2803 ObjectImp *proto = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty()); 2804 proto->put(exec, constructorPropertyName, func, ReadOnly|DontDelete|DontEnum); 2805 func->put(exec, prototypePropertyName, proto, Internal|DontDelete); 2819 2806 2820 2807 int plen = 0; … … 2822 2809 fimp->addParameter(p->ident()); 2823 2810 2824 func.put(exec, lengthPropertyName, Number(plen), ReadOnly|DontDelete|DontEnum); 2825 2826 if (exec->context().imp()->codeType() == EvalCode) { 2827 // ECMA 10.2.2 2828 exec->context().imp()->variableObject().put(exec, ident, func, Internal); 2829 } else { 2830 exec->context().imp()->variableObject().put(exec, ident, func, Internal | DontDelete); 2831 } 2811 func->put(exec, lengthPropertyName, Number(plen), ReadOnly|DontDelete|DontEnum); 2812 2813 // ECMA 10.2.2 2814 context->variableObject()->put(exec, ident, func, Internal | (context->codeType() == EvalCode ? 0 : DontDelete)); 2832 2815 2833 2816 if (body) { 2834 2817 // hack the scope so that the function gets put as a property of func, and it's scope 2835 2818 // contains the func as well as our current scope 2836 Object oldVar = exec->context().imp()->variableObject();2837 exec->context().imp()->setVariableObject(func);2838 exec->context().imp()->pushScope(func);2819 ObjectImp *oldVar = context->variableObject(); 2820 context->setVariableObject(func); 2821 context->pushScope(func); 2839 2822 body->processFuncDecl(exec); 2840 exec->context().imp()->popScope();2841 exec->context().imp()->setVariableObject(oldVar);2823 context->popScope(); 2824 context->setVariableObject(oldVar); 2842 2825 } 2843 2826 } … … 2865 2848 2866 2849 // ECMA 13 2867 Value 2850 ValueImp *FuncExprNode::evaluate(ExecState *exec) 2868 2851 { 2869 2852 FunctionImp *fimp = new DeclaredFunctionImp(exec, Identifier::null(), body, exec->context().imp()->scopeChain()); 2870 Value ret(fimp); 2871 List empty; 2872 Value proto = exec->lexicalInterpreter()->builtinObject().construct(exec,empty); 2853 ValueImp *ret(fimp); 2854 ValueImp *proto = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty()); 2873 2855 fimp->put(exec, prototypePropertyName, proto, Internal|DontDelete); 2874 2856 … … 2933 2915 // The spec says to return c2 here, but it seems that mozilla returns c1 if 2934 2916 // c2 doesn't have a value 2935 if ( !c2.value().isNull())2917 if (c2.value()) 2936 2918 c1 = c2; 2937 2919 }
Note:
See TracChangeset
for help on using the changeset viewer.