Bug 966912 - Part 4: Entering a with statement doesn't push onto the stack r=luke

--HG--
extra : rebase_source : fe40b9c21298fc9f86b9542b70fb9cc34cf1e44d
This commit is contained in:
Andy Wingo 2014-02-04 18:18:24 +01:00
parent e323e8ab4f
commit ba7766a4a4
5 changed files with 20 additions and 38 deletions

View File

@ -544,8 +544,6 @@ NonLocalExitScope::prepareForNonLocalJump(StmtInfoBCE *toStmt)
break;
case STMT_WITH:
/* There's a With object on the stack that we need to pop. */
FLUSH_POPS();
if (Emit1(cx, bce, JSOP_LEAVEWITH) < 0)
return false;
JS_ASSERT(stmt->isNestedScope);

View File

@ -832,8 +832,7 @@ js::TypeOfValue(const Value &v)
* of the with block with sp + stackIndex.
*/
static bool
EnterWith(JSContext *cx, AbstractFramePtr frame, HandleValue val, uint32_t stackDepth,
HandleObject staticWith)
EnterWith(JSContext *cx, AbstractFramePtr frame, HandleValue val, HandleObject staticWith)
{
JS_ASSERT(staticWith->is<StaticWithObject>());
RootedObject obj(cx);
@ -846,8 +845,7 @@ EnterWith(JSContext *cx, AbstractFramePtr frame, HandleValue val, uint32_t stack
}
RootedObject scopeChain(cx, frame.scopeChain());
DynamicWithObject *withobj = DynamicWithObject::create(cx, obj, scopeChain, stackDepth,
staticWith);
DynamicWithObject *withobj = DynamicWithObject::create(cx, obj, scopeChain, staticWith);
if (!withobj)
return false;
@ -1752,28 +1750,16 @@ CASE(JSOP_ENTERWITH)
RootedValue &val = rootValue0;
RootedObject &staticWith = rootObject0;
val = REGS.sp[-1];
REGS.sp--;
staticWith = script->getObject(REGS.pc);
if (!EnterWith(cx, REGS.fp(), val, REGS.stackDepth() - 1, staticWith))
if (!EnterWith(cx, REGS.fp(), val, staticWith))
goto error;
/*
* We must ensure that different "with" blocks have different stack depth
* associated with them. This allows the try handler search to properly
* recover the scope chain. Thus we must keep the stack at least at the
* current level.
*
* We set sp[-1] to the current "with" object to help asserting the
* enter/leave balance in [leavewith].
*/
REGS.sp[-1].setObject(*REGS.fp()->scopeChain());
}
END_CASE(JSOP_ENTERWITH)
CASE(JSOP_LEAVEWITH)
JS_ASSERT(REGS.sp[-1].toObject() == *REGS.fp()->scopeChain());
REGS.fp()->popWith(cx);
REGS.sp--;
END_CASE(JSOP_LEAVEWITH)
CASE(JSOP_RETURN)

View File

@ -49,8 +49,8 @@
/* Long-standing JavaScript bytecodes. */ \
macro(JSOP_UNDEFINED, 1, js_undefined_str, "", 1, 0, 1, JOF_BYTE) \
macro(JSOP_UNUSED2, 2, "unused2", NULL, 1, 1, 0, JOF_BYTE) \
macro(JSOP_ENTERWITH, 3, "enterwith", NULL, 5, 1, 1, JOF_OBJECT) \
macro(JSOP_LEAVEWITH, 4, "leavewith", NULL, 1, 1, 0, JOF_BYTE) \
macro(JSOP_ENTERWITH, 3, "enterwith", NULL, 5, 1, 0, JOF_OBJECT) \
macro(JSOP_LEAVEWITH, 4, "leavewith", NULL, 1, 0, 0, JOF_BYTE) \
macro(JSOP_RETURN, 5, "return", NULL, 1, 1, 0, JOF_BYTE) \
macro(JSOP_GOTO, 6, "goto", NULL, 5, 0, 0, JOF_JUMP) \
macro(JSOP_IFEQ, 7, "ifeq", NULL, 5, 1, 0, JOF_JUMP|JOF_DETECTING) \

View File

@ -403,7 +403,7 @@ CloneStaticWithObject(JSContext *cx, HandleObject enclosingScope, Handle<StaticW
}
DynamicWithObject *
DynamicWithObject::create(JSContext *cx, HandleObject object, HandleObject enclosing, uint32_t depth,
DynamicWithObject::create(JSContext *cx, HandleObject object, HandleObject enclosing,
HandleObject staticWith)
{
JS_ASSERT(staticWith->is<StaticWithObject>());
@ -426,7 +426,6 @@ DynamicWithObject::create(JSContext *cx, HandleObject object, HandleObject enclo
return nullptr;
obj->as<ScopeObject>().setEnclosingScope(enclosing);
obj->setReservedSlot(DEPTH_SLOT, PrivateUint32Value(depth));
obj->setFixedSlot(OBJECT_SLOT, ObjectValue(*object));
obj->setFixedSlot(THIS_SLOT, ObjectValue(*thisp));

View File

@ -308,15 +308,7 @@ class DeclEnvObject : public ScopeObject
class NestedScopeObject : public ScopeObject
{
protected:
static const unsigned DEPTH_SLOT = 1;
public:
/* Return the abstract stack depth right before entering this nested scope. */
uint32_t stackDepth() const {
return getReservedSlot(DEPTH_SLOT).toPrivateUint32();
}
/*
* A refinement of enclosingScope that returns nullptr if the enclosing
* scope is not a NestedScopeObject.
@ -362,7 +354,7 @@ class NestedScopeObject : public ScopeObject
class StaticWithObject : public NestedScopeObject
{
public:
static const unsigned RESERVED_SLOTS = 2;
static const unsigned RESERVED_SLOTS = 1;
static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT2_BACKGROUND;
static const Class class_;
@ -373,18 +365,17 @@ class StaticWithObject : public NestedScopeObject
// With scope objects on the run-time scope chain.
class DynamicWithObject : public NestedScopeObject
{
static const unsigned OBJECT_SLOT = 2;
static const unsigned THIS_SLOT = 3;
static const unsigned OBJECT_SLOT = 1;
static const unsigned THIS_SLOT = 2;
public:
static const unsigned RESERVED_SLOTS = 4;
static const unsigned RESERVED_SLOTS = 3;
static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT4_BACKGROUND;
static const Class class_;
static DynamicWithObject *
create(JSContext *cx, HandleObject object, HandleObject enclosing, uint32_t depth,
HandleObject staticWith);
create(JSContext *cx, HandleObject object, HandleObject enclosing, HandleObject staticWith);
StaticWithObject& staticWith() const {
return getProto()->as<StaticWithObject>();
@ -403,12 +394,20 @@ class DynamicWithObject : public NestedScopeObject
class BlockObject : public NestedScopeObject
{
protected:
static const unsigned DEPTH_SLOT = 1;
public:
static const unsigned RESERVED_SLOTS = 2;
static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT4_BACKGROUND;
static const Class class_;
/* Return the abstract stack depth right before entering this nested scope. */
uint32_t stackDepth() const {
return getReservedSlot(DEPTH_SLOT).toPrivateUint32();
}
/* Return the number of variables associated with this block. */
uint32_t slotCount() const {
return propertyCountForCompilation();