Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upAnnex E incompatibilities should include "early Reference Error" #257
Comments
saurik
changed the title from
Annex D incompatibilities should include "early Reference Error"
to
Annex E incompatibilities should include "early Reference Error"
Dec 16, 2015
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
anba
Dec 16, 2015
Contributor
In earlier ECMAScript versions, the syntax ++++a would lead to a ReferenceError when executed, but was considered valid code: if it existed in some large script and was never used, it would not lead to a failure. In ECMAScript 2015,
This is specified as an early error since ECMAScript 5 (ES5, ch. 16). ECMAScript 3 made it an implementation dependent choice whether or not to report early errors for invalid assignments. Specifically this sentence from ES3:
An implementation may treat any instance of the following kinds of runtime errors as a syntax error and therefore report it early:
was changed in ES5 to:
An implementation must treat any instance of the following kinds of errors as an early error:
The assignment to a function call is a special case:
ES5 allowed function calls to return a Reference value (ES5, ch. 8.6.2, Table 9), this feature was removed in ES2015 as documented in Annex E.
This is specified as an early error since ECMAScript 5 (ES5, ch. 16). ECMAScript 3 made it an implementation dependent choice whether or not to report early errors for invalid assignments. Specifically this sentence from ES3:
was changed in ES5 to:
The assignment to a function call is a special case: |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
littledan
Dec 16, 2015
Member
It's still a dilemma in Chrome whether to prohibit these sorts of things. Does anyone have data about whether they are used on the web?
|
It's still a dilemma in Chrome whether to prohibit these sorts of things. Does anyone have data about whether they are used on the web? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
allenwb
Dec 16, 2015
Member
So this has all been extensively discussed in TC39 when these changes were introduced.
When the change from optional early error to mandatory early error was made in ES5, I believe the state of the web was that some of the "top 5" browsers (that was the criteria we used back then) reported early errors and others did not. That meant that code that that depended upon late error treatment was not interoperable across browsers on the web. In other words, it was a non-breaking change.
Reference returning host functions (and the syntax that allowed their invocation) was in the spec. to support VBScript compatibility in early versions of IE. I'm pretty sure you can find meeting notes that document this decision.
|
So this has all been extensively discussed in TC39 when these changes were introduced. When the change from optional early error to mandatory early error was made in ES5, I believe the state of the web was that some of the "top 5" browsers (that was the criteria we used back then) reported early errors and others did not. That meant that code that that depended upon late error treatment was not interoperable across browsers on the web. In other words, it was a non-breaking change. Reference returning host functions (and the syntax that allowed their invocation) was in the spec. to support VBScript compatibility in early versions of IE. I'm pretty sure you can find meeting notes that document this decision. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
littledan
Dec 16, 2015
Member
Thanks for the references, Allen.
Unfortunately, not all browsers can ship something just because some other browser in the past has shipped it. In Chrome, we have to worry about compatibility with subsets of the web which currently work on Chrome, such as websites which are written for the 'mobile web', which in practice means WebKit-based browsers. In other parts of the web platform, WebKit prefixes are unfortunately being standardized for similar reasons. "Websites which work on non-Presto browsers" would probably be another similar subset (not sure how much that affected ES2015 decisions). Sometimes these subsets of web usage have things in common with each other which certain browsers don't follow. We would really like to both adhere to standards and not break the web.
Is there a strong reason why this has to be an early error? What sort of bad consequences would come if we made these runtime errors in the spec?
|
Thanks for the references, Allen. Unfortunately, not all browsers can ship something just because some other browser in the past has shipped it. In Chrome, we have to worry about compatibility with subsets of the web which currently work on Chrome, such as websites which are written for the 'mobile web', which in practice means WebKit-based browsers. In other parts of the web platform, WebKit prefixes are unfortunately being standardized for similar reasons. "Websites which work on non-Presto browsers" would probably be another similar subset (not sure how much that affected ES2015 decisions). Sometimes these subsets of web usage have things in common with each other which certain browsers don't follow. We would really like to both adhere to standards and not break the web. Is there a strong reason why this has to be an early error? What sort of bad consequences would come if we made these runtime errors in the spec? |
bterlson
added
the
editorial change
label
Feb 18, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ajklein
Mar 10, 2016
Contributor
I just tested current SpiderMonkey, JSC, V8, and Chakra, and all fail to throw an error for the following code:
function f() {
g() = 5;
}They all of course throw an error if f is called.
Given the above, it seems like the most reasonable thing would be to specify this behavior. If it must be in an Annex, so be it, but I don't think we have any evidence that early errors in such cases are web-compatible. Until someone presents such evidence, it seems safest to specify the current browser behavior.
|
I just tested current SpiderMonkey, JSC, V8, and Chakra, and all fail to throw an error for the following code: function f() {
g() = 5;
}They all of course throw an error if Given the above, it seems like the most reasonable thing would be to specify this behavior. If it must be in an Annex, so be it, but I don't think we have any evidence that early errors in such cases are web-compatible. Until someone presents such evidence, it seems safest to specify the current browser behavior. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ajklein
Dec 21, 2016
Contributor
@bterlson any thoughts here? Would you merge a PR that made this change, or should I put this on the agenda for a future meeting?
|
@bterlson any thoughts here? Would you merge a PR that made this change, or should I put this on the agenda for a future meeting? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
evilpie
Dec 22, 2016
Contributor
I just wanted to note that SpiderMonkey doesn't parse this syntax in strict mode.
|
I just wanted to note that SpiderMonkey doesn't parse this syntax in strict mode. |
domenic
added
the
web reality
label
Dec 22, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bterlson
Dec 23, 2016
Member
@ajklein We should make a proposal PR. There will be debate about where to put it though (annex B vs. main spec) so it's needs-consensus for sure. Sure would be good to get data about how common this is. We were able to make some changes like this in the past - eg. SM/JSC was able to fix the re-evaluation of LHS references issue.
|
@ajklein We should make a proposal PR. There will be debate about where to put it though (annex B vs. main spec) so it's needs-consensus for sure. Sure would be good to get data about how common this is. We were able to make some changes like this in the past - eg. SM/JSC was able to fix the re-evaluation of LHS references issue. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
littledan
Dec 27, 2016
Member
@bakkot implemented data collection in V8 for the f() = x case, separating out strict and sloppy mode. If all goes well, we should have some good data in four months or so. Does anyone have more information about the ++++x case?
|
@bakkot implemented data collection in V8 for the |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bakkot
Dec 27, 2016
Contributor
@littledan, in ES3 the grammar included UnaryExpression : ++ UnaryExpression, and no Early Errors or anything of the kind to restrict it syntactically. But as far as I'm aware there was no environment in which this was ever anything other than an error at runtime (unlike f() = 0), so browsers either never supported it or stopped supporting it sometime long past. That one, and related things like ++~x etc., are almost certainly safe to leave as-is.
Edit: although as this issue was originally about, those cases should be marked in Annex E.
|
@littledan, in ES3 the grammar included Edit: although as this issue was originally about, those cases should be marked in Annex E. |
saurik commentedDec 16, 2015
In earlier ECMAScript versions, the syntax
++++awould lead to a ReferenceError when executed, but was considered valid code: if it existed in some large script and was never used, it would not lead to a failure. In ECMAScript 2015, this behavior has been changed to require an "early Reference Error" per 12.4.1, 12.5.1, and 12.14.1. As far as I can tell, this has not been marked as being an incompatibility.Worse, while we would pray that people were not relying on this strange syntax, Chrome has judged that in at least one case this behavior is not compatible with the legacy web :/. In researching why V8 was not throwing errors in some circumstances (such as how 12.3.1.5 requires that function calls return false for IsValidSimpleAssignmentTarget), I determined that Chrome backed out this change a while back.
https://codereview.chromium.org/217823003
Mozilla actually has a similar compatibility case in SpiderMonkey, though I can't find any discussion to find out exactly why. (They modify IsValidSimpleAssignmentTarget to gate on a feature flag they call "PermitAssignmentToFunctionCalls", which is in turn controlled by whether a "keyed destructuring" is in place, though I haven't yet taken the time to figure out what is going on there... but the syntax works ;P.)
https://dxr.mozilla.org/mozilla-central/rev/97e537f85183ef31481602ab9e5587a6e7d16b4d/js/src/frontend/Parser.cpp#7272
There is a mention in Annex E that "6.2.3: In ECMAScript 2015, Function calls are not allowed to return a Reference value.", but I do not believe that is a sufficient notice of the incompatibility (and would bet it is not intended to address this case, but I could be wrong?). I also did not see anything in Annex B that "for web compatibility reasons some of these early errors are relaxed", but maybe I'm just being dense.
(The versions of JavaScriptCore I have easy access to currently, which may or may not be terribly up-to-date, simply do not implement any of these early error semantics, so they would not have run into any compatibility concerns that I can try to dig up and report.)