mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-05-28 20:41:33 +00:00
#430: fix reversions with legacy generators, restore/new tests
This commit is contained in:
parent
a9e9d0bb5f
commit
a05b152eef
|
@ -5910,7 +5910,7 @@ Parser<ParseHandler>::forStatement(YieldHandling yieldHandling)
|
|||
if (matched) {
|
||||
iflags = JSITER_FOREACH;
|
||||
isForEach = true;
|
||||
addTelemetry(JSCompartment::DeprecatedForEach);
|
||||
//addTelemetry(JSCompartment::DeprecatedForEach);
|
||||
if (versionNumber() < JSVERSION_LATEST) {
|
||||
if (!report(ParseWarning, pc->sc->strict(), null(), JSMSG_DEPRECATED_FOR_EACH))
|
||||
return null();
|
||||
|
@ -8392,7 +8392,7 @@ Parser<FullParseHandler>::legacyComprehensionTail(ParseNode* bodyExpr, unsigned
|
|||
return null();
|
||||
if (matched) {
|
||||
pn2->pn_iflags |= JSITER_FOREACH;
|
||||
addTelemetry(JSCompartment::DeprecatedForEach);
|
||||
//addTelemetry(JSCompartment::DeprecatedForEach);
|
||||
if (versionNumber() < JSVERSION_LATEST) {
|
||||
if (!report(ParseWarning, pc->sc->strict(), pn2, JSMSG_DEPRECATED_FOR_EACH))
|
||||
return null();
|
||||
|
@ -10084,16 +10084,6 @@ Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TripledotHandling
|
|||
}
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::exprInParens(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError)
|
||||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LP));
|
||||
return expr(inHandling, yieldHandling, tripledotHandling, possibleError, PredictInvoked);
|
||||
}
|
||||
|
||||
// Legacy generator comprehensions can appear anywhere an expression is
|
||||
// enclosed in parentheses, even if those parentheses are part of statement
|
||||
// syntax or a function call:
|
||||
|
@ -10111,6 +10101,44 @@ Parser<ParseHandler>::exprInParens(InHandling inHandling, YieldHandling yieldHan
|
|||
// sum(x*x for (x in y)); // ok
|
||||
// sum(for (x of y) x*x); // SyntaxError: needs more parens
|
||||
//
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::exprInParens(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError)
|
||||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LP));
|
||||
uint32_t begin = pos().begin;
|
||||
uint32_t startYieldOffset = pc->lastYieldOffset;
|
||||
|
||||
Node pn = expr(inHandling, yieldHandling, tripledotHandling, possibleError, PredictInvoked);
|
||||
if (!pn)
|
||||
return null();
|
||||
|
||||
#if JS_HAS_GENERATOR_EXPRS
|
||||
bool matched;
|
||||
if (!tokenStream.matchToken(&matched, TOK_FOR))
|
||||
return null();
|
||||
if (matched) {
|
||||
if (pc->lastYieldOffset != startYieldOffset) {
|
||||
reportWithOffset(ParseError, false, pc->lastYieldOffset,
|
||||
JSMSG_BAD_GENEXP_BODY, js_yield_str);
|
||||
return null();
|
||||
}
|
||||
if (handler.isUnparenthesizedCommaExpression(pn)) {
|
||||
report(ParseError, false, null(), JSMSG_BAD_GENERATOR_SYNTAX);
|
||||
return null();
|
||||
}
|
||||
pn = legacyGeneratorExpr(pn);
|
||||
if (!pn)
|
||||
return null();
|
||||
handler.setBeginPosition(pn, begin);
|
||||
}
|
||||
#endif /* JS_HAS_GENERATOR_EXPRS */
|
||||
|
||||
return pn;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::exprInParens(InHandling inHandling, YieldHandling yieldHandling,
|
||||
|
|
4
js/src/jit-test/tests/arguments/defaults-bug790424.js
Normal file
4
js/src/jit-test/tests/arguments/defaults-bug790424.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
function f1(g=((function () { return 4; }) for (x of [1]))) {
|
||||
return g.next()();
|
||||
}
|
||||
assertEq(f1(), 4);
|
|
@ -16,6 +16,7 @@ assertEq(f3()()(), true);
|
|||
// These should be okay.
|
||||
function f4(f=(function () { with (Object) {} }), g=(function () { "use strict"; })) {}
|
||||
function f5(g=(function () { "use strict"; }), f=(function () { with (Object) {} })) {}
|
||||
function f6(f=(function () { return (x for (y in (function g() {}))); })) {}
|
||||
|
||||
assertThrowsInstanceOf(function () {
|
||||
eval("'use strict'; function f(a=delete x) { }");
|
||||
|
|
7
js/src/jit-test/tests/arguments/genexpr-1.js
Normal file
7
js/src/jit-test/tests/arguments/genexpr-1.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
// No 'arguments' binding in genexprs at toplevel.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
delete this.arguments; // it is defined in the shell
|
||||
var iter = (arguments for (x of [1]));
|
||||
assertThrowsInstanceOf(() => iter.next(), ReferenceError);
|
4
js/src/jit-test/tests/arguments/genexpr-2.js
Normal file
4
js/src/jit-test/tests/arguments/genexpr-2.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
// 'arguments' is lexically scoped in genexprs at toplevel.
|
||||
|
||||
var arguments = 8;
|
||||
assertEq((arguments for (x of [1])).next(), 8);
|
6
js/src/jit-test/tests/arguments/genexpr-3.js
Normal file
6
js/src/jit-test/tests/arguments/genexpr-3.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
// 'arguments' is lexically scoped in genexpr in toplevel let-block.
|
||||
|
||||
{
|
||||
let arguments = [];
|
||||
assertEq((arguments for (p in {a: 1})).next(), arguments);
|
||||
}
|
7
js/src/jit-test/tests/arguments/genexpr-4.js
Normal file
7
js/src/jit-test/tests/arguments/genexpr-4.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
// 'arguments' is lexically scoped in genexpr in function.
|
||||
|
||||
function f() {
|
||||
assertEq((arguments for (x of [0])).next(),
|
||||
(arguments for (y of [1])).next());
|
||||
}
|
||||
f();
|
8
js/src/jit-test/tests/arguments/genexpr-5.js
Normal file
8
js/src/jit-test/tests/arguments/genexpr-5.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
// 'arguments' binding can be closed over and outlives the function activation.
|
||||
|
||||
function f() {
|
||||
return (arguments for (x of [1]));
|
||||
}
|
||||
|
||||
var args = f("ponies").next();
|
||||
assertEq(args[0], "ponies");
|
12
js/src/jit-test/tests/arguments/genexpr-6.js
Normal file
12
js/src/jit-test/tests/arguments/genexpr-6.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
// 'arguments' works in nested genexprs.
|
||||
|
||||
function f() {
|
||||
return ((((((arguments for (u of [0]))
|
||||
for (v of [1]))
|
||||
for (w of [2]))
|
||||
for (x of [3]))
|
||||
for (y of [4]))
|
||||
for (z of [5]));
|
||||
}
|
||||
var args = f("ponies").next().next().next().next().next().next();
|
||||
assertEq(args[0], "ponies");
|
10
js/src/jit-test/tests/basic/bug790629-1.js
Normal file
10
js/src/jit-test/tests/basic/bug790629-1.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
// 'this' in generator-expression in strict-mode toplevel
|
||||
// is the same as global 'this'.
|
||||
|
||||
"use strict";
|
||||
|
||||
var it1 = (this for (x of [0]));
|
||||
assertEq(it1.next(), this);
|
||||
|
||||
var it2 = (this for (x of (this for (y of (this for (z of [0]))))));
|
||||
assertEq(it2.next(), this);
|
11
js/src/jit-test/tests/basic/bug790629-2.js
Normal file
11
js/src/jit-test/tests/basic/bug790629-2.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
// 'this' in escaping generator-expression in a method
|
||||
// is the same as 'this' in the enclosing method.
|
||||
|
||||
var obj = {
|
||||
f: function () {
|
||||
assertEq(this, obj);
|
||||
return (this for (x of [0]));
|
||||
}
|
||||
};
|
||||
|
||||
assertEq(obj.f().next(), obj);
|
11
js/src/jit-test/tests/basic/bug790629-3.js
Normal file
11
js/src/jit-test/tests/basic/bug790629-3.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
// 'this' in escaping generator-expression in a method
|
||||
// is the same as 'this' in the enclosing method
|
||||
// even if the method does not otherwise use 'this'.
|
||||
|
||||
var obj = {
|
||||
f: function () {
|
||||
return (this for (x of [0]));
|
||||
}
|
||||
};
|
||||
|
||||
assertEq(obj.f().next(), obj);
|
13
js/src/jit-test/tests/basic/bug790629-4.js
Normal file
13
js/src/jit-test/tests/basic/bug790629-4.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
// 'this' in a generator-expression non-strict function produces the expected
|
||||
// object.
|
||||
|
||||
Number.prototype.iters = function () {
|
||||
return [(this for (x of [0])),
|
||||
(this for (y of [0]))];
|
||||
};
|
||||
|
||||
var [a, b] = (3).iters();
|
||||
var three = a.next();
|
||||
assertEq(Object.prototype.toString.call(three), '[object Number]');
|
||||
assertEq(+three, 3);
|
||||
assertEq(b.next(), three);
|
|
@ -191,6 +191,18 @@ test('try {for (let x in eval("throw x")) {}} catch (e) {return e;}', undefined,
|
|||
test('try {for each (let x in x) {eval("throw x");}} catch (e) {return e;}', ['ponies'], undefined);
|
||||
test('for each (let {x: y, y: x} in [{x: x, y: x}]) {return y;}', undefined, undefined);
|
||||
|
||||
// genexps
|
||||
test('return (i for (i in x)).next();', {ponies:true});
|
||||
test('return (eval("i") for (i in x)).next();', {ponies:true});
|
||||
test('return (eval("i") for (i in eval("x"))).next();', {ponies:true});
|
||||
test('try {return (eval("throw i") for (i in x)).next();} catch (e) {return e;}', {ponies:true});
|
||||
|
||||
// array comprehension
|
||||
test('return [i for (i in x)][0];', {ponies:true});
|
||||
test('return [eval("i") for (i in x)][0];', {ponies:true});
|
||||
test('return [eval("i") for (i in eval("x"))][0];', {ponies:true});
|
||||
test('try {return [eval("throw i") for (i in x)][0];} catch (e) {return e;}', {ponies:true});
|
||||
|
||||
// don't forget about switch craziness
|
||||
test('var y = 3;switch (function () {return eval("y");}()) {case 3:let y;return x;default:;}');
|
||||
test('switch (x) {case 3:let y;return 3;case 4:let z;return 4;default:return x;}');
|
||||
|
|
14
js/src/jit-test/tests/tenfourfox/legacy-generator.js
Normal file
14
js/src/jit-test/tests/tenfourfox/legacy-generator.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
// array comprehensions
|
||||
var data = "abcdefg";
|
||||
var hexString = [
|
||||
data.charCodeAt(i) for (i in data) if (data.charCodeAt(i) < 100)
|
||||
].join(",");
|
||||
assertEq(hexString, "97,98,99");
|
||||
|
||||
// generator comprehensions
|
||||
var it = [1, 2, 3, 5, 8, 10, 13];
|
||||
var w = (i*2 for (i of it) if (i & 1));
|
||||
assertEq(w.next(), 2);
|
||||
assertEq(w.next(), 6);
|
||||
assertEq(w.next(), 10);
|
||||
assertEq(w.next(), 26);
|
30
js/src/tests/js1_8/regress-380237-02.js
Normal file
30
js/src/tests/js1_8/regress-380237-02.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 380237;
|
||||
var summary = 'Decompilation of generator expressions';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f = function() { g = (d for (d in [0])); g.next(); };
|
||||
expect = 'function() { g = (d for (d in [0])); g.next(); }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
Loading…
Reference in New Issue
Block a user