diff --git a/js/src/jspropertycache.cpp b/js/src/jspropertycache.cpp index dc10ec25621d..e5532809e85f 100644 --- a/js/src/jspropertycache.cpp +++ b/js/src/jspropertycache.cpp @@ -169,6 +169,7 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject */ pobj = obj; + JSObject *scopeObj = NULL; if (JOF_MODE(cs.format) == JOF_NAME) { uint8_t scopeIndex = entry->scopeIndex; while (scopeIndex > 0) { @@ -179,7 +180,7 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject scopeIndex--; } - *objp = pobj; + scopeObj = pobj; } uint8_t protoIndex = entry->protoIndex; @@ -192,6 +193,8 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject } if (pobj->lastProperty() == entry->pshape) { + if (JOF_MODE(cs.format) == JOF_NAME) + *objp = scopeObj; #ifdef DEBUG PropertyName *name = GetNameFromBytecode(cx, pc, op, cs); JS_ASSERT(pobj->nativeContains(cx, NameToId(name))); diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index a9228de50e36..63b31e8f74a4 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -125,7 +125,7 @@ Bindings::add(JSContext *cx, HandleAtom name, BindingKind kind) id = AtomToId(name); } - StackBaseShape base(&CallClass, NULL, BaseShape::VAROBJ); + StackBaseShape base(&CallClass, NULL, BaseShape::VAROBJ | BaseShape::DELEGATE); base.updateGetterSetter(attrs, getter, setter); UnownedBaseShape *nbase = BaseShape::getUnowned(cx, base); diff --git a/js/src/jsscriptinlines.h b/js/src/jsscriptinlines.h index b6fffb29942a..f79746f97def 100644 --- a/js/src/jsscriptinlines.h +++ b/js/src/jsscriptinlines.h @@ -65,7 +65,7 @@ Bindings::initialShape(JSContext *cx) const JS_ASSERT(gc::GetGCKindSlots(kind) == CallObject::RESERVED_SLOTS); return EmptyShape::getInitialShape(cx, &CallClass, NULL, NULL, kind, - BaseShape::VAROBJ); + BaseShape::VAROBJ | BaseShape::DELEGATE); } bool diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index 184e6e442b6a..f13d70750dcc 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -245,6 +245,8 @@ GlobalObject::create(JSContext *cx, Class *clasp) if (!obj->setSingletonType(cx) || !obj->setVarObj(cx)) return NULL; + if (!obj->setDelegate(cx)) + return NULL; /* Construct a regexp statics object for this global object. */ JSObject *res = RegExpStatics::create(cx, obj); diff --git a/js/src/vm/ScopeObject-inl.h b/js/src/vm/ScopeObject-inl.h index 48d923b93b24..eac97c99a1b5 100644 --- a/js/src/vm/ScopeObject-inl.h +++ b/js/src/vm/ScopeObject-inl.h @@ -25,14 +25,12 @@ ScopeObject::enclosingScope() const return getReservedSlot(SCOPE_CHAIN_SLOT).toObject(); } -inline bool -ScopeObject::setEnclosingScope(JSContext *cx, HandleObject obj) +inline void +ScopeObject::setEnclosingScope(HandleObject obj) { - RootedObject self(cx, this); - if (!obj->setDelegate(cx)) - return false; - self->setFixedSlot(SCOPE_CHAIN_SLOT, ObjectValue(*obj)); - return true; + JS_ASSERT_IF(obj->isCall() || obj->isDeclEnv() || obj->isBlock(), + obj->isDelegate()); + setFixedSlot(SCOPE_CHAIN_SLOT, ObjectValue(*obj)); } inline const Value & diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index c5d443717475..8422dd815cbe 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -107,9 +107,7 @@ CallObject::create(JSContext *cx, JSScript *script, HandleObject enclosing, Hand return NULL; } - if (!obj->asScope().setEnclosingScope(cx, enclosing)) - return NULL; - + obj->asScope().setEnclosingScope(enclosing); obj->initFixedSlot(CALLEE_SLOT, ObjectOrNullValue(callee)); /* @@ -121,6 +119,8 @@ CallObject::create(JSContext *cx, JSScript *script, HandleObject enclosing, Hand return NULL; } + JS_ASSERT(obj->isDelegate()); + return &obj->asCall(); } @@ -275,7 +275,8 @@ DeclEnvObject::create(JSContext *cx, StackFrame *fp) RootedShape emptyDeclEnvShape(cx); emptyDeclEnvShape = EmptyShape::getInitialShape(cx, &DeclEnvClass, NULL, - &fp->global(), FINALIZE_KIND); + &fp->global(), FINALIZE_KIND, + BaseShape::DELEGATE); if (!emptyDeclEnvShape) return NULL; @@ -283,9 +284,7 @@ DeclEnvObject::create(JSContext *cx, StackFrame *fp) if (!obj) return NULL; - if (!obj->asScope().setEnclosingScope(cx, fp->scopeChain())) - return NULL; - + obj->asScope().setEnclosingScope(fp->scopeChain()); if (!DefineNativeProperty(cx, obj, RootedId(cx, AtomToId(fp->fun()->atom)), ObjectValue(fp->callee()), NULL, NULL, @@ -315,9 +314,7 @@ WithObject::create(JSContext *cx, HandleObject proto, HandleObject enclosing, ui if (!obj) return NULL; - if (!obj->asScope().setEnclosingScope(cx, enclosing)) - return NULL; - + obj->asScope().setEnclosingScope(enclosing); obj->setReservedSlot(DEPTH_SLOT, PrivateUint32Value(depth)); JSObject *thisp = proto->thisObject(cx); @@ -595,6 +592,8 @@ ClonedBlockObject::create(JSContext *cx, Handle block, Stac obj->asClonedBlock().setVar(i, *src); } + JS_ASSERT(obj->isDelegate()); + return &obj->asClonedBlock(); } @@ -618,7 +617,8 @@ StaticBlockObject::create(JSContext *cx) return NULL; 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) return NULL; diff --git a/js/src/vm/ScopeObject.h b/js/src/vm/ScopeObject.h index b90fa0081971..91f9ef3a18a9 100644 --- a/js/src/vm/ScopeObject.h +++ b/js/src/vm/ScopeObject.h @@ -99,7 +99,7 @@ class ScopeObject : public JSObject * enclosing scope of a ScopeObject is necessarily non-null. */ 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 @@ -168,7 +168,6 @@ class DeclEnvObject : public ScopeObject static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT2; static DeclEnvObject *create(JSContext *cx, StackFrame *fp); - }; class NestedScopeObject : public ScopeObject