Title: [114185] trunk/Source/_javascript_Core
Revision
114185
Author
[email protected]
Date
2012-04-13 17:26:25 -0700 (Fri, 13 Apr 2012)

Log Message

Array.prototype.toString and Array.prototype.toLocaleString should be generic
https://bugs.webkit.org/show_bug.cgi?id=81588

Patch by Hojong Han <[email protected]> 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):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (114184 => 114185)


--- trunk/Source/_javascript_Core/ChangeLog	2012-04-14 00:11:16 UTC (rev 114184)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-04-14 00:26:25 UTC (rev 114185)
@@ -1,3 +1,18 @@
+2012-04-13  Hojong Han  <[email protected]>
+
+        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  <[email protected]>
 
         Don't rely on fixed offsets to patch method checks

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/runtime/CommonIdentifiers.h (114184 => 114185)


--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2012-04-14 00:11:16 UTC (rev 114184)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2012-04-14 00:26:25 UTC (rev 114185)
@@ -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) \

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 );
 }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to