Bug 1085464 - Don't lookup .generator on |with| objects on the scope chain. r=wingo

--HG--
extra : rebase_source : 960bf902b774906d72e815b2a7b9852ca1f0e5bc
This commit is contained in:
Jan de Mooij 2014-10-22 15:17:09 +02:00
parent a8ad646f8b
commit 2060d6bc4e
3 changed files with 27 additions and 2 deletions

View File

@ -1010,6 +1010,10 @@ EmitAtomOp(ExclusiveContext *cx, JSAtom *atom, JSOp op, BytecodeEmitter *bce)
{
MOZ_ASSERT(JOF_OPTYPE(op) == JOF_ATOM);
// .generator lookups should be emitted as JSOP_GETALIASEDVAR instead of
// JSOP_NAME etc, to bypass |with| objects on the scope chain.
MOZ_ASSERT_IF(op == JSOP_NAME || op == JSOP_GETGNAME, atom != cx->names().dotGenerator);
if (op == JSOP_GETPROP && atom == cx->names().length) {
/* Specialize length accesses for the interpreter. */
op = JSOP_LENGTH;

View File

@ -2995,7 +2995,7 @@ LexicalLookup(ContextT *ct, HandleAtom atom, int *slotp, typename ContextT::Stmt
* can potentially override any static bindings introduced by statements
* further up the stack, we have to abort the search.
*/
if (stmt->type == STMT_WITH)
if (stmt->type == STMT_WITH && atom != ct->sc->context->names().dotGenerator)
break;
// Skip statements that do not introduce a new scope
@ -5206,7 +5206,8 @@ Parser<FullParseHandler>::withStatement()
for (AtomDefnRange r = pc->lexdeps->all(); !r.empty(); r.popFront()) {
DefinitionNode defn = r.front().value().get<FullParseHandler>();
DefinitionNode lexdep = handler.resolve(defn);
handler.deoptimizeUsesWithin(lexdep, TokenPos(begin, pos().begin));
if (lexdep->name() != context->names().dotGenerator)
handler.deoptimizeUsesWithin(lexdep, TokenPos(begin, pos().begin));
}
ObjectBox *staticWithBox = newObjectBox(staticWith);

View File

@ -0,0 +1,20 @@
function *f() {
var o = Proxy.createFunction({
get: function() { assertEq(0, 1); },
has: function() { assertEq(0, 2); }
}, function() {});
with (o) {
yield 1;
with ({}) {
yield 2;
}
}
with ({".generator": 100}) {
yield eval("3");
}
}
var s = "";
for (var i of f())
s += i;
assertEq(s, "123");