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/array_object.cpp

    r1623 r1799  
    4040const ClassInfo ArrayInstanceImp::info = {"Array", 0, 0, 0};
    4141
    42 ArrayInstanceImp::ArrayInstanceImp(const Object &proto)
     42ArrayInstanceImp::ArrayInstanceImp(const Object &proto, unsigned initialLength)
    4343  : ObjectImp(proto)
    44 {
     44  , length(initialLength)
     45  , capacity(length)
     46  , storage(length ? new Undefined[length] : 0)
     47{
     48}
     49
     50ArrayInstanceImp::ArrayInstanceImp(const Object &proto, const List &list)
     51  : ObjectImp(proto)
     52  , length(list.size())
     53  , capacity(length)
     54  , storage(length ? new Undefined[length] : 0)
     55{
     56  ListIterator it = list.begin();
     57  const unsigned l = length;
     58  for (unsigned i = 0; i < l; ++i) {
     59    storage[i] = it++;
     60  }
     61}
     62
     63ArrayInstanceImp::~ArrayInstanceImp()
     64{
     65  delete [] storage;
     66}
     67
     68Value ArrayInstanceImp::get(ExecState *exec, const UString &propertyName) const
     69{
     70  if (propertyName == lengthPropertyName)
     71    return Number(length);
     72
     73  bool ok;
     74  unsigned index = propertyName.toULong(&ok);
     75  if (ok) {
     76    if (index >= length)
     77      return Undefined();
     78    return storage[index];
     79  }
     80
     81  return ObjectImp::get(exec, propertyName);
     82}
     83
     84Value ArrayInstanceImp::get(ExecState *exec, unsigned index) const
     85{
     86  if (index >= length)
     87    return Undefined();
     88  return storage[index];
    4589}
    4690
     
    4892void ArrayInstanceImp::put(ExecState *exec, const UString &propertyName, const Value &value, int attr)
    4993{
    50   if ((attr == None || attr == DontDelete) && !canPut(exec,propertyName))
     94  if (propertyName == lengthPropertyName) {
     95    setLength(value.toUInt32(exec));
    5196    return;
    52 
    53   if (hasProperty(exec,propertyName)) {
    54     if (propertyName == "length") {
    55       Value len = get(exec,"length");
    56       unsigned int oldLen = len.toUInt32(exec);
    57       unsigned int newLen = value.toUInt32(exec);
    58       // shrink array
    59       for (unsigned int u = newLen; u < oldLen; u++) {
    60         UString p = UString::from(u);
    61         if (hasOwnProperty(exec, p))
    62           deleteProperty(exec, p);
    63       }
    64       ObjectImp::put(exec, "length", Number(newLen), DontEnum | DontDelete);
    65       return;
    66     }
    67     //    put(p, v);
    68   } //  } else
    69     ObjectImp::put(exec, propertyName, value, attr);
    70 
    71   // array index ?
    72   unsigned int idx;
    73   if (!sscanf(propertyName.cstring().c_str(), "%u", &idx)) /* TODO */
     97  }
     98 
     99  bool ok;
     100  unsigned index = propertyName.toULong(&ok);
     101  if (ok) {
     102    setLength(index + 1);
     103    storage[index] = value;
    74104    return;
    75 
    76   // do we need to update/create the length property ?
    77   if (hasOwnProperty(exec, "length")) {
    78     Value len = get(exec, "length");
    79     if (idx < len.toUInt32(exec))
    80       return;
    81   }
    82 
    83   ObjectImp::put(exec, "length", Number(idx+1), DontDelete | DontEnum);
    84 }
    85 
    86 void ArrayInstanceImp::putDirect(ExecState *exec, const UString &propertyName, const Value &value, int attr)
    87 {
    88   ObjectImp::put(exec,propertyName,value,attr);
    89 }
    90 
    91 bool ArrayInstanceImp::hasOwnProperty(ExecState *exec,
    92                                       const UString &propertyName)
    93 {
    94   // disable this object's prototype temporarily for the hasProperty() call
    95   Value protoBackup = prototype();
    96   setPrototype(Undefined());
    97   bool b = hasProperty(exec, propertyName);
    98   setPrototype(protoBackup);
    99   return b;
     105  }
     106 
     107  ObjectImp::put(exec, propertyName, value, attr);
     108}
     109
     110void ArrayInstanceImp::put(ExecState *exec, unsigned index, const Value &value, int attr)
     111{
     112  setLength(index + 1);
     113  storage[index] = value;
     114}
     115
     116bool ArrayInstanceImp::hasProperty(ExecState *exec, const UString &propertyName) const
     117{
     118  if (propertyName == lengthPropertyName)
     119    return true;
     120 
     121  bool ok;
     122  unsigned index = propertyName.toULong(&ok);
     123  if (ok) {
     124    if (index >= length)
     125      return false;
     126    return !storage[index].isA(UndefinedType);
     127  }
     128 
     129  return ObjectImp::hasProperty(exec, propertyName);
     130}
     131
     132bool ArrayInstanceImp::hasProperty(ExecState *exec, unsigned index) const
     133{
     134  if (index >= length)
     135    return false;
     136  return !storage[index].isA(UndefinedType);
     137}
     138
     139bool ArrayInstanceImp::deleteProperty(ExecState *exec, const UString &propertyName)
     140{
     141  if (propertyName == lengthPropertyName)
     142    return false;
     143 
     144  bool ok;
     145  unsigned index = propertyName.toULong(&ok);
     146  if (ok) {
     147    if (index >= length)
     148      return true;
     149    storage[index] = Undefined();
     150    return true;
     151  }
     152 
     153  return ObjectImp::deleteProperty(exec, propertyName);
     154}
     155
     156bool ArrayInstanceImp::deleteProperty(ExecState *exec, unsigned index)
     157{
     158  if (index >= length)
     159    return true;
     160  storage[index] = Undefined();
     161  return true;
     162}
     163
     164void ArrayInstanceImp::setLength(unsigned newLength)
     165{
     166  if (newLength < length) {
     167    const unsigned l = length;
     168    for (unsigned i = newLength; i < l; ++i)
     169      storage[i] = Undefined();
     170  }
     171  if (newLength > capacity) {
     172    unsigned newCapacity = (newLength * 3 + 1) / 2;
     173    Value *newStorage = new Undefined [newCapacity];
     174    const unsigned l = length;
     175    for (unsigned i = 0; i < l; ++i)
     176      newStorage[i] = storage[i];
     177    delete [] storage;
     178    storage = newStorage;
     179    capacity = newCapacity;
     180  }
     181  length = newLength;
     182}
     183
     184void ArrayInstanceImp::mark()
     185{
     186  ObjectImp::mark();
     187  const unsigned l = length;
     188  for (unsigned i = 0; i < l; ++i) {
     189    ValueImp *imp = storage[i].imp();
     190    if (!imp->marked())
     191      imp->mark();
     192  }
    100193}
    101194
     
    124217ArrayPrototypeImp::ArrayPrototypeImp(ExecState *exec,
    125218                                     ObjectPrototypeImp *objProto)
    126   : ArrayInstanceImp(Object(objProto))
     219  : ArrayInstanceImp(Object(objProto), 0)
    127220{
    128221  Value protect(this);
    129222  setInternalValue(Null());
    130 
    131   // The constructor will be added later, by InterpreterImp, once ArrayObjectImp has been constructed.
    132   put(exec,"length", Number(0), DontEnum | DontDelete);
    133223}
    134224
     
    147237{
    148238  Value protect(this);
    149   put(exec,"length",Number(len),DontDelete|ReadOnly|DontEnum);
     239  put(exec,lengthPropertyName,Number(len),DontDelete|ReadOnly|DontEnum);
    150240}
    151241
     
    158248Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)
    159249{
    160   unsigned int length = thisObj.get(exec,"length").toUInt32(exec);
     250  unsigned int length = thisObj.get(exec,lengthPropertyName).toUInt32(exec);
    161251
    162252  Value result;
     
    184274      if (k >= 1)
    185275        str += separator;
    186       Value element = thisObj.get(exec,UString::from(k));
     276      Value element = thisObj.get(exec,k);
    187277      if (element.type() != UndefinedType && element.type() != NullType)
    188278        str += element.toString(exec);
     
    202292        unsigned int k = 0;
    203293        if (n > 0)
    204           length = curObj.get(exec,"length").toUInt32(exec);
     294          length = curObj.get(exec,lengthPropertyName).toUInt32(exec);
    205295        while (k < length) {
    206           UString p = UString::from(k);
    207           if (curObj.hasProperty(exec,p))
    208             arr.put(exec,UString::from(n), curObj.get(exec,p));
     296          if (curObj.hasProperty(exec,k))
     297            arr.put(exec, n, curObj.get(exec, k));
    209298          n++;
    210299          k++;
    211300        }
    212301      } else {
    213         arr.put(exec,UString::from(n), curArg);
     302        arr.put(exec, n, curArg);
    214303        n++;
    215304      }
     
    219308      curObj = Object::dynamicCast(it++); // may be 0
    220309    }
    221     arr.put(exec,"length", Number(n), DontEnum | DontDelete);
     310    arr.put(exec,lengthPropertyName, Number(n), DontEnum | DontDelete);
    222311
    223312    result = arr;
     
    225314  }
    226315  case Pop:{
    227 
    228316    if (length == 0) {
    229       thisObj.put(exec, "length", Number(length), DontEnum | DontDelete);
     317      thisObj.put(exec, lengthPropertyName, Number(length), DontEnum | DontDelete);
    230318      result = Undefined();
    231319    } else {
    232       UString str = UString::from(length - 1);
    233       result = thisObj.get(exec,str);
    234       thisObj.deleteProperty(exec, str);
    235       thisObj.put(exec, "length", Number(length - 1), DontEnum | DontDelete);
     320      result = thisObj.get(exec, length - 1);
     321      thisObj.put(exec, lengthPropertyName, Number(length - 1), DontEnum | DontDelete);
    236322    }
    237323    break;
     
    239325  case Push: {
    240326    for (int n = 0; n < args.size(); n++)
    241       thisObj.put(exec,UString::from(length + n), args[n]);
     327      thisObj.put(exec, length + n, args[n]);
    242328    length += args.size();
    243     thisObj.put(exec,"length", Number(length), DontEnum | DontDelete);
     329    thisObj.put(exec,lengthPropertyName, Number(length), DontEnum | DontDelete);
    244330    result = Number(length);
    245331    break;
     
    250336
    251337    for (unsigned int k = 0; k < middle; k++) {
    252       UString str = UString::from(k);
    253       UString str2 = UString::from(length - k - 1);
    254       Value obj = thisObj.get(exec,str);
    255       Value obj2 = thisObj.get(exec,str2);
    256       if (thisObj.hasProperty(exec,str2)) {
    257         if (thisObj.hasProperty(exec,str)) {
    258           thisObj.put(exec, str, obj2);
    259           thisObj.put(exec, str2, obj);
     338      unsigned lk1 = length - k - 1;
     339      Value obj = thisObj.get(exec,k);
     340      Value obj2 = thisObj.get(exec,lk1);
     341      if (thisObj.hasProperty(exec,lk1)) {
     342        if (thisObj.hasProperty(exec,k)) {
     343          thisObj.put(exec, k, obj2);
     344          thisObj.put(exec, lk1, obj);
    260345        } else {
    261           thisObj.put(exec, str, obj2);
    262           thisObj.deleteProperty(exec, str2);
     346          thisObj.put(exec, k, obj2);
     347          thisObj.deleteProperty(exec, lk1);
    263348        }
    264349      } else {
    265         if (thisObj.hasProperty(exec, str)) {
    266           thisObj.deleteProperty(exec, str);
    267           thisObj.put(exec, str2, obj);
     350        if (thisObj.hasProperty(exec, k)) {
     351          thisObj.deleteProperty(exec, k);
     352          thisObj.put(exec, lk1, obj);
    268353        } else {
    269354          // why delete something that's not there ? Strange.
    270           thisObj.deleteProperty(exec, str);
    271           thisObj.deleteProperty(exec, str2);
     355          thisObj.deleteProperty(exec, k);
     356          thisObj.deleteProperty(exec, lk1);
    272357        }
    273358      }
     
    278363  case Shift: {
    279364    if (length == 0) {
    280       thisObj.put(exec, "length", Number(length), DontEnum | DontDelete);
     365      thisObj.put(exec, lengthPropertyName, Number(length), DontEnum | DontDelete);
    281366      result = Undefined();
    282367    } else {
    283       result = thisObj.get(exec, "0");
     368      result = thisObj.get(exec, 0);
    284369      for(unsigned int k = 1; k < length; k++) {
    285         UString str = UString::from(k);
    286         UString str2 = UString::from(k-1);
    287         if (thisObj.hasProperty(exec, str)) {
    288           Value obj = thisObj.get(exec, str);
    289           thisObj.put(exec, str2, obj);
     370        if (thisObj.hasProperty(exec, k)) {
     371          Value obj = thisObj.get(exec, k);
     372          thisObj.put(exec, k-1, obj);
    290373        } else
    291           thisObj.deleteProperty(exec, str2);
    292       }
    293       thisObj.deleteProperty(exec, UString::from(length - 1));
    294       thisObj.put(exec, "length", Number(length - 1), DontEnum | DontDelete);
     374          thisObj.deleteProperty(exec, k-1);
     375      }
     376      thisObj.deleteProperty(exec, length - 1);
     377      thisObj.put(exec, lengthPropertyName, Number(length - 1), DontEnum | DontDelete);
    295378    }
    296379    break;
     
    319402    //printf( "Slicing from %d to %d \n", begin, end );
    320403    for(unsigned int k = 0; k < (unsigned int) end-begin; k++) {
    321       UString str = UString::from(k+begin);
    322       if (thisObj.hasProperty(exec,str)) {
    323         UString str2 = UString::from(k);
    324         Value obj = thisObj.get(exec, str);
    325         resObj.put(exec, str2, obj);
    326       }
    327     }
    328     resObj.put(exec, "length", Number(end - begin), DontEnum | DontDelete);
     404      if (thisObj.hasProperty(exec,k+begin)) {
     405        Value obj = thisObj.get(exec, k+begin);
     406        resObj.put(exec, k, obj);
     407      }
     408    }
     409    resObj.put(exec, lengthPropertyName, Number(end - begin), DontEnum | DontDelete);
    329410    break;
    330411  }
     
    333414    printf("KJS Array::Sort length=%d\n", length);
    334415    for ( unsigned int i = 0 ; i<length ; ++i )
    335       printf("KJS Array::Sort: %d: %s\n", i, thisObj.get(UString::from(i)).toString().value().ascii() );
     416      printf("KJS Array::Sort: %d: %s\n", i, thisObj.get(i).toString().value().ascii() );
    336417#endif
    337418    Object sortFunction;
     
    345426
    346427    if (length == 0) {
    347       thisObj.put(exec, "length", Number(0), DontEnum | DontDelete);
     428      thisObj.put(exec, lengthPropertyName, Number(0), DontEnum | DontDelete);
    348429      result = Undefined();
    349430      break;
     
    354435    for ( unsigned int i = 0 ; i<length-1 ; ++i )
    355436      {
    356         Value iObj = thisObj.get(exec,UString::from(i));
     437        Value iObj = thisObj.get(exec,i);
    357438        unsigned int themin = i;
    358439        Value minObj = iObj;
    359440        for ( unsigned int j = i+1 ; j<length ; ++j )
    360441          {
    361             Value jObj = thisObj.get(exec,UString::from(j));
     442            Value jObj = thisObj.get(exec,j);
    362443            int cmp;
    363444            if (jObj.type() == UndefinedType) {
     
    384465          {
    385466            //printf("KJS Array::Sort: swapping %d and %d\n", i, themin );
    386             thisObj.put( exec, UString::from(i), minObj );
    387             thisObj.put( exec, UString::from(themin), iObj );
     467            thisObj.put( exec, i, minObj );
     468            thisObj.put( exec, themin, iObj );
    388469          }
    389470      }
     
    391472    printf("KJS Array::Sort -- Resulting array:\n");
    392473    for ( unsigned int i = 0 ; i<length ; ++i )
    393       printf("KJS Array::Sort: %d: %s\n", i, thisObj.get(UString::from(i)).toString().value().ascii() );
     474      printf("KJS Array::Sort: %d: %s\n", i, thisObj.get(i).toString().value().ascii() );
    394475#endif
    395476    result = thisObj;
     
    409490    //printf( "Splicing from %d, deleteCount=%d \n", begin, deleteCount );
    410491    for(unsigned int k = 0; k < deleteCount; k++) {
    411       UString str = UString::from(k+begin);
    412       if (thisObj.hasProperty(exec,str)) {
    413         UString str2 = UString::from(k);
    414         Value obj = thisObj.get(exec, str);
    415         resObj.put(exec, str2, obj);
    416       }
    417     }
    418     resObj.put(exec, "length", Number(deleteCount), DontEnum | DontDelete);
     492      if (thisObj.hasProperty(exec,k+begin)) {
     493        Value obj = thisObj.get(exec, k+begin);
     494        resObj.put(exec, k, obj);
     495      }
     496    }
     497    resObj.put(exec, lengthPropertyName, Number(deleteCount), DontEnum | DontDelete);
    419498
    420499    unsigned int additionalArgs = maxInt( args.size() - 2, 0 );
     
    425504        for ( unsigned int k = begin; k < length - deleteCount; ++k )
    426505        {
    427           UString str = UString::from(k+deleteCount);
    428           UString str2 = UString::from(k+additionalArgs);
    429           if (thisObj.hasProperty(exec,str)) {
    430             Value obj = thisObj.get(exec, str);
    431             thisObj.put(exec, str2, obj);
     506          if (thisObj.hasProperty(exec,k+deleteCount)) {
     507            Value obj = thisObj.get(exec, k+deleteCount);
     508            thisObj.put(exec, k+additionalArgs, obj);
    432509          }
    433510          else
    434             thisObj.deleteProperty(exec, str2);
     511            thisObj.deleteProperty(exec, k+additionalArgs);
    435512        }
    436513        for ( unsigned int k = length ; k > length - deleteCount + additionalArgs; --k )
    437           thisObj.deleteProperty(exec, UString::from(k-1));
     514          thisObj.deleteProperty(exec, k-1);
    438515      }
    439516      else
     
    441518        for ( unsigned int k = length - deleteCount; (int)k > begin; --k )
    442519        {
    443           UString str = UString::from(k+deleteCount-1);
    444           UString str2 = UString::from(k+additionalArgs-1);
    445           if (thisObj.hasProperty(exec,str)) {
    446             Value obj = thisObj.get(exec, str);
    447             thisObj.put(exec, str2, obj);
     520          if (thisObj.hasProperty(exec,k+deleteCount-1)) {
     521            Value obj = thisObj.get(exec, k+deleteCount-1);
     522            thisObj.put(exec, k+additionalArgs-1, obj);
    448523          }
    449524          else
    450             thisObj.deleteProperty(exec, str2);
     525            thisObj.deleteProperty(exec, k+additionalArgs-1);
    451526        }
    452527      }
     
    454529    for ( unsigned int k = 0; k < additionalArgs; ++k )
    455530    {
    456       thisObj.put(exec, UString::from(k+begin), args[k+2]);
    457     }
    458     thisObj.put(exec, "length", Number(length - deleteCount + additionalArgs), DontEnum | DontDelete);
     531      thisObj.put(exec, k+begin, args[k+2]);
     532    }
     533    thisObj.put(exec, lengthPropertyName, Number(length - deleteCount + additionalArgs), DontEnum | DontDelete);
    459534    break;
    460535  }
     
    463538    for ( unsigned int k = length; k > 0; --k )
    464539    {
    465       UString str = UString::from(k-1);
    466       UString str2 = UString::from(k+nrArgs-1);
    467       if (thisObj.hasProperty(exec,str)) {
    468         Value obj = thisObj.get(exec, str);
    469         thisObj.put(exec, str2, obj);
     540      if (thisObj.hasProperty(exec,k-1)) {
     541        Value obj = thisObj.get(exec, k-1);
     542        thisObj.put(exec, k+nrArgs-1, obj);
    470543      } else {
    471         thisObj.deleteProperty(exec, str2);
     544        thisObj.deleteProperty(exec, k+nrArgs-1);
    472545      }
    473546    }
    474547    for ( unsigned int k = 0; k < nrArgs; ++k )
    475       thisObj.put(exec, UString::from(k), args[k]);
     548      thisObj.put(exec, k, args[k]);
    476549    result = Number(length + nrArgs);
    477     thisObj.put(exec, "length", result, DontEnum | DontDelete);
     550    thisObj.put(exec, lengthPropertyName, result, DontEnum | DontDelete);
    478551    break;
    479552  }
     
    494567  Value protect(this);
    495568  // ECMA 15.4.3.1 Array.prototype
    496   put(exec,"prototype", Object(arrayProto), DontEnum|DontDelete|ReadOnly);
     569  put(exec,prototypePropertyName, Object(arrayProto), DontEnum|DontDelete|ReadOnly);
    497570
    498571  // no. of arguments for constructor
    499   put(exec,"length", Number(1), ReadOnly|DontDelete|DontEnum);
     572  put(exec,lengthPropertyName, Number(1), ReadOnly|DontDelete|DontEnum);
    500573}
    501574
     
    508581Object ArrayObjectImp::construct(ExecState *exec, const List &args)
    509582{
    510   Object result(new ArrayInstanceImp(exec->interpreter()->builtinArrayPrototype()));
    511 
    512   unsigned int len;
    513   ListIterator it = args.begin();
    514   // a single argument might denote the array size
    515   if (args.size() == 1 && it->type() == NumberType)
    516     len = it->toUInt32(exec);
    517   else {
    518     // initialize array
    519     len = args.size();
    520     for (unsigned int u = 0; it != args.end(); it++, u++)
    521       result.put(exec, UString::from(u), *it);
    522   }
    523 
    524   // array size
    525   result.put(exec, "length", Number(len), DontEnum | DontDelete);
    526   static_cast<ArrayInstanceImp*>(result.imp())->putDirect(exec, "length", Number(len), DontEnum | DontDelete);
    527 
    528   return result;
     583  // a single numeric argument denotes the array size (!)
     584  if (args.size() == 1 && args[0].type() == NumberType)
     585    return Object(new ArrayInstanceImp(exec->interpreter()->builtinArrayPrototype(), args[0].toUInt32(exec)));
     586
     587  // otherwise the array is constructed with the arguments in it
     588  return Object(new ArrayInstanceImp(exec->interpreter()->builtinArrayPrototype(), args));
    529589}
    530590
Note: See TracChangeset for help on using the changeset viewer.