Changeset 1799 in webkit for trunk/JavaScriptCore/kjs/value.cpp


Ignore:
Timestamp:
Aug 12, 2002, 1:14:02 PM (23 years ago)
Author:
darin
Message:

top level:

  • Tests/WebFoundation-Misc/ifnsurlextensions-test.m: (TestURLCommon): Add tests for the new WebNSURLExtras methods.
  • Tests/libiftest/IFCheckLeaks.c: (IFCheckLeaksAtExit): Remove workaround for CFPreferences race condition; it's now in WebFoundation.

JavaScriptCore:

Speed improvements. 19% faster on cvs-js-performance, 1% on cvs-static-urls.

Use global string objects for length and other common property names rather
than constantly making and destroying them. Use integer versions of get() and
other related calls rather than always making a string.

Also get rid of many unneeded constructors, destructors, copy constructors, and
assignment operators. And make some functions non-virtual.

  • kjs/internal.h:
  • kjs/internal.cpp: (NumberImp::toUInt32): Implement. (ReferenceImp::ReferenceImp): Special case for numeric property names. (ReferenceImp::getPropertyName): Moved guts here from ValueImp. Handle numeric case. (ReferenceImp::getValue): Moved guts here from ValueImp. Handle numeric case. (ReferenceImp::putValue): Moved guts here from ValueImp. Handle numeric case. (ReferenceImp::deleteValue): Added. Handle numeric case.
  • kjs/array_object.h:
  • kjs/array_object.cpp: All-new array implementation that stores the elements in a C++ array rather than in a property map. (ArrayInstanceImp::ArrayInstanceImp): Allocate the C++ array. (ArrayInstanceImp::~ArrayInstanceImp): Delete the C++ array. (ArrayInstanceImp::get): Implement both the old version and the new overload that takes an unsigned index for speed. (ArrayInstanceImp::put): Implement both the old version and the new overload that takes an unsigned index for speed. (ArrayInstanceImp::hasProperty): Implement both the old version and the new overload that takes an unsigned index for speed. (ArrayInstanceImp::deleteProperty): Implement both the old version and the new overload that takes an unsigned index for speed. (ArrayInstanceImp::setLength): Added. Used by the above to resize the array. (ArrayInstanceImp::mark): Mark the elements of the array too. (ArrayPrototypeImp::ArrayPrototypeImp): Pass the length to the array instance constructor.
  • kjs/bool_object.cpp:
  • kjs/date_object.cpp:
  • kjs/error_object.cpp:
  • kjs/function.cpp:
  • kjs/function_object.cpp:
  • kjs/math_object.cpp:
  • kjs/nodes.cpp:
  • kjs/nodes.h:
  • kjs/number_object.cpp:
  • kjs/object_object.cpp:
  • kjs/regexp_object.cpp:
  • kjs/string_object.cpp:
  • kjs/nodes2string.cpp: (SourceStream::operator<<): Add a special case for char now that you can't create a UString from a char implicitly.
  • kjs/object.h:
  • kjs/object.cpp: (ObjectImp::get): Call through to the string version if the numeric version is not implemented. (ObjectImp::put): Call through to the string version if the numeric version is not implemented. (ObjectImp::hasProperty): Call through to the string version if the numeric version is not implemented. (ObjectImp::deleteProperty): Call through to the string version if the numeric version is not implemented.
  • kjs/types.h:
  • kjs/types.cpp: (Reference::Reference): Added constructors for the numeric property name case.
  • kjs/ustring.h: Made the constructor that turns a character into a string be explicit so we don't get numbers that turn themselves into strings.
  • kjs/ustring.cpp: (UString::UString): Detect the empty string case, and use a shared empty string. (UString::find): Add an overload for single character finds. (UString::rfind): Add an overload for single character finds. (KJS::operator==): Fix bug where it would call strlen(0) if the first string was not null. Also handle non-ASCII characters consistently with the rest of the code by casting to unsigned char just in case.
  • kjs/value.h: Make ValueImp and all subclasses non-copyable and non-assignable.
  • kjs/value.cpp: (ValueImp::toUInt32): New interface, mainly useful so we can detect array indices and not turn them into strings and back. (ValueImp::toInteger): Use the new toUInt32. Probably can use more improvement. (ValueImp::toInt32): Use the new toUInt32. Probably can use more improvement. (ValueImp::toUInt16): Use the new toUInt32. Probably can use more improvement. (ValueImp::getBase): Remove handling of the Reference case. That's in ReferenceImp now. (ValueImp::getPropertyName): Remove handling of the Reference case. That's in ReferenceImp now. (ValueImp::getValue): Remove handling of the Reference case. That's in ReferenceImp now. (ValueImp::putValue): Remove handling of the Reference case. That's in ReferenceImp now. (ValueImp::deleteValue): Added. Used so we can do delete the same way we do put.

WebFoundation:

  • CacheLoader.subproj/WebHTTPResourceLoader.m: (-[WebHTTPProtocolHandler createWFLoadRequest]): Fix handling of paths with queries and some other subtle path and port number handling issues by using _web_hostWithPort and _web_pathWithQuery.
  • Misc.subproj/WebNSURLExtras.h:
  • Misc.subproj/WebNSURLExtras.m: (-[NSURL _web_hostWithPort]): Added. (-[NSURL _web_pathWithQuery]): Added.
  • CacheLoader.subproj/WebResourceLoad.m: (initLoader): Get some random preference before creating threads. This makes it impossible to run into the CFPreferences race condition.

WebCore:

  • force-clean-timestamp: Need a full build because of KJS changes.
  • khtml/ecma/kjs_window.h: Need to store an Object, not an ObjectImp, because there's no way to copy an ObjectImp. KJS changes caught this mistake.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/value.cpp

    r1789 r1799  
    8383}
    8484
     85bool ValueImp::toUInt32(unsigned&) const
     86{
     87  return false;
     88}
     89
    8590// ECMA 9.4
    8691int ValueImp::toInteger(ExecState *exec) const
    8792{
     93  unsigned i;
     94  if (toUInt32(i))
     95    return (int)i;
    8896  return int(roundValue(exec, Value(const_cast<ValueImp*>(this))));
    8997}
     
    9199int ValueImp::toInt32(ExecState *exec) const
    92100{
     101  unsigned i;
     102  if (toUInt32(i))
     103    return (int)i;
     104
    93105  double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
    94106  double d32 = fmod(d, D32);
     
    102114unsigned int ValueImp::toUInt32(ExecState *exec) const
    103115{
     116  unsigned i;
     117  if (toUInt32(i))
     118    return i;
     119
    104120  double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
    105121  double d32 = fmod(d, D32);
     
    110126unsigned short ValueImp::toUInt16(ExecState *exec) const
    111127{
     128  unsigned i;
     129  if (toUInt32(i))
     130    return (unsigned short)i;
     131
    112132  double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
    113133  double d16 = fmod(d, D16);
     
    119139Value ValueImp::getBase(ExecState *exec) const
    120140{
    121   if (type() != ReferenceType) {
    122     Object err = Error::create(exec, ReferenceError, I18N_NOOP("Invalid reference base"));
    123     exec->setException(err);
    124     return err;
    125   }
    126 
    127   return (static_cast<const ReferenceImp*>(this))->getBase();
     141  Object err = Error::create(exec, ReferenceError, I18N_NOOP("Invalid reference base"));
     142  exec->setException(err);
     143  return err;
    128144}
    129145
     
    131147UString ValueImp::getPropertyName(ExecState * /*exec*/) const
    132148{
    133   if (type() != ReferenceType)
    134     // the spec wants a runtime error here. But getValue() and putValue()
    135     // will catch this case on their own earlier. When returning a Null
    136     // string we should be on the safe side.
    137     return UString();
    138 
    139   return (static_cast<const ReferenceImp*>(this))->getPropertyName();
     149  // the spec wants a runtime error here. But getValue() and putValue()
     150  // will catch this case on their own earlier. When returning a Null
     151  // string we should be on the safe side.
     152  return UString();
    140153}
    141154
     
    143156Value ValueImp::getValue(ExecState *exec) const
    144157{
    145   if (type() != ReferenceType)
    146     return Value(const_cast<ValueImp*>(this));
    147 
    148   Value o = getBase(exec);
    149 
    150   if (o.isNull() || o.type() == NullType) {
    151     UString m = I18N_NOOP("Can't find variable: ") + getPropertyName(exec);
    152     Object err = Error::create(exec, ReferenceError, m.ascii());
    153     exec->setException(err);
    154     return err;
    155   }
    156 
    157   if (o.type() != ObjectType) {
    158     UString m = I18N_NOOP("Base is not an object");
    159     Object err = Error::create(exec, ReferenceError, m.ascii());
    160     exec->setException(err);
    161     return err;
    162   }
    163 
    164   return static_cast<ObjectImp*>(o.imp())->get(exec,getPropertyName(exec));
    165 }
    166 
    167 void ValueImp::putValue(ExecState *exec, const Value w)
    168 {
    169   if (type() != ReferenceType) {
    170     Object err = Error::create(exec,ReferenceError);
    171     exec->setException(err);
    172     return;
    173   }
    174 
    175 #ifdef KJS_VERBOSE
    176   printInfo(exec,(UString("setting property ")+getPropertyName(exec)).cstring().c_str(),w);
    177 #endif
    178   Value o = getBase(exec);
    179   if (o.type() == NullType)
    180     exec->interpreter()->globalObject().put(exec,getPropertyName(exec), w);
    181   else {
    182     static_cast<ObjectImp*>(o.imp())->put(exec,getPropertyName(exec), w);
    183   }
    184 
    185   return;
    186 }
    187 
    188 bool KJS::operator==(const Value &v1, const Value &v2)
    189 {
    190   return (v1.imp() == v2.imp());
    191 }
    192 
    193 bool KJS::operator!=(const Value &v1, const Value &v2)
    194 {
    195   return (v1.imp() != v2.imp());
    196 }
    197 
    198 
    199 
     158  return Value(const_cast<ValueImp*>(this));
     159}
     160
     161void ValueImp::putValue(ExecState *exec, const Value& w)
     162{
     163  Object err = Error::create(exec,ReferenceError);
     164  exec->setException(err);
     165}
     166
     167bool ValueImp::deleteValue(ExecState *exec)
     168{
     169  Object err = Error::create(exec,ReferenceError);
     170  exec->setException(err);
     171  return false;
     172}
    200173
    201174// ------------------------------ Value ----------------------------------------
    202 
    203 Value::Value()
    204 {
    205   rep = 0;
    206 }
    207175
    208176Value::Value(ValueImp *v)
     
    251219}
    252220
    253 bool Value::isNull() const
    254 {
    255   return (rep == 0);
    256 }
    257 
    258 ValueImp *Value::imp() const
    259 {
    260   return rep;
    261 }
    262 
    263 Type Value::type() const
    264 {
    265   return rep->type();
    266 }
    267 
    268 bool Value::isA(Type t) const
    269 {
    270   return (type() == t);
    271 }
    272 
    273 Value Value::toPrimitive(ExecState *exec, Type preferredType) const
    274 {
    275   return rep->toPrimitive(exec,preferredType);
    276 }
    277 
    278 bool Value::toBoolean(ExecState *exec) const
    279 {
    280   return rep->toBoolean(exec);
    281 }
    282 
    283 double Value::toNumber(ExecState *exec) const
    284 {
    285   return rep->toNumber(exec);
    286 }
    287 
    288 int Value::toInteger(ExecState *exec) const
    289 {
    290   return rep->toInteger(exec);
    291 }
    292 
    293 int Value::toInt32(ExecState *exec) const
    294 {
    295   return rep->toInt32(exec);
    296 }
    297 
    298 unsigned int Value::toUInt32(ExecState *exec) const
    299 {
    300   return rep->toUInt32(exec);
    301 }
    302 
    303 unsigned short Value::toUInt16(ExecState *exec) const
    304 {
    305   return rep->toUInt16(exec);
    306 }
    307 
    308 UString Value::toString(ExecState *exec) const
    309 {
    310   return rep->toString(exec);
    311 }
    312 
    313 Object Value::toObject(ExecState *exec) const
    314 {
    315   return rep->toObject(exec);
    316 }
    317 
    318 Value Value::getBase(ExecState *exec) const
    319 {
    320   return rep->getBase(exec);
    321 }
    322 
    323 UString Value::getPropertyName(ExecState *exec) const
    324 {
    325   return rep->getPropertyName(exec);
    326 }
    327 
    328 Value Value::getValue(ExecState *exec) const
    329 {
    330   return rep->getValue(exec);
    331 }
    332 
    333 void Value::putValue(ExecState *exec, const Value w)
    334 {
    335   rep->putValue(exec,w);
    336 }
    337 
    338221// ------------------------------ Undefined ------------------------------------
    339222
    340223Undefined::Undefined() : Value(UndefinedImp::staticUndefined)
    341224{
    342 }
    343 
    344 Undefined::~Undefined() {
    345 }
    346 
    347 Undefined::Undefined(UndefinedImp *v) : Value(v)
    348 {
    349 }
    350 
    351 Undefined::Undefined(const Undefined &v) : Value(v)
    352 {
    353 }
    354 
    355 Undefined& Undefined::operator=(const Undefined &v)
    356 {
    357   Value::operator=(v);
    358   return *this;
    359225}
    360226
     
    373239}
    374240
    375 Null::~Null() {
    376 }
    377 
    378 
    379 Null::Null(NullImp *v) : Value(v)
    380 {
    381 }
    382 
    383 Null::Null(const Null &v) : Value(v)
    384 {
    385 }
    386 
    387 Null& Null::operator=(const Null &v)
    388 {
    389   Value::operator=(v);
    390   return *this;
    391 }
    392 
    393241Null Null::dynamicCast(const Value &v)
    394242{
     
    406254}
    407255
    408 Boolean::~Boolean() { }
    409 
    410 
    411 
    412 Boolean::Boolean(BooleanImp *v) : Value(v)
    413 {
    414 }
    415 
    416 Boolean::Boolean(const Boolean &v) : Value(v)
    417 {
    418 }
    419 
    420 Boolean& Boolean::operator=(const Boolean &v)
    421 {
    422   Value::operator=(v);
    423   return *this;
    424 }
    425 
    426 
    427256bool Boolean::value() const
    428257{
     
    445274}
    446275
    447 String::~String() { }
    448 
    449 String::String(StringImp *v) : Value(v)
    450 {
    451 }
    452 
    453 String::String(const String &v) : Value(v)
    454 {
    455 }
    456 
    457 String& String::operator=(const String &v)
    458 {
    459   Value::operator=(v);
    460   return *this;
    461 }
    462 
    463276UString String::value() const
    464277{
     
    492305  : Value(new NumberImp(static_cast<double>(l))) { }
    493306
    494 Number::~Number() { }
    495 
    496 Number::Number(NumberImp *v) : Value(v)
    497 {
    498 }
    499 
    500 Number::Number(const Number &v) : Value(v)
    501 {
    502 }
    503 
    504 Number& Number::operator=(const Number &v)
    505 {
    506   Value::operator=(v);
    507   return *this;
    508 }
    509 
    510307Number Number::dynamicCast(const Value &v)
    511308{
     
    536333  return KJS::isInf(value());
    537334}
    538 
Note: See TracChangeset for help on using the changeset viewer.