Bug 848051 - Allow 'arguments' in generator-expressions. r=ejpbruel.

This commit is contained in:
Jason Orendorff 2013-03-27 14:16:56 -05:00
parent 724a495551
commit 89da1ad9a3
9 changed files with 56 additions and 28 deletions

View File

@ -5848,13 +5848,6 @@ Parser<FullParseHandler>::generatorExpr(ParseNode *kid)
genfn->pn_pos.begin = body->pn_pos.begin = kid->pn_pos.begin;
genfn->pn_pos.end = body->pn_pos.end = tokenStream.currentToken().pos.end;
if (AtomDefnPtr p = genpc.lexdeps->lookup(context->names().arguments)) {
Definition *dn = p.value();
ParseNode *errorNode = dn->dn_uses ? dn->dn_uses : body;
report(ParseError, false, errorNode, JSMSG_BAD_GENEXP_BODY, js_arguments_str);
return null();
}
RootedPropertyName funName(context);
if (!leaveFunction(genfn, funName))
return null();

View 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);

View File

@ -0,0 +1,4 @@
// 'arguments' is lexically scoped in genexprs at toplevel.
var arguments = 8;
assertEq((arguments for (x of [1])).next(), 8);

View 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);
}

View 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();

View 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");

View 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");

View File

@ -1,5 +1,3 @@
// |jit-test| error: SyntaxError;
Error.prototype.__proto__.p = 5;
f = Function("return( \"\" <arguments for(w in[]))");
for (i in f()) {}

View File

@ -24,14 +24,10 @@ function error(str) {
}
const JSMSG_GENEXP_YIELD = error("(function(){((yield) for (x in []))})").message;
const JSMSG_GENEXP_ARGUMENTS = error("(function(){(arguments for (x in []))})").message;
const JSMSG_TOP_YIELD = error("yield").message;
const JSMSG_YIELD_PAREN = error("(function(){yield, 1})").message;
const JSMSG_GENERIC = error("(for)").message;
const JSMSG_GENEXP_PAREN = error("print(1, x for (x in []))").message;
const JSMSG_BAD_GENERATOR_SYNTAX = error("(1, arguments for (x in []))").message;
const JSMSG_GENEXP_MIX = { simple: JSMSG_BAD_GENERATOR_SYNTAX, call: JSMSG_GENEXP_ARGUMENTS };
const JSMSG_BAD_GENERATOR_SYNTAX = error("(1, x for (x in []))").message;
const cases = [
// yield expressions
@ -53,11 +49,8 @@ const cases = [
{ expr: "((((yield 1))))", top: JSMSG_TOP_YIELD, fun: null, gen: JSMSG_GENEXP_YIELD, desc: "deeply nested yield w/ arg" },
// arguments
{ expr: "arguments", top: null, fun: null, gen: JSMSG_GENEXP_ARGUMENTS, desc: "simple arguments" },
{ expr: "1, arguments", top: null, fun: null, gen: JSMSG_GENEXP_ARGUMENTS, desc: "arguments in list" },
{ expr: "(arguments)", top: null, fun: null, gen: JSMSG_GENEXP_ARGUMENTS, desc: "simple arguments, parenthesized" },
{ expr: "(1, arguments)", top: null, fun: null, gen: JSMSG_GENEXP_ARGUMENTS, desc: "arguments in list, parenthesized" },
{ expr: "((((arguments))))", top: null, fun: null, gen: JSMSG_GENEXP_ARGUMENTS, desc: "deeply nested arguments" },
{ expr: "arguments", top: null, fun: null, gen: null, desc: "arguments in list" },
{ expr: "1, arguments", top: null, fun: null, gen: null, desc: "arguments in list" },
// yield in generator expressions
{ expr: "(yield for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENERIC, gen: JSMSG_GENERIC, desc: "simple yield in genexp" },
@ -65,7 +58,7 @@ const cases = [
{ expr: "(yield, 1 for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_YIELD_PAREN, gen: JSMSG_YIELD_PAREN, desc: "simple yield in list in genexp" },
{ expr: "(yield 1, 2 for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_YIELD_PAREN, gen: JSMSG_YIELD_PAREN, desc: "yield w/ arg in list in genexp" },
{ expr: "(1, yield for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENERIC, gen: JSMSG_GENERIC, desc: "simple yield at end of list in genexp" },
{ expr: "(1, yield 2 for (x in []))", top: JSMSG_TOP_YIELD, fun: { simple: JSMSG_GENEXP_YIELD, call: JSMSG_GENEXP_PAREN },
{ expr: "(1, yield 2 for (x in []))", top: JSMSG_TOP_YIELD, fun: { simple: JSMSG_GENEXP_YIELD, call: JSMSG_BAD_GENERATOR_SYNTAX },
gen: JSMSG_GENEXP_YIELD, desc: "yield w/ arg at end of list in genexp" },
{ expr: "((yield) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENEXP_YIELD, gen: JSMSG_GENEXP_YIELD, desc: "simple yield, parenthesized in genexp" },
{ expr: "((yield 1) for (x in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENEXP_YIELD, gen: JSMSG_GENEXP_YIELD, desc: "yield w/ arg, parenthesized in genexp" },
@ -85,16 +78,16 @@ const cases = [
{ expr: "((((1, yield 2)) for (x in [])) for (y in []))", top: JSMSG_TOP_YIELD, fun: JSMSG_GENEXP_YIELD, gen: JSMSG_GENEXP_YIELD, desc: "deeply nested yield in multiple genexps" },
// arguments in generator expressions
{ expr: "(arguments for (x in []))", top: JSMSG_GENEXP_ARGUMENTS, fun: JSMSG_GENEXP_ARGUMENTS, gen: JSMSG_GENEXP_ARGUMENTS, desc: "simple arguments in genexp" },
{ expr: "(1, arguments for (x in []))", top: JSMSG_GENEXP_MIX, fun: JSMSG_GENEXP_MIX, gen: JSMSG_GENEXP_MIX, desc: "arguments in list in genexp" },
{ expr: "((arguments) for (x in []))", top: JSMSG_GENEXP_ARGUMENTS, fun: JSMSG_GENEXP_ARGUMENTS, gen: JSMSG_GENEXP_ARGUMENTS, desc: "arguments, parenthesized in genexp" },
{ expr: "(1, (arguments) for (x in []))", top: JSMSG_GENEXP_MIX, fun: JSMSG_GENEXP_MIX, gen: JSMSG_GENEXP_MIX, desc: "arguments, parenthesized in list in genexp" },
{ expr: "((1, arguments) for (x in []))", top: JSMSG_GENEXP_ARGUMENTS, fun: JSMSG_GENEXP_ARGUMENTS, gen: JSMSG_GENEXP_ARGUMENTS, desc: "arguments in list, parenthesized in genexp" },
{ expr: "(1, (2, arguments) for (x in []))", top: JSMSG_GENEXP_MIX, fun: JSMSG_GENEXP_MIX, gen: JSMSG_GENEXP_MIX, desc: "arguments in list, parenthesized in list in genexp" },
{ expr: "(arguments for (x in []))", top: null, fun: null, gen: null, desc: "simple arguments in genexp" },
{ expr: "(1, arguments for (x in []))", top: JSMSG_BAD_GENERATOR_SYNTAX, fun: JSMSG_BAD_GENERATOR_SYNTAX, gen: JSMSG_BAD_GENERATOR_SYNTAX, desc: "arguments in list in genexp" },
{ expr: "((arguments) for (x in []))", top: null, fun: null, gen: null, desc: "arguments, parenthesized in genexp" },
{ expr: "(1, (arguments) for (x in []))", top: JSMSG_BAD_GENERATOR_SYNTAX, fun: JSMSG_BAD_GENERATOR_SYNTAX, gen: JSMSG_BAD_GENERATOR_SYNTAX, desc: "arguments, parenthesized in list in genexp" },
{ expr: "((1, arguments) for (x in []))", top: null, fun: null, gen: null, desc: "arguments in list, parenthesized in genexp" },
{ expr: "(1, (2, arguments) for (x in []))", top: JSMSG_BAD_GENERATOR_SYNTAX, fun: JSMSG_BAD_GENERATOR_SYNTAX, gen: JSMSG_BAD_GENERATOR_SYNTAX, desc: "arguments in list, parenthesized in list in genexp" },
// deeply nested arguments in generator expressions
{ expr: "((((1, arguments))) for (x in []))", top: JSMSG_GENEXP_ARGUMENTS, fun: JSMSG_GENEXP_ARGUMENTS, gen: JSMSG_GENEXP_ARGUMENTS, desc: "deeply nested arguments in genexp" },
{ expr: "((((1, arguments)) for (x in [])) for (y in []))", top: JSMSG_GENEXP_ARGUMENTS, fun: JSMSG_GENEXP_ARGUMENTS, gen: JSMSG_GENEXP_ARGUMENTS, desc: "deeply nested arguments in multiple genexps" },
{ expr: "((((1, arguments))) for (x in []))", top: null, fun: null, gen: null, desc: "deeply nested arguments in genexp" },
{ expr: "((((1, arguments)) for (x in [])) for (y in []))", top: null, fun: null, gen: null, desc: "deeply nested arguments in multiple genexps" },
// legal yield/arguments in nested function
{ expr: "((function() { yield }) for (x in []))", top: null, fun: null, gen: null, desc: "legal yield in nested function" },