Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (114184 => 114185)
--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2012-04-14 00:11:16 UTC (rev 114184)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2012-04-14 00:26:25 UTC (rev 114185)
@@ -254,11 +254,25 @@
{
JSValue thisValue = exec->hostThisValue();
- bool isRealArray = isJSArray(thisValue);
- if (!isRealArray && !thisValue.inherits(&JSArray::s_info))
- return throwVMTypeError(exec);
+ JSObject* thisObject = thisValue.toObject(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
+ JSValue function = JSValue(thisObject).get(exec, exec->propertyNames().join);
+ if (!function.isCell())
+ return objectProtoFuncToString(exec);
+
+ CallData callData;
+ CallType callType = getCallData(function, callData);
+ if (callType == CallTypeNone)
+ return objectProtoFuncToString(exec);
+
+ if (!isJSArray(thisObject) || callType != CallTypeHost || callData.native.function != arrayProtoFuncJoin)
+ return JSValue::encode(call(exec, function, callType, callData, thisObject, exec->emptyList()));
+
+ ASSERT(isJSArray(thisValue));
JSArray* thisObj = asArray(thisValue);
-
+
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
@@ -273,7 +287,7 @@
for (unsigned k = 0; k < length; k++) {
JSValue element;
- if (isRealArray && thisObj->canGetIndex(k))
+ if (thisObj->canGetIndex(k))
element = thisObj->getIndex(k);
else
element = thisObj->get(exec, k);
@@ -331,9 +345,9 @@
{
JSValue thisValue = exec->hostThisValue();
- if (!thisValue.inherits(&JSArray::s_info))
- return throwVMTypeError(exec);
- JSObject* thisObj = asArray(thisValue);
+ JSObject* thisObj = thisValue.toObject(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (exec->hadException())
@@ -360,11 +374,12 @@
if (callType != CallTypeNone)
str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toUString(exec);
else
- str = element.toUString(exec);
+ return throwVMTypeError(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
stringJoiner.append(str);
- }
+ } else
+ return JSValue::encode(jsEmptyString(exec));
}
return JSValue::encode(stringJoiner.build(exec));
Modified: trunk/Source/_javascript_Core/tests/mozilla/ecma/Array/15.4.4.2.js (114184 => 114185)
--- trunk/Source/_javascript_Core/tests/mozilla/ecma/Array/15.4.4.2.js 2012-04-14 00:11:16 UTC (rev 114184)
+++ trunk/Source/_javascript_Core/tests/mozilla/ecma/Array/15.4.4.2.js 2012-04-14 00:26:25 UTC (rev 114185)
@@ -55,6 +55,31 @@
array[item++] = new TestCase( SECTION, "(new Array( Boolean(1), Boolean(0))).toString()", "true,false", (new Array(Boolean(1),Boolean(0))).toString() );
array[item++] = new TestCase( SECTION, "(new Array(void 0,null)).toString()", ",", (new Array(void 0,null)).toString() );
+ array[item++] = new TestCase( SECTION,
+ "{__proto__: Array.prototype, 0: 'a', 1: 'b', 2: 'c', length: 3}.toString()",
+ "a,b,c",
+ {__proto__: Array.prototype, 0: 'a', 1: 'b', 2: 'c', length: 3}.toString() );
+ array[item++] = new TestCase( SECTION,
+ "{__proto__: Array.prototype, 0: 'a', 1: 'b', 2: 'c', join: function() { return 'join' }}.toString()",
+ "join",
+ {__proto__: Array.prototype, 0: 'a', 1: 'b', 2: 'c', join: function() { return 'join' }}.toString() );
+ array[item++] = new TestCase( SECTION,
+ "Array.prototype.toString.call({join: function() { return 'join' }})",
+ "join",
+ Array.prototype.toString.call({join: function() { return 'join' }}) );
+ array[item++] = new TestCase( SECTION,
+ "Array.prototype.toString.call({sort: function() { return 'sort' }})",
+ "[object Object]",
+ Array.prototype.toString.call({sort: function() { return 'sort' }}) );
+ array[item++] = new TestCase( SECTION,
+ "Array.prototype.toString.call(new Date)",
+ "[object Date]",
+ Array.prototype.toString.call(new Date) );
+ array[item++] = new TestCase( SECTION,
+ "Number.prototype.join = function() { return 'number join' }; Array.prototype.toString.call(42)",
+ "number join",
+ eval("Number.prototype.join = function() { return 'number join' }; Array.prototype.toString.call(42)") );
+
var EXPECT_STRING = "";
var MYARR = new Array();
@@ -67,6 +92,10 @@
array[item++] = new TestCase( SECTION, "MYARR.toString()", EXPECT_STRING, MYARR.toString() );
+ array[item++] = new TestCase( SECTION,
+ "Array.prototype.join = function() { return 'join' }; [0, 1, 2].toString()",
+ "join",
+ eval("Array.prototype.join = function() { return 'join' }; [0, 1, 2].toString()") );
return ( array );
}