[ES6] Implement ES6 arrow function syntax. Prototype of arrow function should be...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Sep 2015 06:58:40 +0000 (06:58 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Sep 2015 06:58:40 +0000 (06:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=147742

Source/JavaScriptCore:

Patch by Aleksandr Skachkov <gskachkov@gmail.com> on 2015-09-03
Reviewed by Saam Barati.

Added correct support of prototype property for arrow function. Arrow function
doesn’t have own prototype property, so (() => {}).hasOwnProperty('prototype') === false.
Changes prevent from creation of 'prototype' property automatically during initialization
of arrow function and allow to assign & delete it later in js code.

* runtime/JSFunction.cpp:
(JSC::JSFunction::getOwnPropertySlot):
(JSC::JSFunction::deleteProperty):
* tests/stress/arrowfunction-prototype.js: Added.

LayoutTests:

Patch by Aleksandr Skachkov <gskachkov@gmail.com> on 2015-09-04
Reviewed by Saam Barati.

Added tests of prototype property for arrow function. Checks that arrow function does not have
prototype property after creating of it and check if it is possible to add/remove it later.

* js/arrowfunction-prototype-expected.txt: Added.
* js/arrowfunction-prototype.html: Added.
* js/script-tests/arrowfunction-prototype.js: Added.

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

LayoutTests/ChangeLog
LayoutTests/js/arrowfunction-prototype-expected.txt [new file with mode: 0644]
LayoutTests/js/arrowfunction-prototype.html [new file with mode: 0644]
LayoutTests/js/script-tests/arrowfunction-prototype.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/JSFunction.cpp
Source/JavaScriptCore/tests/stress/arrowfunction-prototype.js [new file with mode: 0644]

index 07c704d..f4203b4 100644 (file)
@@ -1,3 +1,17 @@
+2015-09-04  Aleksandr Skachkov  <gskachkov@gmail.com>
+
+        [ES6] Implement ES6 arrow function syntax. Prototype of arrow function should be undefined
+        https://bugs.webkit.org/show_bug.cgi?id=147742
+
+        Reviewed by Saam Barati.
+
+        Added tests of prototype property for arrow function. Checks that arrow function does not have 
+        prototype property after creating of it and check if it is possible to add/remove it later.
+
+        * js/arrowfunction-prototype-expected.txt: Added.
+        * js/arrowfunction-prototype.html: Added.
+        * js/script-tests/arrowfunction-prototype.js: Added.
+
 2015-09-03  Chris Dumez  <cdumez@apple.com>
 
         Unreviewed, rebaseline http/tests/w3c/html/dom/dynamic-markup-insertion/opening-the-input-stream/007.html
diff --git a/LayoutTests/js/arrowfunction-prototype-expected.txt b/LayoutTests/js/arrowfunction-prototype-expected.txt
new file mode 100644 (file)
index 0000000..21f6d17
--- /dev/null
@@ -0,0 +1,25 @@
+Tests for ES6 arrow function prototype property
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+() =>  {}
+PASS typeof af1.prototype is 'undefined'
+PASS af1.hasOwnProperty('prototype') is false
+(a) => {a + 1}
+PASS typeof af2.prototype is 'undefined'
+PASS af2.hasOwnProperty('prototype') is false
+(x) =>  x + 1
+PASS typeof af3.prototype is 'undefined'
+PASS af3.hasOwnProperty('prototype') is false
+af1.prototype = function (x) { return x + 1;}
+PASS typeof af1.prototype is 'function'
+PASS af1.prototype.toString() is 'function (x) { return x + 1;}'
+PASS af1.hasOwnProperty('prototype') is true
+delete af1.prototype
+PASS typeof af1.prototype is 'undefined'
+PASS af1.hasOwnProperty('prototype') is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/js/arrowfunction-prototype.html b/LayoutTests/js/arrowfunction-prototype.html
new file mode 100644 (file)
index 0000000..f5e5bed
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="script-tests/arrowfunction-prototype.js"></script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/js/script-tests/arrowfunction-prototype.js b/LayoutTests/js/script-tests/arrowfunction-prototype.js
new file mode 100644 (file)
index 0000000..a42a426
--- /dev/null
@@ -0,0 +1,36 @@
+// Inspired by mozilla tests
+description('Tests for ES6 arrow function prototype property');
+
+var af1 = () =>  {};
+
+debug('() =>  {}');
+shouldBe("typeof af1.prototype", "'undefined'");
+shouldBe("af1.hasOwnProperty('prototype')", "false");
+
+var af2 = (a) => {a + 1};
+
+debug('(a) => {a + 1}');
+shouldBe("typeof af2.prototype", "'undefined'");
+shouldBe("af2.hasOwnProperty('prototype')", "false");
+
+var af3 = (x) =>  x + 1;
+
+debug('(x) =>  x + 1');
+shouldBe("typeof af3.prototype", "'undefined'");
+shouldBe("af3.hasOwnProperty('prototype')", "false");
+
+
+af1.prototype = function (x) { return x + 1;};
+
+debug('af1.prototype = function (x) { return x + 1;}');
+shouldBe("typeof af1.prototype", "'function'");
+shouldBe("af1.prototype.toString()", "'function (x) { return x + 1;}'");
+shouldBe("af1.hasOwnProperty('prototype')", "true");
+
+delete af1.prototype;
+
+debug('delete af1.prototype');
+shouldBe("typeof af1.prototype", "'undefined'");
+shouldBe("af1.hasOwnProperty('prototype')", "false");
+
+var successfullyParsed = true;
index f68b33c..c838444 100644 (file)
@@ -1,3 +1,21 @@
+2015-09-03 Aleksandr Skachkov   <gskachkov@gmail.com>
+
+        [ES6] Implement ES6 arrow function syntax. Prototype of arrow function should be undefined
+        https://bugs.webkit.org/show_bug.cgi?id=147742
+
+        Reviewed by Saam Barati.
+
+        Added correct support of prototype property for arrow function. Arrow function 
+        doesn’t have own prototype property, so (() => {}).hasOwnProperty('prototype') === false.
+        Changes prevent from creation of 'prototype' property automatically during initialization 
+        of arrow function and allow to assign & delete it later in js code. 
+
+
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::getOwnPropertySlot):
+        (JSC::JSFunction::deleteProperty):
+        * tests/stress/arrowfunction-prototype.js: Added.
+
 2015-09-03  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r189338.
index 9db4986..5b2edfb 100644 (file)
@@ -343,7 +343,7 @@ bool JSFunction::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyN
     if (thisObject->isHostOrBuiltinFunction())
         return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
 
-    if (propertyName == exec->propertyNames().prototype) {
+    if (propertyName == exec->propertyNames().prototype && !thisObject->jsExecutable()->isArrowFunction()) {
         VM& vm = exec->vm();
         unsigned attributes;
         PropertyOffset offset = thisObject->getDirectOffset(vm, propertyName, attributes);
@@ -454,13 +454,16 @@ bool JSFunction::deleteProperty(JSCell* cell, ExecState* exec, PropertyName prop
 {
     JSFunction* thisObject = jsCast<JSFunction*>(cell);
     // For non-host functions, don't let these properties by deleted - except by DefineOwnProperty.
-    if (!thisObject->isHostOrBuiltinFunction() && !exec->vm().isInDefineOwnProperty()
-        && (propertyName == exec->propertyNames().arguments
+    if (!thisObject->isHostOrBuiltinFunction() && !exec->vm().isInDefineOwnProperty()) {
+        FunctionExecutable* executable = thisObject->jsExecutable();
+        if (propertyName == exec->propertyNames().arguments
             || propertyName == exec->propertyNames().length
             || propertyName == exec->propertyNames().name
-            || propertyName == exec->propertyNames().prototype
-            || propertyName == exec->propertyNames().caller))
+            || (propertyName == exec->propertyNames().prototype && !executable->isArrowFunction())
+            || propertyName == exec->propertyNames().caller)
         return false;
+    }
+    
     return Base::deleteProperty(thisObject, exec, propertyName);
 }
 
diff --git a/Source/JavaScriptCore/tests/stress/arrowfunction-prototype.js b/Source/JavaScriptCore/tests/stress/arrowfunction-prototype.js
new file mode 100644 (file)
index 0000000..d56437e
--- /dev/null
@@ -0,0 +1,22 @@
+var testCase = function (actual, expected, message) {
+  if (actual !== expected) {
+    throw message + ". Expected '" + expected + "', but was '" + actual + "'";
+  }
+};
+
+var af1 = () =>  {};
+var af2 = (a) => {a + 1};
+var af3 = (x) =>  x + 1;
+
+noInline(af1);
+noInline(af2);
+noInline(af3);
+
+for (var i = 0; i < 10000; ++i) {
+  testCase(typeof af1.prototype, 'undefined', "Error: Not correct result for prototype of arrow function #1");
+  testCase(typeof af2.prototype, 'undefined', "Error: Not correct result for prototype of arrow function #2");
+  testCase(typeof af3.prototype, 'undefined', "Error: Not correct result for prototype of arrow function #5");
+  testCase(af1.hasOwnProperty("prototype"), false, "Error: Not correct result for prototype of arrow function #3");
+  testCase(af2.hasOwnProperty("prototype"), false, "Error: Not correct result for prototype of arrow function #4");
+  testCase(af3.hasOwnProperty("prototype"), false, "Error: Not correct result for prototype of arrow function #6");
+}