Title: [220650] releases/WebKitGTK/webkit-2.18
Revision
220650
Author
carlo...@webkit.org
Date
2017-08-14 00:25:21 -0700 (Mon, 14 Aug 2017)

Log Message

Merge r220481 - Early error on ANY operator before new.target
https://bugs.webkit.org/show_bug.cgi?id=157970

Reviewed by Saam Barati.

Instead of throwing if any unary operator precedes new.target, only
throw if the unary operator updates the reference.

The following become legal in JSC:

```
!new.target
~new.target
typeof new.target
delete new.target
void new.target
```

All of which are legal in v8 and SpiderMonkey in strict and sloppy mode

JSTests:

* stress/new-target-syntax-errors.js:
* stress/new-target.js:

Source/_javascript_Core:

* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseUnaryExpression):

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.18/JSTests/ChangeLog (220649 => 220650)


--- releases/WebKitGTK/webkit-2.18/JSTests/ChangeLog	2017-08-14 07:23:29 UTC (rev 220649)
+++ releases/WebKitGTK/webkit-2.18/JSTests/ChangeLog	2017-08-14 07:25:21 UTC (rev 220650)
@@ -1,3 +1,28 @@
+2017-08-09  Caitlin Potter  <ca...@igalia.com>
+
+        Early error on ANY operator before new.target
+        https://bugs.webkit.org/show_bug.cgi?id=157970
+
+        Reviewed by Saam Barati.
+
+        Instead of throwing if any unary operator precedes new.target, only
+        throw if the unary operator updates the reference.
+
+        The following become legal in JSC:
+
+        ```
+        !new.target
+        ~new.target
+        typeof new.target
+        delete new.target
+        void new.target
+        ```
+
+        All of which are legal in v8 and SpiderMonkey in strict and sloppy mode
+
+        * stress/new-target-syntax-errors.js:
+        * stress/new-target.js:
+
 2017-08-09  Ryan Haddad  <ryanhad...@apple.com>
 
         Skip failing JSC tests stress/regress-169783.js and wasm.yaml/wasm/stress/oom.js.

Modified: releases/WebKitGTK/webkit-2.18/JSTests/stress/default-value-parsing-should-propagate-error.js (220649 => 220650)


--- releases/WebKitGTK/webkit-2.18/JSTests/stress/default-value-parsing-should-propagate-error.js	2017-08-14 07:23:29 UTC (rev 220649)
+++ releases/WebKitGTK/webkit-2.18/JSTests/stress/default-value-parsing-should-propagate-error.js	2017-08-14 07:25:21 UTC (rev 220650)
@@ -16,6 +16,6 @@
 testSyntaxError(`
 function f()
 {
-    ({v = (typeof new.target)} = {})
+    ({v = (++new.target)} = {})
 }
 `, `SyntaxError: Unexpected token '='. Expected a ':' following the property name 'v'.`);

Modified: releases/WebKitGTK/webkit-2.18/JSTests/stress/new-target-syntax-errors.js (220649 => 220650)


--- releases/WebKitGTK/webkit-2.18/JSTests/stress/new-target-syntax-errors.js	2017-08-14 07:23:29 UTC (rev 220649)
+++ releases/WebKitGTK/webkit-2.18/JSTests/stress/new-target-syntax-errors.js	2017-08-14 07:25:21 UTC (rev 220650)
@@ -88,6 +88,14 @@
     shouldNotBeSyntaxError(functionBody);
 }
 
+let otherUnaryOperators = ["!", "~", "+", "-", "typeof ", "void ", "delete "];
+for (let operator of otherUnaryOperators) {
+    function strict(body) { return `"use strict" ${body}`; }
+    let functionBody = `${operator}new.target`;
+    shouldNotBeSyntaxError(functionBody);
+    shouldNotBeSyntaxError(strict(functionBody));
+}
+
 shouldBeSyntaxError(`({foo: new.target} = {foo:20})`);
 
 // Scripts - 15.1.1 Static Semantics: Early Errors

Modified: releases/WebKitGTK/webkit-2.18/JSTests/stress/new-target.js (220649 => 220650)


--- releases/WebKitGTK/webkit-2.18/JSTests/stress/new-target.js	2017-08-14 07:23:29 UTC (rev 220649)
+++ releases/WebKitGTK/webkit-2.18/JSTests/stress/new-target.js	2017-08-14 07:25:21 UTC (rev 220650)
@@ -20,7 +20,7 @@
 // Test without class syntax
 
 function test(result, expected, message) {
-    if (result !== expected)
+    if (result !== expected && !(expected !== expected && result !== result))
         throw "Error: " + message + ". was: " + result + " wanted: " + expected;
 }
 
@@ -125,3 +125,77 @@
 
 };
 newTargetInFunctionInEval();
+
+function testUnaryOps() {
+  var result;
+  function call(f) { f(); return result; }
+  function construct(f) { new f(); return result; }
+  
+  function unaryExclamation() { result = !new.target; }
+  test(construct(unaryExclamation), false, "`!new.target` should be false when new.target is not undefined");
+  test(call(unaryExclamation), true, "`!new.target` should be true when new.target is undefined");
+
+  function unaryBitwiseNot() { result = ~new.target; }
+  test(construct(unaryBitwiseNot), -1, "`~new.target` should be -1");
+  test(call(unaryBitwiseNot), -1, "`~new.target` should be -1");
+
+  function unaryTypeof() { result = typeof new.target; }
+  test(construct(unaryTypeof), "function", "`typeof new.target` should be 'function' when new.target is not undefined");
+  test(call(unaryTypeof), "undefined", "`typeof new.target` should be 'undefined' when new.target is undefined");
+
+  function unaryVoid() { result = void new.target; }
+  test(construct(unaryVoid), undefined, "`void new.target` should be undefined");
+  test(call(unaryVoid), undefined, "`void new.target` should be undefined");
+
+  function unaryAbs() { result = +new.target; }
+  test(construct(unaryAbs), NaN, "+new.target should be NaN");
+  test(call(unaryAbs), NaN, "+new.target should be NaN");
+
+  function unaryNeg() { result = -new.target; }
+  test(construct(unaryNeg), NaN, "-new.target should be NaN");
+  test(call(unaryNeg), NaN, "-new.target should be NaN");
+
+  // Multiple variations of delete are tested for completeness:
+  function unaryDelete() { result = delete new.target; }
+  function strictUnaryDelete() { "use strict"; result = delete new.target; }
+
+  // If Type(ref) is not Reference, return true. (per #sec-delete-operator-runtime-semantics-evaluation)
+  test(construct(unaryDelete), true, "`delete new.target` should be true");
+  test(call(unaryDelete), true, "`delete new.target` should be true");
+  test(construct(strictUnaryDelete), true, "`delete new.target` should be true");
+  test(call(strictUnaryDelete), true, "`delete new.target` should be true");
+
+  var unaryDeleteProp = function unaryDeleteProp() { result = delete new.target.prop; }
+  var strictUnaryDeleteProp = function strictUnaryDeleteProp() { "use strict"; result = delete new.target.prop; }
+  unaryDeleteProp.prop = 1;
+  test(construct(unaryDeleteProp), true, "`delete new.target.prop` should be true when new.target is not undefined and prop is a configurable property");
+  strictUnaryDeleteProp.prop = 1;
+  test(construct(strictUnaryDeleteProp), true, "`delete new.target.prop` should be true when new.target is not undefined and prop is a configurable property");
+  
+  unaryDeleteProp = function unaryDeleteProp() { result = delete new.target.prop; }
+  Object.defineProperty(unaryDeleteProp, "prop", { value: false, configurable: false });
+  test(construct(unaryDeleteProp), false, "`delete new.target.prop` should be false when new.target is not undefined and prop is a non-configurable property");
+
+  strictUnaryDeleteProp = function strictUnaryDeleteProp() { "use strict"; result = delete new.target.prop; }
+  // If deleteStatus is false and IsStrictReference(ref) is true, throw a TypeError exception.
+  Object.defineProperty(strictUnaryDeleteProp, "prop", { value: false, configurable: false });
+  try {
+    var passed = false;
+    construct(strictUnaryDeleteProp);
+  } catch (e) {
+    passed = e instanceof TypeError && e.message.indexOf("delete") >= 0;
+  }
+  test(passed, true, "`delete new.target.prop` should throw a TypeError in strict code when prop is a non-configurable property");
+
+  unaryDeleteProp = function unaryDeleteProp() { result = delete new.target.prop; }
+  unaryDeleteProp.prop = 1;
+  try {
+    var passed = false;
+    call(unaryDeleteProp);
+  } catch (e) {
+    passed = e instanceof TypeError && e.message.indexOf("undefined") >= 0;
+  }
+  test(passed, true, "`delete new.target.prop` should throw a TypeError when new.target is undefined");
+}
+testUnaryOps();
+

Modified: releases/WebKitGTK/webkit-2.18/Source/_javascript_Core/ChangeLog (220649 => 220650)


--- releases/WebKitGTK/webkit-2.18/Source/_javascript_Core/ChangeLog	2017-08-14 07:23:29 UTC (rev 220649)
+++ releases/WebKitGTK/webkit-2.18/Source/_javascript_Core/ChangeLog	2017-08-14 07:25:21 UTC (rev 220650)
@@ -1,3 +1,28 @@
+2017-08-09  Caitlin Potter  <ca...@igalia.com>
+
+        Early error on ANY operator before new.target
+        https://bugs.webkit.org/show_bug.cgi?id=157970
+
+        Reviewed by Saam Barati.
+
+        Instead of throwing if any unary operator precedes new.target, only
+        throw if the unary operator updates the reference.
+
+        The following become legal in JSC:
+
+        ```
+        !new.target
+        ~new.target
+        typeof new.target
+        delete new.target
+        void new.target
+        ```
+
+        All of which are legal in v8 and SpiderMonkey in strict and sloppy mode
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseUnaryExpression):
+
 2017-08-09  Robin Morisset  <rmoris...@apple.com>
 
         Make JSC_validateExceptionChecks=1 succeed on JSTests/stress/v8-deltablue-strict.js.

Modified: releases/WebKitGTK/webkit-2.18/Source/_javascript_Core/parser/Parser.cpp (220649 => 220650)


--- releases/WebKitGTK/webkit-2.18/Source/_javascript_Core/parser/Parser.cpp	2017-08-14 07:23:29 UTC (rev 220649)
+++ releases/WebKitGTK/webkit-2.18/Source/_javascript_Core/parser/Parser.cpp	2017-08-14 07:25:21 UTC (rev 220650)
@@ -4883,7 +4883,7 @@
             failWithMessage("Cannot parse subexpression of ", operatorString(true, lastOperator), "operator");
         failWithMessage("Cannot parse member _expression_");
     }
-    if (UNLIKELY(lastOperator && context.isNewTarget(expr)))
+    if (UNLIKELY(isUpdateOp(static_cast<JSTokenType>(lastOperator)) && context.isNewTarget(expr)))
         internalFailWithMessage(false, "new.target can't come after a prefix operator");
     bool isEvalOrArguments = false;
     if (strictMode() && !m_syntaxAlreadyValidated) {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to