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/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) {