From 6a7eb2d94777b26e4560a6c6cab5fb3835377fd8 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 23 Jul 2012 11:09:59 -0700 Subject: [PATCH] Bug 775684 - rm PND_TOPLEVEL (r=ejpbruel) --HG-- extra : rebase_source : 90fed1498fc1e34d721afa5a3a4ba518ad0cf3c9 --- js/src/frontend/BytecodeEmitter.cpp | 22 ++++---------- js/src/frontend/ParseNode.h | 30 +++++-------------- js/src/frontend/Parser.cpp | 5 ++-- .../tests/js1_8_5/regress/regress-551763-1.js | 3 ++ .../tests/js1_8_5/regress/regress-551763-2.js | 3 ++ 5 files changed, 22 insertions(+), 41 deletions(-) diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 4d0fb1c18bb..ad62ac7e0a5 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -1178,7 +1178,6 @@ TryConvertToGname(BytecodeEmitter *bce, ParseNode *pn, JSOp *op) case JSOP_DECNAME: *op = JSOP_DECGNAME; break; case JSOP_NAMEDEC: *op = JSOP_GNAMEDEC; break; case JSOP_SETCONST: - case JSOP_DELNAME: /* Not supported. */ return false; default: JS_NOT_REACHED("gname"); @@ -1210,12 +1209,14 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn) { JS_ASSERT(pn->isKind(PNK_NAME)); - /* Don't attempt if 'pn' is already bound, deoptimized, or a nop. */ - if ((pn->pn_dflags & PND_BOUND) || pn->isDeoptimized() || pn->getOp() == JSOP_NOP) + /* Don't attempt if 'pn' is already bound or deoptimized or a nop. */ + JSOp op = pn->getOp(); + if (pn->isBound() || pn->isDeoptimized() || op == JSOP_NOP) return true; /* JSOP_CALLEE is pre-bound by definition. */ - JS_ASSERT(!pn->isOp(JSOP_CALLEE)); + JS_ASSERT(op != JSOP_CALLEE); + JS_ASSERT(JOF_OPTYPE(op) == JOF_ATOM); /* * The parser already linked name uses to definitions when (where not @@ -1233,8 +1234,6 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn) return true; } - JSOp op = pn->getOp(); - JS_ASSERT(JOF_OPTYPE(op) == JOF_ATOM); JS_ASSERT_IF(dn->kind() == Definition::CONST, pn->pn_dflags & PND_CONST); /* @@ -1250,16 +1249,6 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn) case JSOP_NAME: case JSOP_SETCONST: break; - case JSOP_DELNAME: - if (dn->kind() != Definition::UNKNOWN) { - if (bce->callerFrame && dn->isTopLevel()) - JS_ASSERT(bce->script->compileAndGo); - else - pn->setOp(JSOP_FALSE); - pn->pn_dflags |= PND_BOUND; - return true; - } - break; default: if (pn->isConst()) { if (bce->sc->needStrictChecks()) { @@ -1394,7 +1383,6 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn) * heavyweight, ensuring that the function name is represented in * the scope chain so that assignment will throw a TypeError. */ - JS_ASSERT(op != JSOP_DELNAME); if (!bce->sc->funIsHeavyweight()) { op = JSOP_CALLEE; pn->pn_dflags |= PND_CONST; diff --git a/js/src/frontend/ParseNode.h b/js/src/frontend/ParseNode.h index 02fce76ff8b..1c49f0bca67 100644 --- a/js/src/frontend/ParseNode.h +++ b/js/src/frontend/ParseNode.h @@ -727,16 +727,15 @@ struct ParseNode { #define PND_LET 0x01 /* let (block-scoped) binding */ #define PND_CONST 0x02 /* const binding (orthogonal to let) */ #define PND_ASSIGNED 0x04 /* set if ever LHS of assignment */ -#define PND_TOPLEVEL 0x08 /* see isTopLevel() below */ -#define PND_BLOCKCHILD 0x10 /* use or def is direct block child */ -#define PND_PLACEHOLDER 0x20 /* placeholder definition for lexdep */ -#define PND_BOUND 0x40 /* bound to a stack or global slot */ -#define PND_DEOPTIMIZED 0x80 /* former pn_used name node, pn_lexdef +#define PND_BLOCKCHILD 0x08 /* use or def is direct block child */ +#define PND_PLACEHOLDER 0x10 /* placeholder definition for lexdep */ +#define PND_BOUND 0x20 /* bound to a stack or global slot */ +#define PND_DEOPTIMIZED 0x40 /* former pn_used name node, pn_lexdef still valid, but this use no longer optimizable via an upvar opcode */ -#define PND_CLOSED 0x100 /* variable is closed over */ -#define PND_DEFAULT 0x200 /* definition is an arg with a default */ -#define PND_IMPLICITARGUMENTS 0x400 /* the definition is a placeholder for +#define PND_CLOSED 0x80 /* variable is closed over */ +#define PND_DEFAULT 0x100 /* definition is an arg with a default */ +#define PND_IMPLICITARGUMENTS 0x200 /* the definition is a placeholder for 'arguments' that has been converted into a definition after the function body has been parsed. */ @@ -785,22 +784,9 @@ struct ParseNode { bool isDeoptimized() const { return test(PND_DEOPTIMIZED); } bool isAssigned() const { return test(PND_ASSIGNED); } bool isClosed() const { return test(PND_CLOSED); } + bool isBound() const { return test(PND_BOUND); } bool isImplicitArguments() const { return test(PND_IMPLICITARGUMENTS); } - /* - * True iff this definition creates a top-level binding in the overall - * script being compiled -- that is, it affects the whole program's - * bindings, not bindings for a specific function (unless this definition - * is in the outermost scope in eval code, executed within a function) or - * the properties of a specific object (through the with statement). - * - * NB: Function sub-statements found in overall program code and not nested - * within other functions are not currently top level, even though (if - * executed) they do create top-level bindings; there is no particular - * rationale for this behavior. - */ - bool isTopLevel() const { return test(PND_TOPLEVEL); } - void become(ParseNode *pn2); void clear(); diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 59e1c77bca9..f963f50f0a4 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -801,8 +801,6 @@ Define(ParseNode *pn, JSAtom *atom, TreeContext *tc, bool let = false) return false; pn->setDefn(true); pn->pn_dflags &= ~PND_PLACEHOLDER; - if (!tc->parent) - pn->pn_dflags |= PND_TOPLEVEL; return true; } @@ -4797,6 +4795,9 @@ Parser::unaryExpr() case PNK_NAME: if (!reportStrictModeError(pn, JSMSG_DEPRECATED_DELETE_OPERAND)) return NULL; + tc->sc->setBindingsAccessedDynamically(); + tc->sc->setFunIsHeavyweight(); + pn2->pn_dflags |= PND_DEOPTIMIZED; pn2->setOp(JSOP_DELNAME); break; default:; diff --git a/js/src/tests/js1_8_5/regress/regress-551763-1.js b/js/src/tests/js1_8_5/regress/regress-551763-1.js index f5f95e605dc..aced2eb7a6d 100644 --- a/js/src/tests/js1_8_5/regress/regress-551763-1.js +++ b/js/src/tests/js1_8_5/regress/regress-551763-1.js @@ -1,3 +1,6 @@ +// |reftest| skip-if(xulRuntime.shell) +// skip in the shell because 'arguments' is defined as a shell utility function + /* Check we can delete arguments in the global space. */ arguments = 42; reportCompare(delete arguments, true, "arguments defined as global"); diff --git a/js/src/tests/js1_8_5/regress/regress-551763-2.js b/js/src/tests/js1_8_5/regress/regress-551763-2.js index 4bcb4174399..50048881808 100644 --- a/js/src/tests/js1_8_5/regress/regress-551763-2.js +++ b/js/src/tests/js1_8_5/regress/regress-551763-2.js @@ -1,3 +1,6 @@ +// |reftest| skip-if(xulRuntime.shell) +// skip in the shell because 'arguments' is defined as a shell utility function + /* Check we can't delete a var-declared arguments in global space. */ var arguments = 42; reportCompare(delete arguments, false, "arguments defined as global variable");