Make all cacheable scope objects into delegates (bug 761685, r=luke).

--HG--
extra : rebase_source : 0fca62a7e3f9fbd83b5133e0d4d12a3f87078583
This commit is contained in:
David Anderson 2012-06-13 18:28:35 -07:00
parent b92b0eb866
commit c4298358d6
7 changed files with 25 additions and 23 deletions

View File

@ -169,6 +169,7 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject
*/ */
pobj = obj; pobj = obj;
JSObject *scopeObj = NULL;
if (JOF_MODE(cs.format) == JOF_NAME) { if (JOF_MODE(cs.format) == JOF_NAME) {
uint8_t scopeIndex = entry->scopeIndex; uint8_t scopeIndex = entry->scopeIndex;
while (scopeIndex > 0) { while (scopeIndex > 0) {
@ -179,7 +180,7 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject
scopeIndex--; scopeIndex--;
} }
*objp = pobj; scopeObj = pobj;
} }
uint8_t protoIndex = entry->protoIndex; uint8_t protoIndex = entry->protoIndex;
@ -192,6 +193,8 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject
} }
if (pobj->lastProperty() == entry->pshape) { if (pobj->lastProperty() == entry->pshape) {
if (JOF_MODE(cs.format) == JOF_NAME)
*objp = scopeObj;
#ifdef DEBUG #ifdef DEBUG
PropertyName *name = GetNameFromBytecode(cx, pc, op, cs); PropertyName *name = GetNameFromBytecode(cx, pc, op, cs);
JS_ASSERT(pobj->nativeContains(cx, NameToId(name))); JS_ASSERT(pobj->nativeContains(cx, NameToId(name)));

View File

@ -125,7 +125,7 @@ Bindings::add(JSContext *cx, HandleAtom name, BindingKind kind)
id = AtomToId(name); id = AtomToId(name);
} }
StackBaseShape base(&CallClass, NULL, BaseShape::VAROBJ); StackBaseShape base(&CallClass, NULL, BaseShape::VAROBJ | BaseShape::DELEGATE);
base.updateGetterSetter(attrs, getter, setter); base.updateGetterSetter(attrs, getter, setter);
UnownedBaseShape *nbase = BaseShape::getUnowned(cx, base); UnownedBaseShape *nbase = BaseShape::getUnowned(cx, base);

View File

@ -65,7 +65,7 @@ Bindings::initialShape(JSContext *cx) const
JS_ASSERT(gc::GetGCKindSlots(kind) == CallObject::RESERVED_SLOTS); JS_ASSERT(gc::GetGCKindSlots(kind) == CallObject::RESERVED_SLOTS);
return EmptyShape::getInitialShape(cx, &CallClass, NULL, NULL, kind, return EmptyShape::getInitialShape(cx, &CallClass, NULL, NULL, kind,
BaseShape::VAROBJ); BaseShape::VAROBJ | BaseShape::DELEGATE);
} }
bool bool

View File

@ -245,6 +245,8 @@ GlobalObject::create(JSContext *cx, Class *clasp)
if (!obj->setSingletonType(cx) || !obj->setVarObj(cx)) if (!obj->setSingletonType(cx) || !obj->setVarObj(cx))
return NULL; return NULL;
if (!obj->setDelegate(cx))
return NULL;
/* Construct a regexp statics object for this global object. */ /* Construct a regexp statics object for this global object. */
JSObject *res = RegExpStatics::create(cx, obj); JSObject *res = RegExpStatics::create(cx, obj);

View File

@ -25,14 +25,12 @@ ScopeObject::enclosingScope() const
return getReservedSlot(SCOPE_CHAIN_SLOT).toObject(); return getReservedSlot(SCOPE_CHAIN_SLOT).toObject();
} }
inline bool inline void
ScopeObject::setEnclosingScope(JSContext *cx, HandleObject obj) ScopeObject::setEnclosingScope(HandleObject obj)
{ {
RootedObject self(cx, this); JS_ASSERT_IF(obj->isCall() || obj->isDeclEnv() || obj->isBlock(),
if (!obj->setDelegate(cx)) obj->isDelegate());
return false; setFixedSlot(SCOPE_CHAIN_SLOT, ObjectValue(*obj));
self->setFixedSlot(SCOPE_CHAIN_SLOT, ObjectValue(*obj));
return true;
} }
inline const Value & inline const Value &

View File

@ -107,9 +107,7 @@ CallObject::create(JSContext *cx, JSScript *script, HandleObject enclosing, Hand
return NULL; return NULL;
} }
if (!obj->asScope().setEnclosingScope(cx, enclosing)) obj->asScope().setEnclosingScope(enclosing);
return NULL;
obj->initFixedSlot(CALLEE_SLOT, ObjectOrNullValue(callee)); obj->initFixedSlot(CALLEE_SLOT, ObjectOrNullValue(callee));
/* /*
@ -121,6 +119,8 @@ CallObject::create(JSContext *cx, JSScript *script, HandleObject enclosing, Hand
return NULL; return NULL;
} }
JS_ASSERT(obj->isDelegate());
return &obj->asCall(); return &obj->asCall();
} }
@ -275,7 +275,8 @@ DeclEnvObject::create(JSContext *cx, StackFrame *fp)
RootedShape emptyDeclEnvShape(cx); RootedShape emptyDeclEnvShape(cx);
emptyDeclEnvShape = EmptyShape::getInitialShape(cx, &DeclEnvClass, NULL, emptyDeclEnvShape = EmptyShape::getInitialShape(cx, &DeclEnvClass, NULL,
&fp->global(), FINALIZE_KIND); &fp->global(), FINALIZE_KIND,
BaseShape::DELEGATE);
if (!emptyDeclEnvShape) if (!emptyDeclEnvShape)
return NULL; return NULL;
@ -283,9 +284,7 @@ DeclEnvObject::create(JSContext *cx, StackFrame *fp)
if (!obj) if (!obj)
return NULL; return NULL;
if (!obj->asScope().setEnclosingScope(cx, fp->scopeChain())) obj->asScope().setEnclosingScope(fp->scopeChain());
return NULL;
if (!DefineNativeProperty(cx, obj, RootedId(cx, AtomToId(fp->fun()->atom)), if (!DefineNativeProperty(cx, obj, RootedId(cx, AtomToId(fp->fun()->atom)),
ObjectValue(fp->callee()), NULL, NULL, ObjectValue(fp->callee()), NULL, NULL,
@ -315,9 +314,7 @@ WithObject::create(JSContext *cx, HandleObject proto, HandleObject enclosing, ui
if (!obj) if (!obj)
return NULL; return NULL;
if (!obj->asScope().setEnclosingScope(cx, enclosing)) obj->asScope().setEnclosingScope(enclosing);
return NULL;
obj->setReservedSlot(DEPTH_SLOT, PrivateUint32Value(depth)); obj->setReservedSlot(DEPTH_SLOT, PrivateUint32Value(depth));
JSObject *thisp = proto->thisObject(cx); JSObject *thisp = proto->thisObject(cx);
@ -595,6 +592,8 @@ ClonedBlockObject::create(JSContext *cx, Handle<StaticBlockObject *> block, Stac
obj->asClonedBlock().setVar(i, *src); obj->asClonedBlock().setVar(i, *src);
} }
JS_ASSERT(obj->isDelegate());
return &obj->asClonedBlock(); return &obj->asClonedBlock();
} }
@ -618,7 +617,8 @@ StaticBlockObject::create(JSContext *cx)
return NULL; return NULL;
RootedShape emptyBlockShape(cx); RootedShape emptyBlockShape(cx);
emptyBlockShape = EmptyShape::getInitialShape(cx, &BlockClass, NULL, NULL, FINALIZE_KIND); emptyBlockShape = EmptyShape::getInitialShape(cx, &BlockClass, NULL, NULL, FINALIZE_KIND,
BaseShape::DELEGATE);
if (!emptyBlockShape) if (!emptyBlockShape)
return NULL; return NULL;

View File

@ -99,7 +99,7 @@ class ScopeObject : public JSObject
* enclosing scope of a ScopeObject is necessarily non-null. * enclosing scope of a ScopeObject is necessarily non-null.
*/ */
inline JSObject &enclosingScope() const; inline JSObject &enclosingScope() const;
inline bool setEnclosingScope(JSContext *cx, HandleObject obj); inline void setEnclosingScope(HandleObject obj);
/* /*
* Get or set an aliased variable contained in this scope. Unaliased * Get or set an aliased variable contained in this scope. Unaliased
@ -168,7 +168,6 @@ class DeclEnvObject : public ScopeObject
static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT2; static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT2;
static DeclEnvObject *create(JSContext *cx, StackFrame *fp); static DeclEnvObject *create(JSContext *cx, StackFrame *fp);
}; };
class NestedScopeObject : public ScopeObject class NestedScopeObject : public ScopeObject