JSValue::toString() should return a JSString* instead of a UString
[WebKit-https.git] / Source / JavaScriptCore / runtime / ArrayPrototype.cpp
1 /*
2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2003, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
4  *  Copyright (C) 2003 Peter Kelly (pmk@post.com)
5  *  Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public
9  *  License as published by the Free Software Foundation; either
10  *  version 2 of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
20  *  USA
21  *
22  */
23
24 #include "config.h"
25 #include "ArrayPrototype.h"
26
27 #include "CachedCall.h"
28 #include "CodeBlock.h"
29 #include "Interpreter.h"
30 #include "JIT.h"
31 #include "JSStringBuilder.h"
32 #include "Lookup.h"
33 #include "ObjectPrototype.h"
34 #include "Operations.h"
35 #include "StringRecursionChecker.h"
36 #include <algorithm>
37 #include <wtf/Assertions.h>
38 #include <wtf/HashSet.h>
39
40 namespace JSC {
41
42 ASSERT_CLASS_FITS_IN_CELL(ArrayPrototype);
43
44 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*);
45 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*);
46 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState*);
47 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState*);
48 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState*);
49 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState*);
50 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState*);
51 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState*);
52 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState*);
53 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState*);
54 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState*);
55 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState*);
56 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState*);
57 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState*);
58 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState*);
59 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState*);
60 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState*);
61 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState*);
62 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState*);
63 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState*);
64 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState*);
65
66 }
67
68 #include "ArrayPrototype.lut.h"
69
70 namespace JSC {
71
72 static inline bool isNumericCompareFunction(ExecState* exec, CallType callType, const CallData& callData)
73 {
74     if (callType != CallTypeJS)
75         return false;
76
77     FunctionExecutable* executable = callData.js.functionExecutable;
78
79     JSObject* error = executable->compileForCall(exec, callData.js.scopeChain);
80     if (error)
81         return false;
82
83     return executable->generatedBytecodeForCall().isNumericCompareFunction();
84 }
85
86 // ------------------------------ ArrayPrototype ----------------------------
87
88 const ClassInfo ArrayPrototype::s_info = {"Array", &JSArray::s_info, 0, ExecState::arrayPrototypeTable, CREATE_METHOD_TABLE(ArrayPrototype)};
89
90 /* Source for ArrayPrototype.lut.h
91 @begin arrayPrototypeTable 16
92   toString       arrayProtoFuncToString       DontEnum|Function 0
93   toLocaleString arrayProtoFuncToLocaleString DontEnum|Function 0
94   concat         arrayProtoFuncConcat         DontEnum|Function 1
95   join           arrayProtoFuncJoin           DontEnum|Function 1
96   pop            arrayProtoFuncPop            DontEnum|Function 0
97   push           arrayProtoFuncPush           DontEnum|Function 1
98   reverse        arrayProtoFuncReverse        DontEnum|Function 0
99   shift          arrayProtoFuncShift          DontEnum|Function 0
100   slice          arrayProtoFuncSlice          DontEnum|Function 2
101   sort           arrayProtoFuncSort           DontEnum|Function 1
102   splice         arrayProtoFuncSplice         DontEnum|Function 2
103   unshift        arrayProtoFuncUnShift        DontEnum|Function 1
104   every          arrayProtoFuncEvery          DontEnum|Function 1
105   forEach        arrayProtoFuncForEach        DontEnum|Function 1
106   some           arrayProtoFuncSome           DontEnum|Function 1
107   indexOf        arrayProtoFuncIndexOf        DontEnum|Function 1
108   lastIndexOf    arrayProtoFuncLastIndexOf    DontEnum|Function 1
109   filter         arrayProtoFuncFilter         DontEnum|Function 1
110   reduce         arrayProtoFuncReduce         DontEnum|Function 1
111   reduceRight    arrayProtoFuncReduceRight    DontEnum|Function 1
112   map            arrayProtoFuncMap            DontEnum|Function 1
113 @end
114 */
115
116 // ECMA 15.4.4
117 ArrayPrototype::ArrayPrototype(JSGlobalObject* globalObject, Structure* structure)
118     : JSArray(globalObject->globalData(), structure)
119 {
120 }
121
122 void ArrayPrototype::finishCreation(JSGlobalObject* globalObject)
123 {
124     Base::finishCreation(globalObject->globalData());
125     ASSERT(inherits(&s_info));
126 }
127
128 bool ArrayPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
129 {
130     return getStaticFunctionSlot<JSArray>(exec, ExecState::arrayPrototypeTable(exec), jsCast<ArrayPrototype*>(cell), propertyName, slot);
131 }
132
133 bool ArrayPrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
134 {
135     return getStaticFunctionDescriptor<JSArray>(exec, ExecState::arrayPrototypeTable(exec), jsCast<ArrayPrototype*>(object), propertyName, descriptor);
136 }
137
138 // ------------------------------ Array Functions ----------------------------
139
140 // Helper function
141 static JSValue getProperty(ExecState* exec, JSObject* obj, unsigned index)
142 {
143     PropertySlot slot(obj);
144     if (!obj->getPropertySlot(exec, index, slot))
145         return JSValue();
146     return slot.getValue(exec, index);
147 }
148
149 static void putProperty(ExecState* exec, JSObject* obj, const Identifier& propertyName, JSValue value)
150 {
151     PutPropertySlot slot;
152     obj->methodTable()->put(obj, exec, propertyName, value, slot);
153 }
154
155 static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument, unsigned length, unsigned undefinedValue = 0)
156 {
157     JSValue value = exec->argument(argument);
158     if (value.isUndefined())
159         return undefinedValue;
160
161     double indexDouble = value.toInteger(exec);
162     if (indexDouble < 0) {
163         indexDouble += length;
164         return indexDouble < 0 ? 0 : static_cast<unsigned>(indexDouble);
165     }
166     return indexDouble > length ? length : static_cast<unsigned>(indexDouble);
167 }
168
169 EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
170 {
171     JSValue thisValue = exec->hostThisValue();
172
173     bool isRealArray = isJSArray(thisValue);
174     if (!isRealArray && !thisValue.inherits(&JSArray::s_info))
175         return throwVMTypeError(exec);
176     JSArray* thisObj = asArray(thisValue);
177     
178     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
179     if (exec->hadException())
180         return JSValue::encode(jsUndefined());
181
182     StringRecursionChecker checker(exec, thisObj);
183     if (JSValue earlyReturnValue = checker.earlyReturnValue())
184         return JSValue::encode(earlyReturnValue);
185
186     unsigned totalSize = length ? length - 1 : 0;
187     Vector<RefPtr<StringImpl>, 256> strBuffer(length);
188     bool allStrings8Bit = true;
189
190     for (unsigned k = 0; k < length; k++) {
191         JSValue element;
192         if (isRealArray && thisObj->canGetIndex(k))
193             element = thisObj->getIndex(k);
194         else
195             element = thisObj->get(exec, k);
196         
197         if (element.isUndefinedOrNull())
198             continue;
199         
200         UString str = element.toString(exec)->value(exec);
201         strBuffer[k] = str.impl();
202         totalSize += str.length();
203         allStrings8Bit = allStrings8Bit && str.is8Bit();
204         
205         if (!strBuffer.data()) {
206             throwOutOfMemoryError(exec);
207         }
208         
209         if (exec->hadException())
210             break;
211     }
212     if (!totalSize)
213         return JSValue::encode(jsEmptyString(exec));
214
215     if (allStrings8Bit) {
216         Vector<LChar> buffer;
217         buffer.reserveCapacity(totalSize);
218         if (!buffer.data())
219             return JSValue::encode(throwOutOfMemoryError(exec));
220         
221         for (unsigned i = 0; i < length; i++) {
222             if (i)
223                 buffer.append(',');
224             if (RefPtr<StringImpl> rep = strBuffer[i])
225                 buffer.append(rep->characters8(), rep->length());
226         }
227         ASSERT(buffer.size() == totalSize);
228         return JSValue::encode(jsString(exec, UString::adopt(buffer)));        
229     }
230
231     Vector<UChar> buffer;
232     buffer.reserveCapacity(totalSize);
233     if (!buffer.data())
234         return JSValue::encode(throwOutOfMemoryError(exec));
235         
236     for (unsigned i = 0; i < length; i++) {
237         if (i)
238             buffer.append(',');
239         if (RefPtr<StringImpl> rep = strBuffer[i])
240             buffer.append(rep->characters(), rep->length());
241     }
242     ASSERT(buffer.size() == totalSize);
243     return JSValue::encode(jsString(exec, UString::adopt(buffer)));
244 }
245
246 EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
247 {
248     JSValue thisValue = exec->hostThisValue();
249
250     if (!thisValue.inherits(&JSArray::s_info))
251         return throwVMTypeError(exec);
252     JSObject* thisObj = asArray(thisValue);
253
254     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
255     if (exec->hadException())
256         return JSValue::encode(jsUndefined());
257
258     StringRecursionChecker checker(exec, thisObj);
259     if (JSValue earlyReturnValue = checker.earlyReturnValue())
260         return JSValue::encode(earlyReturnValue);
261
262     JSStringBuilder strBuffer;
263     for (unsigned k = 0; k < length; k++) {
264         if (k >= 1)
265             strBuffer.append(',');
266
267         JSValue element = thisObj->get(exec, k);
268         if (!element.isUndefinedOrNull()) {
269             JSObject* o = element.toObject(exec);
270             JSValue conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
271             UString str;
272             CallData callData;
273             CallType callType = getCallData(conversionFunction, callData);
274             if (callType != CallTypeNone)
275                 str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toString(exec)->value(exec);
276             else
277                 str = element.toString(exec)->value(exec);
278             strBuffer.append(str);
279         }
280     }
281
282     return JSValue::encode(strBuffer.build(exec));
283 }
284
285 EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
286 {
287     JSObject* thisObj = exec->hostThisValue().toObject(exec);
288     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
289     if (exec->hadException())
290         return JSValue::encode(jsUndefined());
291
292     StringRecursionChecker checker(exec, thisObj);
293     if (JSValue earlyReturnValue = checker.earlyReturnValue())
294         return JSValue::encode(earlyReturnValue);
295
296     JSStringBuilder strBuffer;
297
298     UString separator;
299     if (!exec->argument(0).isUndefined())
300         separator = exec->argument(0).toString(exec)->value(exec);
301
302     unsigned k = 0;
303     if (isJSArray(thisObj)) {
304         JSArray* array = asArray(thisObj);
305
306         if (length) {
307             if (!array->canGetIndex(k)) 
308                 goto skipFirstLoop;
309             JSValue element = array->getIndex(k);
310             if (!element.isUndefinedOrNull())
311                 strBuffer.append(element.toString(exec)->value(exec));
312             k++;
313         }
314
315         if (separator.isNull()) {
316             for (; k < length; k++) {
317                 if (!array->canGetIndex(k))
318                     break;
319                 strBuffer.append(',');
320                 JSValue element = array->getIndex(k);
321                 if (!element.isUndefinedOrNull())
322                     strBuffer.append(element.toString(exec)->value(exec));
323             }
324         } else {
325             for (; k < length; k++) {
326                 if (!array->canGetIndex(k))
327                     break;
328                 strBuffer.append(separator);
329                 JSValue element = array->getIndex(k);
330                 if (!element.isUndefinedOrNull())
331                     strBuffer.append(element.toString(exec)->value(exec));
332             }
333         }
334     }
335  skipFirstLoop:
336     for (; k < length; k++) {
337         if (k >= 1) {
338             if (separator.isNull())
339                 strBuffer.append(',');
340             else
341                 strBuffer.append(separator);
342         }
343
344         JSValue element = thisObj->get(exec, k);
345         if (!element.isUndefinedOrNull())
346             strBuffer.append(element.toString(exec)->value(exec));
347     }
348
349     return JSValue::encode(strBuffer.build(exec));
350 }
351
352 EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
353 {
354     JSValue thisValue = exec->hostThisValue();
355     JSArray* arr = constructEmptyArray(exec);
356     unsigned n = 0;
357     JSValue curArg = thisValue.toObject(exec);
358     if (exec->hadException())
359         return JSValue::encode(jsUndefined());
360     size_t i = 0;
361     size_t argCount = exec->argumentCount();
362     while (1) {
363         if (curArg.inherits(&JSArray::s_info)) {
364             unsigned length = curArg.get(exec, exec->propertyNames().length).toUInt32(exec);
365             JSObject* curObject = curArg.toObject(exec);
366             for (unsigned k = 0; k < length; ++k) {
367                 JSValue v = getProperty(exec, curObject, k);
368                 if (exec->hadException())
369                     return JSValue::encode(jsUndefined());
370                 if (v)
371                     arr->methodTable()->putByIndex(arr, exec, n, v);
372                 n++;
373             }
374         } else {
375             arr->methodTable()->putByIndex(arr, exec, n, curArg);
376             n++;
377         }
378         if (i == argCount)
379             break;
380         curArg = (exec->argument(i));
381         ++i;
382     }
383     arr->setLength(exec, n);
384     return JSValue::encode(arr);
385 }
386
387 EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec)
388 {
389     JSValue thisValue = exec->hostThisValue();
390
391     if (isJSArray(thisValue))
392         return JSValue::encode(asArray(thisValue)->pop(exec));
393
394     JSObject* thisObj = thisValue.toObject(exec);
395     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
396     if (exec->hadException())
397         return JSValue::encode(jsUndefined());
398
399     JSValue result;
400     if (length == 0) {
401         putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length));
402         result = jsUndefined();
403     } else {
404         result = thisObj->get(exec, length - 1);
405         thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, length - 1);
406         putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - 1));
407     }
408     return JSValue::encode(result);
409 }
410
411 EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
412 {
413     JSValue thisValue = exec->hostThisValue();
414
415     if (isJSArray(thisValue) && exec->argumentCount() == 1) {
416         JSArray* array = asArray(thisValue);
417         array->push(exec, exec->argument(0));
418         return JSValue::encode(jsNumber(array->length()));
419     }
420
421     JSObject* thisObj = thisValue.toObject(exec);
422     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
423     if (exec->hadException())
424         return JSValue::encode(jsUndefined());
425
426     for (unsigned n = 0; n < exec->argumentCount(); n++) {
427         // Check for integer overflow; where safe we can do a fast put by index.
428         if (length + n >= length)
429             thisObj->methodTable()->putByIndex(thisObj, exec, length + n, exec->argument(n));
430         else {
431             PutPropertySlot slot;
432             Identifier propertyName(exec, JSValue(static_cast<int64_t>(length) + static_cast<int64_t>(n)).toString(exec)->value(exec));
433             thisObj->methodTable()->put(thisObj, exec, propertyName, exec->argument(n), slot);
434         }
435     }
436     JSValue newLength(static_cast<int64_t>(length) + static_cast<int64_t>(exec->argumentCount()));
437     putProperty(exec, thisObj, exec->propertyNames().length, newLength);
438     return JSValue::encode(newLength);
439 }
440
441 EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec)
442 {
443     JSObject* thisObj = exec->hostThisValue().toObject(exec);
444     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
445     if (exec->hadException())
446         return JSValue::encode(jsUndefined());
447
448     unsigned middle = length / 2;
449     for (unsigned k = 0; k < middle; k++) {
450         unsigned lk1 = length - k - 1;
451         JSValue obj2 = getProperty(exec, thisObj, lk1);
452         if (exec->hadException())
453             return JSValue::encode(jsUndefined());
454         JSValue obj = getProperty(exec, thisObj, k);
455         if (exec->hadException())
456             return JSValue::encode(jsUndefined());
457
458         if (obj2)
459             thisObj->methodTable()->putByIndex(thisObj, exec, k, obj2);
460         else
461             thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k);
462
463         if (obj)
464             thisObj->methodTable()->putByIndex(thisObj, exec, lk1, obj);
465         else
466             thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, lk1);
467     }
468     return JSValue::encode(thisObj);
469 }
470
471 EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec)
472 {
473     JSObject* thisObj = exec->hostThisValue().toObject(exec);
474     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
475     if (exec->hadException())
476         return JSValue::encode(jsUndefined());
477
478     JSValue result;
479     if (length == 0) {
480         putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length));
481         result = jsUndefined();
482     } else {
483         result = thisObj->get(exec, 0);
484         if (isJSArray(thisObj))
485             ((JSArray *)thisObj)->shiftCount(exec, 1);
486         else {
487             for (unsigned k = 1; k < length; k++) {
488                 JSValue obj = getProperty(exec, thisObj, k);
489                 if (exec->hadException())
490                     return JSValue::encode(jsUndefined());
491                 if (obj)
492                     thisObj->methodTable()->putByIndex(thisObj, exec, k - 1, obj);
493                 else
494                     thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k - 1);
495             }
496             thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, length - 1);
497         }
498         putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - 1));
499     }
500     return JSValue::encode(result);
501 }
502
503 EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
504 {
505     // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713 or 15.4.4.10
506     JSObject* thisObj = exec->hostThisValue().toObject(exec);
507     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
508     if (exec->hadException())
509         return JSValue::encode(jsUndefined());
510
511     // We return a new array
512     JSArray* resObj = constructEmptyArray(exec);
513     JSValue result = resObj;
514
515     unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
516     unsigned end = argumentClampedIndexFromStartOrEnd(exec, 1, length, length);
517
518     unsigned n = 0;
519     for (unsigned k = begin; k < end; k++, n++) {
520         JSValue v = getProperty(exec, thisObj, k);
521         if (exec->hadException())
522             return JSValue::encode(jsUndefined());
523         if (v)
524             resObj->methodTable()->putByIndex(resObj, exec, n, v);
525     }
526     resObj->setLength(exec, n);
527     return JSValue::encode(result);
528 }
529
530 EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
531 {
532     JSObject* thisObj = exec->hostThisValue().toObject(exec);
533     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
534     if (!length || exec->hadException())
535         return JSValue::encode(thisObj);
536
537     JSValue function = exec->argument(0);
538     CallData callData;
539     CallType callType = getCallData(function, callData);
540
541     if (thisObj->classInfo() == &JSArray::s_info && !asArray(thisObj)->inSparseMode()) {
542         if (isNumericCompareFunction(exec, callType, callData))
543             asArray(thisObj)->sortNumeric(exec, function, callType, callData);
544         else if (callType != CallTypeNone)
545             asArray(thisObj)->sort(exec, function, callType, callData);
546         else
547             asArray(thisObj)->sort(exec);
548         return JSValue::encode(thisObj);
549     }
550
551     // "Min" sort. Not the fastest, but definitely less code than heapsort
552     // or quicksort, and much less swapping than bubblesort/insertionsort.
553     for (unsigned i = 0; i < length - 1; ++i) {
554         JSValue iObj = thisObj->get(exec, i);
555         if (exec->hadException())
556             return JSValue::encode(jsUndefined());
557         unsigned themin = i;
558         JSValue minObj = iObj;
559         for (unsigned j = i + 1; j < length; ++j) {
560             JSValue jObj = thisObj->get(exec, j);
561             if (exec->hadException())
562                 return JSValue::encode(jsUndefined());
563             double compareResult;
564             if (jObj.isUndefined())
565                 compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1)
566             else if (minObj.isUndefined())
567                 compareResult = -1;
568             else if (callType != CallTypeNone) {
569                 MarkedArgumentBuffer l;
570                 l.append(jObj);
571                 l.append(minObj);
572                 compareResult = call(exec, function, callType, callData, jsUndefined(), l).toNumber(exec);
573             } else
574                 compareResult = (jObj.toString(exec) < minObj.toString(exec)) ? -1 : 1;
575
576             if (compareResult < 0) {
577                 themin = j;
578                 minObj = jObj;
579             }
580         }
581         // Swap themin and i
582         if (themin > i) {
583             thisObj->methodTable()->putByIndex(thisObj, exec, i, minObj);
584             thisObj->methodTable()->putByIndex(thisObj, exec, themin, iObj);
585         }
586     }
587     return JSValue::encode(thisObj);
588 }
589
590 EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
591 {
592     // 15.4.4.12
593
594     JSObject* thisObj = exec->hostThisValue().toObject(exec);
595     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
596     if (exec->hadException())
597         return JSValue::encode(jsUndefined());
598
599     if (!exec->argumentCount())
600         return JSValue::encode(constructEmptyArray(exec));
601
602     unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
603
604     unsigned deleteCount = length - begin;
605     if (exec->argumentCount() > 1) {
606         double deleteDouble = exec->argument(1).toInteger(exec);
607         if (deleteDouble < 0)
608             deleteCount = 0;
609         else if (deleteDouble > length - begin)
610             deleteCount = length - begin;
611         else
612             deleteCount = static_cast<unsigned>(deleteDouble);
613     }
614
615     JSArray* resObj = JSArray::tryCreateUninitialized(exec->globalData(), exec->lexicalGlobalObject()->arrayStructure(), deleteCount);
616     if (!resObj)
617         return JSValue::encode(throwOutOfMemoryError(exec));
618
619     JSValue result = resObj;
620     JSGlobalData& globalData = exec->globalData();
621     for (unsigned k = 0; k < deleteCount; k++) {
622         JSValue v = getProperty(exec, thisObj, k + begin);
623         if (exec->hadException())
624             return JSValue::encode(jsUndefined());
625         resObj->initializeIndex(globalData, k, v);
626     }
627     resObj->completeInitialization(deleteCount);
628
629     unsigned additionalArgs = std::max<int>(exec->argumentCount() - 2, 0);
630     if (additionalArgs != deleteCount) {
631         if (additionalArgs < deleteCount) {
632             if ((!begin) && (isJSArray(thisObj)))
633                 ((JSArray *)thisObj)->shiftCount(exec, deleteCount - additionalArgs);
634             else {
635                 for (unsigned k = begin; k < length - deleteCount; ++k) {
636                     JSValue v = getProperty(exec, thisObj, k + deleteCount);
637                     if (exec->hadException())
638                         return JSValue::encode(jsUndefined());
639                     if (v)
640                         thisObj->methodTable()->putByIndex(thisObj, exec, k + additionalArgs, v);
641                     else
642                         thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k + additionalArgs);
643                 }
644                 for (unsigned k = length; k > length - deleteCount + additionalArgs; --k)
645                     thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k - 1);
646             }
647         } else {
648             if ((!begin) && (isJSArray(thisObj)))
649                 ((JSArray *)thisObj)->unshiftCount(exec, additionalArgs - deleteCount);
650             else {
651                 for (unsigned k = length - deleteCount; k > begin; --k) {
652                     JSValue obj = getProperty(exec, thisObj, k + deleteCount - 1);
653                     if (exec->hadException())
654                         return JSValue::encode(jsUndefined());
655                     if (obj)
656                         thisObj->methodTable()->putByIndex(thisObj, exec, k + additionalArgs - 1, obj);
657                     else
658                         thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k + additionalArgs - 1);
659                 }
660             }
661         }
662     }
663     for (unsigned k = 0; k < additionalArgs; ++k)
664         thisObj->methodTable()->putByIndex(thisObj, exec, k + begin, exec->argument(k + 2));
665
666     putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - deleteCount + additionalArgs));
667     return JSValue::encode(result);
668 }
669
670 EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec)
671 {
672     // 15.4.4.13
673
674     JSObject* thisObj = exec->hostThisValue().toObject(exec);
675     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
676     if (exec->hadException())
677         return JSValue::encode(jsUndefined());
678
679     unsigned nrArgs = exec->argumentCount();
680     if ((nrArgs) && (length)) {
681         if (isJSArray(thisObj))
682             ((JSArray *)thisObj)->unshiftCount(exec, nrArgs);
683         else {
684             for (unsigned k = length; k > 0; --k) {
685                 JSValue v = getProperty(exec, thisObj, k - 1);
686                 if (exec->hadException())
687                     return JSValue::encode(jsUndefined());
688                 if (v)
689                     thisObj->methodTable()->putByIndex(thisObj, exec, k + nrArgs - 1, v);
690                 else
691                     thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k + nrArgs - 1);
692             }
693         }
694     }
695     for (unsigned k = 0; k < nrArgs; ++k)
696         thisObj->methodTable()->putByIndex(thisObj, exec, k, exec->argument(k));
697     JSValue result = jsNumber(length + nrArgs);
698     putProperty(exec, thisObj, exec->propertyNames().length, result);
699     return JSValue::encode(result);
700 }
701
702 EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
703 {
704     JSObject* thisObj = exec->hostThisValue().toObject(exec);
705     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
706     if (exec->hadException())
707         return JSValue::encode(jsUndefined());
708
709     JSValue function = exec->argument(0);
710     CallData callData;
711     CallType callType = getCallData(function, callData);
712     if (callType == CallTypeNone)
713         return throwVMTypeError(exec);
714
715     JSValue applyThis = exec->argument(1);
716     JSArray* resultArray = constructEmptyArray(exec);
717
718     unsigned filterIndex = 0;
719     unsigned k = 0;
720     if (callType == CallTypeJS && isJSArray(thisObj)) {
721         JSFunction* f = asFunction(function);
722         JSArray* array = asArray(thisObj);
723         CachedCall cachedCall(exec, f, 3);
724         for (; k < length && !exec->hadException(); ++k) {
725             if (!array->canGetIndex(k))
726                 break;
727             JSValue v = array->getIndex(k);
728             cachedCall.setThis(applyThis);
729             cachedCall.setArgument(0, v);
730             cachedCall.setArgument(1, jsNumber(k));
731             cachedCall.setArgument(2, thisObj);
732             
733             JSValue result = cachedCall.call();
734             if (result.toBoolean(exec))
735                 resultArray->methodTable()->putByIndex(resultArray, exec, filterIndex++, v);
736         }
737         if (k == length)
738             return JSValue::encode(resultArray);
739     }
740     for (; k < length && !exec->hadException(); ++k) {
741         PropertySlot slot(thisObj);
742         if (!thisObj->getPropertySlot(exec, k, slot))
743             continue;
744         JSValue v = slot.getValue(exec, k);
745
746         if (exec->hadException())
747             return JSValue::encode(jsUndefined());
748
749         MarkedArgumentBuffer eachArguments;
750         eachArguments.append(v);
751         eachArguments.append(jsNumber(k));
752         eachArguments.append(thisObj);
753
754         JSValue result = call(exec, function, callType, callData, applyThis, eachArguments);
755         if (result.toBoolean(exec))
756             resultArray->methodTable()->putByIndex(resultArray, exec, filterIndex++, v);
757     }
758     return JSValue::encode(resultArray);
759 }
760
761 EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
762 {
763     JSObject* thisObj = exec->hostThisValue().toObject(exec);
764     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
765     if (exec->hadException())
766         return JSValue::encode(jsUndefined());
767
768     JSValue function = exec->argument(0);
769     CallData callData;
770     CallType callType = getCallData(function, callData);
771     if (callType == CallTypeNone)
772         return throwVMTypeError(exec);
773
774     JSValue applyThis = exec->argument(1);
775
776     JSArray* resultArray = constructEmptyArray(exec, length);
777     unsigned k = 0;
778     if (callType == CallTypeJS && isJSArray(thisObj)) {
779         JSFunction* f = asFunction(function);
780         JSArray* array = asArray(thisObj);
781         CachedCall cachedCall(exec, f, 3);
782         for (; k < length && !exec->hadException(); ++k) {
783             if (UNLIKELY(!array->canGetIndex(k)))
784                 break;
785
786             cachedCall.setThis(applyThis);
787             cachedCall.setArgument(0, array->getIndex(k));
788             cachedCall.setArgument(1, jsNumber(k));
789             cachedCall.setArgument(2, thisObj);
790
791             JSArray::putByIndex(resultArray, exec, k, cachedCall.call());
792         }
793     }
794     for (; k < length && !exec->hadException(); ++k) {
795         PropertySlot slot(thisObj);
796         if (!thisObj->getPropertySlot(exec, k, slot))
797             continue;
798         JSValue v = slot.getValue(exec, k);
799
800         if (exec->hadException())
801             return JSValue::encode(jsUndefined());
802
803         MarkedArgumentBuffer eachArguments;
804         eachArguments.append(v);
805         eachArguments.append(jsNumber(k));
806         eachArguments.append(thisObj);
807
808         if (exec->hadException())
809             return JSValue::encode(jsUndefined());
810
811         JSValue result = call(exec, function, callType, callData, applyThis, eachArguments);
812         resultArray->methodTable()->putByIndex(resultArray, exec, k, result);
813     }
814
815     return JSValue::encode(resultArray);
816 }
817
818 // Documentation for these three is available at:
819 // http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:every
820 // http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach
821 // http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:some
822
823 EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
824 {
825     JSObject* thisObj = exec->hostThisValue().toObject(exec);
826     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
827     if (exec->hadException())
828         return JSValue::encode(jsUndefined());
829
830     JSValue function = exec->argument(0);
831     CallData callData;
832     CallType callType = getCallData(function, callData);
833     if (callType == CallTypeNone)
834         return throwVMTypeError(exec);
835
836     JSValue applyThis = exec->argument(1);
837
838     JSValue result = jsBoolean(true);
839
840     unsigned k = 0;
841     if (callType == CallTypeJS && isJSArray(thisObj)) {
842         JSFunction* f = asFunction(function);
843         JSArray* array = asArray(thisObj);
844         CachedCall cachedCall(exec, f, 3);
845         for (; k < length && !exec->hadException(); ++k) {
846             if (UNLIKELY(!array->canGetIndex(k)))
847                 break;
848             
849             cachedCall.setThis(applyThis);
850             cachedCall.setArgument(0, array->getIndex(k));
851             cachedCall.setArgument(1, jsNumber(k));
852             cachedCall.setArgument(2, thisObj);
853             JSValue result = cachedCall.call();
854             if (!result.toBoolean(cachedCall.newCallFrame(exec)))
855                 return JSValue::encode(jsBoolean(false));
856         }
857     }
858     for (; k < length && !exec->hadException(); ++k) {
859         PropertySlot slot(thisObj);
860         if (!thisObj->getPropertySlot(exec, k, slot))
861             continue;
862
863         MarkedArgumentBuffer eachArguments;
864         eachArguments.append(slot.getValue(exec, k));
865         eachArguments.append(jsNumber(k));
866         eachArguments.append(thisObj);
867
868         if (exec->hadException())
869             return JSValue::encode(jsUndefined());
870
871         bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
872         if (!predicateResult) {
873             result = jsBoolean(false);
874             break;
875         }
876     }
877
878     return JSValue::encode(result);
879 }
880
881 EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
882 {
883     JSObject* thisObj = exec->hostThisValue().toObject(exec);
884     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
885     if (exec->hadException())
886         return JSValue::encode(jsUndefined());
887
888     JSValue function = exec->argument(0);
889     CallData callData;
890     CallType callType = getCallData(function, callData);
891     if (callType == CallTypeNone)
892         return throwVMTypeError(exec);
893
894     JSValue applyThis = exec->argument(1);
895
896     unsigned k = 0;
897     if (callType == CallTypeJS && isJSArray(thisObj)) {
898         JSFunction* f = asFunction(function);
899         JSArray* array = asArray(thisObj);
900         CachedCall cachedCall(exec, f, 3);
901         for (; k < length && !exec->hadException(); ++k) {
902             if (UNLIKELY(!array->canGetIndex(k)))
903                 break;
904
905             cachedCall.setThis(applyThis);
906             cachedCall.setArgument(0, array->getIndex(k));
907             cachedCall.setArgument(1, jsNumber(k));
908             cachedCall.setArgument(2, thisObj);
909
910             cachedCall.call();
911         }
912     }
913     for (; k < length && !exec->hadException(); ++k) {
914         PropertySlot slot(thisObj);
915         if (!thisObj->getPropertySlot(exec, k, slot))
916             continue;
917
918         MarkedArgumentBuffer eachArguments;
919         eachArguments.append(slot.getValue(exec, k));
920         eachArguments.append(jsNumber(k));
921         eachArguments.append(thisObj);
922
923         if (exec->hadException())
924             return JSValue::encode(jsUndefined());
925
926         call(exec, function, callType, callData, applyThis, eachArguments);
927     }
928     return JSValue::encode(jsUndefined());
929 }
930
931 EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
932 {
933     JSObject* thisObj = exec->hostThisValue().toObject(exec);
934     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
935     if (exec->hadException())
936         return JSValue::encode(jsUndefined());
937
938     JSValue function = exec->argument(0);
939     CallData callData;
940     CallType callType = getCallData(function, callData);
941     if (callType == CallTypeNone)
942         return throwVMTypeError(exec);
943
944     JSValue applyThis = exec->argument(1);
945
946     JSValue result = jsBoolean(false);
947
948     unsigned k = 0;
949     if (callType == CallTypeJS && isJSArray(thisObj)) {
950         JSFunction* f = asFunction(function);
951         JSArray* array = asArray(thisObj);
952         CachedCall cachedCall(exec, f, 3);
953         for (; k < length && !exec->hadException(); ++k) {
954             if (UNLIKELY(!array->canGetIndex(k)))
955                 break;
956             
957             cachedCall.setThis(applyThis);
958             cachedCall.setArgument(0, array->getIndex(k));
959             cachedCall.setArgument(1, jsNumber(k));
960             cachedCall.setArgument(2, thisObj);
961             JSValue result = cachedCall.call();
962             if (result.toBoolean(cachedCall.newCallFrame(exec)))
963                 return JSValue::encode(jsBoolean(true));
964         }
965     }
966     for (; k < length && !exec->hadException(); ++k) {
967         PropertySlot slot(thisObj);
968         if (!thisObj->getPropertySlot(exec, k, slot))
969             continue;
970
971         MarkedArgumentBuffer eachArguments;
972         eachArguments.append(slot.getValue(exec, k));
973         eachArguments.append(jsNumber(k));
974         eachArguments.append(thisObj);
975
976         if (exec->hadException())
977             return JSValue::encode(jsUndefined());
978
979         bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
980         if (predicateResult) {
981             result = jsBoolean(true);
982             break;
983         }
984     }
985     return JSValue::encode(result);
986 }
987
988 EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec)
989 {
990     JSObject* thisObj = exec->hostThisValue().toObject(exec);
991     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
992     if (exec->hadException())
993         return JSValue::encode(jsUndefined());
994
995     JSValue function = exec->argument(0);
996     CallData callData;
997     CallType callType = getCallData(function, callData);
998     if (callType == CallTypeNone)
999         return throwVMTypeError(exec);
1000
1001     unsigned i = 0;
1002     JSValue rv;
1003     if (!length && exec->argumentCount() == 1)
1004         return throwVMTypeError(exec);
1005
1006     JSArray* array = 0;
1007     if (isJSArray(thisObj))
1008         array = asArray(thisObj);
1009
1010     if (exec->argumentCount() >= 2)
1011         rv = exec->argument(1);
1012     else if (array && array->canGetIndex(0)){
1013         rv = array->getIndex(0);
1014         i = 1;
1015     } else {
1016         for (i = 0; i < length; i++) {
1017             rv = getProperty(exec, thisObj, i);
1018             if (exec->hadException())
1019                 return JSValue::encode(jsUndefined());
1020             if (rv)
1021                 break;
1022         }
1023         if (!rv)
1024             return throwVMTypeError(exec);
1025         i++;
1026     }
1027
1028     if (callType == CallTypeJS && array) {
1029         CachedCall cachedCall(exec, asFunction(function), 4);
1030         for (; i < length && !exec->hadException(); ++i) {
1031             cachedCall.setThis(jsUndefined());
1032             cachedCall.setArgument(0, rv);
1033             JSValue v;
1034             if (LIKELY(array->canGetIndex(i)))
1035                 v = array->getIndex(i);
1036             else
1037                 break; // length has been made unsafe while we enumerate fallback to slow path
1038             cachedCall.setArgument(1, v);
1039             cachedCall.setArgument(2, jsNumber(i));
1040             cachedCall.setArgument(3, array);
1041             rv = cachedCall.call();
1042         }
1043         if (i == length) // only return if we reached the end of the array
1044             return JSValue::encode(rv);
1045     }
1046
1047     for (; i < length && !exec->hadException(); ++i) {
1048         JSValue prop = getProperty(exec, thisObj, i);
1049         if (exec->hadException())
1050             return JSValue::encode(jsUndefined());
1051         if (!prop)
1052             continue;
1053         
1054         MarkedArgumentBuffer eachArguments;
1055         eachArguments.append(rv);
1056         eachArguments.append(prop);
1057         eachArguments.append(jsNumber(i));
1058         eachArguments.append(thisObj);
1059         
1060         rv = call(exec, function, callType, callData, jsUndefined(), eachArguments);
1061     }
1062     return JSValue::encode(rv);
1063 }
1064
1065 EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec)
1066 {
1067     JSObject* thisObj = exec->hostThisValue().toObject(exec);
1068     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
1069     if (exec->hadException())
1070         return JSValue::encode(jsUndefined());
1071
1072     JSValue function = exec->argument(0);
1073     CallData callData;
1074     CallType callType = getCallData(function, callData);
1075     if (callType == CallTypeNone)
1076         return throwVMTypeError(exec);
1077     
1078     unsigned i = 0;
1079     JSValue rv;
1080     if (!length && exec->argumentCount() == 1)
1081         return throwVMTypeError(exec);
1082
1083     JSArray* array = 0;
1084     if (isJSArray(thisObj))
1085         array = asArray(thisObj);
1086     
1087     if (exec->argumentCount() >= 2)
1088         rv = exec->argument(1);
1089     else if (array && array->canGetIndex(length - 1)){
1090         rv = array->getIndex(length - 1);
1091         i = 1;
1092     } else {
1093         for (i = 0; i < length; i++) {
1094             rv = getProperty(exec, thisObj, length - i - 1);
1095             if (exec->hadException())
1096                 return JSValue::encode(jsUndefined());
1097             if (rv)
1098                 break;
1099         }
1100         if (!rv)
1101             return throwVMTypeError(exec);
1102         i++;
1103     }
1104     
1105     if (callType == CallTypeJS && array) {
1106         CachedCall cachedCall(exec, asFunction(function), 4);
1107         for (; i < length && !exec->hadException(); ++i) {
1108             unsigned idx = length - i - 1;
1109             cachedCall.setThis(jsUndefined());
1110             cachedCall.setArgument(0, rv);
1111             if (UNLIKELY(!array->canGetIndex(idx)))
1112                 break; // length has been made unsafe while we enumerate fallback to slow path
1113             cachedCall.setArgument(1, array->getIndex(idx));
1114             cachedCall.setArgument(2, jsNumber(idx));
1115             cachedCall.setArgument(3, array);
1116             rv = cachedCall.call();
1117         }
1118         if (i == length) // only return if we reached the end of the array
1119             return JSValue::encode(rv);
1120     }
1121     
1122     for (; i < length && !exec->hadException(); ++i) {
1123         unsigned idx = length - i - 1;
1124         JSValue prop = getProperty(exec, thisObj, idx);
1125         if (exec->hadException())
1126             return JSValue::encode(jsUndefined());
1127         if (!prop)
1128             continue;
1129         
1130         MarkedArgumentBuffer eachArguments;
1131         eachArguments.append(rv);
1132         eachArguments.append(prop);
1133         eachArguments.append(jsNumber(idx));
1134         eachArguments.append(thisObj);
1135         
1136         rv = call(exec, function, callType, callData, jsUndefined(), eachArguments);
1137     }
1138     return JSValue::encode(rv);        
1139 }
1140
1141 EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec)
1142 {
1143     // 15.4.4.14
1144     JSObject* thisObj = exec->hostThisValue().toObject(exec);
1145     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
1146     if (exec->hadException())
1147         return JSValue::encode(jsUndefined());
1148
1149     unsigned index = argumentClampedIndexFromStartOrEnd(exec, 1, length);
1150     JSValue searchElement = exec->argument(0);
1151     for (; index < length; ++index) {
1152         JSValue e = getProperty(exec, thisObj, index);
1153         if (exec->hadException())
1154             return JSValue::encode(jsUndefined());
1155         if (!e)
1156             continue;
1157         if (JSValue::strictEqual(exec, searchElement, e))
1158             return JSValue::encode(jsNumber(index));
1159     }
1160
1161     return JSValue::encode(jsNumber(-1));
1162 }
1163
1164 EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState* exec)
1165 {
1166     // 15.4.4.15
1167     JSObject* thisObj = exec->hostThisValue().toObject(exec);
1168     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
1169     if (!length)
1170         return JSValue::encode(jsNumber(-1));
1171
1172     unsigned index = length - 1;
1173     if (exec->argumentCount() >= 2) {
1174         JSValue fromValue = exec->argument(1);
1175         double fromDouble = fromValue.toInteger(exec);
1176         if (fromDouble < 0) {
1177             fromDouble += length;
1178             if (fromDouble < 0)
1179                 return JSValue::encode(jsNumber(-1));
1180         }
1181         if (fromDouble < length)
1182             index = static_cast<unsigned>(fromDouble);
1183     }
1184
1185     JSValue searchElement = exec->argument(0);
1186     do {
1187         ASSERT(index < length);
1188         JSValue e = getProperty(exec, thisObj, index);
1189         if (exec->hadException())
1190             return JSValue::encode(jsUndefined());
1191         if (!e)
1192             continue;
1193         if (JSValue::strictEqual(exec, searchElement, e))
1194             return JSValue::encode(jsNumber(index));
1195     } while (index--);
1196
1197     return JSValue::encode(jsNumber(-1));
1198 }
1199
1200 } // namespace JSC