Add various autorooting, bug 772303. r=terrence

This commit is contained in:
Brian Hackett 2012-08-12 19:50:49 -06:00
parent fa92bb6b0d
commit d3489bd8a1
39 changed files with 561 additions and 417 deletions

View File

@ -86,9 +86,11 @@ class EvalScriptGuard
EvalCacheLookup lookup_;
EvalCache::AddPtr p_;
Rooted<JSLinearString*> lookupStr_;
public:
EvalScriptGuard(JSContext *cx)
: cx_(cx), script_(cx)
: cx_(cx), script_(cx), lookupStr_(cx)
{
lookup_.str = NULL;
}
@ -98,6 +100,7 @@ class EvalScriptGuard
CallDestroyScriptHook(cx_->runtime->defaultFreeOp(), script_);
script_->isActiveEval = false;
script_->isCachedEval = true;
lookup_.str = lookupStr_;
if (lookup_.str && IsEvalCacheCandidate(script_))
cx_->runtime->evalCache.relookupOrAdd(p_, lookup_, script_);
}
@ -105,6 +108,7 @@ class EvalScriptGuard
void lookupInEvalCache(JSLinearString *str, JSFunction *caller, unsigned staticLevel)
{
lookupStr_ = str;
lookup_.str = str;
lookup_.caller = caller;
lookup_.staticLevel = staticLevel;

View File

@ -823,6 +823,8 @@ MapIteratorObject::next_impl(JSContext *cx, CallArgs args)
}
Value pair[2] = { range->front().key.get(), range->front().value };
AutoValueArray root(cx, pair, 2);
JSObject *pairobj = NewDenseCopiedArray(cx, 2, pair);
if (!pairobj)
return false;
@ -970,7 +972,7 @@ MapObject::construct(JSContext *cx, unsigned argc, Value *vp)
if (args.hasDefined(0)) {
ForOfIterator iter(cx, args[0]);
while (iter.next()) {
JSObject *pairobj = js_ValueToNonNullObject(cx, iter.value());
RootedObject pairobj(cx, js_ValueToNonNullObject(cx, iter.value()));
if (!pairobj)
return false;

View File

@ -303,8 +303,10 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions
if (!GetOrderedBindings(cx, funsc.bindings, &names))
return false;
RootedPropertyName name(cx);
for (unsigned i = 0; i < nargs; i++) {
if (!DefineArg(fn, names[i].maybeName, i, &parser))
name = names[i].maybeName;
if (!DefineArg(fn, name, i, &parser))
return false;
}
}

View File

@ -469,7 +469,7 @@ CheckStrictAssignment(JSContext *cx, Parser *parser, ParseNode *lhs)
* tc's token stream if pn is NULL.
*/
bool
CheckStrictBinding(JSContext *cx, Parser *parser, PropertyName *name, ParseNode *pn)
CheckStrictBinding(JSContext *cx, Parser *parser, HandlePropertyName name, ParseNode *pn)
{
if (!parser->tc->sc->needStrictChecks())
return true;
@ -489,7 +489,7 @@ CheckStrictBinding(JSContext *cx, Parser *parser, PropertyName *name, ParseNode
}
static bool
ReportBadParameter(JSContext *cx, Parser *parser, JSAtom *name, unsigned errorNumber)
ReportBadParameter(JSContext *cx, Parser *parser, HandlePropertyName name, unsigned errorNumber)
{
Definition *dn = parser->tc->decls.lookupFirst(name);
JSAutoByteString bytes;
@ -878,13 +878,13 @@ MakeDefIntoUse(Definition *dn, ParseNode *pn, JSAtom *atom, Parser *parser)
* of CheckDestructuring and its friends.
*/
typedef bool
(*Binder)(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser);
(*Binder)(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser);
static bool
BindLet(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser);
BindLet(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser);
static bool
BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser);
BindVarOrConst(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser);
struct frontend::BindData {
BindData(JSContext *cx) : let(cx) {}
@ -1139,7 +1139,7 @@ LeaveFunction(ParseNode *fn, Parser *parser, PropertyName *funName = NULL,
* and the formals specified by the Function constructor.
*/
bool
frontend::DefineArg(ParseNode *pn, PropertyName *name, unsigned i, Parser *parser)
frontend::DefineArg(ParseNode *pn, HandlePropertyName name, unsigned i, Parser *parser)
{
JSContext *cx = parser->context;
TreeContext *tc = parser->tc;
@ -1179,7 +1179,7 @@ frontend::DefineArg(ParseNode *pn, PropertyName *name, unsigned i, Parser *parse
#if JS_HAS_DESTRUCTURING
static bool
BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser)
BindDestructuringArg(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser)
{
TreeContext *tc = parser->tc;
JS_ASSERT(tc->sc->inFunction());
@ -1189,13 +1189,13 @@ BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser
* bindings aren't added to tc->sc->bindings until after all arguments have
* been parsed.
*/
if (tc->decls.lookupFirst(atom)) {
if (tc->decls.lookupFirst(name)) {
parser->reportError(NULL, JSMSG_DESTRUCT_DUP_ARG);
return false;
}
ParseNode *pn = data->pn;
if (!CheckStrictBinding(cx, parser, atom->asPropertyName(), pn))
if (!CheckStrictBinding(cx, parser, name, pn))
return false;
/*
@ -1220,7 +1220,7 @@ BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser
pn->setOp(JSOP_SETLOCAL);
pn->pn_dflags |= PND_BOUND;
return Define(pn, atom, tc);
return Define(pn, name, tc);
}
#endif /* JS_HAS_DESTRUCTURING */
@ -2020,11 +2020,11 @@ ReportRedeclaration(JSContext *cx, Parser *parser, ParseNode *pn, bool isConst,
* data->pn in a slot of the block object.
*/
static bool
BindLet(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser)
BindLet(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser)
{
TreeContext *tc = parser->tc;
ParseNode *pn = data->pn;
if (!CheckStrictBinding(cx, parser, atom->asPropertyName(), pn))
if (!CheckStrictBinding(cx, parser, name, pn))
return false;
Rooted<StaticBlockObject *> blockObj(cx, data->let.blockObj);
@ -2040,10 +2040,10 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser)
*/
if (data->let.varContext == HoistVars) {
JS_ASSERT(!tc->atBodyLevel());
Definition *dn = tc->decls.lookupFirst(atom);
Definition *dn = tc->decls.lookupFirst(name);
if (dn && dn->pn_blockid == tc->blockid())
return ReportRedeclaration(cx, parser, pn, dn->isConst(), atom);
if (!Define(pn, atom, tc, true))
return ReportRedeclaration(cx, parser, pn, dn->isConst(), name);
if (!Define(pn, name, tc, true))
return false;
}
@ -2064,11 +2064,11 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser)
* slot indexed by blockCount off the class-reserved slot base.
*/
bool redeclared;
RootedId id(cx, AtomToId(atom));
RootedId id(cx, NameToId(name));
Shape *shape = StaticBlockObject::addVar(cx, blockObj, id, blockCount, &redeclared);
if (!shape) {
if (redeclared)
ReportRedeclaration(cx, parser, pn, false, atom);
ReportRedeclaration(cx, parser, pn, false, name);
return false;
}
@ -2163,20 +2163,18 @@ BindFunctionLocal(JSContext *cx, BindData *data, DefinitionList::Range &defs, Tr
}
static bool
BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom_, Parser *parser)
BindVarOrConst(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser)
{
RootedAtom atom(cx, atom_);
TreeContext *tc = parser->tc;
ParseNode *pn = data->pn;
/* Default best op for pn is JSOP_NAME; we'll try to improve below. */
pn->setOp(JSOP_NAME);
if (!CheckStrictBinding(cx, parser, atom->asPropertyName(), pn))
if (!CheckStrictBinding(cx, parser, name, pn))
return false;
StmtInfoTC *stmt = LexicalLookup(tc, atom, NULL, (StmtInfoTC *)NULL);
StmtInfoTC *stmt = LexicalLookup(tc, name, NULL, (StmtInfoTC *)NULL);
if (stmt && stmt->type == STMT_WITH) {
pn->pn_dflags |= PND_DEOPTIMIZED;
@ -2184,11 +2182,11 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom_, Parser *parser)
return true;
}
DefinitionList::Range defs = tc->decls.lookupMulti(atom);
DefinitionList::Range defs = tc->decls.lookupMulti(name);
JS_ASSERT_IF(stmt, !defs.empty());
if (defs.empty()) {
if (!Define(pn, atom, tc))
if (!Define(pn, name, tc))
return false;
if (data->op == JSOP_DEFCONST)
@ -2210,32 +2208,32 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom_, Parser *parser)
Definition *dn = defs.front();
Definition::Kind dn_kind = dn->kind();
if (dn_kind == Definition::ARG) {
JSAutoByteString name;
if (!js_AtomToPrintableString(cx, atom, &name))
JSAutoByteString bytes;
if (!js_AtomToPrintableString(cx, name, &bytes))
return false;
if (data->op == JSOP_DEFCONST) {
parser->reportError(pn, JSMSG_REDECLARED_PARAM, name.ptr());
parser->reportError(pn, JSMSG_REDECLARED_PARAM, bytes.ptr());
return false;
}
if (!parser->reportStrictWarning(pn, JSMSG_VAR_HIDES_ARG, name.ptr()))
if (!parser->reportStrictWarning(pn, JSMSG_VAR_HIDES_ARG, bytes.ptr()))
return false;
} else {
bool error = (data->op == JSOP_DEFCONST ||
dn_kind == Definition::CONST ||
(dn_kind == Definition::LET &&
(stmt->type != STMT_CATCH || OuterLet(tc, stmt, atom))));
(stmt->type != STMT_CATCH || OuterLet(tc, stmt, name))));
if (cx->hasStrictOption()
? data->op != JSOP_DEFVAR || dn_kind != Definition::VAR
: error)
{
JSAutoByteString name;
JSAutoByteString bytes;
Parser::Reporter reporter =
error ? &Parser::reportError : &Parser::reportStrictWarning;
if (!js_AtomToPrintableString(cx, atom, &name) ||
if (!js_AtomToPrintableString(cx, name, &bytes) ||
!(parser->*reporter)(pn, JSMSG_REDECLARED_VAR,
Definition::kindString(dn_kind), name.ptr()))
Definition::kindString(dn_kind), bytes.ptr()))
{
return false;
}
@ -2329,8 +2327,10 @@ BindDestructuringVar(JSContext *cx, BindData *data, ParseNode *pn, Parser *parse
{
JS_ASSERT(pn->isKind(PNK_NAME));
RootedPropertyName name(cx, pn->pn_atom->asPropertyName());
data->pn = pn;
if (!data->binder(cx, data, pn->pn_atom, parser))
if (!data->binder(cx, data, name, parser))
return false;
/*
@ -3437,7 +3437,7 @@ Parser::tryStatement()
case TOK_NAME:
{
JSAtom *label = tokenStream.currentToken().name();
RootedPropertyName label(context, tokenStream.currentToken().name());
pn3 = NewBindingNode(label, this);
if (!pn3)
return NULL;
@ -4148,7 +4148,7 @@ Parser::variables(ParseNodeKind kind, StaticBlockObject *blockObj, VarContext va
return NULL;
}
PropertyName *name = tokenStream.currentToken().name();
RootedPropertyName name(context, tokenStream.currentToken().name());
pn2 = NewBindingNode(name, this, varContext);
if (!pn2)
return NULL;

View File

@ -327,7 +327,7 @@ Parser::reportStrictModeError(ParseNode *pn, unsigned errorNumber, ...)
}
bool
DefineArg(ParseNode *pn, PropertyName *name, unsigned i, Parser *parser);
DefineArg(ParseNode *pn, HandlePropertyName name, unsigned i, Parser *parser);
} /* namespace frontend */
} /* namespace js */

View File

@ -283,5 +283,10 @@ for (var i = 0; i <4; i++) {
plainText += plainText;
}
// root checks performed during integer conversion operations can poison
// crypto integers in this test.
if (relaxRootChecks)
relaxRootChecks();
var md5Output = hex_md5(plainText);
assertEq(md5Output, "a831e91e0f70eddcb70dc61c6f82f6cd")

View File

@ -221,5 +221,10 @@ for (var i = 0; i <4; i++) {
plainText += plainText;
}
// root checks performed during integer conversion operations can poison
// crypto integers in this test.
if (relaxRootChecks)
relaxRootChecks();
var sha1Output = hex_sha1(plainText);
assertEq(sha1Output, "2524d264def74cce2498bf112bedf00e6c0b796d")

View File

@ -596,10 +596,12 @@ JS_ValueToUint64(JSContext *cx, jsval v, uint64_t *ip)
}
JS_PUBLIC_API(JSBool)
JS_ValueToInt32(JSContext *cx, jsval v, int32_t *ip)
JS_ValueToInt32(JSContext *cx, jsval vArg, int32_t *ip)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
RootedValue v(cx, vArg);
assertSameCompartment(cx, v);
if (v.isInt32()) {
@ -616,7 +618,7 @@ JS_ValueToInt32(JSContext *cx, jsval v, int32_t *ip)
if (MOZ_DOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) {
js_ReportValueError(cx, JSMSG_CANT_CONVERT,
JSDVG_SEARCH_STACK, v, NULL);
JSDVG_SEARCH_STACK, v, NullPtr());
return false;
}
@ -4957,12 +4959,14 @@ JS_BindCallable(JSContext *cx, JSObject *targetArg, JSRawObject newThis)
JSBool
js_generic_native_method_dispatcher(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
JSFunctionSpec *fs = (JSFunctionSpec *)
vp->toObject().toFunction()->getExtendedSlot(0).toPrivate();
JS_ASSERT((fs->flags & JSFUN_GENERIC_NATIVE) != 0);
if (argc < 1) {
js_ReportMissingArg(cx, *vp, 0);
js_ReportMissingArg(cx, args.calleev(), 0);
return JS_FALSE;
}
@ -5918,8 +5922,8 @@ JS_New(JSContext *cx, JSObject *ctorArg, unsigned argc, jsval *argv)
if (!cx->stack.pushInvokeArgs(cx, argc, &args))
return NULL;
args.calleev().setObject(*ctor);
args.thisv().setNull();
args.setCallee(ObjectValue(*ctor));
args.setThis(NullValue());
PodCopy(args.array(), argv, argc);
if (!InvokeConstructor(cx, args))

View File

@ -1053,15 +1053,16 @@ class JS_PUBLIC_API(AutoGCRooter) {
STRING = -14, /* js::AutoStringRooter */
IDVECTOR = -15, /* js::AutoIdVector */
OBJVECTOR = -16, /* js::AutoObjectVector */
SCRIPTVECTOR =-17, /* js::AutoScriptVector */
PROPDESC = -18, /* js::PropDesc::AutoRooter */
SHAPERANGE = -19, /* js::Shape::Range::AutoRooter */
STACKSHAPE = -20, /* js::StackShape::AutoRooter */
STACKBASESHAPE=-21,/* js::StackBaseShape::AutoRooter */
BINDINGS = -22, /* js::Bindings::AutoRooter */
GETTERSETTER =-23, /* js::AutoRooterGetterSetter */
REGEXPSTATICS=-24, /* js::RegExpStatics::AutoRooter */
HASHABLEVALUE=-25
STRINGVECTOR =-17, /* js::AutoStringVector */
SCRIPTVECTOR =-18, /* js::AutoScriptVector */
PROPDESC = -19, /* js::PropDesc::AutoRooter */
SHAPERANGE = -20, /* js::Shape::Range::AutoRooter */
STACKSHAPE = -21, /* js::StackShape::AutoRooter */
STACKBASESHAPE=-22,/* js::StackBaseShape::AutoRooter */
BINDINGS = -23, /* js::Bindings::AutoRooter */
GETTERSETTER =-24, /* js::AutoRooterGetterSetter */
REGEXPSTATICS=-25, /* js::RegExpStatics::AutoRooter */
HASHABLEVALUE=-26
};
private:
@ -1255,6 +1256,7 @@ class AutoVectorRooter : protected AutoGCRooter
}
size_t length() const { return vector.length(); }
bool empty() const { return vector.empty(); }
bool append(const T &v) { return vector.append(v); }
bool append(const AutoVectorRooter<T> &other) {
@ -1381,8 +1383,15 @@ class CallReceiver
friend CallReceiver CallReceiverFromArgv(Value *);
Value *base() const { return argv_ - 2; }
JSObject &callee() const { JS_ASSERT(!usedRval_); return argv_[-2].toObject(); }
Value &calleev() const { JS_ASSERT(!usedRval_); return argv_[-2]; }
Value &thisv() const { return argv_[-1]; }
JS::HandleValue calleev() const {
JS_ASSERT(!usedRval_);
return JS::HandleValue::fromMarkedLocation(&argv_[-2]);
}
JS::HandleValue thisv() const {
return JS::HandleValue::fromMarkedLocation(&argv_[-1]);
}
JS::MutableHandleValue rval() const {
setUsedRval();
@ -1394,9 +1403,13 @@ class CallReceiver
return argv_ - 1;
}
void setCallee(Value calleev) {
void setCallee(Value calleev) const {
clearUsedRval();
this->calleev() = calleev;
argv_[-2] = calleev;
}
void setThis(Value thisv) const {
argv_[-1] = thisv;
}
};

View File

@ -1535,7 +1535,7 @@ array_join_sub(JSContext *cx, CallArgs &args, bool locale)
// the annotations in this function apply to both toLocaleString and join.
// Step 1
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -1623,7 +1623,7 @@ array_join_sub(JSContext *cx, CallArgs &args, bool locale)
if (!hole && !elt.isNullOrUndefined()) {
if (locale) {
JSObject *robj = ToObject(cx, elt.address());
JSObject *robj = ToObject(cx, elt);
if (!robj)
return false;
RootedId id(cx, NameToId(cx->runtime->atomState.toLocaleStringAtom));
@ -1657,7 +1657,7 @@ array_toString(JSContext *cx, unsigned argc, Value *vp)
JS_CHECK_RECURSION(cx, return false);
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -1677,8 +1677,8 @@ array_toString(JSContext *cx, unsigned argc, Value *vp)
if (!cx->stack.pushInvokeArgs(cx, 0, &ag))
return false;
ag.calleev() = join;
ag.thisv().setObject(*obj);
ag.setCallee(join);
ag.setThis(ObjectValue(*obj));
/* Do the call. */
if (!Invoke(cx, ag))
@ -1808,7 +1808,7 @@ static JSBool
array_reverse(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -2078,7 +2078,7 @@ SortComparatorFunction::operator()(const Value &a, const Value &b, bool *lessOrE
return false;
ag.setCallee(fval);
ag.thisv() = UndefinedValue();
ag.setThis(UndefinedValue());
ag[0] = a;
ag[1] = b;
@ -2118,7 +2118,7 @@ js::array_sort(JSContext *cx, unsigned argc, Value *vp)
fval.setNull();
}
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -2358,7 +2358,7 @@ JSBool
js::array_push(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -2433,7 +2433,7 @@ JSBool
js::array_pop(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
if (obj->isDenseArray())
@ -2462,7 +2462,7 @@ JSBool
js::array_shift(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return JS_FALSE;
@ -2514,7 +2514,7 @@ static JSBool
array_unshift(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -2636,7 +2636,7 @@ array_splice(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -2855,11 +2855,13 @@ mjit::stubs::ArrayConcatTwoArrays(VMFrame &f)
JSBool
js::array_concat(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
/* Treat our |this| object as the first argument; see ECMA 15.4.4.4. */
Value *p = JS_ARGV(cx, vp) - 1;
Value *p = args.array() - 1;
/* Create a new Array object and root it using *vp. */
RootedObject aobj(cx, ToObject(cx, &vp[1]));
RootedObject aobj(cx, ToObject(cx, args.thisv()));
if (!aobj)
return false;
@ -2874,7 +2876,7 @@ js::array_concat(JSContext *cx, unsigned argc, Value *vp)
return JS_FALSE;
TryReuseArrayType(aobj, nobj);
nobj->setArrayLength(cx, length);
vp->setObject(*nobj);
args.rval().setObject(*nobj);
if (argc == 0)
return JS_TRUE;
argc--;
@ -2883,7 +2885,7 @@ js::array_concat(JSContext *cx, unsigned argc, Value *vp)
nobj = NewDenseEmptyArray(cx);
if (!nobj)
return JS_FALSE;
vp->setObject(*nobj);
args.rval().setObject(*nobj);
length = 0;
}
@ -2932,7 +2934,7 @@ array_slice(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -3011,13 +3013,12 @@ static JSBool
array_indexOfHelper(JSContext *cx, IndexOfKind mode, CallArgs &args)
{
uint32_t length, i, stop;
Value tosearch;
int direction;
JSBool hole;
RootedValue elt(cx);
RootedValue tosearch(cx), elt(cx);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
if (!js_GetLengthProperty(cx, obj, &length))
@ -3139,7 +3140,7 @@ static inline bool
array_readonlyCommon(JSContext *cx, CallArgs &args)
{
/* Step 1. */
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -3180,7 +3181,7 @@ array_readonlyCommon(JSContext *cx, CallArgs &args)
if (!ag.pushed() && !cx->stack.pushInvokeArgs(cx, 3, &ag))
return false;
ag.setCallee(ObjectValue(*callable));
ag.thisv() = thisv;
ag.setThis(thisv);
ag[0] = kValue;
ag[1] = NumberValue(k);
ag[2] = ObjectValue(*obj);
@ -3231,7 +3232,7 @@ array_map(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -3281,7 +3282,7 @@ array_map(JSContext *cx, unsigned argc, Value *vp)
if (!ag.pushed() && !cx->stack.pushInvokeArgs(cx, 3, &ag))
return false;
ag.setCallee(ObjectValue(*callable));
ag.thisv() = thisv;
ag.setThis(thisv);
ag[0] = kValue;
ag[1] = NumberValue(k);
ag[2] = ObjectValue(*obj);
@ -3308,7 +3309,7 @@ array_filter(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -3361,7 +3362,7 @@ array_filter(JSContext *cx, unsigned argc, Value *vp)
if (!ag.pushed() && !cx->stack.pushInvokeArgs(cx, 3, &ag))
return false;
ag.setCallee(ObjectValue(*callable));
ag.thisv() = thisv;
ag.setThis(thisv);
ag[0] = kValue;
ag[1] = NumberValue(k);
ag[2] = ObjectValue(*obj);
@ -3416,7 +3417,7 @@ static inline bool
array_reduceCommon(JSContext *cx, CallArgs &args)
{
/* Step 1. */
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -3430,7 +3431,7 @@ array_reduceCommon(JSContext *cx, CallArgs &args)
js_ReportMissingArg(cx, args.calleev(), 0);
return false;
}
JSObject *callable = ValueToCallable(cx, &args[0]);
RootedObject callable(cx, ValueToCallable(cx, &args[0]));
if (!callable)
return false;
@ -3479,7 +3480,7 @@ array_reduceCommon(JSContext *cx, CallArgs &args)
if (!ag.pushed() && !cx->stack.pushInvokeArgs(cx, 4, &ag))
return false;
ag.setCallee(ObjectValue(*callable));
ag.thisv() = UndefinedValue();
ag.setThis(UndefinedValue());
ag[0] = accumulator;
ag[1] = kValue;
ag[2] = NumberValue(k);
@ -3811,9 +3812,9 @@ js_ArrayInfo(JSContext *cx, unsigned argc, Value *vp)
JSObject *array;
for (unsigned i = 0; i < args.length(); i++) {
Value arg = args[i];
RootedValue arg(cx, args[i]);
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, arg, NULL);
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, arg, NullPtr());
if (!bytes)
return JS_FALSE;
if (arg.isPrimitive() ||

View File

@ -298,6 +298,9 @@ AtomizeInline(JSContext *cx, const jschar **pchars, size_t length,
SkipRoot skip(cx, &chars);
/* Workaround for hash values in AddPtr being inadvertently poisoned. */
SkipRoot skip2(cx, &p);
if (ocb == TakeCharOwnership) {
key = js_NewString(cx, const_cast<jschar *>(chars), length);
if (!key)

View File

@ -205,8 +205,8 @@ BooleanGetPrimitiveValueSlow(JSContext *cx, JSObject &obj, Value *vp)
InvokeArgsGuard ag;
if (!cx->stack.pushInvokeArgs(cx, 0, &ag))
return false;
ag.calleev() = cx->compartment->maybeGlobal()->booleanValueOf();
ag.thisv().setObject(obj);
ag.setCallee(cx->compartment->maybeGlobal()->booleanValueOf());
ag.setThis(ObjectValue(obj));
if (!Invoke(cx, ag))
return false;
*vp = ag.rval();

View File

@ -810,8 +810,8 @@ js_ReportIsNotDefined(JSContext *cx, const char *name)
}
JSBool
js_ReportIsNullOrUndefined(JSContext *cx, int spindex, const Value &v,
JSString *fallback)
js_ReportIsNullOrUndefined(JSContext *cx, int spindex, HandleValue v,
HandleString fallback)
{
char *bytes;
JSBool ok;
@ -844,11 +844,11 @@ js_ReportIsNullOrUndefined(JSContext *cx, int spindex, const Value &v,
}
void
js_ReportMissingArg(JSContext *cx, const Value &v, unsigned arg)
js_ReportMissingArg(JSContext *cx, HandleValue v, unsigned arg)
{
char argbuf[11];
char *bytes;
JSAtom *atom;
RootedAtom atom(cx);
JS_snprintf(argbuf, sizeof argbuf, "%u", arg);
bytes = NULL;
@ -867,7 +867,7 @@ js_ReportMissingArg(JSContext *cx, const Value &v, unsigned arg)
JSBool
js_ReportValueErrorFlags(JSContext *cx, unsigned flags, const unsigned errorNumber,
int spindex, const Value &v, JSString *fallback,
int spindex, HandleValue v, HandleString fallback,
const char *arg1, const char *arg2)
{
char *bytes;

View File

@ -1728,11 +1728,11 @@ js_ReportIsNotDefined(JSContext *cx, const char *name);
* Report an attempt to access the property of a null or undefined value (v).
*/
extern JSBool
js_ReportIsNullOrUndefined(JSContext *cx, int spindex, const js::Value &v,
JSString *fallback);
js_ReportIsNullOrUndefined(JSContext *cx, int spindex, js::HandleValue v,
js::HandleString fallback);
extern void
js_ReportMissingArg(JSContext *cx, const js::Value &v, unsigned arg);
js_ReportMissingArg(JSContext *cx, js::HandleValue v, unsigned arg);
/*
* Report error using js_DecompileValueGenerator(cx, spindex, v, fallback) as
@ -1741,7 +1741,7 @@ js_ReportMissingArg(JSContext *cx, const js::Value &v, unsigned arg);
*/
extern JSBool
js_ReportValueErrorFlags(JSContext *cx, unsigned flags, const unsigned errorNumber,
int spindex, const js::Value &v, JSString *fallback,
int spindex, js::HandleValue v, js::HandleString fallback,
const char *arg1, const char *arg2);
#define js_ReportValueError(cx,errorNumber,spindex,v,fallback) \
@ -1888,6 +1888,19 @@ class AutoObjectVector : public AutoVectorRooter<JSObject *>
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
};
class AutoStringVector : public AutoVectorRooter<JSString *>
{
public:
explicit AutoStringVector(JSContext *cx
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoVectorRooter<JSString *>(cx, STRINGVECTOR)
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
}
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
};
class AutoShapeVector : public AutoVectorRooter<Shape *>
{
public:

View File

@ -2589,8 +2589,10 @@ date_toISOString(JSContext *cx, unsigned argc, Value *vp)
static JSBool
date_toJSON(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -2601,7 +2603,7 @@ date_toJSON(JSContext *cx, unsigned argc, Value *vp)
/* Step 3. */
if (tv.isDouble() && !MOZ_DOUBLE_IS_FINITE(tv.toDouble())) {
vp->setNull();
args.rval().setNull();
return true;
}
@ -2618,16 +2620,16 @@ date_toJSON(JSContext *cx, unsigned argc, Value *vp)
}
/* Step 6. */
InvokeArgsGuard args;
if (!cx->stack.pushInvokeArgs(cx, 0, &args))
InvokeArgsGuard ag;
if (!cx->stack.pushInvokeArgs(cx, 0, &ag))
return false;
args.calleev() = toISO;
args.thisv().setObject(*obj);
ag.setCallee(toISO);
ag.setThis(ObjectValue(*obj));
if (!Invoke(cx, args))
if (!Invoke(cx, ag))
return false;
*vp = args.rval();
args.rval().set(ag.rval());
return true;
}

View File

@ -686,7 +686,7 @@ exn_toSource(JSContext *cx, unsigned argc, Value *vp)
JS_CHECK_RECURSION(cx, return false);
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, &args.thisv()));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;

View File

@ -469,7 +469,8 @@ fun_hasInstance(JSContext *cx, HandleObject obj_, const Value *v, JSBool *bp)
* Throw a runtime error if instanceof is called on a function that
* has a non-object as its .prototype value.
*/
js_ReportValueError(cx, JSMSG_BAD_PROTOTYPE, -1, ObjectValue(*obj), NULL);
RootedValue val(cx, ObjectValue(*obj));
js_ReportValueError(cx, JSMSG_BAD_PROTOTYPE, -1, val, NullPtr());
return JS_FALSE;
}
@ -745,13 +746,15 @@ fun_toStringHelper(JSContext *cx, JSObject *obj, unsigned indent)
static JSBool
fun_toString(JSContext *cx, unsigned argc, Value *vp)
{
JS_ASSERT(IsFunctionObject(vp[0]));
CallArgs args = CallArgsFromVp(argc, vp);
JS_ASSERT(IsFunctionObject(args.calleev()));
uint32_t indent = 0;
if (argc != 0 && !ToUint32(cx, vp[2], &indent))
if (args.length() != 0 && !ToUint32(cx, args[0], &indent))
return false;
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, args.thisv());
if (!obj)
return false;
@ -759,7 +762,7 @@ fun_toString(JSContext *cx, unsigned argc, Value *vp)
if (!str)
return false;
vp->setString(str);
args.rval().setString(str);
return true;
}
@ -767,9 +770,10 @@ fun_toString(JSContext *cx, unsigned argc, Value *vp)
static JSBool
fun_toSource(JSContext *cx, unsigned argc, Value *vp)
{
JS_ASSERT(IsFunctionObject(vp[0]));
CallArgs args = CallArgsFromVp(argc, vp);
JS_ASSERT(IsFunctionObject(args.calleev()));
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, args.thisv());
if (!obj)
return false;
@ -777,7 +781,7 @@ fun_toSource(JSContext *cx, unsigned argc, Value *vp)
if (!str)
return false;
vp->setString(str);
args.rval().setString(str);
return true;
}
#endif
@ -809,8 +813,8 @@ js_fun_call(JSContext *cx, unsigned argc, Value *vp)
return JS_FALSE;
/* Push fval, thisv, and the args. */
args.calleev() = fval;
args.thisv() = thisv;
args.setCallee(fval);
args.setThis(thisv);
PodCopy(args.array(), argv, argc);
bool ok = Invoke(cx, args);
@ -855,8 +859,8 @@ js_fun_apply(JSContext *cx, unsigned argc, Value *vp)
return false;
/* Push fval, obj, and aobj's elements as args. */
args.calleev() = fval;
args.thisv() = vp[2];
args.setCallee(fval);
args.setThis(vp[2]);
/* Steps 7-8. */
cx->fp()->forEachUnaliasedActual(CopyTo(args.array()));
@ -886,8 +890,8 @@ js_fun_apply(JSContext *cx, unsigned argc, Value *vp)
return false;
/* Push fval, obj, and aobj's elements as args. */
args.calleev() = fval;
args.thisv() = vp[2];
args.setCallee(fval);
args.setThis(vp[2]);
/* Steps 7-8. */
if (!GetElements(cx, aobj, length, args.array()))
@ -1017,10 +1021,10 @@ CallOrConstructBoundFunction(JSContext *cx, unsigned argc, Value *vp)
PodCopy(args.array() + argslen, vp + 2, argc);
/* 15.3.4.5.1, 15.3.4.5.2 step 5. */
args.calleev().setObject(*target);
args.setCallee(ObjectValue(*target));
if (!constructing)
args.thisv() = boundThis;
args.setThis(boundThis);
if (constructing ? !InvokeConstructor(cx, args) : !Invoke(cx, args))
return false;
@ -1060,7 +1064,7 @@ fun_bind(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
Value &thisv = args.thisv();
Value thisv = args.thisv();
/* Step 2. */
if (!js_IsCallable(thisv)) {
@ -1517,7 +1521,7 @@ js_DefineFunction(JSContext *cx, HandleObject obj, HandleId id, Native native,
void
js::ReportIncompatibleMethod(JSContext *cx, CallReceiver call, Class *clasp)
{
Value &thisv = call.thisv();
Value thisv = call.thisv();
#ifdef DEBUG
if (thisv.isObject()) {

View File

@ -110,7 +110,7 @@ js::BoxNonStrictThis(JSContext *cx, const CallReceiver &call)
* Check for SynthesizeFrame poisoning and fast constructors which
* didn't check their callee properly.
*/
Value &thisv = call.thisv();
Value thisv = call.thisv();
JS_ASSERT(!thisv.isMagic());
#ifdef DEBUG
@ -120,15 +120,17 @@ js::BoxNonStrictThis(JSContext *cx, const CallReceiver &call)
if (thisv.isNullOrUndefined()) {
JSObject *thisp = call.callee().global().thisObject(cx);
JS_ASSERT(!IsPoisonedPtr(thisp));
if (!thisp)
return false;
call.thisv().setObject(*thisp);
call.setThis(ObjectValue(*thisp));
return true;
}
if (!thisv.isObject())
return !!js_PrimitiveToObject(cx, &thisv);
if (!thisv.isObject()) {
if (!js_PrimitiveToObject(cx, &thisv))
return false;
call.setThis(thisv);
}
return true;
}
@ -205,8 +207,8 @@ NoSuchMethod(JSContext *cx, unsigned argc, Value *vp)
JSObject *obj = &vp[0].toObject();
JS_ASSERT(obj->getClass() == &js_NoSuchMethodClass);
args.calleev() = obj->getSlot(JSSLOT_FOUND_FUNCTION);
args.thisv() = vp[1];
args.setCallee(obj->getSlot(JSSLOT_FOUND_FUNCTION));
args.setThis(vp[1]);
args[0] = obj->getSlot(JSSLOT_SAVED_ID);
JSObject *argsobj = NewDenseCopiedArray(cx, argc, vp + 2);
if (!argsobj)
@ -223,7 +225,9 @@ bool
js::ReportIsNotFunction(JSContext *cx, const Value &v, MaybeConstruct construct)
{
unsigned error = construct ? JSMSG_NOT_CONSTRUCTOR : JSMSG_NOT_FUNCTION;
js_ReportValueError3(cx, error, JSDVG_SEARCH_STACK, v, NULL, NULL, NULL);
RootedValue val(cx, v);
js_ReportValueError3(cx, error, JSDVG_SEARCH_STACK, val, NullPtr(), NULL, NULL);
return false;
}
@ -232,7 +236,9 @@ js::ReportIsNotFunction(JSContext *cx, const Value *vp, MaybeConstruct construct
{
ptrdiff_t spIndex = cx->stack.spIndexOf(vp);
unsigned error = construct ? JSMSG_NOT_CONSTRUCTOR : JSMSG_NOT_FUNCTION;
js_ReportValueError3(cx, error, spIndex, *vp, NULL, NULL, NULL);
RootedValue val(cx, *vp);
js_ReportValueError3(cx, error, spIndex, val, NullPtr(), NULL, NULL);
return false;
}
@ -321,7 +327,7 @@ js::InvokeKernel(JSContext *cx, CallArgs args, MaybeConstruct construct)
InitialFrameFlags initial = (InitialFrameFlags) construct;
if (args.calleev().isPrimitive())
return ReportIsNotFunction(cx, &args.calleev(), construct);
return ReportIsNotFunction(cx, args.calleev().address(), construct);
JSObject &callee = args.callee();
Class *clasp = callee.getClass();
@ -334,7 +340,7 @@ js::InvokeKernel(JSContext *cx, CallArgs args, MaybeConstruct construct)
#endif
JS_ASSERT_IF(construct, !clasp->construct);
if (!clasp->call)
return ReportIsNotFunction(cx, &args.calleev(), construct);
return ReportIsNotFunction(cx, args.calleev().address(), construct);
return CallJSNative(cx, clasp->call, args);
}
@ -369,8 +375,8 @@ js::Invoke(JSContext *cx, const Value &thisv, const Value &fval, unsigned argc,
if (!cx->stack.pushInvokeArgs(cx, argc, &args))
return false;
args.calleev() = fval;
args.thisv() = thisv;
args.setCallee(fval);
args.setThis(thisv);
PodCopy(args.array(), argv, argc);
if (args.thisv().isObject()) {
@ -382,7 +388,7 @@ js::Invoke(JSContext *cx, const Value &thisv, const Value &fval, unsigned argc,
JSObject *thisp = args.thisv().toObject().thisObject(cx);
if (!thisp)
return false;
args.thisv().setObject(*thisp);
args.setThis(ObjectValue(*thisp));
}
if (!Invoke(cx, args))
@ -397,10 +403,10 @@ js::InvokeConstructorKernel(JSContext *cx, CallArgs args)
{
JS_ASSERT(!FunctionClass.construct);
args.thisv().setMagic(JS_IS_CONSTRUCTING);
args.setThis(MagicValue(JS_IS_CONSTRUCTING));
if (!args.calleev().isObject())
return ReportIsNotFunction(cx, &args.calleev(), CONSTRUCT);
return ReportIsNotFunction(cx, args.calleev().address(), CONSTRUCT);
JSObject &callee = args.callee();
if (callee.isFunction()) {
@ -414,7 +420,7 @@ js::InvokeConstructorKernel(JSContext *cx, CallArgs args)
}
if (!fun->isInterpretedConstructor())
return ReportIsNotFunction(cx, &args.calleev(), CONSTRUCT);
return ReportIsNotFunction(cx, args.calleev().address(), CONSTRUCT);
if (!InvokeKernel(cx, args, CONSTRUCT))
return false;
@ -425,7 +431,7 @@ js::InvokeConstructorKernel(JSContext *cx, CallArgs args)
Class *clasp = callee.getClass();
if (!clasp->construct)
return ReportIsNotFunction(cx, &args.calleev(), CONSTRUCT);
return ReportIsNotFunction(cx, args.calleev().address(), CONSTRUCT);
return CallJSNativeConstructor(cx, clasp->construct, args);
}
@ -437,8 +443,8 @@ js::InvokeConstructor(JSContext *cx, const Value &fval, unsigned argc, Value *ar
if (!cx->stack.pushInvokeArgs(cx, argc, &args))
return false;
args.calleev() = fval;
args.thisv().setMagic(JS_THIS_POISON);
args.setCallee(fval);
args.setThis(MagicValue(JS_THIS_POISON));
PodCopy(args.array(), argv, argc);
if (!InvokeConstructor(cx, args))
@ -530,8 +536,10 @@ js::HasInstance(JSContext *cx, HandleObject obj, const Value *v, JSBool *bp)
Class *clasp = obj->getClass();
if (clasp->hasInstance)
return clasp->hasInstance(cx, obj, v, bp);
RootedValue val(cx, ObjectValue(*obj));
js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
JSDVG_SEARCH_STACK, ObjectValue(*obj), NULL);
JSDVG_SEARCH_STACK, val, NullPtr());
return JS_FALSE;
}
@ -880,8 +888,8 @@ DoIncDec(JSContext *cx, HandleScript script, jsbytecode *pc, const Value &v, Val
#define FETCH_OBJECT(cx, n, obj) \
JS_BEGIN_MACRO \
Value *vp_ = &regs.sp[n]; \
obj = ToObject(cx, (vp_)); \
HandleValue val = HandleValue::fromMarkedLocation(&regs.sp[n]); \
obj = ToObject(cx, (val)); \
if (!obj) \
goto error; \
JS_END_MACRO
@ -1675,9 +1683,9 @@ END_CASE(JSOP_AND)
BEGIN_CASE(JSOP_IN)
{
const Value &rref = regs.sp[-1];
HandleValue rref = HandleValue::fromMarkedLocation(&regs.sp[-1]);
if (!rref.isObject()) {
js_ReportValueError(cx, JSMSG_IN_NOT_OBJECT, -1, rref, NULL);
js_ReportValueError(cx, JSMSG_IN_NOT_OBJECT, -1, rref, NullPtr());
goto error;
}
RootedObject &obj = rootObject0;
@ -2204,8 +2212,9 @@ BEGIN_CASE(JSOP_TOID)
* There must be an object value below the id, which will not be popped
* but is necessary in interning the id for XML.
*/
Value objval = regs.sp[-2];
Value idval = regs.sp[-1];
RootedValue &objval = rootValue0, &idval = rootValue1;
objval = regs.sp[-2];
idval = regs.sp[-1];
MutableHandleValue res = MutableHandleValue::fromMarkedLocation(&regs.sp[-1]);
if (!ToIdOperation(cx, objval, idval, res))
@ -2300,8 +2309,11 @@ BEGIN_CASE(JSOP_GETXPROP)
BEGIN_CASE(JSOP_LENGTH)
BEGIN_CASE(JSOP_CALLPROP)
{
RootedValue &lval = rootValue0;
lval = regs.sp[-1];
RootedValue rval(cx);
if (!GetPropertyOperation(cx, script, regs.pc, regs.sp[-1], rval.address()))
if (!GetPropertyOperation(cx, regs.pc, &lval, &rval))
goto error;
TypeScript::Monitor(cx, script, regs.pc, rval);
@ -2315,8 +2327,8 @@ BEGIN_CASE(JSOP_SETGNAME)
BEGIN_CASE(JSOP_SETNAME)
BEGIN_CASE(JSOP_SETPROP)
{
const Value &rval = regs.sp[-1];
const Value &lval = regs.sp[-2];
HandleValue lval = HandleValue::fromMarkedLocation(&regs.sp[-2]);
HandleValue rval = HandleValue::fromMarkedLocation(&regs.sp[-1]);
if (!SetPropertyOperation(cx, regs.pc, lval, rval))
goto error;
@ -2329,10 +2341,11 @@ END_CASE(JSOP_SETPROP)
BEGIN_CASE(JSOP_GETELEM)
BEGIN_CASE(JSOP_CALLELEM)
{
Value &lref = regs.sp[-2];
Value &rref = regs.sp[-1];
MutableHandleValue lval = MutableHandleValue::fromMarkedLocation(&regs.sp[-2]);
HandleValue rval = HandleValue::fromMarkedLocation(&regs.sp[-1]);
MutableHandleValue res = MutableHandleValue::fromMarkedLocation(&regs.sp[-2]);
if (!GetElementOperation(cx, op, lref, rref, res))
if (!GetElementOperation(cx, op, lval, rval, res))
goto error;
TypeScript::Monitor(cx, script, regs.pc, res);
regs.sp--;
@ -3263,9 +3276,10 @@ BEGIN_CASE(JSOP_THROW)
BEGIN_CASE(JSOP_INSTANCEOF)
{
const Value &rref = regs.sp[-1];
RootedValue &rref = rootValue0;
rref = regs.sp[-1];
if (rref.isPrimitive()) {
js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS, -1, rref, NULL);
js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS, -1, rref, NullPtr());
goto error;
}
RootedObject &obj = rootObject0;
@ -3703,8 +3717,9 @@ BEGIN_CASE(JSOP_YIELD)
JS_ASSERT(!cx->isExceptionPending());
JS_ASSERT(regs.fp()->isNonEvalFunctionFrame());
if (cx->innermostGenerator()->state == JSGEN_CLOSING) {
js_ReportValueError(cx, JSMSG_BAD_GENERATOR_YIELD, JSDVG_SEARCH_STACK,
ObjectValue(regs.fp()->callee()), NULL);
RootedValue &val = rootValue0;
val.setObject(regs.fp()->callee());
js_ReportValueError(cx, JSMSG_BAD_GENERATOR_YIELD, JSDVG_SEARCH_STACK, val, NullPtr());
goto error;
}
regs.fp()->setReturnValue(regs.sp[-1]);

View File

@ -144,7 +144,7 @@ GuardFunApplyArgumentsOptimization(JSContext *cx)
* problem to the value at |spindex| on the stack.
*/
JS_ALWAYS_INLINE JSObject *
ValuePropertyBearer(JSContext *cx, StackFrame *fp, const Value &v, int spindex)
ValuePropertyBearer(JSContext *cx, StackFrame *fp, HandleValue v, int spindex)
{
if (v.isObject())
return &v.toObject();
@ -159,7 +159,7 @@ ValuePropertyBearer(JSContext *cx, StackFrame *fp, const Value &v, int spindex)
return global.getOrCreateBooleanPrototype(cx);
JS_ASSERT(v.isNull() || v.isUndefined());
js_ReportIsNullOrUndefined(cx, spindex, v, NULL);
js_ReportIsNullOrUndefined(cx, spindex, v, NullPtr());
return NULL;
}
@ -205,27 +205,27 @@ GetPropertyGenericMaybeCallXML(JSContext *cx, JSOp op, HandleObject obj, HandleI
}
inline bool
GetPropertyOperation(JSContext *cx, JSScript *script, jsbytecode *pc, Value &lval, Value *vp)
GetPropertyOperation(JSContext *cx, jsbytecode *pc, MutableHandleValue lval, MutableHandleValue vp)
{
JS_ASSERT(vp != &lval);
JS_ASSERT(vp.address() != lval.address());
JSOp op = JSOp(*pc);
if (op == JSOP_LENGTH) {
/* Optimize length accesses on strings, arrays, and arguments. */
if (lval.isString()) {
*vp = Int32Value(lval.toString()->length());
vp.setInt32(lval.toString()->length());
return true;
}
if (IsOptimizedArguments(cx->fp(), &lval)) {
*vp = Int32Value(cx->fp()->numActualArgs());
if (IsOptimizedArguments(cx->fp(), lval.address())) {
vp.setInt32(cx->fp()->numActualArgs());
return true;
}
if (lval.isObject()) {
JSObject *obj = &lval.toObject();
if (obj->isArray()) {
uint32_t length = obj->getArrayLength();
*vp = NumberValue(length);
vp.setNumber(length);
return true;
}
@ -234,19 +234,19 @@ GetPropertyOperation(JSContext *cx, JSScript *script, jsbytecode *pc, Value &lva
if (!argsobj->hasOverriddenLength()) {
uint32_t length = argsobj->initialLength();
JS_ASSERT(length < INT32_MAX);
*vp = Int32Value(int32_t(length));
vp.setInt32(int32_t(length));
return true;
}
}
if (obj->isTypedArray()) {
*vp = Int32Value(TypedArray::length(obj));
vp.setInt32(TypedArray::length(obj));
return true;
}
}
}
RootedObject obj(cx, ValueToObject(cx, lval));
RootedObject obj(cx, ToObjectFromStack(cx, lval));
if (!obj)
return false;
@ -256,40 +256,38 @@ GetPropertyOperation(JSContext *cx, JSScript *script, jsbytecode *pc, Value &lva
JS_PROPERTY_CACHE(cx).test(cx, pc, obj.get(), obj2.get(), entry, name);
if (!name) {
AssertValidPropertyCacheHit(cx, obj, obj2, entry);
if (!NativeGet(cx, obj, obj2, entry->prop, JSGET_CACHE_RESULT, vp))
if (!NativeGet(cx, obj, obj2, entry->prop, JSGET_CACHE_RESULT, vp.address()))
return false;
return true;
}
RootedId id(cx, NameToId(name));
RootedValue value(cx);
if (obj->getOps()->getProperty) {
if (!GetPropertyGenericMaybeCallXML(cx, op, obj, id, &value))
if (!GetPropertyGenericMaybeCallXML(cx, op, obj, id, vp))
return false;
} else {
if (!GetPropertyHelper(cx, obj, id, JSGET_CACHE_RESULT, &value))
if (!GetPropertyHelper(cx, obj, id, JSGET_CACHE_RESULT, vp))
return false;
}
#if JS_HAS_NO_SUCH_METHOD
if (op == JSOP_CALLPROP &&
JS_UNLIKELY(value.isPrimitive()) &&
JS_UNLIKELY(vp.isPrimitive()) &&
lval.isObject())
{
if (!OnUnknownMethod(cx, obj, IdToValue(id), &value))
if (!OnUnknownMethod(cx, obj, IdToValue(id), vp))
return false;
}
#endif
*vp = value;
return true;
}
inline bool
SetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, const Value &rval)
SetPropertyOperation(JSContext *cx, jsbytecode *pc, HandleValue lval, HandleValue rval)
{
RootedObject obj(cx, ValueToObject(cx, lval));
RootedObject obj(cx, ToObjectFromStack(cx, lval));
if (!obj)
return false;
@ -505,10 +503,8 @@ AddOperation(JSContext *cx, const Value &lhs, const Value &rhs, Value *res)
} else
#endif
{
RootedValue lval_(cx, lhs);
RootedValue rval_(cx, rhs);
Value &lval = lval_.get();
Value &rval = rval_.get();
RootedValue lval(cx, lhs);
RootedValue rval(cx, rhs);
/*
* If either operand is an object, any non-integer result must be
@ -516,9 +512,9 @@ AddOperation(JSContext *cx, const Value &lhs, const Value &rhs, Value *res)
*/
bool lIsObject = lval.isObject(), rIsObject = rval.isObject();
if (!ToPrimitive(cx, &lval))
if (!ToPrimitive(cx, lval.address()))
return false;
if (!ToPrimitive(cx, &rval))
if (!ToPrimitive(cx, rval.address()))
return false;
bool lIsString, rIsString;
if ((lIsString = lval.isString()) | (rIsString = rval.isString())) {
@ -629,14 +625,14 @@ FetchElementId(JSContext *cx, JSObject *obj, const Value &idval, jsid *idp, Muta
}
static JS_ALWAYS_INLINE bool
ToIdOperation(JSContext *cx, const Value &objval, const Value &idval, MutableHandleValue res)
ToIdOperation(JSContext *cx, HandleValue objval, HandleValue idval, MutableHandleValue res)
{
if (idval.isInt32()) {
res.set(idval);
return true;
}
JSObject *obj = ValueToObject(cx, objval);
JSObject *obj = ToObjectFromStack(cx, objval);
if (!obj)
return false;
@ -710,7 +706,8 @@ GetObjectElementOperation(JSContext *cx, JSOp op, HandleObject obj, const Value
}
static JS_ALWAYS_INLINE bool
GetElementOperation(JSContext *cx, JSOp op, Value &lref, const Value &rref, MutableHandleValue res)
GetElementOperation(JSContext *cx, JSOp op, MutableHandleValue lref, HandleValue rref,
MutableHandleValue res)
{
JS_ASSERT(op == JSOP_GETELEM || op == JSOP_CALLELEM);
@ -727,7 +724,7 @@ GetElementOperation(JSContext *cx, JSOp op, Value &lref, const Value &rref, Muta
}
StackFrame *fp = cx->fp();
if (IsOptimizedArguments(fp, &lref)) {
if (IsOptimizedArguments(fp, lref.address())) {
if (rref.isInt32()) {
int32_t i = rref.toInt32();
if (i >= 0 && uint32_t(i) < fp->numActualArgs()) {
@ -739,11 +736,11 @@ GetElementOperation(JSContext *cx, JSOp op, Value &lref, const Value &rref, Muta
if (!JSScript::argumentsOptimizationFailed(cx, fp->script()))
return false;
lref = ObjectValue(fp->argsObj());
lref.set(ObjectValue(fp->argsObj()));
}
bool isObject = lref.isObject();
RootedObject obj(cx, ValueToObject(cx, lref));
RootedObject obj(cx, ToObjectFromStack(cx, lref));
if (!obj)
return false;
if (!GetObjectElementOperation(cx, op, obj, rref, res))

View File

@ -343,7 +343,7 @@ GetCustomIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandle
JS_CHECK_RECURSION(cx, return false);
/* Check whether we have a valid __iterator__ method. */
PropertyName *name = cx->runtime->atomState.iteratorIntrinsicAtom;
RootedPropertyName name(cx, cx->runtime->atomState.iteratorIntrinsicAtom);
if (!GetMethod(cx, obj, name, 0, vp))
return false;
@ -368,8 +368,9 @@ GetCustomIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandle
JSAutoByteString bytes;
if (!js_AtomToPrintableString(cx, name, &bytes))
return false;
RootedValue val(cx, ObjectValue(*obj));
js_ReportValueError2(cx, JSMSG_BAD_TRAP_RETURN_VALUE,
-1, ObjectValue(*obj), NULL, bytes.ptr());
-1, val, NullPtr(), bytes.ptr());
return false;
}
return true;
@ -578,7 +579,8 @@ GetIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandleValue
// for this kind of error anyway, but it would throw an inscrutable
// error message about |method| rather than this nice one about |obj|.
if (!method.isObject() || !method.toObject().isCallable()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, ObjectOrNullValue(obj), NULL);
RootedValue val(cx, ObjectOrNullValue(obj));
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, val, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_ITERABLE, bytes);
@ -589,8 +591,10 @@ GetIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandleValue
if (!Invoke(cx, ObjectOrNullValue(obj), method, 0, NULL, vp.address()))
return false;
if (!ToObject(cx, vp.address()))
JSObject *obj = ToObject(cx, vp);
if (!obj)
return false;
vp.setObject(*obj);
return true;
}
@ -846,7 +850,7 @@ const uint32_t CLOSED_INDEX = UINT32_MAX;
JSObject *
ElementIteratorObject::create(JSContext *cx, Handle<Value> target)
{
GlobalObject *global = GetCurrentGlobal(cx);
Rooted<GlobalObject*> global(cx, GetCurrentGlobal(cx));
Rooted<JSObject*> proto(cx, global->getOrCreateElementIteratorPrototype(cx));
if (!proto)
return NULL;
@ -874,16 +878,16 @@ ElementIteratorObject::next(JSContext *cx, unsigned argc, Value *vp)
bool
ElementIteratorObject::next_impl(JSContext *cx, CallArgs args)
{
JSObject *iterobj = &args.thisv().toObject();
RootedObject iterobj(cx, &args.thisv().toObject());
uint32_t i, length;
Value target = iterobj->getReservedSlot(TargetSlot);
RootedValue target(cx, iterobj->getReservedSlot(TargetSlot));
Rooted<JSObject*> obj(cx);
// Get target.length.
if (target.isString()) {
length = uint32_t(target.toString()->length());
} else {
obj = ValueToObject(cx, target);
obj = ToObjectFromStack(cx, target);
if (!obj)
goto close;
if (!js_GetLengthProperty(cx, obj, &length))
@ -1605,8 +1609,9 @@ generator_send_impl(JSContext *cx, CallArgs args)
}
if (gen->state == JSGEN_NEWBORN && args.hasDefined(0)) {
RootedValue val(cx, args[0]);
js_ReportValueError(cx, JSMSG_BAD_GENERATOR_SEND,
JSDVG_SEARCH_STACK, args[0], NULL);
JSDVG_SEARCH_STACK, val, NullPtr());
return false;
}

View File

@ -329,6 +329,8 @@ js_TraceSharpMap(JSTracer *trc, JSSharpObjectMap *map)
static JSBool
obj_toSource(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
bool comma = false;
const jschar *vchars;
size_t vlength;
@ -345,7 +347,7 @@ obj_toSource(JSContext *cx, unsigned argc, Value *vp)
/* If outermost, we need parentheses to be an expression, not a block. */
bool outermost = (cx->sharpObjectMap.depth == 0);
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -364,7 +366,7 @@ obj_toSource(JSContext *cx, unsigned argc, Value *vp)
JSString *str = js_NewStringCopyZ(cx, "{}");
if (!str)
return false;
vp->setString(str);
args.rval().setString(str);
return true;
}
@ -537,7 +539,7 @@ obj_toSource(JSContext *cx, unsigned argc, Value *vp)
JSString *str = buf.finishString();
if (!str)
return false;
vp->setString(str);
args.rval().setString(str);
return true;
}
#endif /* JS_HAS_TOSOURCE */
@ -594,22 +596,22 @@ InformalValueTypeName(const Value &v)
static JSBool
obj_toString(JSContext *cx, unsigned argc, Value *vp)
{
Value &thisv = vp[1];
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
if (thisv.isUndefined()) {
vp->setString(cx->runtime->atomState.objectUndefinedAtom);
if (args.thisv().isUndefined()) {
args.rval().setString(cx->runtime->atomState.objectUndefinedAtom);
return true;
}
/* Step 2. */
if (thisv.isNull()) {
vp->setString(cx->runtime->atomState.objectNullAtom);
if (args.thisv().isNull()) {
args.rval().setString(cx->runtime->atomState.objectNullAtom);
return true;
}
/* Step 3. */
JSObject *obj = ToObject(cx, &thisv);
JSObject *obj = ToObject(cx, args.thisv());
if (!obj)
return false;
@ -617,7 +619,7 @@ obj_toString(JSContext *cx, unsigned argc, Value *vp)
JSString *str = js::obj_toStringHelper(cx, obj);
if (!str)
return false;
vp->setString(str);
args.rval().setString(str);
return true;
}
@ -630,7 +632,7 @@ obj_toLocaleString(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
JSObject *obj = ToObject(cx, &args.thisv());
JSObject *obj = ToObject(cx, args.thisv());
if (!obj)
return false;
@ -642,10 +644,11 @@ obj_toLocaleString(JSContext *cx, unsigned argc, Value *vp)
static JSBool
obj_valueOf(JSContext *cx, unsigned argc, Value *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
CallArgs args = CallArgsFromVp(argc, vp);
JSObject *obj = ToObject(cx, args.thisv());
if (!obj)
return false;
vp->setObject(*obj);
args.rval().setObject(*obj);
return true;
}
@ -684,20 +687,22 @@ obj_watch_handler(JSContext *cx, JSObject *obj_, jsid id_, jsval old,
static JSBool
obj_watch(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (argc <= 1) {
js_ReportMissingArg(cx, *vp, 1);
js_ReportMissingArg(cx, args.calleev(), 1);
return false;
}
RootedObject callable(cx, ValueToCallable(cx, &vp[3]));
RootedObject callable(cx, ValueToCallable(cx, &args[1]));
if (!callable)
return false;
RootedId propid(cx);
if (!ValueToId(cx, vp[2], propid.address()))
if (!ValueToId(cx, args[0], propid.address()))
return false;
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
@ -706,7 +711,7 @@ obj_watch(JSContext *cx, unsigned argc, Value *vp)
if (!CheckAccess(cx, obj, propid, JSACC_WATCH, &tmp, &attrs))
return false;
vp->setUndefined();
args.rval().setUndefined();
if (obj->isDenseArray() && !JSObject::makeDenseArraySlow(cx, obj))
return false;
@ -716,13 +721,15 @@ obj_watch(JSContext *cx, unsigned argc, Value *vp)
static JSBool
obj_unwatch(JSContext *cx, unsigned argc, Value *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
vp->setUndefined();
args.rval().setUndefined();
jsid id;
if (argc != 0) {
if (!ValueToId(cx, vp[2], &id))
if (!ValueToId(cx, args[0], &id))
return false;
} else {
id = JSID_VOID;
@ -741,21 +748,25 @@ obj_unwatch(JSContext *cx, unsigned argc, Value *vp)
static JSBool
obj_hasOwnProperty(JSContext *cx, unsigned argc, Value *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
return js_HasOwnPropertyHelper(cx, obj->getOps()->lookupGeneric, argc, vp);
return js_HasOwnPropertyHelper(cx, obj->getOps()->lookupGeneric, argc, args.rval().address());
}
JSBool
js_HasOwnPropertyHelper(JSContext *cx, LookupGenericOp lookup, unsigned argc,
Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedId id(cx);
if (!ValueToId(cx, argc != 0 ? vp[2] : UndefinedValue(), id.address()))
if (!ValueToId(cx, args.length() ? args[0] : UndefinedValue(), id.address()))
return JS_FALSE;
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
RootedObject obj2(cx);
@ -764,12 +775,12 @@ js_HasOwnPropertyHelper(JSContext *cx, LookupGenericOp lookup, unsigned argc,
bool has;
if (!Proxy::hasOwn(cx, obj, id, &has))
return false;
vp->setBoolean(has);
args.rval().setBoolean(has);
return true;
}
if (!js_HasOwnProperty(cx, lookup, obj, id, &obj2, &prop))
return JS_FALSE;
vp->setBoolean(!!prop);
args.rval().setBoolean(!!prop);
return JS_TRUE;
}
@ -808,19 +819,21 @@ js_HasOwnProperty(JSContext *cx, LookupGenericOp lookup, HandleObject obj, Handl
static JSBool
obj_isPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
if (argc < 1 || !vp[2].isObject()) {
vp->setBoolean(false);
if (args.length() < 1 || !args[0].isObject()) {
args.rval().setBoolean(false);
return true;
}
/* Step 2. */
JSObject *obj = ToObject(cx, &vp[1]);
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
/* Step 3. */
vp->setBoolean(js_IsDelegate(cx, obj, vp[2]));
args.rval().setBoolean(js_IsDelegate(cx, obj, args[0]));
return true;
}
@ -828,18 +841,20 @@ obj_isPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
static JSBool
obj_propertyIsEnumerable(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
RootedId id(cx);
if (!ValueToId(cx, argc != 0 ? vp[2] : UndefinedValue(), id.address()))
if (!ValueToId(cx, args.length() ? args[0] : UndefinedValue(), id.address()))
return false;
/* Step 2. */
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
/* Steps 3-5. */
return js_PropertyIsEnumerable(cx, obj, id, vp);
return js_PropertyIsEnumerable(cx, obj, id, args.rval().address());
}
JSBool
@ -941,32 +956,34 @@ js::obj_defineSetter(JSContext *cx, unsigned argc, Value *vp)
static JSBool
obj_lookupGetter(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedId id(cx);
if (!ValueToId(cx, argc != 0 ? vp[2] : UndefinedValue(), id.address()))
if (!ValueToId(cx, args.length() ? args[0] : UndefinedValue(), id.address()))
return JS_FALSE;
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return JS_FALSE;
if (obj->isProxy()) {
// The vanilla getter lookup code below requires that the object is
// native. Handle proxies separately.
vp->setUndefined();
args.rval().setUndefined();
AutoPropertyDescriptorRooter desc(cx);
if (!Proxy::getPropertyDescriptor(cx, obj, id, false, &desc))
return JS_FALSE;
if (desc.obj && (desc.attrs & JSPROP_GETTER) && desc.getter)
*vp = CastAsObjectJsval(desc.getter);
args.rval().set(CastAsObjectJsval(desc.getter));
return JS_TRUE;
}
RootedObject pobj(cx);
RootedShape shape(cx);
if (!obj->lookupGeneric(cx, id, &pobj, &shape))
return JS_FALSE;
vp->setUndefined();
args.rval().setUndefined();
if (shape) {
if (pobj->isNative()) {
if (shape->hasGetterValue())
*vp = shape->getterValue();
args.rval().set(shape->getterValue());
}
}
return JS_TRUE;
@ -975,32 +992,34 @@ obj_lookupGetter(JSContext *cx, unsigned argc, Value *vp)
static JSBool
obj_lookupSetter(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedId id(cx);
if (!ValueToId(cx, argc != 0 ? vp[2] : UndefinedValue(), id.address()))
if (!ValueToId(cx, args.length() ? args[0] : UndefinedValue(), id.address()))
return JS_FALSE;
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return JS_FALSE;
if (obj->isProxy()) {
// The vanilla setter lookup code below requires that the object is
// native. Handle proxies separately.
vp->setUndefined();
args.rval().setUndefined();
AutoPropertyDescriptorRooter desc(cx);
if (!Proxy::getPropertyDescriptor(cx, obj, id, false, &desc))
return JS_FALSE;
if (desc.obj && (desc.attrs & JSPROP_SETTER) && desc.setter)
*vp = CastAsObjectJsval(desc.setter);
args.rval().set(CastAsObjectJsval(desc.setter));
return JS_TRUE;
}
RootedObject pobj(cx);
RootedShape shape(cx);
if (!obj->lookupGeneric(cx, id, &pobj, &shape))
return JS_FALSE;
vp->setUndefined();
args.rval().setUndefined();
if (shape) {
if (pobj->isNative()) {
if (shape->hasSetterValue())
*vp = shape->setterValue();
args.rval().set(shape->setterValue());
}
}
return JS_TRUE;
@ -1020,7 +1039,8 @@ obj_getPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
}
if (args[0].isPrimitive()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, vp[2], NULL);
RootedValue val(cx, args[0]);
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, val, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
@ -1038,8 +1058,8 @@ obj_getPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
InvokeArgsGuard nested;
if (!cx->stack.pushInvokeArgs(cx, 0, &nested))
return false;
nested.calleev() = cx->global()->protoGetter();
nested.thisv() = args[0];
nested.setCallee(cx->global()->protoGetter());
nested.setThis(args[0]);
if (!Invoke(cx, nested))
return false;
args.rval().set(nested.rval());
@ -1189,9 +1209,9 @@ GetFirstArgumentAsObject(JSContext *cx, unsigned argc, Value *vp, const char *me
return false;
}
const Value &v = vp[2];
RootedValue v(cx, vp[2]);
if (!v.isObject()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL);
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNEXPECTED_TYPE,
@ -1397,9 +1417,10 @@ bool
Throw(JSContext *cx, JSObject *obj, unsigned errorNumber)
{
if (js_ErrorFormatString[errorNumber].argCount == 1) {
RootedValue val(cx, ObjectValue(*obj));
js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,
JSDVG_IGNORE_STACK, ObjectValue(*obj),
NULL, NULL, NULL);
JSDVG_IGNORE_STACK, val, NullPtr(),
NULL, NULL);
} else {
JS_ASSERT(js_ErrorFormatString[errorNumber].argCount == 0);
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, errorNumber);
@ -1924,19 +1945,22 @@ js_PopulateObject(JSContext *cx, HandleObject newborn, HandleObject props)
static JSBool
obj_defineProperties(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
/* Steps 1 and 7. */
RootedObject obj(cx);
if (!GetFirstArgumentAsObject(cx, argc, vp, "Object.defineProperties", &obj))
if (!GetFirstArgumentAsObject(cx, args.length(), vp, "Object.defineProperties", &obj))
return false;
vp->setObject(*obj);
args.rval().setObject(*obj);
/* Step 2. */
if (argc < 2) {
if (args.length() < 2) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED,
"Object.defineProperties", "0", "s");
return false;
}
RootedObject props(cx, ToObject(cx, &vp[3]));
RootedValue val(cx, args[1]);
RootedObject props(cx, ToObject(cx, val));
if (!props)
return false;
@ -1955,9 +1979,9 @@ obj_create(JSContext *cx, unsigned argc, Value *vp)
}
CallArgs args = CallArgsFromVp(argc, vp);
const Value &v = args[0];
RootedValue v(cx, args[0]);
if (!v.isObjectOrNull()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL);
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNEXPECTED_TYPE,
@ -4697,9 +4721,10 @@ js_GetPropertyHelperInline(JSContext *cx, HandleObject obj, HandleObject receive
cx->stack.currentScript()->warnedAboutUndefinedProp = true;
/* Ok, bad undefined property reference: whine about it. */
RootedValue val(cx, IdToValue(id));
if (!js_ReportValueErrorFlags(cx, flags, JSMSG_UNDEFINED_PROP,
JSDVG_IGNORE_STACK, IdToValue(id),
NULL, NULL, NULL))
JSDVG_IGNORE_STACK, val, NullPtr(),
NULL, NULL))
{
return false;
}
@ -4809,25 +4834,28 @@ js::CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname)
bool
JSObject::reportReadOnly(JSContext *cx, jsid id, unsigned report)
{
RootedValue val(cx, IdToValue(id));
return js_ReportValueErrorFlags(cx, report, JSMSG_READ_ONLY,
JSDVG_IGNORE_STACK, IdToValue(id), NULL,
JSDVG_IGNORE_STACK, val, NullPtr(),
NULL, NULL);
}
bool
JSObject::reportNotConfigurable(JSContext *cx, jsid id, unsigned report)
{
RootedValue val(cx, IdToValue(id));
return js_ReportValueErrorFlags(cx, report, JSMSG_CANT_DELETE,
JSDVG_IGNORE_STACK, IdToValue(id), NULL,
JSDVG_IGNORE_STACK, val, NullPtr(),
NULL, NULL);
}
bool
JSObject::reportNotExtensible(JSContext *cx, unsigned report)
{
RootedValue val(cx, ObjectValue(*this));
return js_ReportValueErrorFlags(cx, report, JSMSG_OBJECT_NOT_EXTENSIBLE,
JSDVG_IGNORE_STACK, ObjectValue(*this),
NULL, NULL, NULL);
JSDVG_IGNORE_STACK, val, NullPtr(),
NULL, NULL);
}
bool
@ -5265,7 +5293,7 @@ DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp
}
/* Avoid recursive death when decompiling in js_ReportValueError. */
JSString *str;
RootedString str(cx);
if (hint == JSTYPE_STRING) {
str = JS_InternString(cx, clasp->name);
if (!str)
@ -5274,7 +5302,8 @@ DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp
str = NULL;
}
js_ReportValueError2(cx, JSMSG_CANT_CONVERT_TO, JSDVG_SEARCH_STACK, ObjectValue(*obj), str,
RootedValue val(cx, ObjectValue(*obj));
js_ReportValueError2(cx, JSMSG_CANT_CONVERT_TO, JSDVG_SEARCH_STACK, val, str,
(hint == JSTYPE_VOID) ? "primitive type" : JS_TYPE_STR(hint));
return false;
}
@ -5489,21 +5518,22 @@ namespace js {
/* Callers must handle the already-object case . */
JSObject *
ToObjectSlow(JSContext *cx, Value *vp)
ToObjectSlow(JSContext *cx, HandleValue val, bool reportScanStack)
{
JS_ASSERT(!vp->isMagic());
JS_ASSERT(!vp->isObject());
JS_ASSERT(!val.isMagic());
JS_ASSERT(!val.isObject());
if (vp->isNullOrUndefined()) {
if (val.isNullOrUndefined()) {
if (reportScanStack) {
js_ReportIsNullOrUndefined(cx, JSDVG_SEARCH_STACK, val, NullPtr());
} else {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CONVERT_TO,
vp->isNull() ? "null" : "undefined", "object");
val.isNull() ? "null" : "undefined", "object");
}
return NULL;
}
JSObject *obj = PrimitiveToObject(cx, *vp);
if (obj)
vp->setObject(*obj);
return obj;
return PrimitiveToObject(cx, val);
}
}
@ -5515,8 +5545,10 @@ js_ValueToNonNullObject(JSContext *cx, const Value &v)
if (!js_ValueToObjectOrNull(cx, v, &obj))
return NULL;
if (!obj)
js_ReportIsNullOrUndefined(cx, JSDVG_SEARCH_STACK, v, NULL);
if (!obj) {
RootedValue val(cx, v);
js_ReportIsNullOrUndefined(cx, JSDVG_SEARCH_STACK, val, NullPtr());
}
return obj;
}

View File

@ -1334,27 +1334,29 @@ js_ValueToNonNullObject(JSContext *cx, const js::Value &v);
namespace js {
/*
* Invokes the ES5 ToObject algorithm on *vp, writing back the object to vp.
* If *vp might already be an object, use ToObject.
* Invokes the ES5 ToObject algorithm on vp, returning the result. If vp might
* already be an object, use ToObject. reportCantConvert controls how null and
* undefined errors are reported.
*/
extern JSObject *
ToObjectSlow(JSContext *cx, Value *vp);
ToObjectSlow(JSContext *cx, HandleValue vp, bool reportScanStack);
/* For object conversion in e.g. native functions. */
JS_ALWAYS_INLINE JSObject *
ToObject(JSContext *cx, Value *vp)
ToObject(JSContext *cx, HandleValue vp)
{
if (vp->isObject())
return &vp->toObject();
return ToObjectSlow(cx, vp);
if (vp.isObject())
return &vp.toObject();
return ToObjectSlow(cx, vp, false);
}
/* As for ToObject, but preserves the original value. */
inline JSObject *
ValueToObject(JSContext *cx, const Value &v)
/* For converting stack values to objects. */
JS_ALWAYS_INLINE JSObject *
ToObjectFromStack(JSContext *cx, HandleValue vp)
{
if (v.isObject())
return &v.toObject();
return js_ValueToNonNullObject(cx, v);
if (vp.isObject())
return &vp.toObject();
return ToObjectSlow(cx, vp, true);
}
} /* namespace js */

View File

@ -295,8 +295,8 @@ PreprocessValue(JSContext *cx, HandleObject holder, KeyType key, MutableHandleVa
if (!cx->stack.pushInvokeArgs(cx, 1, &args))
return false;
args.calleev() = toJSON;
args.thisv() = vp;
args.setCallee(toJSON);
args.setThis(vp);
args[0] = StringValue(keyStr);
if (!Invoke(cx, args))
@ -317,8 +317,8 @@ PreprocessValue(JSContext *cx, HandleObject holder, KeyType key, MutableHandleVa
if (!cx->stack.pushInvokeArgs(cx, 2, &args))
return false;
args.calleev() = ObjectValue(*scx->replacer);
args.thisv() = ObjectValue(*holder);
args.setCallee(ObjectValue(*scx->replacer));
args.setThis(ObjectValue(*holder));
args[0] = StringValue(keyStr);
args[1] = vp;
@ -838,8 +838,8 @@ Walk(JSContext *cx, HandleObject holder, HandleId name, HandleValue reviver, Mut
if (!cx->stack.pushInvokeArgs(cx, 2, &args))
return false;
args.calleev() = reviver;
args.thisv() = ObjectValue(*holder);
args.setCallee(reviver);
args.setThis(ObjectValue(*holder));
args[0] = StringValue(key);
args[1] = val;

View File

@ -6200,9 +6200,10 @@ DecompileExpressionFromStack(JSContext *cx, int spindex, Value v, char **res)
}
char *
js_DecompileValueGenerator(JSContext *cx, int spindex, jsval v,
JSString *fallback)
js::DecompileValueGenerator(JSContext *cx, int spindex, HandleValue v,
HandleString fallbackArg)
{
RootedString fallback(cx, fallbackArg);
{
char *result;
if (!DecompileExpressionFromStack(cx, spindex, v, &result))

View File

@ -321,22 +321,6 @@ js_DecompileToString(JSContext *cx, const char *name, JSFunction *fun,
unsigned indent, JSBool pretty, JSBool grouped, JSBool strict,
JSDecompilerPtr decompiler);
/*
* Find the source expression that resulted in v, and return a newly allocated
* C-string containing it. Fall back on v's string conversion (fallback) if we
* can't find the bytecode that generated and pushed v on the operand stack.
*
* Search the current stack frame if spindex is JSDVG_SEARCH_STACK. Don't
* look for v on the stack if spindex is JSDVG_IGNORE_STACK. Otherwise,
* spindex is the negative index of v, measured from cx->fp->sp, or from a
* lower frame's sp if cx->fp is native.
*
* The caller must call JS_free on the result after a succsesful call.
*/
extern char *
js_DecompileValueGenerator(JSContext *cx, int spindex, jsval v,
JSString *fallback);
/*
* Given bytecode address pc in script's main program code, return the operand
* stack depth just before (JSOp) *pc executes.
@ -361,12 +345,20 @@ js_GetVariableBytecodeLength(jsbytecode *pc);
namespace js {
static inline char *
DecompileValueGenerator(JSContext *cx, int spindex, const Value &v,
JSString *fallback)
{
return js_DecompileValueGenerator(cx, spindex, v, fallback);
}
/*
* Find the source expression that resulted in v, and return a newly allocated
* C-string containing it. Fall back on v's string conversion (fallback) if we
* can't find the bytecode that generated and pushed v on the operand stack.
*
* Search the current stack frame if spindex is JSDVG_SEARCH_STACK. Don't
* look for v on the stack if spindex is JSDVG_IGNORE_STACK. Otherwise,
* spindex is the negative index of v, measured from cx->fp->sp, or from a
* lower frame's sp if cx->fp is native.
*
* The caller must call JS_free on the result after a succsesful call.
*/
char *
DecompileValueGenerator(JSContext *cx, int spindex, HandleValue v, HandleString fallback);
/*
* Sprintf, but with unlimited and automatically allocated buffering.

View File

@ -352,8 +352,10 @@ bool
BaseProxyHandler::hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp)
{
JS_ASSERT(OperationInProgress(cx, proxy));
RootedValue val(cx, ObjectValue(*proxy));
js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
JSDVG_SEARCH_STACK, ObjectValue(*proxy), NULL);
JSDVG_SEARCH_STACK, val, NullPtr());
return false;
}
@ -493,7 +495,7 @@ bool
IndirectProxyHandler::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
CallArgs args)
{
args.thisv() = ObjectValue(*GetProxyTargetObject(&args.thisv().toObject()));
args.setThis(ObjectValue(*GetProxyTargetObject(&args.thisv().toObject())));
if (!test(args.thisv())) {
ReportIncompatible(cx, args);
return false;
@ -825,8 +827,9 @@ ReturnedValueMustNotBePrimitive(JSContext *cx, JSObject *proxy, JSAtom *atom, co
if (v.isPrimitive()) {
JSAutoByteString bytes;
if (js_AtomToPrintableString(cx, atom, &bytes)) {
RootedValue val(cx, ObjectOrNullValue(proxy));
js_ReportValueError2(cx, JSMSG_BAD_TRAP_RETURN_VALUE,
JSDVG_SEARCH_STACK, ObjectOrNullValue(proxy), NULL, bytes.ptr());
JSDVG_SEARCH_STACK, val, NullPtr(), bytes.ptr());
}
return false;
}
@ -1074,10 +1077,12 @@ class AutoPendingProxyOperation {
bool
Proxy::getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set,
Proxy::getPropertyDescriptor(JSContext *cx, JSObject *proxy_, jsid id_, bool set,
PropertyDescriptor *desc)
{
JS_CHECK_RECURSION(cx, return false);
RootedObject proxy(cx, proxy_);
RootedId id(cx, id_);
AutoPendingProxyOperation pending(cx, proxy);
BaseProxyHandler *handler = GetProxyHandler(proxy);
if (!handler->hasPrototype())
@ -1193,9 +1198,11 @@ Proxy::enumerate(JSContext *cx, JSObject *proxy, AutoIdVector &props)
}
bool
Proxy::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
Proxy::has(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
{
JS_CHECK_RECURSION(cx, return false);
RootedObject proxy(cx, proxy_);
RootedId id(cx, id_);
AutoPendingProxyOperation pending(cx, proxy);
BaseProxyHandler *handler = GetProxyHandler(proxy);
if (!handler->hasPrototype())
@ -1258,14 +1265,14 @@ Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id
JS_CHECK_RECURSION(cx, return false);
AutoPendingProxyOperation pending(cx, proxy);
BaseProxyHandler *handler = GetProxyHandler(proxy);
JSObject *proto;
RootedObject proto(cx);
if (handler->hasPrototype()) {
// If we're using a prototype, we still want to use the proxy trap unless
// we have a non-own property with a setter.
bool hasOwn;
AutoPropertyDescriptorRooter desc(cx);
if (handler->hasOwn(cx, proxy, id, &hasOwn) && !hasOwn &&
handler->getPrototypeOf(cx, proxy, &proto) && proto &&
handler->getPrototypeOf(cx, proxy, proto.address()) && proto &&
JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, &desc) &&
desc.obj && desc.setter)
{

View File

@ -186,7 +186,7 @@ class NodeBuilder
if (!funv.isObject() || !funv.toObject().isFunction()) {
js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_NOT_FUNCTION,
JSDVG_SEARCH_STACK, funv, NULL, NULL, NULL);
JSDVG_SEARCH_STACK, funv, NullPtr(), NULL, NULL);
return false;
}
@ -3183,12 +3183,12 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp)
JSObject *builder = NULL;
Value arg = argc > 1 ? JS_ARGV(cx, vp)[1] : UndefinedValue();
RootedValue arg(cx, argc > 1 ? JS_ARGV(cx, vp)[1] : UndefinedValue());
if (!arg.isNullOrUndefined()) {
if (!arg.isObject()) {
js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
JSDVG_SEARCH_STACK, arg, NULL, "not an object", NULL);
JSDVG_SEARCH_STACK, arg, NullPtr(), "not an object", NULL);
return JS_FALSE;
}
@ -3245,7 +3245,7 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp)
if (!prop.isNullOrUndefined()) {
if (!prop.isObject()) {
js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
JSDVG_SEARCH_STACK, prop, NULL, "not an object", NULL);
JSDVG_SEARCH_STACK, prop, NullPtr(), "not an object", NULL);
return JS_FALSE;
}
builder = &prop.toObject();

View File

@ -440,7 +440,7 @@ ThisToStringForStringProto(JSContext *cx, CallReceiver call)
Rooted<jsid> id(cx, NameToId(cx->runtime->atomState.toStringAtom));
if (ClassMethodIsNative(cx, obj, &StringClass, id, js_str_toString)) {
JSString *str = obj->asString().unbox();
call.thisv().setString(str);
call.setThis(StringValue(str));
return str;
}
}
@ -454,7 +454,7 @@ ThisToStringForStringProto(JSContext *cx, CallReceiver call)
if (!str)
return NULL;
call.thisv().setString(str);
call.setThis(StringValue(str));
return str;
}
@ -1022,7 +1022,7 @@ StringMatch(const jschar *text, uint32_t textlen,
static const size_t sRopeMatchThresholdRatioLog2 = 5;
/*
* RopeMatch takes the text to search, the patern to search for in the text.
* RopeMatch takes the text to search and the pattern to search for in the text.
* RopeMatch returns false on OOM and otherwise returns the match index through
* the 'match' outparam (-1 for not found).
*/
@ -1148,6 +1148,9 @@ str_contains(JSContext *cx, unsigned argc, Value *vp)
if (!text)
return false;
// XXX fix for moving GC.
SkipRoot skip(cx, &text);
if (args.hasDefined(1)) {
// Step 4
double posDouble;
@ -1325,6 +1328,9 @@ str_startsWith(JSContext *cx, unsigned argc, Value *vp)
if (!text)
return false;
// XXX fix for moving GC.
SkipRoot skip(cx, &text);
if (args.hasDefined(1)) {
// Step 4
double posDouble;
@ -1368,6 +1374,9 @@ str_endsWith(JSContext *cx, unsigned argc, Value *vp)
if (!text)
return false;
// XXX fix for moving GC.
SkipRoot skip(cx, &text);
if (args.hasDefined(1)) {
// Step 5
double endPosDouble;
@ -1978,7 +1987,7 @@ FindReplaceLength(JSContext *cx, RegExpStatics *res, ReplaceData &rdata, size_t
return false;
args.setCallee(ObjectValue(*lambda));
args.thisv() = UndefinedValue();
args.setThis(UndefinedValue());
/* Push $&, $1, $2, ... */
unsigned argi = 0;
@ -2296,8 +2305,8 @@ str_replace_flat_lambda(JSContext *cx, CallArgs outerArgs, ReplaceData &rdata, c
return false;
CallArgs &args = rdata.args;
args.calleev().setObject(*rdata.lambda);
args.thisv().setUndefined();
args.setCallee(ObjectValue(*rdata.lambda));
args.setThis(UndefinedValue());
Value *sp = args.array();
sp[0].setString(matchStr);
@ -2769,7 +2778,7 @@ static JSBool
str_substr(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
JSString *str = ThisToStringForStringProto(cx, args);
RootedString str(cx, ThisToStringForStringProto(cx, args));
if (!str)
return false;

View File

@ -46,8 +46,8 @@ class StringSegmentRange
* If malloc() shows up in any profiles from this vector, we can add a new
* StackAllocPolicy which stashes a reusable freed-at-gc buffer in the cx.
*/
Vector<JSString *, 32> stack;
JSLinearString *cur;
AutoStringVector stack;
Rooted<JSLinearString*> cur;
bool settle(JSString *str) {
while (str->isRope()) {
@ -62,7 +62,7 @@ class StringSegmentRange
public:
StringSegmentRange(JSContext *cx)
: stack(cx), cur(NULL)
: stack(cx), cur(cx)
{}
JS_WARN_UNUSED_RESULT bool init(JSString *str) {

View File

@ -143,10 +143,9 @@ ArrayBufferObject::fun_slice_impl(JSContext *cx, CallArgs args)
JS_ASSERT(IsArrayBuffer(args.thisv()));
Rooted<JSObject*> thisObj(cx, &args.thisv().toObject());
ArrayBufferObject &arrayBuffer = thisObj->asArrayBuffer();
// these are the default values
uint32_t length = arrayBuffer.byteLength();
uint32_t length = thisObj->asArrayBuffer().byteLength();
uint32_t begin = 0, end = length;
if (args.length() > 0) {
@ -162,7 +161,7 @@ ArrayBufferObject::fun_slice_impl(JSContext *cx, CallArgs args)
if (begin > end)
begin = end;
JSObject *nobj = createSlice(cx, arrayBuffer, begin, end);
JSObject *nobj = createSlice(cx, thisObj->asArrayBuffer(), begin, end);
if (!nobj)
return false;
args.rval().setObject(*nobj);
@ -1678,8 +1677,8 @@ class TypedArrayTemplate
if (!cx->stack.pushInvokeArgs(cx, 3, &ag))
return NULL;
ag.calleev() = cx->compartment->maybeGlobal()->createArrayFromBuffer<NativeType>();
ag.thisv() = ObjectValue(*bufobj);
ag.setCallee(cx->compartment->maybeGlobal()->createArrayFromBuffer<NativeType>());
ag.setThis(ObjectValue(*bufobj));
ag[0] = Int32Value(byteOffsetInt);
ag[1] = Int32Value(lengthInt);
ag[2] = ObjectValue(*proto);
@ -2262,8 +2261,8 @@ DataViewObject::class_constructor(JSContext *cx, unsigned argc, Value *vp)
InvokeArgsGuard ag;
if (!cx->stack.pushInvokeArgs(cx, argc + 1, &ag))
return false;
ag.calleev() = global->createDataViewForThis();
ag.thisv() = ObjectValue(*bufobj);
ag.setCallee(global->createDataViewForThis());
ag.setThis(ObjectValue(*bufobj));
PodCopy(ag.array(), args.array(), args.length());
ag[argc] = ObjectValue(*proto);
if (!Invoke(cx, ag))

View File

@ -205,7 +205,7 @@ static JSPropertySpec namespace_props[] = {
static JSBool
namespace_toString(JSContext *cx, unsigned argc, Value *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, HandleValue::fromMarkedLocation(&vp[1]));
if (!obj)
return JS_FALSE;
if (!obj->isNamespace()) {
@ -395,7 +395,7 @@ ConvertQNameToString(JSContext *cx, JSObject *obj)
static JSBool
qname_toString(JSContext *cx, unsigned argc, Value *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, HandleValue::fromMarkedLocation(&vp[1]));
if (!obj)
return false;
@ -1897,8 +1897,9 @@ ToXML(JSContext *cx, jsval v)
return obj;
bad:
RootedValue val(cx, v);
js_ReportValueError(cx, JSMSG_BAD_XML_CONVERSION,
JSDVG_IGNORE_STACK, v, NULL);
JSDVG_IGNORE_STACK, val, NullPtr());
return NULL;
}
@ -1973,8 +1974,9 @@ ToXMLList(JSContext *cx, jsval v)
return listobj;
bad:
RootedValue val(cx, v);
js_ReportValueError(cx, JSMSG_BAD_XMLLIST_CONVERSION,
JSDVG_IGNORE_STACK, v, NULL);
JSDVG_IGNORE_STACK, val, NullPtr());
return NULL;
}
@ -2789,8 +2791,9 @@ ToAttributeName(JSContext *cx, jsval v)
uri = prefix = cx->runtime->emptyString;
} else {
if (JSVAL_IS_PRIMITIVE(v)) {
RootedValue val(cx, v);
js_ReportValueError(cx, JSMSG_BAD_XML_ATTR_NAME,
JSDVG_IGNORE_STACK, v, NULL);
JSDVG_IGNORE_STACK, val, NullPtr());
return NULL;
}
@ -2825,7 +2828,8 @@ ToAttributeName(JSContext *cx, jsval v)
static void
ReportBadXMLName(JSContext *cx, const Value &idval)
{
js_ReportValueError(cx, JSMSG_BAD_XML_NAME, JSDVG_IGNORE_STACK, idval, NULL);
RootedValue val(cx, idval);
js_ReportValueError(cx, JSMSG_BAD_XML_NAME, JSDVG_IGNORE_STACK, val, NullPtr());
}
namespace js {
@ -5372,7 +5376,7 @@ StartNonListXMLMethod(JSContext *cx, jsval *vp, MutableHandleObject objp)
JS_ASSERT(!JSVAL_IS_PRIMITIVE(*vp));
JS_ASSERT(JSVAL_TO_OBJECT(*vp)->isFunction());
objp.set(ToObject(cx, &vp[1]));
objp.set(ToObject(cx, HandleValue::fromMarkedLocation(&vp[1])));
if (!objp)
return NULL;
if (!objp->isXML()) {
@ -5406,7 +5410,7 @@ StartNonListXMLMethod(JSContext *cx, jsval *vp, MutableHandleObject objp)
/* Beware: these two are not bracketed by JS_BEGIN/END_MACRO. */
#define XML_METHOD_PROLOG \
JSObject *obj = ToObject(cx, &vp[1]); \
JSObject *obj = ToObject(cx, HandleValue::fromMarkedLocation(&vp[1])); \
if (!obj) \
return JS_FALSE; \
if (!obj->isXML()) { \
@ -5490,7 +5494,8 @@ xml_attribute(JSContext *cx, unsigned argc, jsval *vp)
JSObject *qn;
if (argc == 0) {
js_ReportMissingArg(cx, *vp, 0);
RootedValue val(cx, *vp);
js_ReportMissingArg(cx, val, 0);
return JS_FALSE;
}
@ -5500,7 +5505,7 @@ xml_attribute(JSContext *cx, unsigned argc, jsval *vp)
vp[2] = OBJECT_TO_JSVAL(qn); /* local root */
RootedId id(cx, OBJECT_TO_JSID(qn));
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, HandleValue::fromMarkedLocation(&vp[1])));
if (!obj)
return JS_FALSE;
return GetProperty(cx, obj, id, MutableHandleValue::fromMarkedLocation(vp));
@ -5516,7 +5521,7 @@ xml_attributes(JSContext *cx, unsigned argc, jsval *vp)
return JS_FALSE;
RootedId id(cx, OBJECT_TO_JSID(qn));
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, HandleValue::fromMarkedLocation(&vp[1])));
if (!obj)
return JS_FALSE;
return GetProperty(cx, obj, id, MutableHandleValue::fromMarkedLocation(vp));
@ -5676,7 +5681,7 @@ xml_childIndex(JSContext *cx, unsigned argc, jsval *vp)
static JSBool
xml_children(JSContext *cx, unsigned argc, jsval *vp)
{
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, HandleValue::fromMarkedLocation(&vp[1])));
if (!obj)
return false;
RootedId name(cx, NameToId(cx->runtime->atomState.starAtom));
@ -5883,7 +5888,7 @@ xml_hasOwnProperty(JSContext *cx, unsigned argc, jsval *vp)
jsval name;
JSBool found;
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, HandleValue::fromMarkedLocation(&vp[1]));
if (!obj)
return JS_FALSE;
if (!obj->isXML()) {
@ -6925,7 +6930,7 @@ xml_toString_helper(JSContext *cx, JSXML *xml)
static JSBool
xml_toSource(JSContext *cx, unsigned argc, jsval *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, HandleValue::fromMarkedLocation(&vp[1]));
if (!obj)
return JS_FALSE;
JSString *str = ToXMLString(cx, OBJECT_TO_JSVAL(obj), TO_SOURCE_FLAG);
@ -6952,7 +6957,7 @@ xml_toString(JSContext *cx, unsigned argc, jsval *vp)
static JSBool
xml_toXMLString(JSContext *cx, unsigned argc, jsval *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, HandleValue::fromMarkedLocation(&vp[1]));
if (!obj)
return JS_FALSE;
JSString *str = ToXMLString(cx, OBJECT_TO_JSVAL(obj), 0);
@ -6966,7 +6971,7 @@ xml_toXMLString(JSContext *cx, unsigned argc, jsval *vp)
static JSBool
xml_valueOf(JSContext *cx, unsigned argc, jsval *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
JSObject *obj = ToObject(cx, HandleValue::fromMarkedLocation(&vp[1]));
if (!obj)
return false;
*vp = OBJECT_TO_JSVAL(obj);
@ -7066,7 +7071,7 @@ xml_settings(JSContext *cx, unsigned argc, jsval *vp)
if (!settings)
return false;
*vp = OBJECT_TO_JSVAL(settings);
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, HandleValue::fromMarkedLocation(&vp[1])));
if (!obj)
return false;
return CopyXMLSettings(cx, obj, settings);
@ -7078,7 +7083,7 @@ xml_setSettings(JSContext *cx, unsigned argc, jsval *vp)
jsval v;
JSBool ok;
RootedObject obj(cx, ToObject(cx, &vp[1]));
RootedObject obj(cx, ToObject(cx, HandleValue::fromMarkedLocation(&vp[1])));
if (!obj)
return JS_FALSE;
v = (argc == 0) ? JSVAL_VOID : vp[2];
@ -7882,7 +7887,8 @@ js_StepXMLListFilter(JSContext *cx, JSBool initialized)
* value stored in sp[-2].
*/
if (!VALUE_IS_XML(sp[-2])) {
js_ReportValueError(cx, JSMSG_NON_XML_FILTER, -2, sp[-2], NULL);
RootedValue val(cx, sp[-2]);
js_ReportValueError(cx, JSMSG_NON_XML_FILTER, -2, val, NullPtr());
return JS_FALSE;
}
obj = JSVAL_TO_OBJECT(sp[-2]);

View File

@ -1005,7 +1005,8 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
* portion of fun_hasInstance.
*/
if (f.regs.sp[0].isPrimitive()) {
js_ReportValueError(cx, JSMSG_BAD_PROTOTYPE, -1, f.regs.sp[-1], NULL);
RootedValue val(cx, f.regs.sp[-1]);
js_ReportValueError(cx, JSMSG_BAD_PROTOTYPE, -1, val, NullPtr());
return js_InternalThrow(f);
}
nextsp[-1].setBoolean(js_IsDelegate(cx, &f.regs.sp[0].toObject(), f.regs.sp[-2]));

View File

@ -771,7 +771,7 @@ class CallCompiler : public BaseCompiler
return false;
if (callingNew)
args.thisv().setMagic(JS_IS_CONSTRUCTING);
args.setThis(MagicValue(JS_IS_CONSTRUCTING));
RecompilationMonitor monitor(cx);

View File

@ -1948,6 +1948,8 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
}
}
RootedValue objval(f.cx, f.regs.sp[-1]);
if (f.regs.sp[-1].isString()) {
GetPropCompiler cc(f, NULL, *pic, name, stub);
if (name == f.cx->runtime->atomState.lengthAtom) {
@ -1960,7 +1962,7 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
LookupStatus status = cc.generateStringPropertyStub();
if (status == Lookup_Error)
THROW();
JSObject *obj = ValueToObject(f.cx, f.regs.sp[-1]);
JSObject *obj = ToObjectFromStack(f.cx, objval);
if (!obj)
THROW();
if (!obj->getProperty(f.cx, name, MutableHandleValue::fromMarkedLocation(&f.regs.sp[-1])))
@ -1971,7 +1973,7 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
RecompilationMonitor monitor(f.cx);
RootedObject obj(f.cx, ValueToObject(f.cx, f.regs.sp[-1]));
RootedObject obj(f.cx, ToObjectFromStack(f.cx, objval));
if (!obj)
THROW();
@ -1983,7 +1985,7 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
RootedValue v(f.cx);
if (cached) {
if (!GetPropertyOperation(f.cx, f.script(), f.pc(), f.regs.sp[-1], v.address()))
if (!GetPropertyOperation(f.cx, f.pc(), &objval, &v))
THROW();
} else {
if (!obj->getProperty(f.cx, name, &v))
@ -2013,7 +2015,8 @@ ic::SetProp(VMFrame &f, ic::PICInfo *pic)
RecompilationMonitor monitor(f.cx);
JSObject *obj = ValueToObject(f.cx, f.regs.sp[-2]);
RootedValue objval(f.cx, f.regs.sp[-2]);
JSObject *obj = ToObjectFromStack(f.cx, objval);
if (!obj)
THROW();
@ -2550,12 +2553,12 @@ ic::GetElement(VMFrame &f, ic::GetElementIC *ic)
return;
}
RootedValue idval_(cx, f.regs.sp[-1]);
Value &idval = idval_.get();
RootedValue idval(cx, f.regs.sp[-1]);
RecompilationMonitor monitor(cx);
RootedObject obj(cx, ValueToObject(cx, f.regs.sp[-2]));
RootedValue objval(f.cx, f.regs.sp[-2]);
RootedObject obj(cx, ToObjectFromStack(cx, objval));
if (!obj)
THROW();
@ -2583,7 +2586,7 @@ ic::GetElement(VMFrame &f, ic::GetElementIC *ic)
#ifdef DEBUG
f.regs.sp[-2] = MagicValue(JS_GENERIC_MAGIC);
#endif
LookupStatus status = ic->update(f, obj, idval_, id, res);
LookupStatus status = ic->update(f, obj, idval, id, res);
if (status != Lookup_Uncacheable && status != Lookup_NoProperty) {
if (status == Lookup_Error)
THROW();

View File

@ -72,8 +72,8 @@ void JS_FASTCALL
stubs::SetName(VMFrame &f, PropertyName *name)
{
JSContext *cx = f.cx;
const Value &rval = f.regs.sp[-1];
const Value &lval = f.regs.sp[-2];
HandleValue rval = HandleValue::fromMarkedLocation(&f.regs.sp[-1]);
HandleValue lval = HandleValue::fromMarkedLocation(&f.regs.sp[-2]);
if (!SetPropertyOperation(cx, f.pc(), lval, rval))
THROW();
@ -106,11 +106,11 @@ stubs::Name(VMFrame &f)
void JS_FASTCALL
stubs::GetElem(VMFrame &f)
{
Value &lref = f.regs.sp[-2];
Value &rref = f.regs.sp[-1];
MutableHandleValue lval = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-2]);
HandleValue rval = HandleValue::fromMarkedLocation(&f.regs.sp[-1]);
MutableHandleValue res = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-2]);
if (!GetElementOperation(f.cx, JSOp(*f.pc()), lref, rref, res))
if (!GetElementOperation(f.cx, JSOp(*f.pc()), lval, rval, res))
THROW();
}
@ -121,13 +121,13 @@ stubs::SetElem(VMFrame &f)
JSContext *cx = f.cx;
FrameRegs &regs = f.regs;
Value &objval = regs.sp[-3];
HandleValue objval = HandleValue::fromMarkedLocation(&regs.sp[-3]);
Value &idval = regs.sp[-2];
RootedValue rval(cx, regs.sp[-1]);
RootedId id(cx);
Rooted<JSObject*> obj(cx, ValueToObject(cx, objval));
Rooted<JSObject*> obj(cx, ToObjectFromStack(cx, objval));
if (!obj)
THROW();
@ -174,10 +174,10 @@ template void JS_FASTCALL stubs::SetElem<false>(VMFrame &f);
void JS_FASTCALL
stubs::ToId(VMFrame &f)
{
Value &objval = f.regs.sp[-2];
HandleValue objval = HandleValue::fromMarkedLocation(&f.regs.sp[-2]);
MutableHandleValue idval = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-1]);
JSObject *obj = ValueToObject(f.cx, objval);
JSObject *obj = ToObjectFromStack(f.cx, objval);
if (!obj)
THROW();
@ -983,8 +983,10 @@ stubs::GetProp(VMFrame &f, PropertyName *name)
JSContext *cx = f.cx;
FrameRegs &regs = f.regs;
MutableHandleValue objval = MutableHandleValue::fromMarkedLocation(&f.regs.sp[-1]);
RootedValue rval(cx);
if (!GetPropertyOperation(cx, f.script(), f.pc(), f.regs.sp[-1], rval.address()))
if (!GetPropertyOperation(cx, f.pc(), objval, &rval))
THROW();
regs.sp[-1] = rval;
@ -1142,10 +1144,10 @@ stubs::InstanceOf(VMFrame &f)
JSContext *cx = f.cx;
FrameRegs &regs = f.regs;
const Value &rref = regs.sp[-1];
RootedValue rref(cx, regs.sp[-1]);
if (rref.isPrimitive()) {
js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
-1, rref, NULL);
-1, rref, NullPtr());
THROWV(JS_FALSE);
}
RootedObject obj(cx, &rref.toObject());
@ -1167,7 +1169,8 @@ stubs::FastInstanceOf(VMFrame &f)
* Throw a runtime error if instanceof is called on a function that
* has a non-object as its .prototype value.
*/
js_ReportValueError(f.cx, JSMSG_BAD_PROTOTYPE, -1, f.regs.sp[-2], NULL);
RootedValue val(f.cx, f.regs.sp[-2]);
js_ReportValueError(f.cx, JSMSG_BAD_PROTOTYPE, -1, val, NullPtr());
THROW();
}
@ -1365,7 +1368,8 @@ stubs::DelProp(VMFrame &f, PropertyName *name_)
JSContext *cx = f.cx;
RootedPropertyName name(cx, name_);
JSObject *obj = ValueToObject(cx, f.regs.sp[-1]);
RootedValue objval(cx, f.regs.sp[-1]);
JSObject *obj = ToObjectFromStack(cx, objval);
if (!obj)
THROW();
@ -1385,7 +1389,8 @@ stubs::DelElem(VMFrame &f)
{
JSContext *cx = f.cx;
JSObject *obj = ValueToObject(cx, f.regs.sp[-2]);
RootedValue objval(cx, f.regs.sp[-2]);
JSObject *obj = ToObjectFromStack(cx, objval);
if (!obj)
THROW();
@ -1434,7 +1439,8 @@ stubs::In(VMFrame &f)
const Value &rref = f.regs.sp[-1];
if (!rref.isObject()) {
js_ReportValueError(cx, JSMSG_IN_NOT_OBJECT, -1, rref, NULL);
RootedValue val(cx, rref);
js_ReportValueError(cx, JSMSG_IN_NOT_OBJECT, -1, val, NullPtr());
THROWV(JS_FALSE);
}

View File

@ -2534,9 +2534,9 @@ NewSandbox(JSContext *cx, bool lazy)
static JSBool
EvalInContext(JSContext *cx, unsigned argc, jsval *vp)
{
JSString *str;
RootedString str(cx);
RootedObject sobj(cx);
if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S / o", &str, sobj.address()))
if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S / o", str.address(), sobj.address()))
return false;
size_t srclen;

View File

@ -105,8 +105,9 @@ ValueToIdentifier(JSContext *cx, const Value &v, jsid *idp)
if (!ValueToId(cx, v, &id))
return false;
if (!JSID_IS_ATOM(id) || !IsIdentifier(JSID_TO_ATOM(id))) {
RootedValue val(cx, v);
js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
JSDVG_SEARCH_STACK, v, NULL, "not an identifier", NULL);
JSDVG_SEARCH_STACK, val, NullPtr(), "not an identifier", NULL);
return false;
}
*idp = id;
@ -1472,7 +1473,6 @@ Debugger::sweepAll(FreeOp *fop)
for (GlobalObjectSet::Enum e(dbg->debuggees); !e.empty(); e.popFront())
dbg->removeDebuggeeGlobal(fop, e.front(), NULL, &e);
}
}
for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); c++) {
@ -1971,12 +1971,18 @@ Debugger::removeDebuggeeGlobal(FreeOp *fop, GlobalObject *global,
* for sure, and possibly the compartment's debuggee set.
*/
v->erase(p);
if (v->empty())
global->compartment()->removeDebuggee(fop, global, compartmentEnum);
if (debugEnum)
debugEnum->removeFront();
else
debuggees.remove(global);
/*
* The debuggee needs to be removed from the compartment last, as this can
* trigger GCs if the compartment's debug mode is being changed, and the
* global cannot be rooted on the stack without a cx.
*/
if (v->empty())
global->compartment()->removeDebuggee(fop, global, compartmentEnum);
}
/*
@ -3171,7 +3177,7 @@ DebuggerArguments_getArg(JSContext *cx, unsigned argc, Value *vp)
* Put the Debugger.Frame into the this-value slot, then use THIS_FRAME
* to check that it is still live and get the fp.
*/
args.thisv() = argsobj->getReservedSlot(JSSLOT_DEBUGARGUMENTS_FRAME);
args.setThis(argsobj->getReservedSlot(JSSLOT_DEBUGARGUMENTS_FRAME));
THIS_FRAME(cx, argc, vp, "get argument", ca2, thisobj, fp);
/*
@ -3907,7 +3913,9 @@ DebuggerObject_defineProperties(JSContext *cx, unsigned argc, Value *vp)
{
THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "defineProperties", args, dbg, obj);
REQUIRE_ARGC("Debugger.Object.defineProperties", 1);
RootedObject props(cx, ToObject(cx, &args[0]));
RootedValue arg(cx, args[0]);
RootedObject props(cx, ToObject(cx, arg));
if (!props)
return false;

View File

@ -418,10 +418,11 @@ DenseElementsHeader::defineElement(JSContext *cx, Handle<ObjectImpl*> obj, uint3
*succeeded = false;
if (!shouldThrow)
return true;
RootedValue val(cx, ObjectValue(*obj));
MOZ_ALWAYS_FALSE(js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_OBJECT_NOT_EXTENSIBLE,
JSDVG_IGNORE_STACK,
ObjectValue(*obj),
NULL, NULL, NULL));
val, NullPtr(),
NULL, NULL));
return false;
}
@ -466,10 +467,11 @@ TypedElementsHeader<T>::defineElement(JSContext *cx, Handle<ObjectImpl*> obj,
{
/* XXX jwalden This probably isn't how typed arrays should behave... */
*succeeded = false;
RootedValue val(cx, ObjectValue(*obj));
js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_OBJECT_NOT_EXTENSIBLE,
JSDVG_IGNORE_STACK,
ObjectValue(*obj),
NULL, NULL, NULL);
val, NullPtr(), NULL, NULL);
return false;
}
@ -629,8 +631,8 @@ js::GetElement(JSContext *cx, Handle<ObjectImpl*> obj, Handle<ObjectImpl*> recei
return false;
/* Push get, receiver, and no args. */
args.calleev() = get;
args.thisv() = ObjectValue(*current);
args.setCallee(get);
args.setThis(ObjectValue(*current));
bool ok = Invoke(cx, args);
*vp = args.rval();
@ -861,8 +863,8 @@ js::SetElement(JSContext *cx, Handle<ObjectImpl*> obj, Handle<ObjectImpl*> recei
return false;
/* Push set, receiver, and v as the sole argument. */
args.calleev() = setter;
args.thisv() = ObjectValue(*current);
args.setCallee(setter);
args.setThis(ObjectValue(*current));
args[0] = v;
*succeeded = true;

View File

@ -1369,8 +1369,9 @@ class DebugScopeProxy : public BaseProxyHandler
bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp) MOZ_OVERRIDE
{
RootedValue val(cx, IdToValue(id));
return js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_CANT_DELETE,
JSDVG_IGNORE_STACK, IdToValue(id), NULL,
JSDVG_IGNORE_STACK, val, NullPtr(),
NULL, NULL);
}