https://bugs.webkit.org/show_bug.cgi?id=64900
authorbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jul 2011 18:59:38 +0000 (18:59 +0000)
committerbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jul 2011 18:59:38 +0000 (18:59 +0000)
Function.prototype.apply should accept an array-like object as its second argument

Reviewed by Sam Weinig.

Source/JavaScriptCore:

* interpreter/Interpreter.cpp:
(JSC::Interpreter::privateExecute):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* runtime/FunctionPrototype.cpp:
(JSC::functionProtoFuncApply):
    - Remove the type error if object is not an array.

LayoutTests:

* fast/js/function-apply-expected.txt:
* fast/js/script-tests/function-apply.js:
    - Add a test for array-like objects.
* sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.4/15.3.4.3_Function.prototype.apply/S15.3.4.3_A6_T1-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.4/15.3.4.3_Function.prototype.apply/S15.3.4.3_A6_T4-expected.txt:
    - These tests are incorrect & assert ES3 behaviour.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@91483 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/js/function-apply-expected.txt
LayoutTests/fast/js/script-tests/function-apply.js
LayoutTests/sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.4/15.3.4.3_Function.prototype.apply/S15.3.4.3_A6_T1-expected.txt
LayoutTests/sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.4/15.3.4.3_Function.prototype.apply/S15.3.4.3_A6_T4-expected.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/jit/JITStubs.cpp
Source/JavaScriptCore/runtime/FunctionPrototype.cpp

index c684d12..51beffb 100644 (file)
@@ -1,3 +1,17 @@
+2011-07-21  Gavin Barraclough  <barraclough@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=64900
+        Function.prototype.apply should accept an array-like object as its second argument
+
+        Reviewed by Sam Weinig.
+
+        * fast/js/function-apply-expected.txt:
+        * fast/js/script-tests/function-apply.js:
+            - Add a test for array-like objects.
+        * sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.4/15.3.4.3_Function.prototype.apply/S15.3.4.3_A6_T1-expected.txt:
+        * sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.4/15.3.4.3_Function.prototype.apply/S15.3.4.3_A6_T4-expected.txt:
+            - These tests are incorrect & assert ES3 behaviour.
+
 2011-07-21  Enrica Casucci  <enrica@apple.com>
 
         Cannot click to position the caret to the right of an image with display:block style.
index 4f683ad..f64d1c6 100644 (file)
@@ -1,4 +1,4 @@
-Tests to ensure that Function.apply works correctly for Arrays and arguments.
+Tests to ensure that Function.apply works correctly for Arrays, arguments and array-like objects.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
@@ -36,6 +36,7 @@ PASS var a = []; a.length = 0x10000; [].constructor.apply('', a).length is 0x100
 PASS var a = []; a.length = 0x10001; [].constructor.apply('', a).length is 0x10000
 PASS var a = []; a.length = 0xFFFFFFFE; [].constructor.apply('', a).length is 0x10000
 PASS var a = []; a.length = 0xFFFFFFFF; [].constructor.apply('', a).length is 0x10000
+PASS (function(a,b,c,d){ return d ? -1 : (a+b+c); }).apply(undefined, {length:3, 0:100, 1:20, 2:3}) is 123
 PASS successfullyParsed is true
 
 TEST COMPLETE
index cddef33..ebc6c34 100644 (file)
@@ -1,4 +1,4 @@
-description('Tests to ensure that Function.apply works correctly for Arrays and arguments.');
+description('Tests to ensure that Function.apply works correctly for Arrays, arguments and array-like objects.');
 
 function argumentsApply1(a, b, c)
 {
@@ -291,4 +291,7 @@ shouldBe("var a = []; a.length = 0x10001; [].constructor.apply('', a).length", "
 shouldBe("var a = []; a.length = 0xFFFFFFFE; [].constructor.apply('', a).length", "0x10000");
 shouldBe("var a = []; a.length = 0xFFFFFFFF; [].constructor.apply('', a).length", "0x10000");
 
+// ES5 permits apply with array-like objects.
+shouldBe("(function(a,b,c,d){ return d ? -1 : (a+b+c); }).apply(undefined, {length:3, 0:100, 1:20, 2:3})", '123');
+
 var successfullyParsed = true;
index 37aa487..fcf1f15 100644 (file)
@@ -1,5 +1,20 @@
 2011-07-21  Gavin Barraclough  <barraclough@apple.com>
 
+        https://bugs.webkit.org/show_bug.cgi?id=64900
+        Function.prototype.apply should accept an array-like object as its second argument
+
+        Reviewed by Sam Weinig.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::privateExecute):
+        * jit/JITStubs.cpp:
+        (JSC::DEFINE_STUB_FUNCTION):
+        * runtime/FunctionPrototype.cpp:
+        (JSC::functionProtoFuncApply):
+            - Remove the type error if object is not an array.
+
+2011-07-21  Gavin Barraclough  <barraclough@apple.com>
+
         https://bugs.webkit.org/show_bug.cgi?id=64964
         DFG JIT - Enable support for eval code
 
index 3f785ce..788ce05 100644 (file)
@@ -4313,7 +4313,7 @@ skip_id_custom_self:
                     goto vm_throw;
                 }
                 array->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount);
-            } else if (asObject(arguments)->inherits(&JSArray::s_info)) {
+            } else {
                 JSObject* argObject = asObject(arguments);
                 argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
                 argCount = min<uint32_t>(argCount, Arguments::MaxArguments);
@@ -4328,9 +4328,6 @@ skip_id_custom_self:
                     argsBuffer[i] = asObject(arguments)->get(callFrame, i);
                     CHECK_FOR_EXCEPTION();
                 }
-            } else {
-                exceptionValue = createInvalidParamError(callFrame, "Function.prototype.apply", arguments);
-                goto vm_throw;
             }
         }
         CHECK_FOR_EXCEPTION();
index c2c48d2..3413d16 100644 (file)
@@ -2559,7 +2559,7 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs)
                 VM_THROW_EXCEPTION();
             }
             array->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount);
-        } else if (asObject(arguments)->inherits(&JSArray::s_info)) {
+        } else {
             JSObject* argObject = asObject(arguments);
             argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
             argCount = min(argCount, static_cast<uint32_t>(Arguments::MaxArguments));
@@ -2574,9 +2574,6 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs)
                 argsBuffer[i] = asObject(arguments)->get(callFrame, i);
                 CHECK_FOR_EXCEPTION();
             }
-        } else {
-            stackFrame.globalData->exception = createInvalidParamError(callFrame, "Function.prototype.apply", arguments);
-            VM_THROW_EXCEPTION();
         }
     }
 
index c347691..96cd677 100644 (file)
@@ -121,12 +121,11 @@ EncodedJSValue JSC_HOST_CALL functionProtoFuncApply(ExecState* exec)
             asArguments(array)->fillArgList(exec, applyArgs);
         else if (isJSArray(&exec->globalData(), array))
             asArray(array)->fillArgList(exec, applyArgs);
-        else if (asObject(array)->inherits(&JSArray::s_info)) {
-            unsigned length = asArray(array)->get(exec, exec->propertyNames().length).toUInt32(exec);
+        else {
+            unsigned length = asObject(array)->get(exec, exec->propertyNames().length).toUInt32(exec);
             for (unsigned i = 0; i < length; ++i)
                 applyArgs.append(asArray(array)->get(exec, i));
-        } else
-            return throwVMTypeError(exec);
+        }
     }
 
     return JSValue::encode(call(exec, thisValue, callType, callData, exec->argument(0), applyArgs));