mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
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:
parent
e323e8ab4f
commit
ba7766a4a4
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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) \
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user