Bug 761391 - Add some more exact stack rooters; r=bhackett

Another bevy of missing roots brought about by recent churn.
This commit is contained in:
Terrence Cole 2012-06-05 16:52:41 -07:00
parent 104dbfc7b6
commit bc6b6320e6
18 changed files with 69 additions and 55 deletions

View File

@ -122,6 +122,7 @@ class Handle
typedef Handle<JSObject*> HandleObject;
typedef Handle<JSFunction*> HandleFunction;
typedef Handle<JSScript*> HandleScript;
typedef Handle<JSString*> HandleString;
typedef Handle<jsid> HandleId;
typedef Handle<Value> HandleValue;
@ -224,6 +225,7 @@ Handle<T>::Handle(const Rooted<S> &root)
typedef Rooted<JSObject*> RootedObject;
typedef Rooted<JSFunction*> RootedFunction;
typedef Rooted<JSScript*> RootedScript;
typedef Rooted<JSString*> RootedString;
typedef Rooted<jsid> RootedId;
typedef Rooted<Value> RootedValue;

View File

@ -5301,7 +5301,8 @@ JS_ExecuteScript(JSContext *cx, JSObject *obj, JSScript *scriptArg, jsval *rval)
* mozilla, but there doesn't seem to be one, so we handle it here.
*/
if (scriptArg->compartment() != obj->compartment()) {
script = CloneScript(cx, scriptArg);
RootedScript scriptArgRoot(cx, scriptArg);
script = CloneScript(cx, scriptArgRoot);
if (!script.get())
return false;
} else {

View File

@ -426,7 +426,7 @@ js::CloneInterpretedFunction(JSContext *cx, JSFunction *srcFun)
if (!clone->clearType(cx))
return NULL;
JSScript *clonedScript = CloneScript(cx, srcFun->script());
JSScript *clonedScript = CloneScript(cx, RootedScript(cx, srcFun->script()));
if (!clonedScript)
return NULL;
@ -1295,7 +1295,7 @@ js_CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
* functions.
*/
if (clone->isInterpreted()) {
JSScript *script = clone->script();
RootedScript script(cx, clone->script());
JS_ASSERT(script);
JS_ASSERT(script->compartment() == fun->compartment());
JS_ASSERT(script->compartment() != cx->compartment);

View File

@ -5508,15 +5508,18 @@ JSObject::shouldSplicePrototype(JSContext *cx)
}
bool
JSObject::splicePrototype(JSContext *cx, JSObject *proto)
JSObject::splicePrototype(JSContext *cx, JSObject *proto_)
{
RootedObject proto(cx, proto_);
RootedObject self(cx, this);
/*
* For singleton types representing only a single JSObject, the proto
* can be rearranged as needed without destroying type information for
* the old or new types. Note that type constraints propagating properties
* from the old prototype are not removed.
*/
JS_ASSERT_IF(cx->typeInferenceEnabled(), hasSingletonType());
JS_ASSERT_IF(cx->typeInferenceEnabled(), self->hasSingletonType());
/* Inner objects may not appear on prototype chains. */
JS_ASSERT_IF(proto, !proto->getClass()->ext.outerObject);
@ -5525,7 +5528,7 @@ JSObject::splicePrototype(JSContext *cx, JSObject *proto)
* Force type instantiation when splicing lazy types. This may fail,
* in which case inference will be disabled for the compartment.
*/
TypeObject *type = getType(cx);
TypeObject *type = self->getType(cx);
TypeObject *protoType = NULL;
if (proto) {
protoType = proto->getType(cx);
@ -5537,7 +5540,7 @@ JSObject::splicePrototype(JSContext *cx, JSObject *proto)
TypeObject *type = proto ? proto->getNewType(cx) : cx->compartment->getEmptyType(cx);
if (!type)
return false;
type_ = type;
self->type_ = type;
return true;
}

View File

@ -2329,11 +2329,11 @@ BEGIN_CASE(JSOP_GETXPROP)
BEGIN_CASE(JSOP_LENGTH)
BEGIN_CASE(JSOP_CALLPROP)
{
Value rval;
if (!GetPropertyOperation(cx, regs.pc, regs.sp[-1], &rval))
RootedValue rval(cx);
if (!GetPropertyOperation(cx, regs.pc, regs.sp[-1], rval.address()))
goto error;
TypeScript::Monitor(cx, script, regs.pc, rval);
TypeScript::Monitor(cx, script, regs.pc, rval.reference());
regs.sp[-1] = rval;
assertSameCompartment(cx, regs.sp[-1]);

View File

@ -287,9 +287,9 @@ SetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, const Val
/* Fast path for, e.g., plain Object instance properties. */
obj->nativeSetSlotWithType(cx, shape, rval);
} else {
Value rref = rval;
RootedValue rref(cx, rval);
bool strict = cx->stack.currentScript()->strictModeCode;
if (!js_NativeSet(cx, obj, shape, false, strict, &rref))
if (!js_NativeSet(cx, obj, shape, false, strict, rref.address()))
return false;
}
return true;

View File

@ -1930,7 +1930,7 @@ DefinePropertyOnObject(JSContext *cx, HandleObject obj, HandleId id, const PropD
JS_ASSERT(obj == obj2);
const Shape *shape = reinterpret_cast<Shape *>(current);
Rooted<const Shape *> shape(cx, reinterpret_cast<Shape *>(current));
do {
if (desc.isAccessorDescriptor()) {
if (!shape->isAccessorDescriptor())
@ -4972,7 +4972,7 @@ js_NativeSet(JSContext *cx, JSObject *obj, const Shape *shape, bool added, bool
Rooted<const Shape *> shapeRoot(cx, shape);
int32_t sample = cx->runtime->propertyRemovals;
if (!shape->set(cx, RootedObject(cx, obj), strict, vp))
if (!shapeRoot->set(cx, RootedObject(cx, obj), strict, vp))
return false;
/*

View File

@ -965,7 +965,7 @@ JSObject::replaceWithNewEquivalentShape(JSContext *cx, Shape *oldShape, Shape *n
RootedShape newRoot(cx, newShape);
if (!toDictionaryMode(cx))
return NULL;
oldShape = self->lastProperty();
oldShape = selfRoot->lastProperty();
self = selfRoot;
newShape = newRoot;
}
@ -976,7 +976,7 @@ JSObject::replaceWithNewEquivalentShape(JSContext *cx, Shape *oldShape, Shape *n
newShape = js_NewGCShape(cx);
if (!newShape)
return NULL;
new (newShape) Shape(oldShape->base()->unowned(), 0);
new (newShape) Shape(oldRoot->base()->unowned(), 0);
self = selfRoot;
oldShape = oldRoot;
}
@ -1315,7 +1315,7 @@ EmptyShape::getInitialShape(JSContext *cx, Class *clasp, JSObject *proto, JSObje
}
void
NewObjectCache::invalidateEntriesForShape(JSContext *cx, Shape *shape, JSObject *proto)
NewObjectCache::invalidateEntriesForShape(JSContext *cx, Shape *shape, JSObject *proto_)
{
Class *clasp = shape->getObjectClass();
@ -1323,7 +1323,8 @@ NewObjectCache::invalidateEntriesForShape(JSContext *cx, Shape *shape, JSObject
if (CanBeFinalizedInBackground(kind, clasp))
kind = GetBackgroundAllocKind(kind);
GlobalObject *global = &shape->getObjectParent()->global();
Rooted<GlobalObject *> global(cx, &shape->getObjectParent()->global());
RootedObject proto(cx, proto_);
types::TypeObject *type = proto->getNewType(cx);
EntryIndex entry;

View File

@ -1110,8 +1110,8 @@ Shape::search(JSContext *cx, Shape *start, jsid id, Shape ***pspp, bool adding)
if (start->isBigEnoughForAShapeTable()) {
RootedShape startRoot(cx, start);
RootedId idRoot(cx, id);
if (start->hashify(cx)) {
Shape **spp = start->table().search(id, adding);
if (startRoot->hashify(cx)) {
Shape **spp = startRoot->table().search(id, adding);
return SHAPE_FETCH(spp);
}
start = startRoot;

View File

@ -259,7 +259,7 @@ Shape::getUserId(JSContext *cx, jsid *idp) const
return ValueToId(cx, Int32Value(id), idp);
*idp = INT_TO_JSID(id);
} else {
*idp = propid();
*idp = self->propid();
}
return true;
}
@ -274,11 +274,12 @@ Shape::get(JSContext* cx, HandleObject receiver, JSObject* obj, JSObject *pobj,
return InvokeGetterOrSetter(cx, receiver, fval, 0, 0, vp);
}
Rooted<const Shape *> self(cx, this);
RootedId id(cx);
if (!getUserId(cx, id.address()))
if (!self->getUserId(cx, id.address()))
return false;
return CallJSPropertyOp(cx, getterOp(), receiver, id, vp);
return CallJSPropertyOp(cx, self->getterOp(), receiver, id, vp);
}
inline bool
@ -294,8 +295,9 @@ Shape::set(JSContext* cx, HandleObject obj, bool strict, Value* vp) const
if (attrs & JSPROP_GETTER)
return js_ReportGetterOnlyAssignment(cx);
Rooted<const Shape *> self(cx, this);
RootedId id(cx);
if (!getUserId(cx, id.address()))
if (!self->getUserId(cx, id.address()))
return false;
/*
@ -304,10 +306,10 @@ Shape::set(JSContext* cx, HandleObject obj, bool strict, Value* vp) const
*/
if (obj->isWith()) {
RootedObject nobj(cx, &obj->asWith().object());
return CallJSPropertyOpSetter(cx, setterOp(), nobj, id, strict, vp);
return CallJSPropertyOpSetter(cx, self->setterOp(), nobj, id, strict, vp);
}
return CallJSPropertyOpSetter(cx, setterOp(), obj, id, strict, vp);
return CallJSPropertyOpSetter(cx, self->setterOp(), obj, id, strict, vp);
}
inline void

View File

@ -1684,7 +1684,7 @@ Rebase(JSScript *dst, JSScript *src, T *srcp)
}
JSScript *
js::CloneScript(JSContext *cx, JSScript *src)
js::CloneScript(JSContext *cx, HandleScript src)
{
/* NB: Keep this in sync with XDRScript. */
@ -1707,6 +1707,7 @@ js::CloneScript(JSContext *cx, JSScript *src)
/* Bindings */
Bindings bindings(cx);
Bindings::AutoRooter bindingsRoot(cx, &bindings);
BindingNames names(cx);
if (!src->bindings.getLocalNameArray(cx, &names))
return NULL;

View File

@ -1050,7 +1050,7 @@ inline void
CurrentScriptFileLineOrigin(JSContext *cx, unsigned *linenop, LineOption = NOT_CALLED_FROM_JSOP_EVAL);
extern JSScript *
CloneScript(JSContext *cx, JSScript *script);
CloneScript(JSContext *cx, HandleScript script);
/*
* NB: after a successful XDR_DECODE, XDRScript callers must do any required

View File

@ -1422,14 +1422,14 @@ class TypedArrayTemplate
obj->setSlot(FIELD_BUFFER, ObjectValue(*bufobj));
JS_ASSERT(bufobj->isArrayBuffer());
ArrayBufferObject &buffer = bufobj->asArrayBuffer();
Rooted<ArrayBufferObject *> buffer(cx, &bufobj->asArrayBuffer());
/*
* N.B. The base of the array's data is stored in the object's
* private data rather than a slot, to avoid alignment restrictions
* on private Values.
*/
obj->setPrivate(buffer.dataPointer() + byteOffset);
obj->setPrivate(buffer->dataPointer() + byteOffset);
obj->setSlot(FIELD_LENGTH, Int32Value(len));
obj->setSlot(FIELD_BYTEOFFSET, Int32Value(byteOffset));
@ -1445,10 +1445,10 @@ class TypedArrayTemplate
return NULL;
obj->setLastPropertyInfallible(empty);
DebugOnly<uint32_t> bufferByteLength = buffer.byteLength();
DebugOnly<uint32_t> bufferByteLength = buffer->byteLength();
JS_ASSERT(bufferByteLength - getByteOffset(obj) >= getByteLength(obj));
JS_ASSERT(getByteOffset(obj) <= bufferByteLength);
JS_ASSERT(buffer.dataPointer() <= getDataOffset(obj));
JS_ASSERT(buffer->dataPointer() <= getDataOffset(obj));
JS_ASSERT(getDataOffset(obj) <= offsetData(obj, bufferByteLength));
JS_ASSERT(obj->numFixedSlots() == NUM_FIXED_SLOTS);

View File

@ -2143,7 +2143,7 @@ DumpStack(JSContext *cx, unsigned argc, Value *vp)
uint32_t index = 0;
for (; !iter.done(); ++index, ++iter) {
Value v;
RootedValue v(cx);
if (iter.isNonEvalFunctionFrame() || iter.isNativeCall()) {
v = iter.calleev();
} else if (iter.isEvalFrame()) {
@ -2151,9 +2151,9 @@ DumpStack(JSContext *cx, unsigned argc, Value *vp)
} else {
v = StringValue(globalStr);
}
if (!JS_WrapValue(cx, &v))
if (!JS_WrapValue(cx, v.address()))
return false;
if (!JS_SetElement(cx, arr, index, &v))
if (!JS_SetElement(cx, arr, index, v.address()))
return false;
}

View File

@ -941,7 +941,7 @@ Debugger::fireEnterFrame(JSContext *cx, Value *vp)
}
void
Debugger::fireNewScript(JSContext *cx, Handle<JSScript*> script)
Debugger::fireNewScript(JSContext *cx, HandleScript script)
{
RootedObject hook(cx, getHook(OnNewScript));
JS_ASSERT(hook);
@ -2376,7 +2376,7 @@ Class DebuggerScript_class = {
};
JSObject *
Debugger::newDebuggerScript(JSContext *cx, Handle<JSScript*> script)
Debugger::newDebuggerScript(JSContext *cx, HandleScript script)
{
assertSameCompartment(cx, object.get());
@ -2392,7 +2392,7 @@ Debugger::newDebuggerScript(JSContext *cx, Handle<JSScript*> script)
}
JSObject *
Debugger::wrapScript(JSContext *cx, Handle<JSScript*> script)
Debugger::wrapScript(JSContext *cx, HandleScript script)
{
assertSameCompartment(cx, object.get());
JS_ASSERT(cx->compartment != script->compartment());
@ -4396,7 +4396,7 @@ DebuggerEnv_getVariable(JSContext *cx, unsigned argc, Value *vp)
if (!ValueToIdentifier(cx, args[0], id.address()))
return false;
Value v;
RootedValue v(cx);
{
AutoCompartment ac(cx, env);
if (!ac.enter() || !cx->compartment->wrapId(cx, id.address()))
@ -4404,11 +4404,11 @@ DebuggerEnv_getVariable(JSContext *cx, unsigned argc, Value *vp)
/* This can trigger getters. */
ErrorCopier ec(ac, dbg->toJSObject());
if (!env->getGeneric(cx, id, &v))
if (!env->getGeneric(cx, id, v.address()))
return false;
}
if (!dbg->wrapDebuggeeValue(cx, &v))
if (!dbg->wrapDebuggeeValue(cx, v.address()))
return false;
args.rval() = v;
return true;

View File

@ -190,13 +190,13 @@ class Debugger {
* Allocate and initialize a Debugger.Script instance whose referent is
* |script|.
*/
JSObject *newDebuggerScript(JSContext *cx, Handle<JSScript*> script);
JSObject *newDebuggerScript(JSContext *cx, HandleScript script);
/*
* Receive a "new script" event from the engine. A new script was compiled
* or deserialized.
*/
void fireNewScript(JSContext *cx, Handle<JSScript*> script);
void fireNewScript(JSContext *cx, HandleScript script);
static inline Debugger *fromLinks(JSCList *links);
inline Breakpoint *firstBreakpoint() const;
@ -337,7 +337,7 @@ class Debugger {
* needed. The context |cx| must be in the debugger compartment; |script|
* must be a script in a debuggee compartment.
*/
JSObject *wrapScript(JSContext *cx, Handle<JSScript*> script);
JSObject *wrapScript(JSContext *cx, HandleScript script);
private:
Debugger(const Debugger &) MOZ_DELETE;

View File

@ -1369,7 +1369,7 @@ int DebugScopeProxy::family = 0;
DebugScopeProxy DebugScopeProxy::singleton;
/* static */ DebugScopeObject *
DebugScopeObject::create(JSContext *cx, ScopeObject &scope, JSObject &enclosing)
DebugScopeObject::create(JSContext *cx, ScopeObject &scope, HandleObject enclosing)
{
JSObject *obj = NewProxyObject(cx, &DebugScopeProxy::singleton, ObjectValue(scope),
NULL /* proto */, &scope.global(),
@ -1377,8 +1377,8 @@ DebugScopeObject::create(JSContext *cx, ScopeObject &scope, JSObject &enclosing)
if (!obj)
return NULL;
JS_ASSERT(!enclosing.isScope());
SetProxyExtra(obj, ENCLOSING_EXTRA, ObjectValue(enclosing));
JS_ASSERT(!enclosing->isScope());
SetProxyExtra(obj, ENCLOSING_EXTRA, ObjectValue(*enclosing.value()));
return &obj->asDebugScope();
}
@ -1729,19 +1729,19 @@ GetDebugScopeForScope(JSContext *cx, ScopeObject &scope, ScopeIter enclosing)
if (DebugScopeObject *debugScope = debugScopes.hasDebugScope(cx, scope))
return debugScope;
JSObject *enclosingDebug = GetDebugScope(cx, enclosing);
RootedObject enclosingDebug(cx, GetDebugScope(cx, enclosing));
if (!enclosingDebug)
return NULL;
JSObject &maybeDecl = scope.enclosingScope();
if (maybeDecl.isDeclEnv()) {
JS_ASSERT(CallObjectLambdaName(scope.asCall().getCalleeFunction()));
enclosingDebug = DebugScopeObject::create(cx, maybeDecl.asDeclEnv(), *enclosingDebug);
enclosingDebug = DebugScopeObject::create(cx, maybeDecl.asDeclEnv(), enclosingDebug);
if (!enclosingDebug)
return NULL;
}
DebugScopeObject *debugScope = DebugScopeObject::create(cx, scope, *enclosingDebug);
DebugScopeObject *debugScope = DebugScopeObject::create(cx, scope, enclosingDebug);
if (!debugScope)
return NULL;
@ -1754,11 +1754,13 @@ GetDebugScopeForScope(JSContext *cx, ScopeObject &scope, ScopeIter enclosing)
static DebugScopeObject *
GetDebugScopeForMissing(JSContext *cx, ScopeIter si)
{
SkipRoot si_(cx, &si);
DebugScopes &debugScopes = *cx->runtime->debugScopes;
if (DebugScopeObject *debugScope = debugScopes.hasDebugScope(cx, si))
return debugScope;
JSObject *enclosingDebug = GetDebugScope(cx, si.enclosing());
RootedObject enclosingDebug(cx, GetDebugScope(cx, si.enclosing()));
if (!enclosingDebug)
return NULL;
@ -1778,12 +1780,12 @@ GetDebugScopeForMissing(JSContext *cx, ScopeIter si)
if (callobj->enclosingScope().isDeclEnv()) {
JS_ASSERT(CallObjectLambdaName(callobj->getCalleeFunction()));
DeclEnvObject &declenv = callobj->enclosingScope().asDeclEnv();
enclosingDebug = DebugScopeObject::create(cx, declenv, *enclosingDebug);
enclosingDebug = DebugScopeObject::create(cx, declenv, enclosingDebug);
if (!enclosingDebug)
return NULL;
}
debugScope = DebugScopeObject::create(cx, *callobj, *enclosingDebug);
debugScope = DebugScopeObject::create(cx, *callobj, enclosingDebug);
break;
}
case ScopeIter::Block: {
@ -1792,7 +1794,7 @@ GetDebugScopeForMissing(JSContext *cx, ScopeIter si)
if (!block)
return NULL;
debugScope = DebugScopeObject::create(cx, *block, *enclosingDebug);
debugScope = DebugScopeObject::create(cx, *block, enclosingDebug);
break;
}
case ScopeIter::With:

View File

@ -12,6 +12,8 @@
#include "jsobj.h"
#include "jsweakmap.h"
#include "gc/Barrier.h"
namespace js {
/*****************************************************************************/
@ -402,7 +404,7 @@ class DebugScopeObject : public JSObject
static const unsigned ENCLOSING_EXTRA = 0;
public:
static DebugScopeObject *create(JSContext *cx, ScopeObject &scope, JSObject &enclosing);
static DebugScopeObject *create(JSContext *cx, ScopeObject &scope, HandleObject enclosing);
ScopeObject &scope() const;
JSObject &enclosingScope() const;