Commit 364138ec authored by barraclough@apple.com's avatar barraclough@apple.com

Array.prototype.toString should be generic

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

Reviewed by Sam Weinig.

Source/JavaScriptCore: 

* runtime/ArrayPrototype.cpp:
(JSC::arrayProtoFuncToString):
    - check for join function, use fast case if base object is array & join is present & default.
* runtime/CommonIdentifiers.h:
    - added 'join'.

LayoutTests: 

* fast/js/array-functions-non-arrays-expected.txt:
    - check in new results
* fast/js/array-prototype-properties-expected.txt:
    - new more detailed error message.
* fast/js/script-tests/array-functions-non-arrays.js:
    - added new test cases, fix incorrect one.
* sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.2_Array_prototype_toString/S15.4.4.2_A2_T1-expected.txt:
    - check in failing result (test is wrong)



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@114405 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 374e959b
2012-04-16 Gavin Barraclough <barraclough@apple.com>
Array.prototype.toString should be generic
https://bugs.webkit.org/show_bug.cgi?id=81588
Reviewed by Sam Weinig.
* fast/js/array-functions-non-arrays-expected.txt:
- check in new results
* fast/js/array-prototype-properties-expected.txt:
- new more detailed error message.
* fast/js/script-tests/array-functions-non-arrays.js:
- added new test cases, fix incorrect one.
* sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.2_Array_prototype_toString/S15.4.4.2_A2_T1-expected.txt:
- check in failing result (test is wrong)
2012-04-17 Stephen Chenney <schenney@chromium.org>
Update long-failing Chromium expectations.
......@@ -7,7 +7,16 @@ PASS properties(['b', 'a']) is '0:b, 1:a, length:2(DontDelete, DontEnum)'
PASS properties({ length:2, 0:'b', 1:'a' }) is '0:b, 1:a, length:2'
PASS properties(new OneItemConstructor) is '0:a(FromPrototype), length:1(FromPrototype)'
PASS properties(new TwoItemConstructor) is '0:b(FromPrototype), 1:a(FromPrototype), length:2(FromPrototype)'
PASS Array.prototype.toString.call({}) threw exception TypeError: Type error.
PASS Array.prototype.toString.call({}) is "[object Object]"
PASS Array.prototype.toString.call(new Date) is "[object Date]"
PASS Array.prototype.toString.call({sort: function() { return 'sort' }}) is "[object Object]"
PASS Array.prototype.toString.call({join: function() { return 'join' }}) is "join"
PASS Array.prototype.toString.call({__proto__: Array.prototype, 0: 'a', 1: 'b', 2: 'c', length: 3}) is "a,b,c"
PASS ({__proto__: Array.prototype, 0: 'a', 1: 'b', 2: 'c', length: 3}).toString() is "a,b,c"
PASS Array.prototype.toString.call({__proto__: Array.prototype, 0: 'a', 1: 'b', 2: 'c', length: 3, join: function() { return 'join' }}) is "join"
PASS ({__proto__: Array.prototype, 0: 'a', 1: 'b', 2: 'c', length: 3, join: function() { return 'join' }}).toString() is "join"
PASS Array.prototype.toString.call(42) is "Number.prototype.join:42"
PASS [0, 1, 2].toString() is "array-join"
PASS Array.prototype.toLocaleString.call({}) threw exception TypeError: Type error.
PASS Array.prototype.concat.call(x = { length:2, 0:'b', 1:'a' }) is [x]
PASS Array.prototype.join.call({}) is ''
......
......@@ -3,7 +3,7 @@ This is a test case for bug 64679.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS Array.prototype.toString.call(undefined) threw exception TypeError: Type error.
PASS Array.prototype.toString.call(undefined) threw exception TypeError: 'undefined' is not an object (evaluating 'Array.prototype.toString.call(undefined)').
PASS Array.prototype.toLocaleString.call(undefined) threw exception TypeError: Type error.
PASS Array.prototype.concat.call(undefined, []) threw exception TypeError: 'undefined' is not an object (evaluating 'Array.prototype.concat.call(undefined, [])').
PASS Array.prototype.join.call(undefined, []) threw exception TypeError: 'undefined' is not an object (evaluating 'Array.prototype.join.call(undefined, [])').
......
......@@ -76,7 +76,21 @@ shouldBe("properties({ length:2, 0:'b', 1:'a' })", "'0:b, 1:a, length:2'");
shouldBe("properties(new OneItemConstructor)", "'0:a(FromPrototype), length:1(FromPrototype)'");
shouldBe("properties(new TwoItemConstructor)", "'0:b(FromPrototype), 1:a(FromPrototype), length:2(FromPrototype)'");
shouldThrow("Array.prototype.toString.call({})");
shouldBe("Array.prototype.toString.call({})", '"' + ({}).toString() + '"');
shouldBe("Array.prototype.toString.call(new Date)", '"' + Object.prototype.toString.call(new Date) + '"');
shouldBe("Array.prototype.toString.call({sort: function() { return 'sort' }})", '"' + Object.prototype.toString.call({}) + '"');
shouldBe("Array.prototype.toString.call({join: function() { return 'join' }})", '"join"');
shouldBe("Array.prototype.toString.call({__proto__: Array.prototype, 0: 'a', 1: 'b', 2: 'c', length: 3})", '"a,b,c"');
shouldBe("({__proto__: Array.prototype, 0: 'a', 1: 'b', 2: 'c', length: 3}).toString()", '"a,b,c"');
shouldBe("Array.prototype.toString.call({__proto__: Array.prototype, 0: 'a', 1: 'b', 2: 'c', length: 3, join: function() { return 'join' }})", '"join"');
shouldBe("({__proto__: Array.prototype, 0: 'a', 1: 'b', 2: 'c', length: 3, join: function() { return 'join' }}).toString()", '"join"');
Number.prototype.join = function() { return "Number.prototype.join:" + this; }
shouldBe("Array.prototype.toString.call(42)", '"Number.prototype.join:42"');
var arrayJoin = Array.prototype.join;
Array.prototype.join = function() { return 'array-join' };
shouldBe("[0, 1, 2].toString()", '"array-join"');
Array.prototype.join = arrayJoin;
shouldThrow("Array.prototype.toLocaleString.call({})");
shouldBe("Array.prototype.concat.call(x = { length:2, 0:'b', 1:'a' })", "[x]");
......
S15.4.4.2_A2_T1
PASS
FAIL SputnikError: #1.2: var obj = {}; obj.toString = Array.prototype.toString; obj.toString() throw TypeError. Actual: SputnikError: #1.1: var obj = {}; obj.toString = Array.prototype.toString; obj.toString() throw TypeError. Actual: [object Object]
TEST COMPLETE
2012-04-16 Gavin Barraclough <barraclough@apple.com>
Array.prototype.toString should be generic
https://bugs.webkit.org/show_bug.cgi?id=81588
Reviewed by Sam Weinig.
* runtime/ArrayPrototype.cpp:
(JSC::arrayProtoFuncToString):
- check for join function, use fast case if base object is array & join is present & default.
* runtime/CommonIdentifiers.h:
- added 'join'.
2012-04-16 Carlos Garcia Campos <cgarcia@igalia.com>
Unreviewed. Fix make distcheck issues.
......@@ -28,6 +28,7 @@
#include "CodeBlock.h"
#include "Interpreter.h"
#include "JIT.h"
#include "JSStringBuilder.h"
#include "JSStringJoiner.h"
#include "Lookup.h"
#include "ObjectPrototype.h"
......@@ -254,9 +255,27 @@ 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);
// 1. Let array be the result of calling ToObject on the this value.
JSObject* thisObject = thisValue.toObject(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
// 2. Let func be the result of calling the [[Get]] internal method of array with argument "join".
JSValue function = JSValue(thisObject).get(exec, exec->propertyNames().join);
// 3. If IsCallable(func) is false, then let func be the standard built-in method Object.prototype.toString (15.2.4.2).
if (!function.isCell())
return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable()->className(thisObject), "]"));
CallData callData;
CallType callType = getCallData(function, callData);
if (callType == CallTypeNone)
return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable()->className(thisObject), "]"));
// 4. Return the result of calling the [[Call]] internal method of func providing array as the this value and an empty arguments list.
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);
......@@ -273,7 +292,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);
......
......@@ -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) \
......
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