[JSC] Invalid AssignmentTargetType should be an early error.
https://bugs.webkit.org/show_bug.cgi?id=197603
Reviewed by Keith Miller.
JSTests:
* test262/expectations.yaml:
Update expectations to reflect new SyntaxErrors.
(Ideally, these should all be viewed as passing in the near future.)
* stress/async-await-basic.js:
* stress/big-int-literals.js:
Update tests to reflect new SyntaxErrors.
* ChakraCore.yaml:
* ChakraCore/test/EH/try6.baseline-jsc:
* ChakraCore/test/Error/variousErrors3.baseline-jsc: Added.
Update baselines to reflect new SyntaxErrors.
Source/JavaScriptCore:
Since ES6, expressions like 0++, ++0, 0 = 0, and 0 += 0 are all specified as early errors:
https://tc39.github.io/ecma262/#sec-update-expressions-static-semantics-early-errors
https://tc39.github.io/ecma262/#sec-assignment-operators-static-semantics-early-errors
We currently throw late ReferenceErrors for these -- let's turn them into early SyntaxErrors.
(This is based on the expectation that https://github.com/tc39/ecma262/pull/1527 will be accepted;
if that doesn't come to pass, we can subsequently introduce early ReferenceError and revise these.)
* bytecompiler/NodesCodegen.cpp:
(JSC::PostfixNode::emitBytecode): Add an assert for "function call LHS" case.
(JSC::PrefixNode::emitBytecode): Add an assert for "function call LHS" case.
* parser/ASTBuilder.h:
(JSC::ASTBuilder::isLocation): Added.
(JSC::ASTBuilder::isAssignmentLocation): Fix misleading parameter name.
(JSC::ASTBuilder::isFunctionCall): Added.
(JSC::ASTBuilder::makeAssignNode): Add an assert for "function call LHS" case.
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::isLocation): Added.
(JSC::SyntaxChecker::isAssignmentLocation): Fix incorrect definition and align with ASTBuilder.
(JSC::SyntaxChecker::isFunctionCall): Added.
* parser/Nodes.h:
(JSC::ExpressionNode::isFunctionCall const): Added.
Ensure that the parser can check whether an expression node is a function call.
* parser/Parser.cpp:
(JSC::Parser<LexerType>::isSimpleAssignmentTarget): Added.
(JSC::Parser<LexerType>::parseAssignmentExpression):
(JSC::Parser<LexerType>::parseUnaryExpression): See below.
* parser/Parser.h:
Throw SyntaxError whenever an assignment or update expression's target is invalid.
Unfortunately, it seems that web compatibility obliges us to exempt the "function call LHS" case in sloppy mode.
(https://github.com/tc39/ecma262/issues/257#issuecomment-195106880)
Additional cleanup items:
- Make use of `semanticFailIfTrue` for `isMetaProperty` checks, as it's equivalent.
- Rename `requiresLExpr` to `hasPrefixUpdateOp` since it's now confusing,
and get rid of `modifiesExpr` since it refers to the exact same condition.
- Stop setting `lastOperator` near the end -- one case was incorrect and regardless neither is used.
LayoutTests:
* fast/events/window-onerror4-expected.txt:
* ietestcenter/Javascript/11.13.1-1-1-expected.txt:
* ietestcenter/Javascript/11.13.1-1-2-expected.txt:
* ietestcenter/Javascript/11.13.1-1-3-expected.txt:
* ietestcenter/Javascript/11.13.1-1-4-expected.txt:
* js/basic-strict-mode-expected.txt:
* js/dom/assign-expected.txt:
* js/dom/line-column-numbers-expected.txt:
* js/dom/line-column-numbers.html:
* js/dom/postfix-syntax-expected.txt:
* js/dom/prefix-syntax-expected.txt:
* js/dom/script-tests/line-column-numbers.js:
* js/function-toString-parentheses-expected.txt:
* js/parser-syntax-check-expected.txt:
* js/parser-xml-close-comment-expected.txt:
* js/script-tests/function-toString-parentheses.js:
* js/script-tests/parser-syntax-check.js:
Update tests & expectations to reflect new SyntaxErrors.
* js/script-tests/toString-prefix-postfix-preserve-parens.js:
* js/toString-prefix-postfix-preserve-parens-expected.txt:
None of the prefix/postfix tests make sense here now that they're all SyntaxErrors;
remove them and just leave the typeof tests.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@245406 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JSTests/ChakraCore.yaml b/JSTests/ChakraCore.yaml
index 59f00a5..2ad0fd0 100644
--- a/JSTests/ChakraCore.yaml
+++ b/JSTests/ChakraCore.yaml
@@ -551,7 +551,7 @@
- path: ChakraCore/test/Error/CallNonFunction.js
cmd: runChakra :baseline, "NoException", "CallNonFunction_3.baseline-jsc", []
- path: ChakraCore/test/Error/variousErrors.js
- cmd: runChakra :baseline, "NoException", "variousErrors3.baseline", []
+ cmd: runChakra :baseline, "NoException", "variousErrors3.baseline-jsc", []
- path: ChakraCore/test/Error/bug560940.js
cmd: runChakra :pass, "NoException", "", []
- path: ChakraCore/test/Error/inlineSameFunc.js
diff --git a/JSTests/ChakraCore/test/EH/try6.baseline-jsc b/JSTests/ChakraCore/test/EH/try6.baseline-jsc
index 8896d1f..83510b7 100644
--- a/JSTests/ChakraCore/test/EH/try6.baseline-jsc
+++ b/JSTests/ChakraCore/test/EH/try6.baseline-jsc
@@ -16,4 +16,4 @@
Finally bar 2
Except foobaz 2 thrown
english (passed)
-ReferenceError: Postfix ++ operator applied to value that is not a reference.
+SyntaxError: Postfix ++ operator applied to value that is not a reference.
diff --git a/JSTests/ChakraCore/test/Error/variousErrors3.baseline-jsc b/JSTests/ChakraCore/test/Error/variousErrors3.baseline-jsc
new file mode 100644
index 0000000..e1dc4e0
--- /dev/null
+++ b/JSTests/ChakraCore/test/Error/variousErrors3.baseline-jsc
@@ -0,0 +1,8 @@
+42 = 42 :: SyntaxError
+'x' = 42 :: SyntaxError
+true = 42 :: SyntaxError
+null = 42 :: SyntaxError
+delete this .. true
+delete true .. true
+delete 10 .. true
+delete null .. true
diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog
index 33d8b0a..e68c826 100644
--- a/JSTests/ChangeLog
+++ b/JSTests/ChangeLog
@@ -1,3 +1,23 @@
+2019-05-16 Ross Kirsling <ross.kirsling@sony.com>
+
+ [JSC] Invalid AssignmentTargetType should be an early error.
+ https://bugs.webkit.org/show_bug.cgi?id=197603
+
+ Reviewed by Keith Miller.
+
+ * test262/expectations.yaml:
+ Update expectations to reflect new SyntaxErrors.
+ (Ideally, these should all be viewed as passing in the near future.)
+
+ * stress/async-await-basic.js:
+ * stress/big-int-literals.js:
+ Update tests to reflect new SyntaxErrors.
+
+ * ChakraCore.yaml:
+ * ChakraCore/test/EH/try6.baseline-jsc:
+ * ChakraCore/test/Error/variousErrors3.baseline-jsc: Added.
+ Update baselines to reflect new SyntaxErrors.
+
2019-05-15 Saam Barati <sbarati@apple.com>
Bound liveness of SetArgumentMaybe nodes when maximal flush insertion phase is enabled
diff --git a/JSTests/stress/async-await-basic.js b/JSTests/stress/async-await-basic.js
index dfeefef..0eb23b0 100644
--- a/JSTests/stress/async-await-basic.js
+++ b/JSTests/stress/async-await-basic.js
@@ -270,28 +270,15 @@
var t3 = !!!!!await Promise.resolve(true);
log.push('step 5 ' + t3);
- try {
- var t4 = ++await 1;
- } catch(e) {
- if (e instanceof ReferenceError) {
- log.push('step 6 ');
- }
- }
-
- try {
- var t5 = --await 1;
- } catch(e) {
- if (e instanceof ReferenceError) {
- log.push('step 7');
- }
- }
+ shouldThrowSyntaxError("var t4 = ++await 1;");
+ shouldThrowSyntaxError("var t5 = --await 1;");
return void await 'test';
};
log = [];
shouldBeAsync(undefined, () => awaitEpression(5));
-shouldBe("start:5 step 1 step 2 -2 step 3 12345 step 4 -54321 step 5 false step 6 step 7", log.join(" "));
+shouldBe("start:5 step 1 step 2 -2 step 3 12345 step 4 -54321 step 5 false", log.join(" "));
// MethoodDefinition SyntaxErrors
shouldThrowSyntaxError("var obj = { async foo : true };", "Unexpected token ':'. Expected a parenthesis for argument list.");
diff --git a/JSTests/stress/big-int-literals.js b/JSTests/stress/big-int-literals.js
index 6c48090..54957e8 100644
--- a/JSTests/stress/big-int-literals.js
+++ b/JSTests/stress/big-int-literals.js
@@ -104,10 +104,4 @@
assertThrowSyntaxError("100nn");
assertThrowSyntaxError("1a0nn");
assertThrowSyntaxError("10E20n");
-
-try {
- eval("--10n");
- assert(false);
-} catch(e) {
- assert(e instanceof ReferenceError);
-}
+assertThrowSyntaxError("--10n");
diff --git a/JSTests/test262/expectations.yaml b/JSTests/test262/expectations.yaml
index 3fa025f..e37273d 100644
--- a/JSTests/test262/expectations.yaml
+++ b/JSTests/test262/expectations.yaml
@@ -1807,7 +1807,7 @@
test/language/arguments-object/mapped/nonconfigurable-nonwritable-descriptors-set-by-param.js:
default: 'Test262Error: Expected obj[0] to have configurable:false.'
test/language/asi/S7.9_A5.7_T1.js:
- default: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: The prefix-increment operator requires a reference expression.'
strict mode: 'SyntaxError: The prefix-increment operator requires a reference expression.'
test/language/block-scope/syntax/redeclaration/async-function-name-redeclaration-attempt-with-async-function.js:
default: 'Test262: This statement should not be evaluated.'
@@ -2060,29 +2060,29 @@
default: 'Test262Error: Expected SameValue(«true», «false») to be true'
strict mode: 'Test262Error: Expected SameValue(«true», «false») to be true'
test/language/expressions/assignment/non-simple-target.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/assignment/target-boolean.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/assignment/target-cover-newtarget.js:
default: "SyntaxError: new.target can't be the left hand side of an assignment expression."
strict mode: "SyntaxError: new.target can't be the left hand side of an assignment expression."
test/language/expressions/assignment/target-cover-yieldexpr.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/assignment/target-newtarget.js:
default: "SyntaxError: new.target can't be the left hand side of an assignment expression."
strict mode: "SyntaxError: new.target can't be the left hand side of an assignment expression."
test/language/expressions/assignment/target-null.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/assignment/target-number.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/assignment/target-string.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/async-arrow-function/await-as-param-ident-nested-arrow-parameter-position.js:
default: 'Test262: This statement should not be evaluated.'
strict mode: 'Test262: This statement should not be evaluated.'
@@ -2090,11 +2090,11 @@
default: 'Test262: This statement should not be evaluated.'
strict mode: 'Test262: This statement should not be evaluated.'
test/language/expressions/async-function/early-errors-expression-not-simple-assignment-target.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/await/early-errors-await-not-simple-assignment-target.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/call/eval-realm-indirect.js:
default: 'Test262Error: Expected SameValue(«inside», «outside») to be true'
test/language/expressions/call/eval-spread-empty-leading.js:
@@ -2300,92 +2300,92 @@
default: 'Test262Error: Expected true but got false'
strict mode: 'Test262Error: Expected true but got false'
test/language/expressions/compound-assignment/add-non-simple.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/compound-assignment/btws-and-non-simple.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/compound-assignment/btws-or-non-simple.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/compound-assignment/btws-xor-non-simple.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/compound-assignment/div-non-simple.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/compound-assignment/left-shift-non-simple.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/compound-assignment/mod-div-non-simple.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/compound-assignment/mult-non-simple.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/compound-assignment/right-shift-non-simple.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/compound-assignment/subtract-non-simple.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/compound-assignment/u-right-shift-non-simple.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/conditional/in-branch-1.js:
default: "SyntaxError: Unexpected keyword 'in'. Expected ':' in ternary operator."
strict mode: "SyntaxError: Unexpected keyword 'in'. Expected ':' in ternary operator."
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-1-update-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Postfix ++ operator applied to value that is not a reference.'
+ strict mode: 'SyntaxError: Postfix ++ operator applied to value that is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-10-lhs-assignment-operator-assignment-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-11-lhs-assignment-operator-assignment-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-12-lhs-assignment-operator-assignment-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-13-lhs-assignment-operator-assignment-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-14-lhs-assignment-operator-assignment-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-15-lhs-assignment-operator-assignment-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-16-lhs-assignment-operator-assignment-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-17-lhs-assignment-operator-assignment-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-2-update-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Postfix -- operator applied to value that is not a reference.'
+ strict mode: 'SyntaxError: Postfix -- operator applied to value that is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-3-update-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Prefix -- operator applied to value that is not a reference.'
+ strict mode: 'SyntaxError: Prefix -- operator applied to value that is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-4-update-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Prefix -- operator applied to value that is not a reference.'
+ strict mode: 'SyntaxError: Prefix -- operator applied to value that is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-5-lhs-equals-assignment-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-6-lhs-assignment-operator-assignment-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-7-lhs-assignment-operator-assignment-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-8-lhs-assignment-operator-assignment-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/dynamic-import/syntax/invalid/invalid-asssignmenttargettype-reference-error-9-lhs-assignment-operator-assignment-expression.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/function/name.js:
default: 'Test262Error: Expected SameValue(«true», «false») to be true'
strict mode: 'Test262Error: Expected SameValue(«true», «false») to be true'
@@ -2477,8 +2477,8 @@
default: "SyntaxError: new.target can't come before a postfix operator."
strict mode: "SyntaxError: new.target can't come before a postfix operator."
test/language/expressions/postfix-decrement/target-cover-yieldexpr.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Postfix -- operator applied to value that is not a reference.'
+ strict mode: 'SyntaxError: Postfix -- operator applied to value that is not a reference.'
test/language/expressions/postfix-decrement/target-newtarget.js:
default: "SyntaxError: new.target can't come before a postfix operator."
strict mode: "SyntaxError: new.target can't come before a postfix operator."
@@ -2500,8 +2500,8 @@
default: "SyntaxError: new.target can't come before a postfix operator."
strict mode: "SyntaxError: new.target can't come before a postfix operator."
test/language/expressions/postfix-increment/target-cover-yieldexpr.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Postfix ++ operator applied to value that is not a reference.'
+ strict mode: 'SyntaxError: Postfix ++ operator applied to value that is not a reference.'
test/language/expressions/postfix-increment/target-newtarget.js:
default: "SyntaxError: new.target can't come before a postfix operator."
strict mode: "SyntaxError: new.target can't come before a postfix operator."
@@ -2523,8 +2523,8 @@
default: "SyntaxError: new.target can't come after a prefix operator."
strict mode: "SyntaxError: new.target can't come after a prefix operator."
test/language/expressions/prefix-decrement/target-cover-yieldexpr.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Prefix -- operator applied to value that is not a reference.'
+ strict mode: 'SyntaxError: Prefix -- operator applied to value that is not a reference.'
test/language/expressions/prefix-decrement/target-newtarget.js:
default: "SyntaxError: new.target can't come after a prefix operator."
strict mode: "SyntaxError: new.target can't come after a prefix operator."
@@ -2546,8 +2546,8 @@
default: "SyntaxError: new.target can't come after a prefix operator."
strict mode: "SyntaxError: new.target can't come after a prefix operator."
test/language/expressions/prefix-increment/target-cover-yieldexpr.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Prefix -- operator applied to value that is not a reference.'
+ strict mode: 'SyntaxError: Prefix -- operator applied to value that is not a reference.'
test/language/expressions/prefix-increment/target-newtarget.js:
default: "SyntaxError: new.target can't come after a prefix operator."
strict mode: "SyntaxError: new.target can't come after a prefix operator."
@@ -2555,8 +2555,8 @@
default: 'Test262Error: did not perform ArgumentsListEvaluation Expected SameValue(«true», «false») to be true'
strict mode: 'Test262Error: did not perform ArgumentsListEvaluation Expected SameValue(«true», «false») to be true'
test/language/expressions/this/S11.1.1_A1.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/expressions/yield/star-iterable.js:
default: 'Test262Error: First result `done` flag Expected SameValue(«false», «undefined») to be true'
strict mode: 'Test262Error: First result `done` flag Expected SameValue(«false», «undefined») to be true'
@@ -2777,10 +2777,16 @@
module: "SyntaxError: Unexpected identifier 'as'. Expected 'from' before exported module name."
test/language/module-code/instn-once.js:
module: "SyntaxError: Unexpected identifier 'as'. Expected 'from' before exported module name."
+test/language/module-code/instn-resolve-empty-export.js:
+ module: 'SyntaxError: Postfix ++ operator applied to value that is not a reference.'
+test/language/module-code/instn-resolve-empty-import.js:
+ module: 'SyntaxError: Postfix ++ operator applied to value that is not a reference.'
+test/language/module-code/instn-resolve-err-reference.js:
+ module: 'SyntaxError: Postfix ++ operator applied to value that is not a reference.'
test/language/module-code/instn-resolve-order-depth.js:
module: "SyntaxError: 'break' is only valid inside a switch or loop statement."
test/language/module-code/instn-resolve-order-src.js:
- module: "SyntaxError: 'break' is only valid inside a switch or loop statement."
+ module: 'SyntaxError: Postfix ++ operator applied to value that is not a reference.'
test/language/module-code/instn-star-as-props-dflt-skip.js:
module: "SyntaxError: Unexpected identifier 'as'. Expected 'from' before exported module name."
test/language/module-code/instn-star-props-nrml.js:
@@ -2800,7 +2806,7 @@
test/language/module-code/parse-err-hoist-lex-gen.js:
module: 'Test262: This statement should not be evaluated.'
test/language/module-code/parse-err-reference.js:
- module: 'Test262: This statement should not be evaluated.'
+ module: 'SyntaxError: Postfix ++ operator applied to value that is not a reference.'
test/language/statements/class/class-name-ident-await-escaped.js:
default: "SyntaxError: Unexpected escaped characters in keyword token: 'aw\\u0061it'"
strict mode: "SyntaxError: Unexpected escaped characters in keyword token: 'aw\\u0061it'"
@@ -3174,17 +3180,17 @@
test/language/statements/with/let-array-with-newline.js:
default: 'Test262: This statement should not be evaluated.'
test/language/types/boolean/S8.3_A2.1.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/types/boolean/S8.3_A2.2.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/types/reference/S8.7.2_A1_T1.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/types/reference/S8.7.2_A1_T2.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
+ default: 'SyntaxError: Left side of assignment is not a reference.'
+ strict mode: 'SyntaxError: Left side of assignment is not a reference.'
test/language/types/reference/put-value-prop-base-primitive-realm.js:
default: 'Test262Error: number Expected SameValue(«0», «1») to be true'
strict mode: 'Test262Error: number Expected SameValue(«0», «1») to be true'
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 0b6abe6..5386f04 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,34 @@
+2019-05-16 Ross Kirsling <ross.kirsling@sony.com>
+
+ [JSC] Invalid AssignmentTargetType should be an early error.
+ https://bugs.webkit.org/show_bug.cgi?id=197603
+
+ Reviewed by Keith Miller.
+
+ * fast/events/window-onerror4-expected.txt:
+ * ietestcenter/Javascript/11.13.1-1-1-expected.txt:
+ * ietestcenter/Javascript/11.13.1-1-2-expected.txt:
+ * ietestcenter/Javascript/11.13.1-1-3-expected.txt:
+ * ietestcenter/Javascript/11.13.1-1-4-expected.txt:
+ * js/basic-strict-mode-expected.txt:
+ * js/dom/assign-expected.txt:
+ * js/dom/line-column-numbers-expected.txt:
+ * js/dom/line-column-numbers.html:
+ * js/dom/postfix-syntax-expected.txt:
+ * js/dom/prefix-syntax-expected.txt:
+ * js/dom/script-tests/line-column-numbers.js:
+ * js/function-toString-parentheses-expected.txt:
+ * js/parser-syntax-check-expected.txt:
+ * js/parser-xml-close-comment-expected.txt:
+ * js/script-tests/function-toString-parentheses.js:
+ * js/script-tests/parser-syntax-check.js:
+ Update tests & expectations to reflect new SyntaxErrors.
+
+ * js/script-tests/toString-prefix-postfix-preserve-parens.js:
+ * js/toString-prefix-postfix-preserve-parens-expected.txt:
+ None of the prefix/postfix tests make sense here now that they're all SyntaxErrors;
+ remove them and just leave the typeof tests.
+
2019-05-16 Youenn Fablet <youenn@apple.com>
Layout Test http/wpt/cache-storage/cache-quota-add.any.html is a flaky failure
diff --git a/LayoutTests/fast/events/window-onerror4-expected.txt b/LayoutTests/fast/events/window-onerror4-expected.txt
index 0a49a26..a35b58e 100644
--- a/LayoutTests/fast/events/window-onerror4-expected.txt
+++ b/LayoutTests/fast/events/window-onerror4-expected.txt
@@ -1,4 +1,4 @@
You should see a log record if window.onerror is working properly for this test.Bug 8519.
-Error caught successfully: ReferenceError: Left side of assignment is not a reference. File: undefined Line: 1 Column: 3 Error: ReferenceError: Left side of assignment is not a reference.
+Error caught successfully: SyntaxError: Left side of assignment is not a reference. File: window-onerror4.html Line: 16 Column: 9 Error: SyntaxError: Left side of assignment is not a reference.
diff --git a/LayoutTests/ietestcenter/Javascript/11.13.1-1-1-expected.txt b/LayoutTests/ietestcenter/Javascript/11.13.1-1-1-expected.txt
index a37ae34..95b2737a 100644
--- a/LayoutTests/ietestcenter/Javascript/11.13.1-1-1-expected.txt
+++ b/LayoutTests/ietestcenter/Javascript/11.13.1-1-1-expected.txt
@@ -4,7 +4,7 @@
PASS ES5Harness.preconditionPassed is true
-PASS ES5Harness.testPassed is true
+FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/ietestcenter/Javascript/11.13.1-1-2-expected.txt b/LayoutTests/ietestcenter/Javascript/11.13.1-1-2-expected.txt
index eb825b8..be22e41 100644
--- a/LayoutTests/ietestcenter/Javascript/11.13.1-1-2-expected.txt
+++ b/LayoutTests/ietestcenter/Javascript/11.13.1-1-2-expected.txt
@@ -4,7 +4,7 @@
PASS ES5Harness.preconditionPassed is true
-PASS ES5Harness.testPassed is true
+FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/ietestcenter/Javascript/11.13.1-1-3-expected.txt b/LayoutTests/ietestcenter/Javascript/11.13.1-1-3-expected.txt
index e1e02a5..64fbb02 100644
--- a/LayoutTests/ietestcenter/Javascript/11.13.1-1-3-expected.txt
+++ b/LayoutTests/ietestcenter/Javascript/11.13.1-1-3-expected.txt
@@ -4,7 +4,7 @@
PASS ES5Harness.preconditionPassed is true
-PASS ES5Harness.testPassed is true
+FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/ietestcenter/Javascript/11.13.1-1-4-expected.txt b/LayoutTests/ietestcenter/Javascript/11.13.1-1-4-expected.txt
index 272f992..7305ee9 100644
--- a/LayoutTests/ietestcenter/Javascript/11.13.1-1-4-expected.txt
+++ b/LayoutTests/ietestcenter/Javascript/11.13.1-1-4-expected.txt
@@ -4,7 +4,7 @@
PASS ES5Harness.preconditionPassed is true
-PASS ES5Harness.testPassed is true
+FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/js/basic-strict-mode-expected.txt b/LayoutTests/js/basic-strict-mode-expected.txt
index 7316ad4..fc33b85 100644
--- a/LayoutTests/js/basic-strict-mode-expected.txt
+++ b/LayoutTests/js/basic-strict-mode-expected.txt
@@ -133,17 +133,17 @@
PASS 'use strict'; function f() { arguments-- } threw exception SyntaxError: 'arguments' cannot be modified in strict mode..
PASS (function(){'use strict'; function f() { arguments-- }}) threw exception SyntaxError: 'arguments' cannot be modified in strict mode..
PASS global.eval('"use strict"; if (0) ++arguments; true;') threw exception SyntaxError: Cannot modify 'arguments' in strict mode..
-PASS 'use strict'; ++(1, eval) threw exception ReferenceError: Prefix ++ operator applied to value that is not a reference..
+PASS 'use strict'; ++(1, eval) threw exception SyntaxError: Prefix ++ operator applied to value that is not a reference..
PASS (function(){'use strict'; ++(1, eval)}) threw exception SyntaxError: Cannot modify 'eval' in strict mode..
-PASS 'use strict'; ++(1, 2, 3, eval) threw exception ReferenceError: Prefix ++ operator applied to value that is not a reference..
+PASS 'use strict'; ++(1, 2, 3, eval) threw exception SyntaxError: Prefix ++ operator applied to value that is not a reference..
PASS (function(){'use strict'; ++(1, 2, 3, eval)}) threw exception SyntaxError: Cannot modify 'eval' in strict mode..
-PASS 'use strict'; (1, eval)++ threw exception ReferenceError: Postfix ++ operator applied to value that is not a reference..
+PASS 'use strict'; (1, eval)++ threw exception SyntaxError: Postfix ++ operator applied to value that is not a reference..
PASS (function(){'use strict'; (1, eval)++}) threw exception SyntaxError: Cannot modify 'eval' in strict mode..
-PASS 'use strict'; --(1, eval) threw exception ReferenceError: Prefix -- operator applied to value that is not a reference..
+PASS 'use strict'; --(1, eval) threw exception SyntaxError: Prefix -- operator applied to value that is not a reference..
PASS (function(){'use strict'; --(1, eval)}) threw exception SyntaxError: Cannot modify 'eval' in strict mode..
-PASS 'use strict'; (1, eval)-- threw exception ReferenceError: Postfix -- operator applied to value that is not a reference..
+PASS 'use strict'; (1, eval)-- threw exception SyntaxError: Postfix -- operator applied to value that is not a reference..
PASS (function(){'use strict'; (1, eval)--}) threw exception SyntaxError: 'eval' cannot be modified in strict mode..
-PASS 'use strict'; (1, 2, 3, eval)-- threw exception ReferenceError: Postfix -- operator applied to value that is not a reference..
+PASS 'use strict'; (1, 2, 3, eval)-- threw exception SyntaxError: Postfix -- operator applied to value that is not a reference..
PASS (function(){'use strict'; (1, 2, 3, eval)--}) threw exception SyntaxError: 'eval' cannot be modified in strict mode..
PASS 'use strict'; function f() { ++(1, arguments) } threw exception SyntaxError: Cannot modify 'arguments' in strict mode..
PASS (function(){'use strict'; function f() { ++(1, arguments) }}) threw exception SyntaxError: Cannot modify 'arguments' in strict mode..
diff --git a/LayoutTests/js/dom/assign-expected.txt b/LayoutTests/js/dom/assign-expected.txt
index 27ab287..a215905 100644
--- a/LayoutTests/js/dom/assign-expected.txt
+++ b/LayoutTests/js/dom/assign-expected.txt
@@ -13,8 +13,8 @@
PASS ((x)) = 8; x is 8
PASS ((window.x)) = 9; x is 9
PASS ((window["x"])) = 10; x is 10
-PASS (y, x) = "FAIL"; threw exception ReferenceError: Left side of assignment is not a reference..
-PASS (true ? x : y) = "FAIL"; threw exception ReferenceError: Left side of assignment is not a reference..
+PASS (y, x) = "FAIL"; threw exception SyntaxError: Left side of assignment is not a reference..
+PASS (true ? x : y) = "FAIL"; threw exception SyntaxError: Left side of assignment is not a reference..
PASS x++ = "FAIL"; threw exception SyntaxError: Left hand side of operator '=' must be a reference..
PASS successfullyParsed is true
diff --git a/LayoutTests/js/dom/line-column-numbers-expected.txt b/LayoutTests/js/dom/line-column-numbers-expected.txt
index 7fbd84e..86d065c 100644
--- a/LayoutTests/js/dom/line-column-numbers-expected.txt
+++ b/LayoutTests/js/dom/line-column-numbers-expected.txt
@@ -138,12 +138,12 @@
19 g at line-column-numbers.html:190:30
--> Case 21 Stack Trace:
- 0 toFuzz21 at line-column-numbers.html:206:26
- 1 global code at line-column-numbers.html:209:13
+ 0 eval at [native code]
+ 1 global code at line-column-numbers.html:205:9
--> Case 22 Stack Trace:
- 0 toFuzz22 at line-column-numbers.html:220:36
- 1 global code at line-column-numbers.html:224:13
+ 0 toFuzz22 at line-column-numbers.html:221:36
+ 1 global code at line-column-numbers.html:225:13
--> Case 1 Stack Trace:
0 global code at line-column-numbers.js:3:26
@@ -280,12 +280,12 @@
19 g at line-column-numbers.js:127:30
--> Case 21 Stack Trace:
- 0 toFuzz21b at line-column-numbers.js:141:26
- 1 global code at line-column-numbers.js:144:14
+ 0 eval at [native code]
+ 1 global code at line-column-numbers.js:140:9
--> Case 22 Stack Trace:
- 0 toFuzz22b at line-column-numbers.js:153:36
- 1 global code at line-column-numbers.js:157:14
+ 0 toFuzz22b at line-column-numbers.js:154:36
+ 1 global code at line-column-numbers.js:158:14
PASS successfullyParsed is true
diff --git a/LayoutTests/js/dom/line-column-numbers.html b/LayoutTests/js/dom/line-column-numbers.html
index 094a927..f816053 100644
--- a/LayoutTests/js/dom/line-column-numbers.html
+++ b/LayoutTests/js/dom/line-column-numbers.html
@@ -202,11 +202,12 @@
<script>testId++;</script>
<script>
try {
- function toFuzz21() {
- if (PriorityQueue.prototype.doSort() instanceof (this ^= function() {
- })) return 2;
- }
- toFuzz21();
+ eval(
+ "function toFuzz21() {\n" +
+ " if (PriorityQueue.prototype.doSort() instanceof (this ^= function () {})) return 2;\n" +
+ "}\n" +
+ "toFuzz21();"
+ );
} catch(e) {
printStack(e.stack);
}
diff --git a/LayoutTests/js/dom/postfix-syntax-expected.txt b/LayoutTests/js/dom/postfix-syntax-expected.txt
index 891c4e5..2562f30 100644
--- a/LayoutTests/js/dom/postfix-syntax-expected.txt
+++ b/LayoutTests/js/dom/postfix-syntax-expected.txt
@@ -13,8 +13,8 @@
PASS ((x))++ is 7
PASS ((window.x))++ is 8
PASS ((window["x"]))++ is 9
-PASS (y, x)++ threw exception ReferenceError: Postfix ++ operator applied to value that is not a reference..
-PASS (true ? x : y)++ threw exception ReferenceError: Postfix ++ operator applied to value that is not a reference..
+PASS (y, x)++ threw exception SyntaxError: Postfix ++ operator applied to value that is not a reference..
+PASS (true ? x : y)++ threw exception SyntaxError: Postfix ++ operator applied to value that is not a reference..
PASS x++++ threw exception SyntaxError: Unexpected token '++'.
PASS x is 0
PASS y is 0
diff --git a/LayoutTests/js/dom/prefix-syntax-expected.txt b/LayoutTests/js/dom/prefix-syntax-expected.txt
index a65672a..837e10a 100644
--- a/LayoutTests/js/dom/prefix-syntax-expected.txt
+++ b/LayoutTests/js/dom/prefix-syntax-expected.txt
@@ -13,9 +13,9 @@
PASS ++((x)) is 8
PASS ++((window.x)) is 9
PASS ++((window["x"])) is 10
-PASS ++(y, x) threw exception ReferenceError: Prefix ++ operator applied to value that is not a reference..
-PASS ++(true ? x : y) threw exception ReferenceError: Prefix ++ operator applied to value that is not a reference..
-PASS ++++x threw exception ReferenceError: Prefix ++ operator applied to value that is not a reference..
+PASS ++(y, x) threw exception SyntaxError: Prefix ++ operator applied to value that is not a reference..
+PASS ++(true ? x : y) threw exception SyntaxError: Prefix ++ operator applied to value that is not a reference..
+PASS ++++x threw exception SyntaxError: The prefix-increment operator requires a reference expression..
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/js/dom/script-tests/line-column-numbers.js b/LayoutTests/js/dom/script-tests/line-column-numbers.js
index 88119ed..456f0d7 100644
--- a/LayoutTests/js/dom/script-tests/line-column-numbers.js
+++ b/LayoutTests/js/dom/script-tests/line-column-numbers.js
@@ -137,11 +137,12 @@
// Case 21: Regression test from https://bugs.webkit.org/show_bug.cgi?id=118662
testId++;
try {
- function toFuzz21b() {
- if (PriorityQueue.prototype.doSort() instanceof (this ^= function() {
- })) return 2;
- }
- toFuzz21b();
+ eval(
+ "function toFuzz21() {\n" +
+ " if (PriorityQueue.prototype.doSort() instanceof (this ^= function () {})) return 2;\n" +
+ "}\n" +
+ "toFuzz21();"
+ );
} catch(e) {
printStack(e.stack);
}
diff --git a/LayoutTests/js/function-toString-parentheses-expected.txt b/LayoutTests/js/function-toString-parentheses-expected.txt
index 9d66640..8f4a088 100644
--- a/LayoutTests/js/function-toString-parentheses-expected.txt
+++ b/LayoutTests/js/function-toString-parentheses-expected.txt
@@ -217,7 +217,7 @@
PASS compileAndSerialize('(a = b) + c') is '(a = b) + c'
PASS compileAndSerialize('a = (b + c)') is 'a = (b + c)'
PASS compileAndSerialize('a + b = c') threw exception SyntaxError: Left hand side of operator '=' must be a reference..
-PASS compileAndSerialize('(a + b) = c') is '(a + b) = c'
+PASS compileAndSerialize('(a + b) = c') threw exception SyntaxError: Left side of assignment is not a reference..
PASS compileAndSerialize('a + (b = c)') is 'a + (b = c)'
PASS compileAndSerialize('a *= b *= c') is 'a *= b *= c'
PASS compileAndSerialize('(a *= b) *= c') is '(a *= b) *= c'
@@ -229,7 +229,7 @@
PASS compileAndSerialize('(a *= b) + c') is '(a *= b) + c'
PASS compileAndSerialize('a *= (b + c)') is 'a *= (b + c)'
PASS compileAndSerialize('a + b *= c') threw exception SyntaxError: Left hand side of operator '*=' must be a reference..
-PASS compileAndSerialize('(a + b) *= c') is '(a + b) *= c'
+PASS compileAndSerialize('(a + b) *= c') threw exception SyntaxError: Left side of assignment is not a reference..
PASS compileAndSerialize('a + (b *= c)') is 'a + (b *= c)'
PASS compileAndSerialize('a /= b /= c') is 'a /= b /= c'
PASS compileAndSerialize('(a /= b) /= c') is '(a /= b) /= c'
@@ -241,7 +241,7 @@
PASS compileAndSerialize('(a /= b) + c') is '(a /= b) + c'
PASS compileAndSerialize('a /= (b + c)') is 'a /= (b + c)'
PASS compileAndSerialize('a + b /= c') threw exception SyntaxError: Left hand side of operator '/=' must be a reference..
-PASS compileAndSerialize('(a + b) /= c') is '(a + b) /= c'
+PASS compileAndSerialize('(a + b) /= c') threw exception SyntaxError: Left side of assignment is not a reference..
PASS compileAndSerialize('a + (b /= c)') is 'a + (b /= c)'
PASS compileAndSerialize('a %= b %= c') is 'a %= b %= c'
PASS compileAndSerialize('(a %= b) %= c') is '(a %= b) %= c'
@@ -253,7 +253,7 @@
PASS compileAndSerialize('(a %= b) + c') is '(a %= b) + c'
PASS compileAndSerialize('a %= (b + c)') is 'a %= (b + c)'
PASS compileAndSerialize('a + b %= c') threw exception SyntaxError: Left hand side of operator '%=' must be a reference..
-PASS compileAndSerialize('(a + b) %= c') is '(a + b) %= c'
+PASS compileAndSerialize('(a + b) %= c') threw exception SyntaxError: Left side of assignment is not a reference..
PASS compileAndSerialize('a + (b %= c)') is 'a + (b %= c)'
PASS compileAndSerialize('a += b += c') is 'a += b += c'
PASS compileAndSerialize('(a += b) += c') is '(a += b) += c'
@@ -265,7 +265,7 @@
PASS compileAndSerialize('(a += b) + c') is '(a += b) + c'
PASS compileAndSerialize('a += (b + c)') is 'a += (b + c)'
PASS compileAndSerialize('a + b += c') threw exception SyntaxError: Left hand side of operator '+=' must be a reference..
-PASS compileAndSerialize('(a + b) += c') is '(a + b) += c'
+PASS compileAndSerialize('(a + b) += c') threw exception SyntaxError: Left side of assignment is not a reference..
PASS compileAndSerialize('a + (b += c)') is 'a + (b += c)'
PASS compileAndSerialize('a -= b -= c') is 'a -= b -= c'
PASS compileAndSerialize('(a -= b) -= c') is '(a -= b) -= c'
@@ -277,7 +277,7 @@
PASS compileAndSerialize('(a -= b) + c') is '(a -= b) + c'
PASS compileAndSerialize('a -= (b + c)') is 'a -= (b + c)'
PASS compileAndSerialize('a + b -= c') threw exception SyntaxError: Left hand side of operator '-=' must be a reference..
-PASS compileAndSerialize('(a + b) -= c') is '(a + b) -= c'
+PASS compileAndSerialize('(a + b) -= c') threw exception SyntaxError: Left side of assignment is not a reference..
PASS compileAndSerialize('a + (b -= c)') is 'a + (b -= c)'
PASS compileAndSerialize('a <<= b <<= c') is 'a <<= b <<= c'
PASS compileAndSerialize('(a <<= b) <<= c') is '(a <<= b) <<= c'
@@ -289,7 +289,7 @@
PASS compileAndSerialize('(a <<= b) + c') is '(a <<= b) + c'
PASS compileAndSerialize('a <<= (b + c)') is 'a <<= (b + c)'
PASS compileAndSerialize('a + b <<= c') threw exception SyntaxError: Left hand side of operator '<<=' must be a reference..
-PASS compileAndSerialize('(a + b) <<= c') is '(a + b) <<= c'
+PASS compileAndSerialize('(a + b) <<= c') threw exception SyntaxError: Left side of assignment is not a reference..
PASS compileAndSerialize('a + (b <<= c)') is 'a + (b <<= c)'
PASS compileAndSerialize('a >>= b >>= c') is 'a >>= b >>= c'
PASS compileAndSerialize('(a >>= b) >>= c') is '(a >>= b) >>= c'
@@ -301,7 +301,7 @@
PASS compileAndSerialize('(a >>= b) + c') is '(a >>= b) + c'
PASS compileAndSerialize('a >>= (b + c)') is 'a >>= (b + c)'
PASS compileAndSerialize('a + b >>= c') threw exception SyntaxError: Left hand side of operator '>>=' must be a reference..
-PASS compileAndSerialize('(a + b) >>= c') is '(a + b) >>= c'
+PASS compileAndSerialize('(a + b) >>= c') threw exception SyntaxError: Left side of assignment is not a reference..
PASS compileAndSerialize('a + (b >>= c)') is 'a + (b >>= c)'
PASS compileAndSerialize('a >>>= b >>>= c') is 'a >>>= b >>>= c'
PASS compileAndSerialize('(a >>>= b) >>>= c') is '(a >>>= b) >>>= c'
@@ -313,7 +313,7 @@
PASS compileAndSerialize('(a >>>= b) + c') is '(a >>>= b) + c'
PASS compileAndSerialize('a >>>= (b + c)') is 'a >>>= (b + c)'
PASS compileAndSerialize('a + b >>>= c') threw exception SyntaxError: Left hand side of operator '>>>=' must be a reference..
-PASS compileAndSerialize('(a + b) >>>= c') is '(a + b) >>>= c'
+PASS compileAndSerialize('(a + b) >>>= c') threw exception SyntaxError: Left side of assignment is not a reference..
PASS compileAndSerialize('a + (b >>>= c)') is 'a + (b >>>= c)'
PASS compileAndSerialize('a &= b &= c') is 'a &= b &= c'
PASS compileAndSerialize('(a &= b) &= c') is '(a &= b) &= c'
@@ -325,7 +325,7 @@
PASS compileAndSerialize('(a &= b) + c') is '(a &= b) + c'
PASS compileAndSerialize('a &= (b + c)') is 'a &= (b + c)'
PASS compileAndSerialize('a + b &= c') threw exception SyntaxError: Left hand side of operator '&=' must be a reference..
-PASS compileAndSerialize('(a + b) &= c') is '(a + b) &= c'
+PASS compileAndSerialize('(a + b) &= c') threw exception SyntaxError: Left side of assignment is not a reference..
PASS compileAndSerialize('a + (b &= c)') is 'a + (b &= c)'
PASS compileAndSerialize('a ^= b ^= c') is 'a ^= b ^= c'
PASS compileAndSerialize('(a ^= b) ^= c') is '(a ^= b) ^= c'
@@ -337,7 +337,7 @@
PASS compileAndSerialize('(a ^= b) + c') is '(a ^= b) + c'
PASS compileAndSerialize('a ^= (b + c)') is 'a ^= (b + c)'
PASS compileAndSerialize('a + b ^= c') threw exception SyntaxError: Left hand side of operator '^=' must be a reference..
-PASS compileAndSerialize('(a + b) ^= c') is '(a + b) ^= c'
+PASS compileAndSerialize('(a + b) ^= c') threw exception SyntaxError: Left side of assignment is not a reference..
PASS compileAndSerialize('a + (b ^= c)') is 'a + (b ^= c)'
PASS compileAndSerialize('a |= b |= c') is 'a |= b |= c'
PASS compileAndSerialize('(a |= b) |= c') is '(a |= b) |= c'
@@ -349,7 +349,7 @@
PASS compileAndSerialize('(a |= b) + c') is '(a |= b) + c'
PASS compileAndSerialize('a |= (b + c)') is 'a |= (b + c)'
PASS compileAndSerialize('a + b |= c') threw exception SyntaxError: Left hand side of operator '|=' must be a reference..
-PASS compileAndSerialize('(a + b) |= c') is '(a + b) |= c'
+PASS compileAndSerialize('(a + b) |= c') threw exception SyntaxError: Left side of assignment is not a reference..
PASS compileAndSerialize('a + (b |= c)') is 'a + (b |= c)'
PASS compileAndSerialize('delete a + b') is 'delete a + b'
PASS compileAndSerialize('(delete a) + b') is '(delete a) + b'
@@ -368,12 +368,12 @@
PASS compileAndSerialize('!(typeof a)') is '!(typeof a)'
PASS compileAndSerialize('++a + b') is '++a + b'
PASS compileAndSerialize('(++a) + b') is '(++a) + b'
-PASS compileAndSerialize('++(a + b)') is '++(a + b)'
+PASS compileAndSerialize('++(a + b)') threw exception SyntaxError: Prefix ++ operator applied to value that is not a reference..
PASS compileAndSerialize('!++a') is '!++a'
PASS compileAndSerialize('!(++a)') is '!(++a)'
PASS compileAndSerialize('--a + b') is '--a + b'
PASS compileAndSerialize('(--a) + b') is '(--a) + b'
-PASS compileAndSerialize('--(a + b)') is '--(a + b)'
+PASS compileAndSerialize('--(a + b)') threw exception SyntaxError: Prefix -- operator applied to value that is not a reference..
PASS compileAndSerialize('!--a') is '!--a'
PASS compileAndSerialize('!(--a)') is '!(--a)'
PASS compileAndSerialize('+ a + b') is '+ a + b'
@@ -398,10 +398,10 @@
PASS compileAndSerialize('!(!a)') is '!(!a)'
PASS compileAndSerialize('!a++') is '!a++'
PASS compileAndSerialize('!(a++)') is '!(a++)'
-PASS compileAndSerialize('(!a)++') is '(!a)++'
+PASS compileAndSerialize('(!a)++') threw exception SyntaxError: Postfix ++ operator applied to value that is not a reference..
PASS compileAndSerialize('!a--') is '!a--'
PASS compileAndSerialize('!(a--)') is '!(a--)'
-PASS compileAndSerialize('(!a)--') is '(!a)--'
+PASS compileAndSerialize('(!a)--') threw exception SyntaxError: Postfix -- operator applied to value that is not a reference..
PASS compileAndSerialize('(-1)[a]') is '(-1)[a]'
PASS compileAndSerialize('(-1)[a] = b') is '(-1)[a] = b'
PASS compileAndSerialize('(-1)[a] += b') is '(-1)[a] += b'
@@ -441,42 +441,42 @@
PASS compileAndSerialize('(1).a++') is '(1).a++'
PASS compileAndSerialize('++(1).a') is '++(1).a'
PASS compileAndSerialize('(1).a()') is '(1).a()'
-PASS compileAndSerialize('(-1) = a') is '(-1) = a'
-PASS compileAndSerialize('(- 0) = a') is '(- 0) = a'
-PASS compileAndSerialize('1 = a') is '1 = a'
-PASS compileAndSerialize('(-1) *= a') is '(-1) *= a'
-PASS compileAndSerialize('(- 0) *= a') is '(- 0) *= a'
-PASS compileAndSerialize('1 *= a') is '1 *= a'
-PASS compileAndSerialize('(-1) /= a') is '(-1) /= a'
-PASS compileAndSerialize('(- 0) /= a') is '(- 0) /= a'
-PASS compileAndSerialize('1 /= a') is '1 /= a'
-PASS compileAndSerialize('(-1) %= a') is '(-1) %= a'
-PASS compileAndSerialize('(- 0) %= a') is '(- 0) %= a'
-PASS compileAndSerialize('1 %= a') is '1 %= a'
-PASS compileAndSerialize('(-1) += a') is '(-1) += a'
-PASS compileAndSerialize('(- 0) += a') is '(- 0) += a'
-PASS compileAndSerialize('1 += a') is '1 += a'
-PASS compileAndSerialize('(-1) -= a') is '(-1) -= a'
-PASS compileAndSerialize('(- 0) -= a') is '(- 0) -= a'
-PASS compileAndSerialize('1 -= a') is '1 -= a'
-PASS compileAndSerialize('(-1) <<= a') is '(-1) <<= a'
-PASS compileAndSerialize('(- 0) <<= a') is '(- 0) <<= a'
-PASS compileAndSerialize('1 <<= a') is '1 <<= a'
-PASS compileAndSerialize('(-1) >>= a') is '(-1) >>= a'
-PASS compileAndSerialize('(- 0) >>= a') is '(- 0) >>= a'
-PASS compileAndSerialize('1 >>= a') is '1 >>= a'
-PASS compileAndSerialize('(-1) >>>= a') is '(-1) >>>= a'
-PASS compileAndSerialize('(- 0) >>>= a') is '(- 0) >>>= a'
-PASS compileAndSerialize('1 >>>= a') is '1 >>>= a'
-PASS compileAndSerialize('(-1) &= a') is '(-1) &= a'
-PASS compileAndSerialize('(- 0) &= a') is '(- 0) &= a'
-PASS compileAndSerialize('1 &= a') is '1 &= a'
-PASS compileAndSerialize('(-1) ^= a') is '(-1) ^= a'
-PASS compileAndSerialize('(- 0) ^= a') is '(- 0) ^= a'
-PASS compileAndSerialize('1 ^= a') is '1 ^= a'
-PASS compileAndSerialize('(-1) |= a') is '(-1) |= a'
-PASS compileAndSerialize('(- 0) |= a') is '(- 0) |= a'
-PASS compileAndSerialize('1 |= a') is '1 |= a'
+PASS compileAndSerialize('(-1) = a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(- 0) = a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('1 = a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(-1) *= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(- 0) *= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('1 *= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(-1) /= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(- 0) /= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('1 /= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(-1) %= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(- 0) %= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('1 %= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(-1) += a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(- 0) += a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('1 += a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(-1) -= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(- 0) -= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('1 -= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(-1) <<= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(- 0) <<= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('1 <<= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(-1) >>= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(- 0) >>= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('1 >>= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(-1) >>>= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(- 0) >>>= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('1 >>>= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(-1) &= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(- 0) &= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('1 &= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(-1) ^= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(- 0) ^= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('1 ^= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(-1) |= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('(- 0) |= a') threw exception SyntaxError: Left side of assignment is not a reference..
+PASS compileAndSerialize('1 |= a') threw exception SyntaxError: Left side of assignment is not a reference..
PASS compileAndSerializeLeftmostTest('({ }).x') is '({ }).x'
PASS compileAndSerializeLeftmostTest('x = { }') is 'x = { }'
PASS compileAndSerializeLeftmostTest('(function () { })()') is '(function () { })()'
diff --git a/LayoutTests/js/parser-syntax-check-expected.txt b/LayoutTests/js/parser-syntax-check-expected.txt
index 12f08f5..d1a44c5 100644
--- a/LayoutTests/js/parser-syntax-check-expected.txt
+++ b/LayoutTests/js/parser-syntax-check-expected.txt
@@ -24,32 +24,32 @@
PASS Invalid: "function f() { new -a }". Produced the following syntax error: "SyntaxError: Unexpected token '-'"
PASS Valid: "new (-1)" with TypeError
PASS Valid: "function f() { new (-1) }"
-PASS Valid: "a: b: c: new f(x++)++" with ReferenceError
-PASS Valid: "function f() { a: b: c: new f(x++)++ }"
+PASS Invalid: "a: b: c: new f(x++)++". Produced the following syntax error: "SyntaxError: Postfix ++ operator applied to value that is not a reference."
+PASS Invalid: "function f() { a: b: c: new f(x++)++ }". Produced the following syntax error: "SyntaxError: Postfix ++ operator applied to value that is not a reference."
PASS Valid: "(a)++" with ReferenceError
PASS Valid: "function f() { (a)++ }"
-PASS Valid: "(1--).x" with ReferenceError
-PASS Valid: "function f() { (1--).x }"
+PASS Invalid: "(1--).x". Produced the following syntax error: "SyntaxError: Postfix -- operator applied to value that is not a reference."
+PASS Invalid: "function f() { (1--).x }". Produced the following syntax error: "SyntaxError: Postfix -- operator applied to value that is not a reference."
PASS Invalid: "a-- ++". Produced the following syntax error: "SyntaxError: Unexpected token '++'"
PASS Invalid: "function f() { a-- ++ }". Produced the following syntax error: "SyntaxError: Unexpected token '++'"
PASS Invalid: "(a:) --b". Produced the following syntax error: "SyntaxError: Unexpected token ':'. Expected ')' to end a compound expression."
PASS Invalid: "function f() { (a:) --b }". Produced the following syntax error: "SyntaxError: Unexpected token ':'. Expected ')' to end a compound expression."
-PASS Valid: "++ -- ++ a" with ReferenceError
-PASS Valid: "function f() { ++ -- ++ a }"
-PASS Valid: "++ new new a ++" with ReferenceError
-PASS Valid: "function f() { ++ new new a ++ }"
+PASS Invalid: "++ -- ++ a". Produced the following syntax error: "SyntaxError: The prefix-increment operator requires a reference expression."
+PASS Invalid: "function f() { ++ -- ++ a }". Produced the following syntax error: "SyntaxError: The prefix-increment operator requires a reference expression."
+PASS Invalid: "++ new new a ++". Produced the following syntax error: "SyntaxError: Prefix ++ operator applied to value that is not a reference."
+PASS Invalid: "function f() { ++ new new a ++ }". Produced the following syntax error: "SyntaxError: Prefix ++ operator applied to value that is not a reference."
PASS Valid: "delete void 0"
PASS Valid: "function f() { delete void 0 }"
PASS Invalid: "delete the void". Produced the following syntax error: "SyntaxError: Unexpected keyword 'void'. Parse error."
PASS Invalid: "function f() { delete the void }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'void'. Parse error."
PASS Invalid: "(a++". Produced the following syntax error: "SyntaxError: Unexpected end of script"
PASS Invalid: "function f() { (a++ }". Produced the following syntax error: "SyntaxError: Unexpected token '}'. Expected ')' to end a compound expression."
-PASS Valid: "++a--" with ReferenceError
-PASS Valid: "function f() { ++a-- }"
-PASS Valid: "++((a))--" with ReferenceError
-PASS Valid: "function f() { ++((a))-- }"
-PASS Valid: "(a.x++)++" with ReferenceError
-PASS Valid: "function f() { (a.x++)++ }"
+PASS Invalid: "++a--". Produced the following syntax error: "SyntaxError: The increment operator requires a reference expression."
+PASS Invalid: "function f() { ++a-- }". Produced the following syntax error: "SyntaxError: The increment operator requires a reference expression."
+PASS Invalid: "++((a))--". Produced the following syntax error: "SyntaxError: The increment operator requires a reference expression."
+PASS Invalid: "function f() { ++((a))-- }". Produced the following syntax error: "SyntaxError: The increment operator requires a reference expression."
+PASS Invalid: "(a.x++)++". Produced the following syntax error: "SyntaxError: Postfix ++ operator applied to value that is not a reference."
+PASS Invalid: "function f() { (a.x++)++ }". Produced the following syntax error: "SyntaxError: Postfix ++ operator applied to value that is not a reference."
PASS Invalid: "1: null". Produced the following syntax error: "SyntaxError: Unexpected token ':'. Parse error."
PASS Invalid: "function f() { 1: null }". Produced the following syntax error: "SyntaxError: Unexpected token ':'. Parse error."
PASS Invalid: "+-!~". Produced the following syntax error: "SyntaxError: Unexpected end of script"
@@ -110,16 +110,16 @@
PASS Valid: "function f() { - - true % 5 }"
PASS Invalid: "- false = 3". Produced the following syntax error: "SyntaxError: Left hand side of operator '=' must be a reference."
PASS Invalid: "function f() { - false = 3 }". Produced the following syntax error: "SyntaxError: Left hand side of operator '=' must be a reference."
-PASS Valid: "a: b: c: (1 + null) = 3" with ReferenceError
-PASS Valid: "function f() { a: b: c: (1 + null) = 3 }"
+PASS Invalid: "a: b: c: (1 + null) = 3". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
+PASS Invalid: "function f() { a: b: c: (1 + null) = 3 }". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
PASS Valid: "a[2] = b.l += c /= 4 * 7 ^ !6" with ReferenceError
PASS Valid: "function f() { a[2] = b.l += c /= 4 * 7 ^ !6 }"
PASS Invalid: "a + typeof b += c in d". Produced the following syntax error: "SyntaxError: Left hand side of operator '+=' must be a reference."
PASS Invalid: "function f() { a + typeof b += c in d }". Produced the following syntax error: "SyntaxError: Left hand side of operator '+=' must be a reference."
PASS Invalid: "typeof a &= typeof b". Produced the following syntax error: "SyntaxError: Left hand side of operator '&=' must be a reference."
PASS Invalid: "function f() { typeof a &= typeof b }". Produced the following syntax error: "SyntaxError: Left hand side of operator '&=' must be a reference."
-PASS Valid: "a: ((typeof (a))) >>>= a || b.l && c" with ReferenceError
-PASS Valid: "function f() { a: ((typeof (a))) >>>= a || b.l && c }"
+PASS Invalid: "a: ((typeof (a))) >>>= a || b.l && c". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
+PASS Invalid: "function f() { a: ((typeof (a))) >>>= a || b.l && c }". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
PASS Valid: "a: b: c[a /= f[a %= b]].l[c[x] = 7] -= a ? b <<= f : g" with ReferenceError
PASS Valid: "function f() { a: b: c[a /= f[a %= b]].l[c[x] = 7] -= a ? b <<= f : g }"
PASS Valid: "-void+x['y'].l == x.l != 5 - f[7]" with ReferenceError
@@ -127,8 +127,8 @@
Function calls (and new with arguments)
PASS Valid: "a()()()" with ReferenceError
PASS Valid: "function f() { a()()() }"
-PASS Valid: "s: l: a[2](4 == 6, 5 = 6)(f[4], 6)" with ReferenceError
-PASS Valid: "function f() { s: l: a[2](4 == 6, 5 = 6)(f[4], 6) }"
+PASS Invalid: "s: l: a[2](4 == 6, 5 = 6)(f[4], 6)". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
+PASS Invalid: "function f() { s: l: a[2](4 == 6, 5 = 6)(f[4], 6) }". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
PASS Valid: "s: eval(a.apply(), b.call(c[5] - f[7]))" with ReferenceError
PASS Valid: "function f() { s: eval(a.apply(), b.call(c[5] - f[7])) }"
PASS Invalid: "a(". Produced the following syntax error: "SyntaxError: Unexpected end of script"
@@ -357,8 +357,8 @@
PASS Valid: "function f() { const a = void 7 - typeof 8, b = 8 }"
PASS Invalid: "const a, a, a = void 7 - typeof 8, a = 8". Produced the following syntax error: "SyntaxError: Unexpected token ','. const declared variable 'a' must have an initializer."
PASS Invalid: "function f() { const a, a, a = void 7 - typeof 8, a = 8 }". Produced the following syntax error: "SyntaxError: Unexpected token ','. const declared variable 'a' must have an initializer."
-PASS Valid: "const x_x = 6 /= 7 ? e : f" with ReferenceError
-PASS Valid: "function f() { const x_x = 6 /= 7 ? e : f }"
+PASS Invalid: "const x_x = 6 /= 7 ? e : f". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
+PASS Invalid: "function f() { const x_x = 6 /= 7 ? e : f }". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
PASS Invalid: "var a = ?". Produced the following syntax error: "SyntaxError: Unexpected token '?'"
PASS Invalid: "function f() { var a = ? }". Produced the following syntax error: "SyntaxError: Unexpected token '?'"
PASS Invalid: "const a = *7". Produced the following syntax error: "SyntaxError: Unexpected token '*'"
@@ -504,8 +504,8 @@
PASS Valid: "function f() { for ((a ? b : c) in c) break }"
PASS Valid: "for (var a in b in c) break" with ReferenceError
PASS Valid: "function f() { for (var a in b in c) break }"
-PASS Valid: "for (var a = 5 += 6 in b) break" with ReferenceError
-PASS Valid: "function f() { for (var a = 5 += 6 in b) break }"
+PASS Invalid: "for (var a = 5 += 6 in b) break". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
+PASS Invalid: "function f() { for (var a = 5 += 6 in b) break }". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
PASS Valid: "for (var a = foo('should be hit') in b) break" with ReferenceError
PASS Valid: "function f() { for (var a = foo('should be hit') in b) break }"
PASS Invalid: "for (var a += 5 in b) break". Produced the following syntax error: "SyntaxError: Unexpected token '+='. Expected either 'in' or 'of' in enumeration syntax."
@@ -524,8 +524,8 @@
PASS Invalid: "function f() { for (var a = (b in c in d) break }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'break'. Expected either 'in' or 'of' in enumeration syntax."
PASS Invalid: "for (var (a) in b) { }". Produced the following syntax error: "SyntaxError: Unexpected token '('. Expected a parameter pattern or a ')' in parameter list."
PASS Invalid: "function f() { for (var (a) in b) { } }". Produced the following syntax error: "SyntaxError: Unexpected token '('. Expected a parameter pattern or a ')' in parameter list."
-PASS Valid: "for (var a = 7, b = c < d >= d ; f()[6]++ ; --i()[1]++ ) {}" with ReferenceError
-PASS Valid: "function f() { for (var a = 7, b = c < d >= d ; f()[6]++ ; --i()[1]++ ) {} }"
+PASS Invalid: "for (var a = 7, b = c < d >= d ; f()[6]++ ; --i()[1]++ ) {}". Produced the following syntax error: "SyntaxError: The decrement operator requires a reference expression."
+PASS Invalid: "function f() { for (var a = 7, b = c < d >= d ; f()[6]++ ; --i()[1]++ ) {} }". Produced the following syntax error: "SyntaxError: The decrement operator requires a reference expression."
PASS Invalid: "for (var {a} = 20 in b) { }". Produced the following syntax error: "SyntaxError: Cannot assign to the loop variable inside a for-in loop header."
PASS Invalid: "function f() { for (var {a} = 20 in b) { } }". Produced the following syntax error: "SyntaxError: Cannot assign to the loop variable inside a for-in loop header."
PASS Invalid: "for (var {a} = 20 of b) { }". Produced the following syntax error: "SyntaxError: Cannot assign to the loop variable inside a for-of loop header."
@@ -878,8 +878,8 @@
PASS Valid: "function f() { if (0) obj.foo\u03bb; }"
PASS Valid: "if (0) new a(b+c).d = 5"
PASS Valid: "function f() { if (0) new a(b+c).d = 5 }"
-PASS Valid: "if (0) new a(b+c) = 5"
-PASS Valid: "function f() { if (0) new a(b+c) = 5 }"
+PASS Invalid: "if (0) new a(b+c) = 5". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
+PASS Invalid: "function f() { if (0) new a(b+c) = 5 }". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
PASS Valid: "([1 || 1].a = 1)"
PASS Valid: "function f() { ([1 || 1].a = 1) }"
PASS Valid: "({a: 1 || 1}.a = 1)"
@@ -1043,14 +1043,14 @@
PASS Valid: "function f() { ({a}=1)() }"
PASS Valid: "({a:a}=1)()" with TypeError
PASS Valid: "function f() { ({a:a}=1)() }"
-PASS Valid: "({a}=1)=1" with ReferenceError
-PASS Valid: "function f() { ({a}=1)=1 }"
-PASS Valid: "({a:a}=1)=1" with ReferenceError
-PASS Valid: "function f() { ({a:a}=1)=1 }"
-PASS Valid: "({a}=1=1)" with ReferenceError
-PASS Valid: "function f() { ({a}=1=1) }"
-PASS Valid: "({a:a}=1=1)" with ReferenceError
-PASS Valid: "function f() { ({a:a}=1=1) }"
+PASS Invalid: "({a}=1)=1". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
+PASS Invalid: "function f() { ({a}=1)=1 }". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
+PASS Invalid: "({a:a}=1)=1". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
+PASS Invalid: "function f() { ({a:a}=1)=1 }". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
+PASS Invalid: "({a}=1=1)". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
+PASS Invalid: "function f() { ({a}=1=1) }". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
+PASS Invalid: "({a:a}=1=1)". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
+PASS Invalid: "function f() { ({a:a}=1=1) }". Produced the following syntax error: "SyntaxError: Left side of assignment is not a reference."
PASS Invalid: "var {x}". Produced the following syntax error: "SyntaxError: Unexpected end of script"
PASS Invalid: "function f() { var {x} }". Produced the following syntax error: "SyntaxError: Unexpected token '}'. Expected an initializer in destructuring variable declaration."
PASS Invalid: "var {x, y}". Produced the following syntax error: "SyntaxError: Unexpected end of script"
diff --git a/LayoutTests/js/parser-xml-close-comment-expected.txt b/LayoutTests/js/parser-xml-close-comment-expected.txt
index 06dfd6c..8ecf14c 100644
--- a/LayoutTests/js/parser-xml-close-comment-expected.txt
+++ b/LayoutTests/js/parser-xml-close-comment-expected.txt
@@ -3,11 +3,11 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS 'should be a syntax error' --> threw exception SyntaxError: Unexpected end of script.
-PASS /**/ 1--> threw exception SyntaxError: Unexpected end of script.
-PASS /**/ 1 --> threw exception SyntaxError: Unexpected end of script.
-PASS 1 /**/--> threw exception SyntaxError: Unexpected end of script.
-PASS 1 /**/ --> threw exception SyntaxError: Unexpected end of script.
+PASS 'should be a syntax error' --> threw exception SyntaxError: Postfix -- operator applied to value that is not a reference..
+PASS /**/ 1--> threw exception SyntaxError: Postfix -- operator applied to value that is not a reference..
+PASS /**/ 1 --> threw exception SyntaxError: Postfix -- operator applied to value that is not a reference..
+PASS 1 /**/--> threw exception SyntaxError: Postfix -- operator applied to value that is not a reference..
+PASS 1 /**/ --> threw exception SyntaxError: Postfix -- operator applied to value that is not a reference..
PASS 1/*
*/--> is 1
PASS 1/*
diff --git a/LayoutTests/js/script-tests/function-toString-parentheses.js b/LayoutTests/js/script-tests/function-toString-parentheses.js
index d648b4e..81ce13f 100644
--- a/LayoutTests/js/script-tests/function-toString-parentheses.js
+++ b/LayoutTests/js/script-tests/function-toString-parentheses.js
@@ -104,7 +104,7 @@
testRightAssociativeSame("=", op);
testLowerFirst(op, "+");
shouldThrow("compileAndSerialize('a + b " + op + " c')");
- testKeepParentheses("(a + b) " + op + " c");
+ shouldThrow("compileAndSerialize('(a + b) " + op + " c')");
testKeepParentheses("a + (b " + op + " c)");
}
@@ -115,7 +115,10 @@
var op = prefixOperators[i] + prefixOperatorSpace[i];
testKeepParentheses("" + op + "a + b");
testOptionalParentheses("(" + op + "a) + b");
- testKeepParentheses("" + op + "(a + b)");
+ if (prefixOperators[i] !== "++" && prefixOperators[i] !== "--")
+ testKeepParentheses("" + op + "(a + b)");
+ else
+ shouldThrow("compileAndSerialize('" + op + "(a + b)')");
testKeepParentheses("!" + op + "a");
testOptionalParentheses("!(" + op + "a)");
}
@@ -123,11 +126,11 @@
testKeepParentheses("!a++");
testOptionalParentheses("!(a++)");
-testKeepParentheses("(!a)++");
+shouldThrow("compileAndSerialize('(!a)++')");
testKeepParentheses("!a--");
testOptionalParentheses("!(a--)");
-testKeepParentheses("(!a)--");
+shouldThrow("compileAndSerialize('(!a)--')");
testKeepParentheses("(-1)[a]");
testKeepParentheses("(-1)[a] = b");
@@ -182,9 +185,9 @@
for (i = 0; i < assignmentOperators.length; ++i) {
var op = assignmentOperators[i];
- testKeepParentheses("(-1) " + op + " a");
- testKeepParentheses("(- 0) " + op + " a");
- testKeepParentheses("1 " + op + " a");
+ shouldThrow("compileAndSerialize('(-1) " + op + " a')");
+ shouldThrow("compileAndSerialize('(- 0) " + op + " a')");
+ shouldThrow("compileAndSerialize('1 " + op + " a')");
}
shouldBe("compileAndSerializeLeftmostTest('({ }).x')", "'({ }).x'");
diff --git a/LayoutTests/js/script-tests/parser-syntax-check.js b/LayoutTests/js/script-tests/parser-syntax-check.js
index 26a0d13..c49c90b 100644
--- a/LayoutTests/js/script-tests/parser-syntax-check.js
+++ b/LayoutTests/js/script-tests/parser-syntax-check.js
@@ -83,19 +83,19 @@
valid ("a: +~!new a");
invalid("new -a");
valid ("new (-1)")
-valid ("a: b: c: new f(x++)++")
+invalid("a: b: c: new f(x++)++")
valid ("(a)++");
-valid ("(1--).x");
+invalid("(1--).x");
invalid("a-- ++");
invalid("(a:) --b");
-valid ("++ -- ++ a");
-valid ("++ new new a ++");
+invalid("++ -- ++ a");
+invalid("++ new new a ++");
valid ("delete void 0");
invalid("delete the void");
invalid("(a++");
-valid ("++a--");
-valid ("++((a))--");
-valid ("(a.x++)++");
+invalid("++a--");
+invalid("++((a))--");
+invalid("(a.x++)++");
invalid("1: null");
invalid("+-!~");
invalid("+-!~((");
@@ -131,18 +131,18 @@
invalid("a in instanceof b.l");
valid ("- - true % 5");
invalid("- false = 3");
-valid ("a: b: c: (1 + null) = 3");
+invalid("a: b: c: (1 + null) = 3");
valid ("a[2] = b.l += c /= 4 * 7 ^ !6");
invalid("a + typeof b += c in d");
invalid("typeof a &= typeof b");
-valid ("a: ((typeof (a))) >>>= a || b.l && c");
+invalid("a: ((typeof (a))) >>>= a || b.l && c");
valid ("a: b: c[a /= f[a %= b]].l[c[x] = 7] -= a ? b <<= f : g");
valid ("-void+x['y'].l == x.l != 5 - f[7]");
debug ("Function calls (and new with arguments)");
valid ("a()()()");
-valid ("s: l: a[2](4 == 6, 5 = 6)(f[4], 6)");
+invalid("s: l: a[2](4 == 6, 5 = 6)(f[4], 6)");
valid ("s: eval(a.apply(), b.call(c[5] - f[7]))");
invalid("a(");
invalid("a(5");
@@ -268,7 +268,7 @@
valid ("var varr = 3 in 1");
valid ("const a = void 7 - typeof 8, b = 8");
invalid("const a, a, a = void 7 - typeof 8, a = 8");
-valid ("const x_x = 6 /= 7 ? e : f");
+invalid("const x_x = 6 /= 7 ? e : f");
invalid("var a = ?");
invalid("const a = *7");
invalid("var a = :)");
@@ -345,7 +345,7 @@
invalid("for (a ? b : c in c) break");
valid ("for ((a ? b : c) in c) break");
valid ("for (var a in b in c) break");
-valid("for (var a = 5 += 6 in b) break");
+invalid("for (var a = 5 += 6 in b) break");
valid("for (var a = foo('should be hit') in b) break");
invalid("for (var a += 5 in b) break");
invalid("for (var a = in b) break");
@@ -355,7 +355,7 @@
valid("for (var a = (b in c) in d) break");
invalid("for (var a = (b in c in d) break");
invalid("for (var (a) in b) { }");
-valid ("for (var a = 7, b = c < d >= d ; f()[6]++ ; --i()[1]++ ) {}");
+invalid("for (var a = 7, b = c < d >= d ; f()[6]++ ; --i()[1]++ ) {}");
invalid("for (var {a} = 20 in b) { }");
invalid("for (var {a} = 20 of b) { }");
invalid("for (var {a} = 20 in b) { }");
@@ -543,7 +543,7 @@
valid("if (0) obj.foo_; ")
valid("if (0) obj.foo\\u03bb; ")
valid("if (0) new a(b+c).d = 5");
-valid("if (0) new a(b+c) = 5");
+invalid("if (0) new a(b+c) = 5");
valid("([1 || 1].a = 1)");
valid("({a: 1 || 1}.a = 1)");
@@ -631,10 +631,10 @@
valid("delete ({a:a}=1)")
valid("({a}=1)()")
valid("({a:a}=1)()")
-valid("({a}=1)=1")
-valid("({a:a}=1)=1")
-valid("({a}=1=1)")
-valid("({a:a}=1=1)")
+invalid("({a}=1)=1")
+invalid("({a:a}=1)=1")
+invalid("({a}=1=1)")
+invalid("({a:a}=1=1)")
invalid("var {x}")
invalid("var {x, y}")
invalid("var {x} = 20, {x, y}")
diff --git a/LayoutTests/js/script-tests/toString-prefix-postfix-preserve-parens.js b/LayoutTests/js/script-tests/toString-prefix-postfix-preserve-parens.js
index c923e7d..d294558 100644
--- a/LayoutTests/js/script-tests/toString-prefix-postfix-preserve-parens.js
+++ b/LayoutTests/js/script-tests/toString-prefix-postfix-preserve-parens.js
@@ -1,61 +1,7 @@
description(
-"This test checks that toString() round-trip on a function that has prefix, postfix and typeof operators applied to group expression will not remove the grouping. Also checks that evaluation of such a expression produces run-time exception"
+"This test checks that toString() round-trip on a function that has a typeof operator applied to a group expression will not remove the grouping."
);
-function postfix_should_preserve_parens(x, y, z) {
- (x, y)++;
- return y;
-}
-
-function prefix_should_preserve_parens(x, y, z) {
- ++(x, y);
- return x;
-
-}
-
-function both_should_preserve_parens(x, y, z) {
- ++(x, y)--;
- return x;
-
-}
-
-function postfix_should_preserve_parens_multi(x, y, z) {
- (((x, y)))--;
- return x;
-}
-
-function prefix_should_preserve_parens_multi(x, y, z) {
- --(((x, y)));
- return x;
-}
-
-function both_should_preserve_parens_multi(x, y, z) {
- ++(((x, y)))--;
- return x;
-}
-
-function postfix_should_preserve_parens_multi1(x, y, z) {
- (((x)), y)--;
- return x;
-}
-
-function prefix_should_preserve_parens_multi1(x, y, z) {
- --(((x)), y);
- return x;
-}
-
-function prefix_should_preserve_parens_multi2(x, y, z) {
- var z = 0;
- --(((x), y), z);
- return x;
-}
-
-function postfix_should_preserve_parens_multi2(x, y, z) {
- var z = 0;
- (((x), y) ,z)++;
- return x;
-}
-
// if these return a variable (such as y) instead of
// the result of typeof, this means that the parenthesis
// got lost somewhere.
@@ -91,17 +37,6 @@
}
-function testToStringAndRTFailure(fn)
-{
- testToString(fn);
-
- // check that function call produces run-time exception
- shouldThrow(""+fn+ "(1, 2, 3);");
-
- // check that function call produces run-time exception after eval(unevalf)
- shouldThrow("eval(unevalf("+fn+ "))(1, 2, 3);");
-}
-
function testToStringAndReturn(fn, p1, p2, retval)
{
@@ -114,17 +49,6 @@
shouldBe("eval(unevalf("+fn+ "))" + "(" + p1 + ", " + p2 +");", retval);
}
-
-testToStringAndRTFailure("prefix_should_preserve_parens");
-testToStringAndRTFailure("postfix_should_preserve_parens");
-testToStringAndRTFailure("both_should_preserve_parens");
-testToStringAndRTFailure("prefix_should_preserve_parens_multi");
-testToStringAndRTFailure("postfix_should_preserve_parens_multi");
-testToStringAndRTFailure("prefix_should_preserve_parens_multi1");
-testToStringAndRTFailure("postfix_should_preserve_parens_multi1");
-testToStringAndRTFailure("prefix_should_preserve_parens_multi2");
-testToStringAndRTFailure("postfix_should_preserve_parens_multi2");
-
testToStringAndReturn("typeof_should_preserve_parens", "'a'", 1, "'number'");
testToStringAndReturn("typeof_should_preserve_parens1", "'a'", 1, "'number'");
testToStringAndReturn("typeof_should_preserve_parens2", "'a'", 1, "'number'");
diff --git a/LayoutTests/js/toString-prefix-postfix-preserve-parens-expected.txt b/LayoutTests/js/toString-prefix-postfix-preserve-parens-expected.txt
index 036fedb..b7e3aa1 100644
--- a/LayoutTests/js/toString-prefix-postfix-preserve-parens-expected.txt
+++ b/LayoutTests/js/toString-prefix-postfix-preserve-parens-expected.txt
@@ -1,44 +1,8 @@
-This test checks that toString() round-trip on a function that has prefix, postfix and typeof operators applied to group expression will not remove the grouping. Also checks that evaluation of such a expression produces run-time exception
+This test checks that toString() round-trip on a function that has a typeof operator applied to a group expression will not remove the grouping.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS unevalf(eval(unevalf(prefix_should_preserve_parens))) is unevalf(prefix_should_preserve_parens)
-PASS /.*\(+x\)*, y\)/.test(unevalf(prefix_should_preserve_parens)) is true
-PASS prefix_should_preserve_parens(1, 2, 3); threw exception ReferenceError: Prefix ++ operator applied to value that is not a reference..
-PASS eval(unevalf(prefix_should_preserve_parens))(1, 2, 3); threw exception ReferenceError: Prefix ++ operator applied to value that is not a reference..
-PASS unevalf(eval(unevalf(postfix_should_preserve_parens))) is unevalf(postfix_should_preserve_parens)
-PASS /.*\(+x\)*, y\)/.test(unevalf(postfix_should_preserve_parens)) is true
-PASS postfix_should_preserve_parens(1, 2, 3); threw exception ReferenceError: Postfix ++ operator applied to value that is not a reference..
-PASS eval(unevalf(postfix_should_preserve_parens))(1, 2, 3); threw exception ReferenceError: Postfix ++ operator applied to value that is not a reference..
-PASS unevalf(eval(unevalf(both_should_preserve_parens))) is unevalf(both_should_preserve_parens)
-PASS /.*\(+x\)*, y\)/.test(unevalf(both_should_preserve_parens)) is true
-PASS both_should_preserve_parens(1, 2, 3); threw exception ReferenceError: Prefix ++ operator applied to value that is not a reference..
-PASS eval(unevalf(both_should_preserve_parens))(1, 2, 3); threw exception ReferenceError: Prefix ++ operator applied to value that is not a reference..
-PASS unevalf(eval(unevalf(prefix_should_preserve_parens_multi))) is unevalf(prefix_should_preserve_parens_multi)
-PASS /.*\(+x\)*, y\)/.test(unevalf(prefix_should_preserve_parens_multi)) is true
-PASS prefix_should_preserve_parens_multi(1, 2, 3); threw exception ReferenceError: Prefix -- operator applied to value that is not a reference..
-PASS eval(unevalf(prefix_should_preserve_parens_multi))(1, 2, 3); threw exception ReferenceError: Prefix -- operator applied to value that is not a reference..
-PASS unevalf(eval(unevalf(postfix_should_preserve_parens_multi))) is unevalf(postfix_should_preserve_parens_multi)
-PASS /.*\(+x\)*, y\)/.test(unevalf(postfix_should_preserve_parens_multi)) is true
-PASS postfix_should_preserve_parens_multi(1, 2, 3); threw exception ReferenceError: Postfix -- operator applied to value that is not a reference..
-PASS eval(unevalf(postfix_should_preserve_parens_multi))(1, 2, 3); threw exception ReferenceError: Postfix -- operator applied to value that is not a reference..
-PASS unevalf(eval(unevalf(prefix_should_preserve_parens_multi1))) is unevalf(prefix_should_preserve_parens_multi1)
-PASS /.*\(+x\)*, y\)/.test(unevalf(prefix_should_preserve_parens_multi1)) is true
-PASS prefix_should_preserve_parens_multi1(1, 2, 3); threw exception ReferenceError: Prefix -- operator applied to value that is not a reference..
-PASS eval(unevalf(prefix_should_preserve_parens_multi1))(1, 2, 3); threw exception ReferenceError: Prefix -- operator applied to value that is not a reference..
-PASS unevalf(eval(unevalf(postfix_should_preserve_parens_multi1))) is unevalf(postfix_should_preserve_parens_multi1)
-PASS /.*\(+x\)*, y\)/.test(unevalf(postfix_should_preserve_parens_multi1)) is true
-PASS postfix_should_preserve_parens_multi1(1, 2, 3); threw exception ReferenceError: Postfix -- operator applied to value that is not a reference..
-PASS eval(unevalf(postfix_should_preserve_parens_multi1))(1, 2, 3); threw exception ReferenceError: Postfix -- operator applied to value that is not a reference..
-PASS unevalf(eval(unevalf(prefix_should_preserve_parens_multi2))) is unevalf(prefix_should_preserve_parens_multi2)
-PASS /.*\(+x\)*, y\)/.test(unevalf(prefix_should_preserve_parens_multi2)) is true
-PASS prefix_should_preserve_parens_multi2(1, 2, 3); threw exception ReferenceError: Prefix -- operator applied to value that is not a reference..
-PASS eval(unevalf(prefix_should_preserve_parens_multi2))(1, 2, 3); threw exception ReferenceError: Prefix -- operator applied to value that is not a reference..
-PASS unevalf(eval(unevalf(postfix_should_preserve_parens_multi2))) is unevalf(postfix_should_preserve_parens_multi2)
-PASS /.*\(+x\)*, y\)/.test(unevalf(postfix_should_preserve_parens_multi2)) is true
-PASS postfix_should_preserve_parens_multi2(1, 2, 3); threw exception ReferenceError: Postfix ++ operator applied to value that is not a reference..
-PASS eval(unevalf(postfix_should_preserve_parens_multi2))(1, 2, 3); threw exception ReferenceError: Postfix ++ operator applied to value that is not a reference..
PASS unevalf(eval(unevalf(typeof_should_preserve_parens))) is unevalf(typeof_should_preserve_parens)
PASS /.*\(+x\)*, y\)/.test(unevalf(typeof_should_preserve_parens)) is true
PASS typeof_should_preserve_parens('a', 1); is 'number'
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 5b4da47..c550636 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,50 @@
+2019-05-16 Ross Kirsling <ross.kirsling@sony.com>
+
+ [JSC] Invalid AssignmentTargetType should be an early error.
+ https://bugs.webkit.org/show_bug.cgi?id=197603
+
+ Reviewed by Keith Miller.
+
+ Since ES6, expressions like 0++, ++0, 0 = 0, and 0 += 0 are all specified as early errors:
+ https://tc39.github.io/ecma262/#sec-update-expressions-static-semantics-early-errors
+ https://tc39.github.io/ecma262/#sec-assignment-operators-static-semantics-early-errors
+
+ We currently throw late ReferenceErrors for these -- let's turn them into early SyntaxErrors.
+ (This is based on the expectation that https://github.com/tc39/ecma262/pull/1527 will be accepted;
+ if that doesn't come to pass, we can subsequently introduce early ReferenceError and revise these.)
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::PostfixNode::emitBytecode): Add an assert for "function call LHS" case.
+ (JSC::PrefixNode::emitBytecode): Add an assert for "function call LHS" case.
+
+ * parser/ASTBuilder.h:
+ (JSC::ASTBuilder::isLocation): Added.
+ (JSC::ASTBuilder::isAssignmentLocation): Fix misleading parameter name.
+ (JSC::ASTBuilder::isFunctionCall): Added.
+ (JSC::ASTBuilder::makeAssignNode): Add an assert for "function call LHS" case.
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::isLocation): Added.
+ (JSC::SyntaxChecker::isAssignmentLocation): Fix incorrect definition and align with ASTBuilder.
+ (JSC::SyntaxChecker::isFunctionCall): Added.
+ * parser/Nodes.h:
+ (JSC::ExpressionNode::isFunctionCall const): Added.
+ Ensure that the parser can check whether an expression node is a function call.
+
+ * parser/Parser.cpp:
+ (JSC::Parser<LexerType>::isSimpleAssignmentTarget): Added.
+ (JSC::Parser<LexerType>::parseAssignmentExpression):
+ (JSC::Parser<LexerType>::parseUnaryExpression): See below.
+ * parser/Parser.h:
+ Throw SyntaxError whenever an assignment or update expression's target is invalid.
+ Unfortunately, it seems that web compatibility obliges us to exempt the "function call LHS" case in sloppy mode.
+ (https://github.com/tc39/ecma262/issues/257#issuecomment-195106880)
+
+ Additional cleanup items:
+ - Make use of `semanticFailIfTrue` for `isMetaProperty` checks, as it's equivalent.
+ - Rename `requiresLExpr` to `hasPrefixUpdateOp` since it's now confusing,
+ and get rid of `modifiesExpr` since it refers to the exact same condition.
+ - Stop setting `lastOperator` near the end -- one case was incorrect and regardless neither is used.
+
2019-05-15 Saam Barati <sbarati@apple.com>
Bound liveness of SetArgumentMaybe nodes when maximal flush insertion phase is enabled
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 21301da..629d416 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -1666,6 +1666,7 @@
if (m_expr->isDotAccessorNode())
return emitDot(generator, dst);
+ ASSERT(m_expr->isFunctionCall());
return emitThrowReferenceError(generator, m_operator == OpPlusPlus
? "Postfix ++ operator applied to value that is not a reference."_s
: "Postfix -- operator applied to value that is not a reference."_s);
@@ -1879,6 +1880,7 @@
if (m_expr->isDotAccessorNode())
return emitDot(generator, dst);
+ ASSERT(m_expr->isFunctionCall());
return emitThrowReferenceError(generator, m_operator == OpPlusPlus
? "Prefix ++ operator applied to value that is not a reference."_s
: "Prefix -- operator applied to value that is not a reference."_s);
diff --git a/Source/JavaScriptCore/parser/ASTBuilder.h b/Source/JavaScriptCore/parser/ASTBuilder.h
index e321221..dc878c5 100644
--- a/Source/JavaScriptCore/parser/ASTBuilder.h
+++ b/Source/JavaScriptCore/parser/ASTBuilder.h
@@ -627,9 +627,14 @@
return pattern->isBindingNode();
}
- bool isAssignmentLocation(const Expression& pattern)
+ bool isLocation(const Expression& node)
{
- return pattern->isAssignmentLocation();
+ return node->isLocation();
+ }
+
+ bool isAssignmentLocation(const Expression& node)
+ {
+ return node->isAssignmentLocation();
}
bool isObjectLiteral(const Expression& node)
@@ -647,6 +652,11 @@
return isObjectLiteral(node) || isArrayLiteral(node);
}
+ bool isFunctionCall(const Expression& node)
+ {
+ return node->isFunctionCall();
+ }
+
bool shouldSkipPauseLocation(StatementNode* statement) const
{
return !statement || statement->isLabel();
@@ -1467,8 +1477,10 @@
ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
{
- if (!loc->isLocation())
+ if (!loc->isLocation()) {
+ ASSERT(loc->isFunctionCall());
return new (m_parserArena) AssignErrorNode(location, divot, start, end);
+ }
if (loc->isResolveNode()) {
ResolveNode* resolve = static_cast<ResolveNode*>(loc);
diff --git a/Source/JavaScriptCore/parser/Nodes.h b/Source/JavaScriptCore/parser/Nodes.h
index 728f736..60ba5ee 100644
--- a/Source/JavaScriptCore/parser/Nodes.h
+++ b/Source/JavaScriptCore/parser/Nodes.h
@@ -204,6 +204,7 @@
virtual bool isImportMeta() const { return false; }
virtual bool isBytecodeIntrinsicNode() const { return false; }
virtual bool isBinaryOpNode() const { return false; }
+ virtual bool isFunctionCall() const { return false; }
virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label&, Label&, FallThroughMode);
@@ -869,6 +870,8 @@
private:
RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ bool isFunctionCall() const override { return true; }
+
ArgumentsNode* m_args;
};
@@ -879,6 +882,8 @@
private:
RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ bool isFunctionCall() const override { return true; }
+
ExpressionNode* m_expr;
ArgumentsNode* m_args;
};
@@ -890,6 +895,8 @@
private:
RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ bool isFunctionCall() const override { return true; }
+
const Identifier& m_ident;
ArgumentsNode* m_args;
};
@@ -901,6 +908,8 @@
private:
RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ bool isFunctionCall() const override { return true; }
+
ExpressionNode* m_base;
ExpressionNode* m_subscript;
ArgumentsNode* m_args;
@@ -915,6 +924,8 @@
RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
protected:
+ bool isFunctionCall() const override { return true; }
+
ExpressionNode* m_base;
const Identifier& m_ident;
ArgumentsNode* m_args;
@@ -945,6 +956,8 @@
private:
RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ bool isFunctionCall() const override { return m_type == Type::Function; }
+
EmitterType m_emitter;
const Identifier& m_ident;
ArgumentsNode* m_args;
diff --git a/Source/JavaScriptCore/parser/Parser.cpp b/Source/JavaScriptCore/parser/Parser.cpp
index a3b851c..45ac908 100644
--- a/Source/JavaScriptCore/parser/Parser.cpp
+++ b/Source/JavaScriptCore/parser/Parser.cpp
@@ -3631,6 +3631,14 @@
RELEASE_ASSERT_NOT_REACHED();
return "error";
}
+
+template <typename LexerType>
+template <typename TreeBuilder> bool Parser<LexerType>::isSimpleAssignmentTarget(TreeBuilder& context, TreeExpression expr)
+{
+ // Web compatibility concerns prevent us from handling a function call LHS as an early error in sloppy mode.
+ // This behavior is currently unspecified, but see: https://github.com/tc39/ecma262/issues/257#issuecomment-195106880
+ return context.isLocation(expr) || (!strictMode() && context.isFunctionCall(expr));
+}
template <typename LexerType>
template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmentExpression(TreeBuilder& context, ExpressionErrorClassifier& classifier)
@@ -3737,8 +3745,8 @@
}
m_parserState.nonTrivialExpressionCount++;
hadAssignment = true;
- if (UNLIKELY(context.isMetaProperty(lhs)))
- internalFailWithMessage(false, metaPropertyName(context, lhs), " can't be the left hand side of an assignment expression");
+ semanticFailIfTrue(context.isMetaProperty(lhs), metaPropertyName(context, lhs), " can't be the left hand side of an assignment expression");
+ semanticFailIfFalse(isSimpleAssignmentTarget(context, lhs), "Left side of assignment is not a reference");
context.assignmentStackAppend(assignmentStack, lhs, start, tokenStartPosition(), m_parserState.assignmentCount, op);
start = tokenStartPosition();
m_parserState.assignmentCount++;
@@ -4929,8 +4937,7 @@
typename TreeBuilder::UnaryExprContext unaryExprContext(context);
AllowInOverride allowInOverride(this);
int tokenStackDepth = 0;
- bool modifiesExpr = false;
- bool requiresLExpr = false;
+ bool hasPrefixUpdateOp = false;
unsigned lastOperator = 0;
if (UNLIKELY(match(AWAIT) && currentFunctionScope()->isAsyncFunctionBoundary()))
@@ -4939,20 +4946,17 @@
JSTokenLocation location(tokenLocation());
while (isUnaryOp(m_token.m_type)) {
- if (strictMode()) {
- switch (m_token.m_type) {
- case PLUSPLUS:
- case MINUSMINUS:
- case AUTOPLUSPLUS:
- case AUTOMINUSMINUS:
- semanticFailIfTrue(requiresLExpr, "The ", operatorString(true, lastOperator), " operator requires a reference expression");
- modifiesExpr = true;
- requiresLExpr = true;
- break;
- default:
- semanticFailIfTrue(requiresLExpr, "The ", operatorString(true, lastOperator), " operator requires a reference expression");
- break;
- }
+ switch (m_token.m_type) {
+ case PLUSPLUS:
+ case MINUSMINUS:
+ case AUTOPLUSPLUS:
+ case AUTOMINUSMINUS:
+ semanticFailIfTrue(hasPrefixUpdateOp, "The ", operatorString(true, lastOperator), " operator requires a reference expression");
+ hasPrefixUpdateOp = true;
+ break;
+ default:
+ semanticFailIfTrue(hasPrefixUpdateOp, "The ", operatorString(true, lastOperator), " operator requires a reference expression");
+ break;
}
lastOperator = m_token.m_type;
m_parserState.nonLHSCount++;
@@ -4968,37 +4972,37 @@
failWithMessage("Cannot parse subexpression of ", operatorString(true, lastOperator), "operator");
failWithMessage("Cannot parse member expression");
}
- if (UNLIKELY(isUpdateOp(static_cast<JSTokenType>(lastOperator)) && context.isMetaProperty(expr)))
- internalFailWithMessage(false, metaPropertyName(context, expr), " can't come after a prefix operator");
+ if (isUpdateOp(static_cast<JSTokenType>(lastOperator))) {
+ semanticFailIfTrue(context.isMetaProperty(expr), metaPropertyName(context, expr), " can't come after a prefix operator");
+ semanticFailIfFalse(isSimpleAssignmentTarget(context, expr), "Prefix ", lastOperator == PLUSPLUS ? "++" : "--", " operator applied to value that is not a reference");
+ }
bool isEvalOrArguments = false;
if (strictMode()) {
if (context.isResolve(expr))
isEvalOrArguments = *m_parserState.lastIdentifier == m_vm->propertyNames->eval || *m_parserState.lastIdentifier == m_vm->propertyNames->arguments;
}
- failIfTrueIfStrict(isEvalOrArguments && modifiesExpr, "Cannot modify '", m_parserState.lastIdentifier->impl(), "' in strict mode");
+ failIfTrueIfStrict(isEvalOrArguments && hasPrefixUpdateOp, "Cannot modify '", m_parserState.lastIdentifier->impl(), "' in strict mode");
switch (m_token.m_type) {
case PLUSPLUS:
- if (UNLIKELY(context.isMetaProperty(expr)))
- internalFailWithMessage(false, metaPropertyName(context, expr), " can't come before a postfix operator");
+ semanticFailIfTrue(context.isMetaProperty(expr), metaPropertyName(context, expr), " can't come before a postfix operator");
+ semanticFailIfFalse(isSimpleAssignmentTarget(context, expr), "Postfix ++ operator applied to value that is not a reference");
m_parserState.nonTrivialExpressionCount++;
m_parserState.nonLHSCount++;
expr = context.makePostfixNode(location, expr, OpPlusPlus, subExprStart, lastTokenEndPosition(), tokenEndPosition());
m_parserState.assignmentCount++;
failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", m_parserState.lastIdentifier->impl(), "' in strict mode");
- semanticFailIfTrue(requiresLExpr, "The ", operatorString(false, lastOperator), " operator requires a reference expression");
- lastOperator = PLUSPLUS;
+ semanticFailIfTrue(hasPrefixUpdateOp, "The ", operatorString(false, lastOperator), " operator requires a reference expression");
next();
break;
case MINUSMINUS:
- if (UNLIKELY(context.isMetaProperty(expr)))
- internalFailWithMessage(false, metaPropertyName(context, expr), " can't come before a postfix operator");
+ semanticFailIfTrue(context.isMetaProperty(expr), metaPropertyName(context, expr), " can't come before a postfix operator");
+ semanticFailIfFalse(isSimpleAssignmentTarget(context, expr), "Postfix -- operator applied to value that is not a reference");
m_parserState.nonTrivialExpressionCount++;
m_parserState.nonLHSCount++;
expr = context.makePostfixNode(location, expr, OpMinusMinus, subExprStart, lastTokenEndPosition(), tokenEndPosition());
m_parserState.assignmentCount++;
failIfTrueIfStrict(isEvalOrArguments, "'", m_parserState.lastIdentifier->impl(), "' cannot be modified in strict mode");
- semanticFailIfTrue(requiresLExpr, "The ", operatorString(false, lastOperator), " operator requires a reference expression");
- lastOperator = PLUSPLUS;
+ semanticFailIfTrue(hasPrefixUpdateOp, "The ", operatorString(false, lastOperator), " operator requires a reference expression");
next();
break;
default:
@@ -5006,10 +5010,6 @@
}
JSTextPosition end = lastTokenEndPosition();
-
- if (!TreeBuilder::CreatesAST && (!strictMode()))
- return expr;
-
while (tokenStackDepth) {
switch (context.unaryTokenStackLastType(tokenStackDepth)) {
case EXCLAMATION:
diff --git a/Source/JavaScriptCore/parser/Parser.h b/Source/JavaScriptCore/parser/Parser.h
index 8158993..10a3121 100644
--- a/Source/JavaScriptCore/parser/Parser.h
+++ b/Source/JavaScriptCore/parser/Parser.h
@@ -1665,6 +1665,8 @@
template <class TreeBuilder> NEVER_INLINE const char* metaPropertyName(TreeBuilder&, TreeExpression);
+ template <class TreeBuilder> ALWAYS_INLINE bool isSimpleAssignmentTarget(TreeBuilder&, TreeExpression);
+
ALWAYS_INLINE int isBinaryOperator(JSTokenType);
bool allowAutomaticSemicolon();
diff --git a/Source/JavaScriptCore/parser/SyntaxChecker.h b/Source/JavaScriptCore/parser/SyntaxChecker.h
index 97cfadb..419958b 100644
--- a/Source/JavaScriptCore/parser/SyntaxChecker.h
+++ b/Source/JavaScriptCore/parser/SyntaxChecker.h
@@ -393,11 +393,16 @@
return pattern == BindingDestructuring;
}
- bool isAssignmentLocation(ExpressionType type)
+ bool isLocation(ExpressionType type)
{
return type == ResolveExpr || type == DotExpr || type == BracketExpr;
}
+ bool isAssignmentLocation(ExpressionType type)
+ {
+ return isLocation(type) || type == DestructuringAssignment;
+ }
+
bool isObjectLiteral(ExpressionType type)
{
return type == ObjectLiteralExpr;
@@ -413,6 +418,11 @@
return isObjectLiteral(type) || isArrayLiteral(type);
}
+ bool isFunctionCall(ExpressionType type)
+ {
+ return type == CallExpr;
+ }
+
bool shouldSkipPauseLocation(int) const { return true; }
void setEndOffset(int, int) { }