summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime/ArrayPrototype.cpp')
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.cpp106
1 files changed, 74 insertions, 32 deletions
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index 488effd..fdbcd95 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -165,16 +165,20 @@ static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
+
bool isRealArray = isJSArray(&exec->globalData(), thisValue);
if (!isRealArray && !thisValue.inherits(&JSArray::s_info))
return throwVMTypeError(exec);
JSArray* thisObj = asArray(thisValue);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
StringRecursionChecker checker(exec, thisObj);
if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
return earlyReturnValue;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned totalSize = length ? length - 1 : 0;
#if OS(SYMBIAN)
// Symbian has very limited stack size available.
@@ -225,16 +229,20 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
+
if (!thisValue.inherits(&JSArray::s_info))
return throwVMTypeError(exec);
JSObject* thisObj = asArray(thisValue);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
StringRecursionChecker checker(exec, thisObj);
if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
return earlyReturnValue;
JSStringBuilder strBuffer;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned k = 0; k < length; k++) {
if (k >= 1)
strBuffer.append(',');
@@ -260,6 +268,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
StringRecursionChecker checker(exec, thisObj);
if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
@@ -271,7 +282,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
if (!exec->argument(0).isUndefined())
separator = exec->argument(0).toString(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (isJSArray(&exec->globalData(), thisObj)) {
JSArray* array = asArray(thisObj);
@@ -355,12 +365,16 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
+
if (isJSArray(&exec->globalData(), thisValue))
return JSValue::encode(asArray(thisValue)->pop());
JSObject* thisObj = thisValue.toThisObject(exec);
- JSValue result;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
+ JSValue result;
if (length == 0) {
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length));
result = jsUndefined();
@@ -375,6 +389,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
+
if (isJSArray(&exec->globalData(), thisValue) && exec->argumentCount() == 1) {
JSArray* array = asArray(thisValue);
array->push(exec, exec->argument(0));
@@ -383,6 +398,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
JSObject* thisObj = thisValue.toThisObject(exec);
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
for (unsigned n = 0; n < exec->argumentCount(); n++)
thisObj->put(exec, length + n, exec->argument(n));
length += exec->argumentCount();
@@ -394,8 +412,10 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
- unsigned middle = length / 2;
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ unsigned middle = length / 2;
for (unsigned k = 0; k < middle; k++) {
unsigned lk1 = length - k - 1;
JSValue obj2 = getProperty(exec, thisObj, lk1);
@@ -420,6 +440,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec)
JSValue result;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
if (length == 0) {
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length));
result = jsUndefined();
@@ -451,6 +474,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
JSValue result = resObj;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
unsigned end = argumentClampedIndexFromStartOrEnd(exec, 1, length, length);
@@ -466,6 +492,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (!length || exec->hadException())
+ return JSValue::encode(thisObj);
JSValue function = exec->argument(0);
CallData callData;
@@ -481,11 +510,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
return JSValue::encode(thisObj);
}
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
-
- if (!length)
- return JSValue::encode(thisObj);
-
// "Min" sort. Not the fastest, but definitely less code than heapsort
// or quicksort, and much less swapping than bubblesort/insertionsort.
for (unsigned i = 0; i < length - 1; ++i) {
@@ -523,14 +547,16 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
{
- JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
// 15.4.4.12
+ JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
if (!exec->argumentCount())
return JSValue::encode(constructEmptyArray(exec));
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
unsigned deleteCount = length - begin;
@@ -589,10 +615,13 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec)
{
- JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
// 15.4.4.13
+
+ JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
unsigned nrArgs = exec->argumentCount();
if ((nrArgs) && (length)) {
if (isJSArray(&exec->globalData(), thisObj))
@@ -616,6 +645,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -627,7 +659,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
JSArray* resultArray = constructEmptyArray(exec);
unsigned filterIndex = 0;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
JSFunction* f = asFunction(function);
@@ -674,6 +705,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -683,8 +717,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
-
JSArray* resultArray = constructEmptyArray(exec, length);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
@@ -731,6 +763,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -742,7 +777,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
JSValue result = jsBoolean(true);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
JSFunction* f = asFunction(function);
@@ -787,6 +821,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -796,7 +833,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
JSFunction* f = asFunction(function);
@@ -832,6 +868,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -843,7 +882,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
JSValue result = jsBoolean(false);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
JSFunction* f = asFunction(function);
@@ -885,7 +923,10 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
JSValue function = exec->argument(0);
CallData callData;
CallType callType = getCallData(function, callData);
@@ -894,9 +935,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec)
unsigned i = 0;
JSValue rv;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (!length && exec->argumentCount() == 1)
return throwVMTypeError(exec);
+
JSArray* array = 0;
if (isJSArray(&exec->globalData(), thisObj))
array = asArray(thisObj);
@@ -955,7 +996,10 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
JSValue function = exec->argument(0);
CallData callData;
CallType callType = getCallData(function, callData);
@@ -964,9 +1008,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec)
unsigned i = 0;
JSValue rv;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (!length && exec->argumentCount() == 1)
return throwVMTypeError(exec);
+
JSArray* array = 0;
if (isJSArray(&exec->globalData(), thisObj))
array = asArray(thisObj);
@@ -1023,13 +1067,13 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec)
{
- // JavaScript 1.5 Extension by Mozilla
- // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf
+ // 15.4.4.14
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
- unsigned index = argumentClampedIndexFromStartOrEnd(exec, 1, length);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ unsigned index = argumentClampedIndexFromStartOrEnd(exec, 1, length);
JSValue searchElement = exec->argument(0);
for (; index < length; ++index) {
JSValue e = getProperty(exec, thisObj, index);
@@ -1044,10 +1088,8 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState* exec)
{
- // JavaScript 1.6 Extension by Mozilla
- // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf
+ // 15.4.4.15
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (!length)
return JSValue::encode(jsNumber(-1));