[ES6] Implement Reflect.apply
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 26 Jul 2015 20:52:58 +0000 (20:52 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 26 Jul 2015 20:52:58 +0000 (20:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=147306

Reviewed by Sam Weinig.

Implement Reflect.apply.
The large part of this can be implemented by the @apply builtin annotation.
The only thing which is different from the Funciton.prototype.apply is the third parameter,
"argumentsList" is needed to be an object.

* builtins/ReflectObject.js:
(apply):
(deleteProperty):
* runtime/ReflectObject.cpp:
* tests/stress/reflect-apply.js: Added.
(shouldBe):
(shouldThrow):
(get shouldThrow):
(.get shouldThrow):
(get var.array.get length):
(get var.array.get 0):
(.get var):
* tests/stress/reflect-delete-property.js:

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/builtins/ReflectObject.js
Source/JavaScriptCore/runtime/ReflectObject.cpp
Source/JavaScriptCore/tests/stress/reflect-apply.js [new file with mode: 0644]
Source/JavaScriptCore/tests/stress/reflect-delete-property.js

index 134dfe7..8365bca 100644 (file)
@@ -1,3 +1,29 @@
+2015-07-26  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Implement Reflect.apply
+        https://bugs.webkit.org/show_bug.cgi?id=147306
+
+        Reviewed by Sam Weinig.
+
+        Implement Reflect.apply.
+        The large part of this can be implemented by the @apply builtin annotation.
+        The only thing which is different from the Funciton.prototype.apply is the third parameter,
+        "argumentsList" is needed to be an object.
+
+        * builtins/ReflectObject.js:
+        (apply):
+        (deleteProperty):
+        * runtime/ReflectObject.cpp:
+        * tests/stress/reflect-apply.js: Added.
+        (shouldBe):
+        (shouldThrow):
+        (get shouldThrow):
+        (.get shouldThrow):
+        (get var.array.get length):
+        (get var.array.get 0):
+        (.get var):
+        * tests/stress/reflect-delete-property.js:
+
 2015-07-25  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         [ES6] Add Reflect namespace and add Reflect.deleteProperty
index 15013ac..166af07 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+function apply(target, thisArgument, argumentsList)
+{
+    "use strict";
+
+    if (typeof target !== "function")
+        throw new @TypeError("Reflect.apply requires the first argument be a function");
+
+    if (!@isObject(argumentsList))
+        throw new @TypeError("Reflect.apply requires the third argument be an object");
+
+    return target.@apply(thisArgument, argumentsList);
+}
+
 function deleteProperty(target, propertyKey)
 {
     // Intentionally keep the code the sloppy mode to suppress the TypeError
     // raised by the delete operator under the strict mode.
 
     if (!@isObject(target))
-        throw new @TypeError("Reflect.deleteProperty requires the first argument be a object");
+        throw new @TypeError("Reflect.deleteProperty requires the first argument be an object");
 
     return delete target[propertyKey];
 }
index 8e13d67..a64b7c0 100644 (file)
@@ -39,7 +39,8 @@ const ClassInfo ReflectObject::s_info = { "Reflect", &Base::s_info, &reflectObje
 
 /* Source for ReflectObject.lut.h
 @begin reflectObjectTable
-    deleteProperty  reflectObjectGet DontEnum|Function 2
+    apply           reflectObjectApply          DontEnum|Function 3
+    deleteProperty  reflectObjectDeleteProperty DontEnum|Function 2
 @end
 */
 
diff --git a/Source/JavaScriptCore/tests/stress/reflect-apply.js b/Source/JavaScriptCore/tests/stress/reflect-apply.js
new file mode 100644 (file)
index 0000000..0f692c7
--- /dev/null
@@ -0,0 +1,91 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function shouldThrow(func, message) {
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("not thrown.");
+    if (String(error) !== message)
+        throw new Error("bad error: " + String(error));
+}
+
+shouldBe(Reflect.apply.length, 3);
+
+shouldThrow(() => {
+    Reflect.apply("hello", 42);
+}, `TypeError: Reflect.apply requires the first argument be a function`);
+
+shouldThrow(() => {
+    Reflect.apply(function () { }, 42, null);
+}, `TypeError: Reflect.apply requires the third argument be an object`);
+
+shouldThrow(() => {
+    var array = {
+        get length() {
+            throw new Error("ok");
+        },
+        get 0() {
+            throw new Error("ng");
+        }
+    };
+    Reflect.apply(function () { }, {}, array);
+}, `Error: ok`);
+
+shouldThrow(() => {
+    var array = {
+        get length() {
+            return 1;
+        },
+        get 0() {
+            throw new Error("ok");
+        }
+    };
+    Reflect.apply(function () { }, {}, array);
+}, `Error: ok`);
+
+var array = {
+    get length() {
+        return 0;
+    },
+    get 0() {
+        throw new Error("ng");
+    }
+};
+shouldBe(Reflect.apply(function () { return arguments.length }, {}, array), 0);
+
+var globalObject = this;
+shouldBe(Reflect.apply(function () {
+    "use strict";
+    shouldBe(arguments[0], 0);
+    shouldBe(arguments[1], 1);
+    shouldBe(arguments[2], 2);
+    shouldBe(this, null);
+    return arguments.length;
+}, null, [0,1,2]), 3)
+
+shouldBe(Reflect.apply(function () {
+    shouldBe(arguments[0], 0);
+    shouldBe(arguments[1], 1);
+    shouldBe(arguments[2], 2);
+    shouldBe(this, globalObject);
+    return arguments.length;
+}, null, [0,1,2]), 3)
+
+var thisObject = {};
+shouldBe(Reflect.apply(function () {
+    "use strict";
+    shouldBe(this, thisObject);
+    return arguments.length;
+}, thisObject, []), 0)
+
+shouldBe(Reflect.apply(function () {
+    shouldBe(this, thisObject);
+    return arguments.length;
+}, thisObject, []), 0)
index cb8f97a..1f08651 100644 (file)
@@ -20,7 +20,7 @@ shouldBe(Reflect.deleteProperty.length, 2);
 
 shouldThrow(() => {
     Reflect.deleteProperty("hello", 42);
-}, `TypeError: Reflect.deleteProperty requires the first argument be a object`);
+}, `TypeError: Reflect.deleteProperty requires the first argument be an object`);
 
 var object = { hello: 42 };
 shouldBe(object.hello, 42);
@@ -49,7 +49,7 @@ var toPropertyKey = {
 
 shouldThrow(() => {
     Reflect.deleteProperty("hello", toPropertyKey);
-}, `TypeError: Reflect.deleteProperty requires the first argument be a object`);
+}, `TypeError: Reflect.deleteProperty requires the first argument be an object`);
 
 shouldThrow(() => {
     Reflect.deleteProperty({}, toPropertyKey);