Array.prototype.toString and Array.prototype.toLocaleString should be generic

https://bugs.webkit.org/show_bug.cgi?id=81588

Patch by Hojong Han <hojong.han@samsung.com> on 2012-04-13
Reviewed by Gavin Barraclough.

* runtime/ArrayPrototype.cpp:
(JSC::arrayProtoFuncToString):
(JSC::arrayProtoFuncToLocaleString):
* runtime/CommonIdentifiers.h:
* tests/mozilla/ecma/Array/15.4.4.2.js:
(getTestCases.array.item.new.TestCase):
(getTestCases):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@114185 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 012a3287
2012-04-13 Hojong Han <hojong.han@samsung.com>
Array.prototype.toString and Array.prototype.toLocaleString should be generic
https://bugs.webkit.org/show_bug.cgi?id=81588
Reviewed by Gavin Barraclough.
* runtime/ArrayPrototype.cpp:
(JSC::arrayProtoFuncToString):
(JSC::arrayProtoFuncToLocaleString):
* runtime/CommonIdentifiers.h:
* tests/mozilla/ecma/Array/15.4.4.2.js:
(getTestCases.array.item.new.TestCase):
(getTestCases):
2012-04-13 Gavin Barraclough <barraclough@apple.com>
Don't rely on fixed offsets to patch method checks
......@@ -254,11 +254,25 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
{
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 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
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 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
{
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 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
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));
......
......@@ -72,7 +72,8 @@
macro(value) \
macro(valueOf) \
macro(writable) \
macro(displayName)
macro(displayName)\
macro(join)
#define JSC_COMMON_IDENTIFIERS_EACH_KEYWORD(macro) \
macro(null) \
......
......@@ -55,6 +55,31 @@ function getTestCases() {
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 @@ function getTestCases() {
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 );
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment