Changeset 10084 in webkit for trunk/JavaScriptCore/kjs/string_object.cpp
- Timestamp:
- Aug 7, 2005, 9:07:46 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/string_object.cpp
r10076 r10084 51 51 } 52 52 53 Value 54 { 55 return Value(static_cast<StringInstanceImp *>(slot.slotBase())->internalValue().toString(exec).size());56 } 57 58 Value 59 { 60 const UChar c = static_cast<StringInstanceImp *>(slot.slotBase())->internalValue() .toString(exec)[slot.index()];61 return Value(UString(&c, 1));53 ValueImp *StringInstanceImp::lengthGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot &slot) 54 { 55 return jsNumber(static_cast<StringInstanceImp *>(slot.slotBase())->internalValue()->toString(exec).size()); 56 } 57 58 ValueImp *StringInstanceImp::indexGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot &slot) 59 { 60 const UChar c = static_cast<StringInstanceImp *>(slot.slotBase())->internalValue()->toString(exec)[slot.index()]; 61 return jsString(UString(&c, 1)); 62 62 } 63 63 … … 72 72 const unsigned index = propertyName.toArrayIndex(&ok); 73 73 if (ok) { 74 const UString s = internalValue() .toString(exec);74 const UString s = internalValue()->toString(exec); 75 75 const unsigned length = s.size(); 76 76 if (index >= length) … … 83 83 } 84 84 85 void StringInstanceImp::put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr)85 void StringInstanceImp::put(ExecState *exec, const Identifier &propertyName, ValueImp *value, int attr) 86 86 { 87 87 if (propertyName == lengthPropertyName) … … 143 143 : StringInstanceImp(objProto) 144 144 { 145 Value protect(this);146 145 // The constructor will be added later, after StringObjectImp has been built 147 putDirect(lengthPropertyName, NumberImp::zero(), DontDelete|ReadOnly|DontEnum); 148 146 putDirect(lengthPropertyName, jsZero(), DontDelete|ReadOnly|DontEnum); 149 147 } 150 148 … … 158 156 StringProtoFuncImp::StringProtoFuncImp(ExecState *exec, int i, int len) 159 157 : InternalFunctionImp( 160 static_cast<FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype() .imp())158 static_cast<FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype()) 161 159 ), id(i) 162 160 { 163 Value protect(this);164 161 putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum); 165 162 } … … 172 169 static inline bool regExpIsGlobal(RegExpImp *regExp, ExecState *exec) 173 170 { 174 Value 175 return globalProperty.type() != UndefinedType && globalProperty.toBoolean(exec);171 ValueImp *globalProperty = regExp->get(exec,"global"); 172 return !globalProperty->isUndefined() && globalProperty->toBoolean(exec); 176 173 } 177 174 … … 260 257 } 261 258 262 static Value replace(ExecState *exec, const UString &source, const Value &pattern, const Value &replacement)259 static ValueImp *replace(ExecState *exec, const UString &source, ValueImp *pattern, ValueImp *replacement) 263 260 { 264 261 ObjectImp *replacementFunction = 0; 265 262 UString replacementString; 266 263 267 if (replacement .type() == ObjectType && replacement.toObject(exec).implementsCall())268 replacementFunction = replacement .toObject(exec).imp();264 if (replacement->isObject() && replacement->toObject(exec)->implementsCall()) 265 replacementFunction = replacement->toObject(exec); 269 266 else 270 replacementString = replacement .toString(exec);271 272 if (pattern .type() == ObjectType && pattern.toObject(exec).inherits(&RegExpImp::info)) {273 RegExpImp* imp = static_cast<RegExpImp *>( pattern .toObject(exec).imp() );267 replacementString = replacement->toString(exec); 268 269 if (pattern->isObject() && pattern->toObject(exec)->inherits(&RegExpImp::info)) { 270 RegExpImp* imp = static_cast<RegExpImp *>( pattern->toObject(exec) ); 274 271 RegExp *reg = imp->regExp(); 275 272 bool global = regExpIsGlobal(imp, exec); 276 273 277 RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp() .imp());274 RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp()); 278 275 279 276 int matchIndex = 0; … … 303 300 List args; 304 301 305 args.append( Value(matchString));302 args.append(jsString(matchString)); 306 303 307 304 for (unsigned i = 0; i < reg->subPatterns(); i++) { … … 309 306 int matchLen = (*ovector)[(i + 1) * 2 + 1] - matchStart; 310 307 311 args.append( Value(source.substr(matchStart, matchLen)));308 args.append(jsString(source.substr(matchStart, matchLen))); 312 309 } 313 310 314 args.append( Value(completeMatchStart));315 args.append( Value(source));311 args.append(jsNumber(completeMatchStart)); 312 args.append(jsString(source)); 316 313 317 314 replacementString = replacementFunction->call(exec, exec->dynamicInterpreter()->globalObject(), 318 args) .toString(exec);315 args)->toString(exec); 319 316 } 320 317 … … 345 342 346 343 // First arg is a string 347 UString patternString = pattern .toString(exec);344 UString patternString = pattern->toString(exec); 348 345 int matchPos = source.find(patternString); 349 346 int matchLen = patternString.size(); … … 355 352 List args; 356 353 357 args.append( Value(source.substr(matchPos, matchLen)));358 args.append( Value(matchPos));359 args.append( Value(source));354 args.append(jsString(source.substr(matchPos, matchLen))); 355 args.append(jsNumber(matchPos)); 356 args.append(jsString(source)); 360 357 361 358 replacementString = replacementFunction->call(exec, exec->dynamicInterpreter()->globalObject(), 362 args) .toString(exec);359 args)->toString(exec); 363 360 } 364 361 … … 367 364 368 365 // ECMA 15.5.4.2 - 15.5.4.20 369 Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)370 { 371 Value result;366 ValueImp *StringProtoFuncImp::callAsFunction(ExecState *exec, ObjectImp *thisObj, const List &args) 367 { 368 ValueImp *result = NULL; 372 369 373 370 // toString and valueOf are no generic function. 374 371 if (id == ToString || id == ValueOf) { 375 if ( thisObj.isNull() || !thisObj.inherits(&StringInstanceImp::info)) {376 Object 372 if (!thisObj || !thisObj->inherits(&StringInstanceImp::info)) { 373 ObjectImp *err = Error::create(exec,TypeError); 377 374 exec->setException(err); 378 375 return err; 379 376 } 380 377 381 return String(thisObj .internalValue().toString(exec));378 return String(thisObj->internalValue()->toString(exec)); 382 379 } 383 380 … … 387 384 double d = 0.0; 388 385 389 UString s = thisObj .toString(exec);386 UString s = thisObj->toString(exec); 390 387 391 388 int len = s.size(); 392 Value 393 Value 389 ValueImp *a0 = args[0]; 390 ValueImp *a1 = args[1]; 394 391 395 392 switch (id) { … … 401 398 // Other browsers treat an omitted parameter as 0 rather than NaN. 402 399 // That doesn't match the ECMA standard, but is needed for site compatibility. 403 dpos = a0 .isA(UndefinedType) ? 0 : a0.toInteger(exec);400 dpos = a0->isUndefined() ? 0 : a0->toInteger(exec); 404 401 if (dpos >= 0 && dpos < len) // false for NaN 405 402 u = s.substr(static_cast<int>(dpos), 1); … … 411 408 // Other browsers treat an omitted parameter as 0 rather than NaN. 412 409 // That doesn't match the ECMA standard, but is needed for site compatibility. 413 dpos = a0 .isA(UndefinedType) ? 0 : a0.toInteger(exec);410 dpos = a0->isUndefined() ? 0 : a0->toInteger(exec); 414 411 if (dpos >= 0 && dpos < len) // false for NaN 415 412 result = Number(s[static_cast<int>(dpos)].unicode()); 416 413 else 417 result = Number(NaN);414 result = jsNaN(); 418 415 break; 419 416 case Concat: { 420 417 ListIterator it = args.begin(); 421 418 for ( ; it != args.end() ; ++it) { 422 s += it-> dispatchToString(exec);419 s += it->toString(exec); 423 420 } 424 421 result = String(s); … … 426 423 } 427 424 case IndexOf: 428 u2 = a0 .toString(exec);429 if (a1 .type() == UndefinedType)425 u2 = a0->toString(exec); 426 if (a1->isUndefined()) 430 427 dpos = 0; 431 428 else { 432 dpos = a1 .toInteger(exec);429 dpos = a1->toInteger(exec); 433 430 if (dpos >= 0) { // false for NaN 434 431 if (dpos > len) … … 440 437 break; 441 438 case LastIndexOf: 442 u2 = a0 .toString(exec);443 d = a1 .toNumber(exec);444 if (a1 .type() == UndefinedType|| KJS::isNaN(d))439 u2 = a0->toString(exec); 440 d = a1->toNumber(exec); 441 if (a1->isUndefined() || KJS::isNaN(d)) 445 442 dpos = len; 446 443 else { 447 dpos = a1 .toInteger(exec);444 dpos = a1->toInteger(exec); 448 445 if (dpos >= 0) { // false for NaN 449 446 if (dpos > len) … … 459 456 RegExp *reg, *tmpReg = 0; 460 457 RegExpImp *imp = 0; 461 if (a0 .isA(ObjectType) && a0.toObject(exec).inherits(&RegExpImp::info))458 if (a0->isObject() && a0->getObject()->inherits(&RegExpImp::info)) 462 459 { 463 imp = static_cast<RegExpImp *>( a0.toObject(exec).imp());460 imp = static_cast<RegExpImp *>(a0); 464 461 reg = imp->regExp(); 465 462 } … … 470 467 * replaced with the result of the expression new RegExp(regexp). 471 468 */ 472 reg = tmpReg = new RegExp(a0 .toString(exec), RegExp::None);473 } 474 RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp() .imp());469 reg = tmpReg = new RegExp(a0->toString(exec), RegExp::None); 470 } 471 RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp()); 475 472 int **ovector = regExpObj->registerRegexp(reg, u); 476 473 UString mstr = reg->match(u, -1, &pos, ovector); … … 493 490 while (pos >= 0) { 494 491 if (mstr.isNull()) 495 list.append( UndefinedImp::staticUndefined);492 list.append(jsUndefined()); 496 493 else 497 494 list.append(String(mstr)); … … 509 506 result = Null(); 510 507 } else { 511 result = exec->lexicalInterpreter()->builtinArray() .construct(exec, list);508 result = exec->lexicalInterpreter()->builtinArray()->construct(exec, list); 512 509 } 513 510 } … … 522 519 { 523 520 // The arg processing is very much like ArrayProtoFunc::Slice 524 double begin = args[0] .toInteger(exec);521 double begin = args[0]->toInteger(exec); 525 522 if (begin >= 0) { // false for NaN 526 523 if (begin > len) … … 532 529 } 533 530 double end = len; 534 if ( args[1].type() != UndefinedType) {535 end = args[1] .toInteger(exec);531 if (!args[1]->isUndefined()) { 532 end = args[1]->toInteger(exec); 536 533 if (end >= 0) { // false for NaN 537 534 if (end > len) … … 548 545 } 549 546 case Split: { 550 Object 551 Object res = Object::dynamicCast(constructor.construct(exec,List::empty()));547 ObjectImp *constructor = exec->lexicalInterpreter()->builtinArray(); 548 ObjectImp *res = static_cast<ObjectImp *>(constructor->construct(exec,List::empty())); 552 549 result = res; 553 550 u = s; 554 551 i = p0 = 0; 555 uint32_t limit = a1 .type() == UndefinedType ? 0xFFFFFFFFU : a1.toUInt32(exec);556 if (a0 .type() == ObjectType && Object::dynamicCast(a0).inherits(&RegExpImp::info)) {557 Object obj0 = Object::dynamicCast(a0);558 RegExp reg(obj0 .get(exec,"source").toString(exec));552 uint32_t limit = a1->isUndefined() ? 0xFFFFFFFFU : a1->toUInt32(exec); 553 if (a0->isObject() && static_cast<ObjectImp *>(a0)->inherits(&RegExpImp::info)) { 554 ObjectImp *obj0 = static_cast<ObjectImp *>(a0); 555 RegExp reg(obj0->get(exec,"source")->toString(exec)); 559 556 if (u.isEmpty() && !reg.match(u, 0).isNull()) { 560 557 // empty string matched by regexp -> empty array 561 res .put(exec,lengthPropertyName, Number(0));558 res->put(exec,lengthPropertyName, Number(0)); 562 559 break; 563 560 } … … 573 570 pos = mpos + (mstr.isEmpty() ? 1 : mstr.size()); 574 571 if (mpos != p0 || !mstr.isEmpty()) { 575 res .put(exec,i, String(u.substr(p0, mpos-p0)));572 res->put(exec,i, String(u.substr(p0, mpos-p0))); 576 573 p0 = mpos + mstr.size(); 577 574 i++; … … 579 576 } 580 577 } else { 581 u2 = a0 .toString(exec);578 u2 = a0->toString(exec); 582 579 if (u2.isEmpty()) { 583 580 if (u.isEmpty()) { … … 587 584 } else { 588 585 while (static_cast<uint32_t>(i) != limit && i < u.size()-1) 589 res .put(exec, i++, String(u.substr(p0++, 1)));586 res->put(exec, i++, String(u.substr(p0++, 1))); 590 587 } 591 588 } else { 592 589 while (static_cast<uint32_t>(i) != limit && (pos = u.find(u2, p0)) >= 0) { 593 res .put(exec, i, String(u.substr(p0, pos-p0)));590 res->put(exec, i, String(u.substr(p0, pos-p0))); 594 591 p0 = pos + u2.size(); 595 592 i++; … … 599 596 // add remaining string, if any 600 597 if (static_cast<uint32_t>(i) != limit) 601 res .put(exec, i++, String(u.substr(p0)));602 res .put(exec,lengthPropertyName, Number(i));598 res->put(exec, i++, String(u.substr(p0))); 599 res->put(exec,lengthPropertyName, Number(i)); 603 600 } 604 601 break; 605 602 case Substr: { 606 double d = a0 .toInteger(exec);607 double d2 = a1 .toInteger(exec);603 double d = a0->toInteger(exec); 604 double d2 = a1->toInteger(exec); 608 605 if (!(d >= 0)) { // true for NaN 609 606 d += len; … … 623 620 } 624 621 case Substring: { 625 double start = a0 .toNumber(exec);626 double end = a1 .toNumber(exec);622 double start = a0->toNumber(exec); 623 double end = a1->toNumber(exec); 627 624 if (KJS::isNaN(start)) 628 625 start = 0; … … 637 634 if (end > len) 638 635 end = len; 639 if (a1 .type() == UndefinedType)636 if (a1->isUndefined()) 640 637 end = len; 641 638 if (start > end) { … … 690 687 break; 691 688 case Fontcolor: 692 result = String("<font color=\"" + a0 .toString(exec) + "\">" + s + "</font>");689 result = String("<font color=\"" + a0->toString(exec) + "\">" + s + "</font>"); 693 690 break; 694 691 case Fontsize: 695 result = String("<font size=\"" + a0 .toString(exec) + "\">" + s + "</font>");692 result = String("<font size=\"" + a0->toString(exec) + "\">" + s + "</font>"); 696 693 break; 697 694 case Anchor: 698 result = String("<a name=\"" + a0 .toString(exec) + "\">" + s + "</a>");695 result = String("<a name=\"" + a0->toString(exec) + "\">" + s + "</a>"); 699 696 break; 700 697 case Link: 701 result = String("<a href=\"" + a0 .toString(exec) + "\">" + s + "</a>");698 result = String("<a href=\"" + a0->toString(exec) + "\">" + s + "</a>"); 702 699 break; 703 700 #endif … … 714 711 : InternalFunctionImp(funcProto) 715 712 { 716 Value protect(this);717 713 // ECMA 15.5.3.1 String.prototype 718 714 putDirect(prototypePropertyName, stringProto, DontEnum|DontDelete|ReadOnly); … … 722 718 723 719 // no. of arguments for constructor 724 putDirect(lengthPropertyName, NumberImp::one(), ReadOnly|DontDelete|DontEnum);720 putDirect(lengthPropertyName, jsOne(), ReadOnly|DontDelete|DontEnum); 725 721 } 726 722 … … 732 728 733 729 // ECMA 15.5.2 734 Object 735 { 736 ObjectImp *proto = exec->lexicalInterpreter()->builtinStringPrototype() .imp();730 ObjectImp *StringObjectImp::construct(ExecState *exec, const List &args) 731 { 732 ObjectImp *proto = exec->lexicalInterpreter()->builtinStringPrototype(); 737 733 if (args.size() == 0) 738 return Object(new StringInstanceImp(proto));739 return Object(new StringInstanceImp(proto, args.begin()->dispatchToString(exec)));734 return new StringInstanceImp(proto); 735 return new StringInstanceImp(proto, args.begin()->toString(exec)); 740 736 } 741 737 … … 746 742 747 743 // ECMA 15.5.1 748 Value StringObjectImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)744 ValueImp *StringObjectImp::callAsFunction(ExecState *exec, ObjectImp */*thisObj*/, const List &args) 749 745 { 750 746 if (args.isEmpty()) 751 747 return String(""); 752 748 else { 753 Value 754 return String(v .toString(exec));749 ValueImp *v = args[0]; 750 return String(v->toString(exec)); 755 751 } 756 752 } … … 762 758 : InternalFunctionImp(funcProto) 763 759 { 764 Value protect(this); 765 putDirect(lengthPropertyName, NumberImp::one(), DontDelete|ReadOnly|DontEnum); 760 putDirect(lengthPropertyName, jsOne(), DontDelete|ReadOnly|DontEnum); 766 761 } 767 762 … … 771 766 } 772 767 773 Value StringObjectFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)768 ValueImp *StringObjectFuncImp::callAsFunction(ExecState *exec, ObjectImp */*thisObj*/, const List &args) 774 769 { 775 770 UString s;
Note:
See TracChangeset
for help on using the changeset viewer.