Bug 833396 - Fix some rooting issues found by static analysis r=sphink

This commit is contained in:
Jon Coppeard 2013-01-21 17:41:49 +00:00
parent a11603147d
commit 8183eae08b
12 changed files with 89 additions and 78 deletions

View File

@ -86,8 +86,8 @@ js::ScriptDebugPrologue(JSContext *cx, AbstractFramePtr frame)
cx->runtime->debugHooks.callHookData));
}
Value rval;
JSTrapStatus status = Debugger::onEnterFrame(cx, &rval);
RootedValue rval(cx);
JSTrapStatus status = Debugger::onEnterFrame(cx, rval.address());
switch (status) {
case JSTRAP_CONTINUE:
break;
@ -206,9 +206,11 @@ CheckDebugMode(JSContext *cx)
}
JS_PUBLIC_API(JSBool)
JS_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep)
JS_SetSingleStepMode(JSContext *cx, JSScript *scriptArg, JSBool singleStep)
{
RootedScript script(cx, scriptArg);
assertSameCompartment(cx, script);
if (!CheckDebugMode(cx))
return JS_FALSE;
@ -216,8 +218,10 @@ JS_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep)
}
JS_PUBLIC_API(JSBool)
JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc, JSTrapHandler handler, jsval closure)
JS_SetTrap(JSContext *cx, JSScript *scriptArg, jsbytecode *pc, JSTrapHandler handler, jsval closureArg)
{
RootedScript script(cx, scriptArg);
RootedValue closure(cx, closureArg);
assertSameCompartment(cx, script, closure);
if (!CheckDebugMode(cx))
@ -286,10 +290,8 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj_, jsid id,
{
assertSameCompartment(cx, obj_);
RootedObject obj(cx, obj_), closure(cx, closure_);
JSObject *origobj = obj;
obj = GetInnerObject(cx, obj);
RootedObject origobj(cx, obj_), closure(cx, closure_);
RootedObject obj(cx, GetInnerObject(cx, origobj));
if (!obj)
return false;
@ -831,7 +833,7 @@ GetPropertyDesc(JSContext *cx, JSObject *obj_, HandleShape shape, JSPropertyDesc
RootedObject obj(cx, obj_);
JSBool wasThrowing = cx->isExceptionPending();
Value lastException = UndefinedValue();
RootedValue lastException(cx, UndefinedValue());
if (wasThrowing)
lastException = cx->getPendingException();
cx->clearPendingException();
@ -918,22 +920,29 @@ JS_GetPropertyDescArray(JSContext *cx, JSObject *obj_, JSPropertyDescArray *pda)
pd = cx->pod_malloc<JSPropertyDesc>(obj->propertyCount());
if (!pd)
return false;
for (Shape::Range r = obj->lastProperty()->all(); !r.empty(); r.popFront()) {
pd[i].id = JSVAL_NULL;
pd[i].value = JSVAL_NULL;
pd[i].alias = JSVAL_NULL;
if (!js_AddRoot(cx, &pd[i].id, NULL))
goto bad;
if (!js_AddRoot(cx, &pd[i].value, NULL))
goto bad;
RootedShape shape(cx, const_cast<Shape *>(&r.front()));
if (!GetPropertyDesc(cx, obj, shape, &pd[i]))
goto bad;
if ((pd[i].flags & JSPD_ALIAS) && !js_AddRoot(cx, &pd[i].alias, NULL))
goto bad;
if (++i == obj->propertyCount())
break;
{
Shape::Range r(obj->lastProperty()->all());
Shape::Range::AutoRooter rooter(cx, &r);
RootedShape shape(cx);
for (; !r.empty(); r.popFront()) {
pd[i].id = JSVAL_NULL;
pd[i].value = JSVAL_NULL;
pd[i].alias = JSVAL_NULL;
if (!js_AddRoot(cx, &pd[i].id, NULL))
goto bad;
if (!js_AddRoot(cx, &pd[i].value, NULL))
goto bad;
shape = const_cast<Shape *>(&r.front());
if (!GetPropertyDesc(cx, obj, shape, &pd[i]))
goto bad;
if ((pd[i].flags & JSPD_ALIAS) && !js_AddRoot(cx, &pd[i].alias, NULL))
goto bad;
if (++i == obj->propertyCount())
break;
}
}
pda->length = i;
pda->array = pd;
return true;

View File

@ -824,7 +824,7 @@ fun_toSource(JSContext *cx, unsigned argc, Value *vp)
JSBool
js_fun_call(JSContext *cx, unsigned argc, Value *vp)
{
Value fval = vp[1];
RootedValue fval(cx, vp[1]);
if (!js_IsCallable(fval)) {
ReportIncompatibleMethod(cx, CallReceiverFromVp(vp), &FunctionClass);
@ -832,10 +832,8 @@ js_fun_call(JSContext *cx, unsigned argc, Value *vp)
}
Value *argv = vp + 2;
Value thisv;
if (argc == 0) {
thisv.setUndefined();
} else {
RootedValue thisv(cx, UndefinedValue());
if (argc != 0) {
thisv = argv[0];
argc--;
@ -1061,7 +1059,7 @@ JSFunction::initializeLazyScript(JSContext *cx)
JSBool
js::CallOrConstructBoundFunction(JSContext *cx, unsigned argc, Value *vp)
{
JSFunction *fun = vp[0].toObject().toFunction();
RootedFunction fun(cx, vp[0].toObject().toFunction());
JS_ASSERT(fun->isBoundFunction());
bool constructing = IsConstructing(vp);
@ -1380,8 +1378,6 @@ js::Function(JSContext *cx, unsigned argc, Value *vp)
}
#endif
JS::Anchor<JSString *> strAnchor(NULL);
RootedString str(cx);
if (!args.length())
str = cx->runtime->emptyString;
@ -1392,7 +1388,8 @@ js::Function(JSContext *cx, unsigned argc, Value *vp)
JSStableString *stable = str->ensureStable(cx);
if (!stable)
return false;
strAnchor.set(str);
JS::Anchor<JSString *> strAnchor(str);
StableCharPtr chars = stable->chars();
size_t length = stable->length();
@ -1571,7 +1568,7 @@ js_DefineFunction(JSContext *cx, HandleObject obj, HandleId id, Native native,
void
js::ReportIncompatibleMethod(JSContext *cx, CallReceiver call, Class *clasp)
{
Value thisv = call.thisv();
RootedValue thisv(cx, call.thisv());
#ifdef DEBUG
if (thisv.isObject()) {

View File

@ -1050,8 +1050,8 @@ GetSingletonPropertyType(JSContext *cx, RawObject rawObjArg, HandleId id)
if (!obj->isNative())
return Type::UnknownType();
Value v;
if (HasDataProperty(cx, obj, id, &v)) {
RootedValue v(cx);
if (HasDataProperty(cx, obj, id, v.address())) {
if (v.isUndefined())
return Type::UnknownType();
return GetValueType(cx, v);
@ -2404,7 +2404,6 @@ TypeCompartment::addAllocationSiteTypeObject(JSContext *cx, AllocationSiteKey ke
if (!js_GetClassPrototype(cx, key.kind, &proto, NULL))
return NULL;
RootedScript keyScript(cx, key.script);
Rooted<TaggedProto> tagged(cx, TaggedProto(proto));
res = newTypeObject(cx, GetClassForProtoKey(key.kind), tagged);
if (!res) {

View File

@ -55,6 +55,8 @@ using namespace js::gc;
using mozilla::ArrayLength;
typedef Rooted<PropertyIteratorObject*> RootedPropertyIteratorObject;
static const gc::AllocKind ITERATOR_FINALIZE_KIND = gc::FINALIZE_OBJECT2;
void
@ -1074,7 +1076,7 @@ template<typename StringPredicate>
static bool
SuppressDeletedPropertyHelper(JSContext *cx, HandleObject obj, StringPredicate predicate)
{
PropertyIteratorObject *iterobj = cx->enumerators;
RootedPropertyIteratorObject iterobj(cx, cx->enumerators);
while (iterobj) {
again:
NativeIterator *ni = iterobj->getNativeIterator();
@ -1561,7 +1563,7 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, HandleObject obj,
gen->regs = cx->regs();
cx->enterGenerator(gen); /* OOM check above. */
PropertyIteratorObject *enumerators = cx->enumerators;
RootedPropertyIteratorObject enumerators(cx, cx->enumerators);
cx->enumerators = gen->enumerators;
RootedScript script(cx, fp->script());

View File

@ -1062,6 +1062,7 @@ JSObject::sealOrFreeze(JSContext *cx, HandleObject obj, ImmutabilityType it)
for (size_t i = 0; i < shapes.length(); i++) {
StackShape child(shapes[i]);
StackShape::AutoRooter rooter(cx, &child);
child.attrs |= getSealedOrFrozenAttributes(child.attrs, it);
if (!JSID_IS_EMPTY(child.propid))
@ -1591,9 +1592,10 @@ JSObject::deleteByValue(JSContext *cx, HandleObject obj,
}
JS_FRIEND_API(bool)
JS_CopyPropertiesFrom(JSContext *cx, JSObject *targetArg, JSObject *obj)
JS_CopyPropertiesFrom(JSContext *cx, JSObject *targetArg, JSObject *objArg)
{
RootedObject target(cx, targetArg);
RootedObject obj(cx, objArg);
// If we're not native, then we cannot copy properties.
JS_ASSERT(target->isNative() == obj->isNative());
@ -1631,7 +1633,7 @@ JS_CopyPropertiesFrom(JSContext *cx, JSObject *targetArg, JSObject *obj)
}
static bool
CopySlots(JSContext *cx, JSObject *from, JSObject *to)
CopySlots(JSContext *cx, HandleObject from, HandleObject to)
{
JS_ASSERT(!from->isNative() && !to->isNative());
JS_ASSERT(from->getClass() == to->getClass());
@ -1663,8 +1665,8 @@ js::CloneObject(JSContext *cx, HandleObject obj, Handle<js::TaggedProto> proto,
JSMSG_CANT_CLONE_OBJECT);
return NULL;
}
JSObject *clone = NewObjectWithGivenProto(cx, obj->getClass(),
proto, parent, obj->getAllocKind());
RootedObject clone(cx, NewObjectWithGivenProto(cx, obj->getClass(),
proto, parent, obj->getAllocKind()));
if (!clone)
return NULL;
if (obj->isNative()) {
@ -1721,9 +1723,11 @@ struct JSObject::TradeGutsReserved {
};
bool
JSObject::ReserveForTradeGuts(JSContext *cx, JSObject *a, JSObject *b,
JSObject::ReserveForTradeGuts(JSContext *cx, JSObject *aArg, JSObject *bArg,
TradeGutsReserved &reserved)
{
RootedObject a(cx, aArg);
RootedObject b(cx, bArg);
AssertCanGC();
JS_ASSERT(a->compartment() == b->compartment());
AutoCompartment ac(cx, a);
@ -1751,15 +1755,13 @@ JSObject::ReserveForTradeGuts(JSContext *cx, JSObject *a, JSObject *b,
* Swap prototypes and classes on the two objects, so that TradeGuts can
* preserve the types of the two objects.
*/
RootedObject na(cx, a);
RootedObject nb(cx, b);
Class *aClass = a->getClass();
Class *bClass = b->getClass();
Rooted<TaggedProto> aProto(cx, a->getTaggedProto());
Rooted<TaggedProto> bProto(cx, b->getTaggedProto());
if (!SetClassAndProto(cx, na, bClass, bProto, false))
if (!SetClassAndProto(cx, a, bClass, bProto, false))
return false;
if (!SetClassAndProto(cx, nb, aClass, aProto, false))
if (!SetClassAndProto(cx, b, aClass, aProto, false))
return false;
if (a->sizeOfThis() == b->sizeOfThis())

View File

@ -810,11 +810,11 @@ class JSObject : public js::ObjectImpl
/* Change the given property into a sibling with the same id in this scope. */
static js::UnrootedShape changeProperty(JSContext *cx, js::HandleObject obj,
js::RawShape shape, unsigned attrs, unsigned mask,
js::HandleShape shape, unsigned attrs, unsigned mask,
JSPropertyOp getter, JSStrictPropertyOp setter);
static inline bool changePropertyAttributes(JSContext *cx, js::HandleObject obj,
js::Shape *shape, unsigned attrs);
js::HandleShape shape, unsigned attrs);
/* Remove the property named by id from this object. */
bool removeProperty(JSContext *cx, jsid id);

View File

@ -157,7 +157,7 @@ JSObject::setSpecialAttributes(JSContext *cx, js::HandleObject obj,
/* static */ inline bool
JSObject::changePropertyAttributes(JSContext *cx, js::HandleObject obj,
js::Shape *shape, unsigned attrs)
js::HandleShape shape, unsigned attrs)
{
return !!changeProperty(cx, obj, shape, attrs, 0, shape->getter(), shape->setter());
}

View File

@ -682,13 +682,13 @@ js_Stringify(JSContext *cx, MutableHandleValue vp, JSObject *replacer_, Value sp
/* Step 5. */
if (space.isObject()) {
JSObject &spaceObj = space.toObject();
if (ObjectClassIs(spaceObj, ESClass_Number, cx)) {
RootedObject spaceObj(cx, &space.toObject());
if (ObjectClassIs(*spaceObj, ESClass_Number, cx)) {
double d;
if (!ToNumber(cx, space, &d))
return false;
space = NumberValue(d);
} else if (ObjectClassIs(spaceObj, ESClass_String, cx)) {
} else if (ObjectClassIs(*spaceObj, ESClass_String, cx)) {
JSString *str = ToStringSlow(cx, space);
if (!str)
return false;

View File

@ -1683,12 +1683,12 @@ DecompileSwitch(SprintStack *ss, TableEntry *table, unsigned tableLength,
ptrdiff_t off, off2, diff, caseExprOff, todo;
const char *rval;
unsigned i;
jsval key;
JSString *str;
cx = ss->sprinter.context;
jp = ss->printer;
RootedValue key(cx);
jsbytecode *lvalpc;
const char *lval = PopStr(ss, JSOP_NOP, &lvalpc);
@ -2610,7 +2610,7 @@ InitSprintStack(JSContext *cx, SprintStack *ss, JSPrinter *jp, unsigned depth)
static jsbytecode *
Decompile(SprintStack *ss, jsbytecode *pc, int nb)
{
JSContext *cx;
JSContext *cx = ss->sprinter.context;
JSPrinter *jp, *jp2;
jsbytecode *startpc, *endpc, *pc2, *done, *lvalpc, *rvalpc, *xvalpc;
ptrdiff_t tail, todo, len, oplen, cond, next;
@ -2620,9 +2620,9 @@ Decompile(SprintStack *ss, jsbytecode *pc, int nb)
const char *lval, *rval, *xval, *fmt, *token;
unsigned nuses;
int i, argc;
JSAtom *atom;
RootedAtom atom(cx);
JSObject *obj;
JSFunction *fun = NULL; /* init to shut GCC up */
RootedFunction fun(cx);
JSString *str;
JSBool ok;
JSBool foreach;
@ -2722,7 +2722,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, int nb)
jsbytecode *lastlvalpc = NULL, *lastrvalpc = NULL;
cx = ss->sprinter.context;
JS_CHECK_RECURSION(cx, return NULL);
jp = ss->printer;
@ -3615,7 +3614,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, int nb)
case JSOP_GETALIASEDVAR:
case JSOP_CALLLOCAL:
case JSOP_GETLOCAL:
if (IsVarSlot(jp, pc, &atom, &i))
if (IsVarSlot(jp, pc, atom.address(), &i))
goto do_name;
LOCAL_ASSERT((unsigned)i < ss->top);
sn = js_GetSrcNote(cx, jp->script, pc);
@ -3648,7 +3647,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, int nb)
case JSOP_SETALIASEDVAR:
case JSOP_SETLOCAL:
if (IsVarSlot(jp, pc, &atom, &i))
if (IsVarSlot(jp, pc, atom.address(), &i))
goto do_setname;
lval = GetLocal(ss, i);
rval = PopStrDupe(ss, op, &rvalpc);
@ -3656,7 +3655,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, int nb)
case JSOP_INCALIASEDVAR:
case JSOP_DECALIASEDVAR:
if (IsVarSlot(jp, pc, &atom, &i))
if (IsVarSlot(jp, pc, atom.address(), &i))
goto do_incatom;
lval = GetLocal(ss, i);
goto do_inclval;
@ -3665,14 +3664,14 @@ Decompile(SprintStack *ss, jsbytecode *pc, int nb)
case JSOP_DECLOCAL:
/* INCLOCAL/DECLOCAL are followed by GETLOCAL containing the slot. */
JS_ASSERT(pc[JSOP_INCLOCAL_LENGTH] == JSOP_GETLOCAL);
if (IsVarSlot(jp, pc + JSOP_INCLOCAL_LENGTH, &atom, &i))
if (IsVarSlot(jp, pc + JSOP_INCLOCAL_LENGTH, atom.address(), &i))
goto do_incatom;
lval = GetLocal(ss, i);
goto do_inclval;
case JSOP_ALIASEDVARINC:
case JSOP_ALIASEDVARDEC:
if (IsVarSlot(jp, pc, &atom, &i))
if (IsVarSlot(jp, pc, atom.address(), &i))
goto do_atominc;
lval = GetLocal(ss, i);
goto do_lvalinc;
@ -3681,7 +3680,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, int nb)
case JSOP_LOCALDEC:
/* LOCALINC/LOCALDEC are followed by GETLOCAL containing the slot. */
JS_ASSERT(pc[JSOP_LOCALINC_LENGTH] == JSOP_GETLOCAL);
if (IsVarSlot(jp, pc + JSOP_LOCALINC_LENGTH, &atom, &i))
if (IsVarSlot(jp, pc + JSOP_LOCALINC_LENGTH, atom.address(), &i))
goto do_atominc;
lval = GetLocal(ss, i);
goto do_lvalinc;
@ -4765,10 +4764,11 @@ Decompile(SprintStack *ss, jsbytecode *pc, int nb)
sn = js_GetSrcNote(cx, jp->script, pc);
if (sn && SN_TYPE(sn) == SRC_GENEXP) {
BindingVector *outerLocalNames;
JSScript *inner, *outer;
JSScript *inner;
RootedScript outer(cx);
Vector<DecompiledOpcode> *decompiledOpcodes;
SprintStack ss2(cx);
JSFunction *outerfun;
RootedFunction outerfun(cx);
fun = jp->script->getFunction(GET_UINT32_INDEX(pc));
@ -5536,7 +5536,7 @@ DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, unsigned len,
}
/* Call recursive subroutine to do the hard work. */
JSScript *oldscript = jp->script;
RootedScript oldscript(cx, jp->script);
BindingVector *oldLocalNames = jp->localNames;
if (!SetPrinterLocalNames(cx, script, jp))
return false;
@ -5980,7 +5980,7 @@ ExpressionDecompiler::decompilePC(jsbytecode *pc)
case JSOP_LENGTH:
case JSOP_GETPROP:
case JSOP_CALLPROP: {
JSAtom *prop = (op == JSOP_LENGTH) ? cx->names().length : loadAtom(pc);
RootedAtom prop(cx, (op == JSOP_LENGTH) ? cx->names().length : loadAtom(pc));
if (!decompilePC(pcstack[-1]))
return false;
if (IsIdentifier(prop)) {
@ -6914,8 +6914,8 @@ js::GetPCCountScriptSummary(JSContext *cx, size_t index)
return NULL;
}
ScriptAndCounts sac = (*rt->scriptAndCountsVector)[index];
JSScript *script = sac.script;
const ScriptAndCounts &sac = (*rt->scriptAndCountsVector)[index];
RootedScript script(cx, sac.script);
/*
* OOM on buffer appends here will not be caught immediately, but since
@ -7027,7 +7027,7 @@ struct AutoDestroyPrinter
static bool
GetPCCountJSON(JSContext *cx, const ScriptAndCounts &sac, StringBuffer &buf)
{
JSScript *script = sac.script;
RootedScript script(cx, sac.script);
buf.append('{');
AppendJSONProperty(buf, "text", NO_COMMA);

View File

@ -3236,17 +3236,17 @@ proxy_createFunction(JSContext *cx, unsigned argc, Value *vp)
"createFunction", "1", "");
return false;
}
JSObject *handler = NonNullObject(cx, vp[2]);
RootedObject handler(cx, NonNullObject(cx, vp[2]));
if (!handler)
return false;
JSObject *proto, *parent;
RootedObject proto(cx), parent(cx);
parent = vp[0].toObject().getParent();
proto = parent->global().getOrCreateFunctionPrototype(cx);
if (!proto)
return false;
parent = proto->getParent();
JSObject *call = ValueToCallable(cx, &vp[3]);
RootedObject call(cx, ValueToCallable(cx, &vp[3]));
if (!call)
return false;
JSObject *construct = NULL;

View File

@ -735,8 +735,8 @@ JSObject::putProperty(JSContext *cx, HandleObject obj, HandleId id,
}
/* static */ UnrootedShape
JSObject::changeProperty(JSContext *cx, HandleObject obj, RawShape shape, unsigned attrs, unsigned mask,
PropertyOp getter, StrictPropertyOp setter)
JSObject::changeProperty(JSContext *cx, HandleObject obj, HandleShape shape, unsigned attrs,
unsigned mask, PropertyOp getter, StrictPropertyOp setter)
{
JS_ASSERT(obj->nativeContains(cx, shape));

View File

@ -50,6 +50,8 @@ using namespace js;
using namespace js::gc;
using namespace js::frontend;
typedef Rooted<GlobalObject *> RootedGlobalObject;
/* static */ unsigned
Bindings::argumentsVarIndex(JSContext *cx, InternalBindingsHandle bindings)
{
@ -2368,7 +2370,7 @@ js::CloneFunctionScript(JSContext *cx, HandleFunction original, HandleFunction c
clone->setScript(cscript);
cscript->setFunction(clone);
GlobalObject *global = script->compileAndGo ? &script->global() : NULL;
RootedGlobalObject global(cx, script->compileAndGo ? &script->global() : NULL);
script = clone->nonLazyScript();
CallNewScriptHook(cx, script, clone);