2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
4 * Copyright (C) 2003 Peter Kelly (pmk@post.com)
5 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
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.
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.
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
25 #include "array_object.h"
26 #include "array_object.lut.h"
28 #include "error_object.h"
30 #include "operations.h"
32 #include <wtf/Assertions.h>
33 #include <wtf/HashSet.h>
35 #include <algorithm> // for std::min
39 // ------------------------------ ArrayPrototype ----------------------------
41 const ClassInfo ArrayPrototype::info = {"Array", &ArrayInstance::info, 0, ExecState::arrayTable};
43 /* Source for array_object.lut.h
45 toString arrayProtoFuncToString DontEnum|Function 0
46 toLocaleString arrayProtoFuncToLocaleString DontEnum|Function 0
47 concat arrayProtoFuncConcat DontEnum|Function 1
48 join arrayProtoFuncJoin DontEnum|Function 1
49 pop arrayProtoFuncPop DontEnum|Function 0
50 push arrayProtoFuncPush DontEnum|Function 1
51 reverse arrayProtoFuncReverse DontEnum|Function 0
52 shift arrayProtoFuncShift DontEnum|Function 0
53 slice arrayProtoFuncSlice DontEnum|Function 2
54 sort arrayProtoFuncSort DontEnum|Function 1
55 splice arrayProtoFuncSplice DontEnum|Function 2
56 unshift arrayProtoFuncUnShift DontEnum|Function 1
57 every arrayProtoFuncEvery DontEnum|Function 1
58 forEach arrayProtoFuncForEach DontEnum|Function 1
59 some arrayProtoFuncSome DontEnum|Function 1
60 indexOf arrayProtoFuncIndexOf DontEnum|Function 1
61 lastIndexOf arrayProtoFuncLastIndexOf DontEnum|Function 1
62 filter arrayProtoFuncFilter DontEnum|Function 1
63 map arrayProtoFuncMap DontEnum|Function 1
68 ArrayPrototype::ArrayPrototype(ExecState*, ObjectPrototype* objProto)
69 : ArrayInstance(objProto, 0)
73 bool ArrayPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
75 return getStaticFunctionSlot<ArrayInstance>(exec, ExecState::arrayTable(exec), this, propertyName, slot);
79 // ------------------------------ Array Functions ----------------------------
82 static JSValue* getProperty(ExecState* exec, JSObject* obj, unsigned index)
85 if (!obj->getPropertySlot(exec, index, slot))
87 return slot.getValue(exec, obj, index);
90 JSValue* arrayProtoFuncToString(ExecState* exec, JSObject* thisObj, const List&)
92 if (!thisObj->inherits(&ArrayInstance::info))
93 return throwError(exec, TypeError);
95 bool alreadyVisited = !exec->dynamicGlobalObject()->arrayVisitedElements().add(thisObj).second;
96 Vector<UChar, 256> strBuffer;
98 return jsString(exec, UString(0, 0)); // return an empty string, avoding infinite recursion.
100 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
101 for (unsigned k = 0; k < length; k++) {
103 strBuffer.append(',');
104 if (!strBuffer.data()) {
105 JSObject* error = Error::create(exec, GeneralError, "Out of memory");
106 exec->setException(error);
110 JSValue* element = thisObj->get(exec, k);
111 if (element->isUndefinedOrNull())
114 UString str = element->toString(exec);
115 strBuffer.append(str.data(), str.size());
117 if (!strBuffer.data()) {
118 JSObject* error = Error::create(exec, GeneralError, "Out of memory");
119 exec->setException(error);
122 if (exec->hadException())
125 exec->dynamicGlobalObject()->arrayVisitedElements().remove(thisObj);
126 return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
129 JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const List&)
131 if (!thisObj->inherits(&ArrayInstance::info))
132 return throwError(exec, TypeError);
134 bool alreadyVisited = !exec->dynamicGlobalObject()->arrayVisitedElements().add(thisObj).second;
135 Vector<UChar, 256> strBuffer;
137 return jsString(exec, UString(0, 0)); // return an empty string, avoding infinite recursion.
139 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
140 for (unsigned k = 0; k < length; k++) {
142 strBuffer.append(',');
143 if (!strBuffer.data()) {
144 JSObject* error = Error::create(exec, GeneralError, "Out of memory");
145 exec->setException(error);
149 JSValue* element = thisObj->get(exec, k);
150 if (element->isUndefinedOrNull())
153 JSObject* o = element->toObject(exec);
154 JSValue* conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
156 if (conversionFunction->isObject() && static_cast<JSObject*>(conversionFunction)->implementsCall())
157 str = static_cast<JSObject*>(conversionFunction)->call(exec, o, exec->emptyList())->toString(exec);
159 str = element->toString(exec);
160 strBuffer.append(str.data(), str.size());
162 if (!strBuffer.data()) {
163 JSObject* error = Error::create(exec, GeneralError, "Out of memory");
164 exec->setException(error);
167 if (exec->hadException())
170 exec->dynamicGlobalObject()->arrayVisitedElements().remove(thisObj);
171 return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
174 JSValue* arrayProtoFuncJoin(ExecState* exec, JSObject* thisObj, const List& args)
176 bool alreadyVisited = !exec->dynamicGlobalObject()->arrayVisitedElements().add(thisObj).second;
177 Vector<UChar, 256> strBuffer;
179 return jsString(exec, UString(0, 0)); // return an empty string, avoding infinite recursion.
182 UString separator = args[0]->isUndefined() ? UString(&comma, 1) : args[0]->toString(exec);
184 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
185 for (unsigned k = 0; k < length; k++) {
187 strBuffer.append(separator.data(), separator.size());
188 if (!strBuffer.data()) {
189 JSObject* error = Error::create(exec, GeneralError, "Out of memory");
190 exec->setException(error);
194 JSValue* element = thisObj->get(exec, k);
195 if (element->isUndefinedOrNull())
198 UString str = element->toString(exec);
199 strBuffer.append(str.data(), str.size());
201 if (!strBuffer.data()) {
202 JSObject* error = Error::create(exec, GeneralError, "Out of memory");
203 exec->setException(error);
206 if (exec->hadException())
209 exec->dynamicGlobalObject()->arrayVisitedElements().remove(thisObj);
210 return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
213 JSValue* arrayProtoFuncConcat(ExecState* exec, JSObject* thisObj, const List& args)
215 JSObject* arr = static_cast<JSObject*>(exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList()));
217 JSValue* curArg = thisObj;
218 JSObject* curObj = static_cast<JSObject* >(thisObj);
219 List::const_iterator it = args.begin();
220 List::const_iterator end = args.end();
222 if (curArg->isObject() && curObj->inherits(&ArrayInstance::info)) {
224 // Older versions tried to optimize out getting the length of thisObj
225 // by checking for n != 0, but that doesn't work if thisObj is an empty array.
226 unsigned length = curObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
228 if (JSValue* v = getProperty(exec, curObj, k))
229 arr->put(exec, n, v);
234 arr->put(exec, n, curArg);
240 curObj = static_cast<JSObject*>(curArg); // may be 0
243 arr->put(exec, exec->propertyNames().length, jsNumber(exec, n));
247 JSValue* arrayProtoFuncPop(ExecState* exec, JSObject* thisObj, const List&)
250 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
252 thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));
253 result = jsUndefined();
255 result = thisObj->get(exec, length - 1);
256 thisObj->deleteProperty(exec, length - 1);
257 thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - 1));
262 JSValue* arrayProtoFuncPush(ExecState* exec, JSObject* thisObj, const List& args)
264 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
265 for (unsigned n = 0; n < args.size(); n++)
266 thisObj->put(exec, length + n, args[n]);
267 length += args.size();
268 thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));
269 return jsNumber(exec, length);
272 JSValue* arrayProtoFuncReverse(ExecState* exec, JSObject* thisObj, const List&)
274 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
275 unsigned middle = length / 2;
277 for (unsigned k = 0; k < middle; k++) {
278 unsigned lk1 = length - k - 1;
279 JSValue* obj2 = getProperty(exec, thisObj, lk1);
280 JSValue* obj = getProperty(exec, thisObj, k);
283 thisObj->put(exec, k, obj2);
285 thisObj->deleteProperty(exec, k);
288 thisObj->put(exec, lk1, obj);
290 thisObj->deleteProperty(exec, lk1);
295 JSValue* arrayProtoFuncShift(ExecState* exec, JSObject* thisObj, const List&)
299 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
301 thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));
302 result = jsUndefined();
304 result = thisObj->get(exec, 0);
305 for (unsigned k = 1; k < length; k++) {
306 if (JSValue* obj = getProperty(exec, thisObj, k))
307 thisObj->put(exec, k - 1, obj);
309 thisObj->deleteProperty(exec, k - 1);
311 thisObj->deleteProperty(exec, length - 1);
312 thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - 1));
317 JSValue* arrayProtoFuncSlice(ExecState* exec, JSObject* thisObj, const List& args)
319 // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713 or 15.4.4.10
321 // We return a new array
322 JSObject* resObj = static_cast<JSObject* >(exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList()));
323 JSValue* result = resObj;
324 double begin = args[0]->toInteger(exec);
325 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
335 if (args[1]->isUndefined())
338 end = args[1]->toInteger(exec);
350 int b = static_cast<int>(begin);
351 int e = static_cast<int>(end);
352 for (int k = b; k < e; k++, n++) {
353 if (JSValue* v = getProperty(exec, thisObj, k))
354 resObj->put(exec, n, v);
356 resObj->put(exec, exec->propertyNames().length, jsNumber(exec, n));
360 JSValue* arrayProtoFuncSort(ExecState* exec, JSObject* thisObj, const List& args)
362 JSObject* sortFunction = 0;
363 if (!args[0]->isUndefined()) {
364 sortFunction = args[0]->toObject(exec);
365 if (!sortFunction->implementsCall())
369 if (thisObj->classInfo() == &ArrayInstance::info) {
371 static_cast<ArrayInstance*>(thisObj)->sort(exec, sortFunction);
373 static_cast<ArrayInstance*>(thisObj)->sort(exec);
377 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
382 // "Min" sort. Not the fastest, but definitely less code than heapsort
383 // or quicksort, and much less swapping than bubblesort/insertionsort.
384 for (unsigned i = 0; i < length - 1; ++i) {
385 JSValue* iObj = thisObj->get(exec, i);
387 JSValue* minObj = iObj;
388 for (unsigned j = i + 1; j < length; ++j) {
389 JSValue* jObj = thisObj->get(exec, j);
390 double compareResult;
391 if (jObj->isUndefined())
392 compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1)
393 else if (minObj->isUndefined())
395 else if (sortFunction) {
399 compareResult = sortFunction->call(exec, exec->globalThisValue(), l)->toNumber(exec);
401 compareResult = (jObj->toString(exec) < minObj->toString(exec)) ? -1 : 1;
403 if (compareResult < 0) {
410 thisObj->put(exec, i, minObj);
411 thisObj->put(exec, themin, iObj);
417 JSValue* arrayProtoFuncSplice(ExecState* exec, JSObject* thisObj, const List& args)
420 JSObject* resObj = static_cast<JSObject* >(exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList()));
421 JSValue* result = resObj;
422 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
424 return jsUndefined();
425 int begin = args[0]->toUInt32(exec);
427 begin = std::max<int>(begin + length, 0);
429 begin = std::min<int>(begin, length);
431 unsigned deleteCount;
433 deleteCount = std::min<int>(std::max<int>(args[1]->toUInt32(exec), 0), length - begin);
435 deleteCount = length - begin;
437 for (unsigned k = 0; k < deleteCount; k++) {
438 if (JSValue* v = getProperty(exec, thisObj, k + begin))
439 resObj->put(exec, k, v);
441 resObj->put(exec, exec->propertyNames().length, jsNumber(exec, deleteCount));
443 unsigned additionalArgs = std::max<int>(args.size() - 2, 0);
444 if (additionalArgs != deleteCount) {
445 if (additionalArgs < deleteCount) {
446 for (unsigned k = begin; k < length - deleteCount; ++k) {
447 if (JSValue* v = getProperty(exec, thisObj, k + deleteCount))
448 thisObj->put(exec, k + additionalArgs, v);
450 thisObj->deleteProperty(exec, k + additionalArgs);
452 for (unsigned k = length; k > length - deleteCount + additionalArgs; --k)
453 thisObj->deleteProperty(exec, k - 1);
455 for (unsigned k = length - deleteCount; (int)k > begin; --k) {
456 if (JSValue* obj = getProperty(exec, thisObj, k + deleteCount - 1))
457 thisObj->put(exec, k + additionalArgs - 1, obj);
459 thisObj->deleteProperty(exec, k + additionalArgs - 1);
463 for (unsigned k = 0; k < additionalArgs; ++k)
464 thisObj->put(exec, k + begin, args[k + 2]);
466 thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - deleteCount + additionalArgs));
470 JSValue* arrayProtoFuncUnShift(ExecState* exec, JSObject* thisObj, const List& args)
473 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
474 unsigned nrArgs = args.size();
476 for (unsigned k = length; k > 0; --k) {
477 if (JSValue* v = getProperty(exec, thisObj, k - 1))
478 thisObj->put(exec, k + nrArgs - 1, v);
480 thisObj->deleteProperty(exec, k + nrArgs - 1);
483 for (unsigned k = 0; k < nrArgs; ++k)
484 thisObj->put(exec, k, args[k]);
485 JSValue* result = jsNumber(exec, length + nrArgs);
486 thisObj->put(exec, exec->propertyNames().length, result);
490 JSValue* arrayProtoFuncFilter(ExecState* exec, JSObject* thisObj, const List& args)
492 JSObject* eachFunction = args[0]->toObject(exec);
494 if (!eachFunction->implementsCall())
495 return throwError(exec, TypeError);
497 JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() : args[1]->toObject(exec);
498 JSObject* resultArray = static_cast<JSObject*>(exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList()));
500 unsigned filterIndex = 0;
501 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
502 for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
505 if (!thisObj->getPropertySlot(exec, k, slot))
508 JSValue* v = slot.getValue(exec, thisObj, k);
512 eachArguments.append(v);
513 eachArguments.append(jsNumber(exec, k));
514 eachArguments.append(thisObj);
516 JSValue* result = eachFunction->call(exec, applyThis, eachArguments);
518 if (result->toBoolean(exec))
519 resultArray->put(exec, filterIndex++, v);
524 JSValue* arrayProtoFuncMap(ExecState* exec, JSObject* thisObj, const List& args)
526 JSObject* eachFunction = args[0]->toObject(exec);
527 if (!eachFunction->implementsCall())
528 return throwError(exec, TypeError);
530 JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() : args[1]->toObject(exec);
532 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
535 mapArgs.append(jsNumber(exec, length));
536 JSObject* resultArray = static_cast<JSObject*>(exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, mapArgs));
538 for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
540 if (!thisObj->getPropertySlot(exec, k, slot))
543 JSValue* v = slot.getValue(exec, thisObj, k);
547 eachArguments.append(v);
548 eachArguments.append(jsNumber(exec, k));
549 eachArguments.append(thisObj);
551 JSValue* result = eachFunction->call(exec, applyThis, eachArguments);
552 resultArray->put(exec, k, result);
558 // Documentation for these three is available at:
559 // http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:every
560 // http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach
561 // http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:some
563 JSValue* arrayProtoFuncEvery(ExecState* exec, JSObject* thisObj, const List& args)
565 JSObject* eachFunction = args[0]->toObject(exec);
567 if (!eachFunction->implementsCall())
568 return throwError(exec, TypeError);
570 JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() : args[1]->toObject(exec);
572 JSValue* result = jsBoolean(true);
574 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
575 for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
578 if (!thisObj->getPropertySlot(exec, k, slot))
583 eachArguments.append(slot.getValue(exec, thisObj, k));
584 eachArguments.append(jsNumber(exec, k));
585 eachArguments.append(thisObj);
587 bool predicateResult = eachFunction->call(exec, applyThis, eachArguments)->toBoolean(exec);
589 if (!predicateResult) {
590 result = jsBoolean(false);
598 JSValue* arrayProtoFuncForEach(ExecState* exec, JSObject* thisObj, const List& args)
600 JSObject* eachFunction = args[0]->toObject(exec);
602 if (!eachFunction->implementsCall())
603 return throwError(exec, TypeError);
605 JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() : args[1]->toObject(exec);
607 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
608 for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
610 if (!thisObj->getPropertySlot(exec, k, slot))
614 eachArguments.append(slot.getValue(exec, thisObj, k));
615 eachArguments.append(jsNumber(exec, k));
616 eachArguments.append(thisObj);
618 eachFunction->call(exec, applyThis, eachArguments);
620 return jsUndefined();
623 JSValue* arrayProtoFuncSome(ExecState* exec, JSObject* thisObj, const List& args)
625 JSObject* eachFunction = args[0]->toObject(exec);
627 if (!eachFunction->implementsCall())
628 return throwError(exec, TypeError);
630 JSObject* applyThis = args[1]->isUndefinedOrNull() ? exec->globalThisValue() : args[1]->toObject(exec);
632 JSValue* result = jsBoolean(false);
634 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
635 for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
637 if (!thisObj->getPropertySlot(exec, k, slot))
641 eachArguments.append(slot.getValue(exec, thisObj, k));
642 eachArguments.append(jsNumber(exec, k));
643 eachArguments.append(thisObj);
645 bool predicateResult = eachFunction->call(exec, applyThis, eachArguments)->toBoolean(exec);
647 if (predicateResult) {
648 result = jsBoolean(true);
655 JSValue* arrayProtoFuncIndexOf(ExecState* exec, JSObject* thisObj, const List& args)
657 // JavaScript 1.5 Extension by Mozilla
658 // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf
661 double d = args[1]->toInteger(exec);
662 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
669 index = static_cast<unsigned>(d);
672 JSValue* searchElement = args[0];
673 for (; index < length; ++index) {
674 JSValue* e = getProperty(exec, thisObj, index);
677 if (strictEqual(exec, searchElement, e))
678 return jsNumber(exec, index);
681 return jsNumber(exec, -1);
684 JSValue* arrayProtoFuncLastIndexOf(ExecState* exec, JSObject* thisObj, const List& args)
686 // JavaScript 1.6 Extension by Mozilla
687 // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf
689 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
690 int index = length - 1;
691 double d = args[1]->toIntegerPreserveNaN(exec);
696 return jsNumber(exec, -1);
699 index = static_cast<int>(d);
701 JSValue* searchElement = args[0];
702 for (; index >= 0; --index) {
703 JSValue* e = getProperty(exec, thisObj, index);
706 if (strictEqual(exec, searchElement, e))
707 return jsNumber(exec, index);
710 return jsNumber(exec, -1);
713 // ------------------------------ ArrayObjectImp -------------------------------
715 ArrayObjectImp::ArrayObjectImp(ExecState* exec, FunctionPrototype* funcProto, ArrayPrototype* arrayProto)
716 : InternalFunctionImp(funcProto, arrayProto->classInfo()->className)
718 // ECMA 15.4.3.1 Array.prototype
719 putDirect(exec->propertyNames().prototype, arrayProto, DontEnum|DontDelete|ReadOnly);
721 // no. of arguments for constructor
722 putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
725 bool ArrayObjectImp::implementsConstruct() const
731 JSObject* ArrayObjectImp::construct(ExecState* exec, const List& args)
733 // a single numeric argument denotes the array size (!)
734 if (args.size() == 1 && args[0]->isNumber()) {
735 uint32_t n = args[0]->toUInt32(exec);
736 if (n != args[0]->toNumber(exec))
737 return throwError(exec, RangeError, "Array size is not a small enough positive integer.");
738 return new (exec) ArrayInstance(exec->lexicalGlobalObject()->arrayPrototype(), n);
741 // otherwise the array is constructed with the arguments in it
742 return new (exec) ArrayInstance(exec->lexicalGlobalObject()->arrayPrototype(), args);
746 JSValue* ArrayObjectImp::callAsFunction(ExecState* exec, JSObject*, const List& args)
748 // equivalent to 'new Array(....)'
749 return construct(exec,args);