Add more rooters, bug 772303. r=billm

This commit is contained in:
Brian Hackett 2012-07-10 19:17:29 -06:00
parent db58cb939f
commit 6cee4cb673
57 changed files with 532 additions and 383 deletions

View File

@ -351,15 +351,14 @@ static inline bool
WarnOnTooManyArgs(JSContext *cx, const CallArgs &args)
{
if (args.length() > 1) {
if (JSScript *script = cx->stack.currentScript()) {
if (!script->warnedAboutTwoArgumentEval) {
static const char TWO_ARGUMENT_WARNING[] =
"Support for eval(code, scopeObject) has been removed. "
"Use |with (scopeObject) eval(code);| instead.";
if (!JS_ReportWarning(cx, TWO_ARGUMENT_WARNING))
return false;
script->warnedAboutTwoArgumentEval = true;
}
Rooted<JSScript*> script(cx, cx->stack.currentScript());
if (script && !script->warnedAboutTwoArgumentEval) {
static const char TWO_ARGUMENT_WARNING[] =
"Support for eval(code, scopeObject) has been removed. "
"Use |with (scopeObject) eval(code);| instead.";
if (!JS_ReportWarning(cx, TWO_ARGUMENT_WARNING))
return false;
script->warnedAboutTwoArgumentEval = true;
} else {
// In the case of an indirect call without a caller frame, avoid a
// potential warning-flood by doing nothing.

View File

@ -253,7 +253,7 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args)
return true;
}
JSAtom *source;
RootedAtom source(cx);
if (sourceValue.isUndefined()) {
source = cx->runtime->emptyString;
} else {
@ -571,11 +571,9 @@ ExecuteRegExp(JSContext *cx, Native native, unsigned argc, Value *vp)
return false;
/* Step 3. */
JSLinearString *linearInput = input->ensureLinear(cx);
Rooted<JSLinearString*> linearInput(cx, input->ensureLinear(cx));
if (!linearInput)
return false;
const jschar *chars = linearInput->chars();
size_t length = input->length();
/* Step 4. */
const Value &lastIndex = reobj->getLastIndex();
@ -589,6 +587,9 @@ ExecuteRegExp(JSContext *cx, Native native, unsigned argc, Value *vp)
if (!re->global() && !re->sticky())
i = 0;
const jschar *chars = linearInput->chars();
size_t length = input->length();
/* Step 9a. */
if (i < 0 || i > length) {
reobj->zeroLastIndex();

View File

@ -244,7 +244,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
if (Emit1(cx, &bce, JSOP_STOP) < 0)
return NULL;
if (!script->fullyInitFromEmitter(cx, &bce))
if (!JSScript::fullyInitFromEmitter(cx, script, &bce))
return NULL;
bce.tellDebuggerAboutCompiledScript(cx);

View File

@ -2613,7 +2613,7 @@ frontend::EmitFunctionScript(JSContext *cx, BytecodeEmitter *bce, ParseNode *bod
if (Emit1(cx, bce, JSOP_STOP) < 0)
return false;
if (!bce->script->fullyInitFromEmitter(cx, bce))
if (!JSScript::fullyInitFromEmitter(cx, bce->script, bce))
return false;
// Initialize fun->script() so that the debugger has a valid fun->script().
@ -5951,7 +5951,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
case PNK_ARGSBODY:
{
JSFunction *fun = bce->sc->fun();
RootedFunction fun(cx, bce->sc->fun());
ParseNode *pnlast = pn->last();
// Carefully emit everything in the right order:

View File

@ -61,7 +61,7 @@ struct BytecodeEmitter
BytecodeEmitter *const parent; /* enclosing function or global context */
const Rooted<JSScript*> script; /* the JSScript we're ultimately producing */
Rooted<JSScript*> script; /* the JSScript we're ultimately producing */
struct {
jsbytecode *base; /* base of JS bytecode vector */

View File

@ -1053,9 +1053,9 @@ Parser::newFunction(TreeContext *tc, JSAtom *atom, FunctionSyntaxKind kind)
JSFUN_INTERPRETED | (kind == Expression ? JSFUN_LAMBDA : 0),
parent, atom);
if (fun && !compileAndGo) {
if (!fun->clearParent(context))
if (!JSObject::clearParent(context, fun))
return NULL;
if (!fun->clearType(context))
if (!JSObject::clearType(context, fun))
return NULL;
fun->setEnvironment(NULL);
}
@ -2101,8 +2101,8 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, Parser *parser)
* slot indexed by blockCount off the class-reserved slot base.
*/
bool redeclared;
jsid id = AtomToId(atom);
Shape *shape = blockObj->addVar(cx, id, blockCount, &redeclared);
RootedId id(cx, AtomToId(atom));
Shape *shape = StaticBlockObject::addVar(cx, blockObj, id, blockCount, &redeclared);
if (!shape) {
if (redeclared)
ReportRedeclaration(cx, parser, pn, false, atom);
@ -2150,7 +2150,7 @@ PopStatementTC(TreeContext *tc)
}
static inline bool
OuterLet(TreeContext *tc, StmtInfoTC *stmt, JSAtom *atom)
OuterLet(TreeContext *tc, StmtInfoTC *stmt, HandleAtom atom)
{
while (stmt->downScope) {
stmt = LexicalLookup(tc, atom, NULL, stmt->downScope);
@ -2198,8 +2198,10 @@ 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, JSAtom *atom_, Parser *parser)
{
RootedAtom atom(cx, atom_);
TreeContext *tc = parser->tc;
ParseNode *pn = data->pn;
@ -2398,7 +2400,7 @@ NoteLValue(JSContext *cx, ParseNode *pn, SharedContext *sc, unsigned dflag = PND
static bool
NoteNameUse(ParseNode *pn, Parser *parser)
{
PropertyName *name = pn->pn_atom->asPropertyName();
RootedPropertyName name(parser->context, pn->pn_atom->asPropertyName());
StmtInfoTC *stmt = LexicalLookup(parser->tc, name, NULL, (StmtInfoTC *)NULL);
DefinitionList::Range defs = parser->tc->decls.lookupMulti(name);
@ -2650,7 +2652,8 @@ CheckDestructuring(JSContext *cx, BindData *data, ParseNode *left, Parser *parse
*/
if (toplevel && blockObj && blockCountBefore == blockObj->slotCount()) {
bool redeclared;
if (!blockObj->addVar(cx, INT_TO_JSID(blockCountBefore), blockCountBefore, &redeclared))
RootedId id(cx, INT_TO_JSID(blockCountBefore));
if (!StaticBlockObject::addVar(cx, blockObj, id, blockCountBefore, &redeclared))
return false;
JS_ASSERT(!redeclared);
JS_ASSERT(blockObj->slotCount() == blockCountBefore + 1);
@ -5130,7 +5133,7 @@ CompExprTransplanter::transplant(ParseNode *pn)
AdjustBlockId(dn, adjust, tc);
}
JSAtom *atom = pn->pn_atom;
RootedAtom atom(parser->context, pn->pn_atom);
#ifdef DEBUG
StmtInfoTC *stmt = LexicalLookup(tc, atom, NULL, (StmtInfoTC *)NULL);
JS_ASSERT(!stmt || stmt != tc->topStmt);
@ -7074,9 +7077,9 @@ Parser::primaryExpr(TokenKind tt, bool afterDoubleDot)
return NULL;
if (!compileAndGo) {
if (!reobj->clearParent(context))
if (!JSObject::clearParent(context, reobj))
return NULL;
if (!reobj->clearType(context))
if (!JSObject::clearType(context, reobj))
return NULL;
}

View File

@ -167,7 +167,7 @@ frontend::FinishPopStatement(ContextT *ct)
template <class ContextT>
typename ContextT::StmtInfo *
frontend::LexicalLookup(ContextT *ct, JSAtom *atom, int *slotp, typename ContextT::StmtInfo *stmt)
frontend::LexicalLookup(ContextT *ct, HandleAtom atom, int *slotp, typename ContextT::StmtInfo *stmt)
{
if (!stmt)
stmt = ct->topScopeStmt;

View File

@ -431,7 +431,7 @@ FinishPopStatement(ContextT *ct);
*/
template <class ContextT>
typename ContextT::StmtInfo *
LexicalLookup(ContextT *ct, JSAtom *atom, int *slotp, typename ContextT::StmtInfo *stmt);
LexicalLookup(ContextT *ct, HandleAtom atom, int *slotp, typename ContextT::StmtInfo *stmt);
} // namespace frontend

View File

@ -134,6 +134,9 @@ class Handle
Handle() {}
const T *ptr;
template <typename S>
void operator =(S v) MOZ_DELETE;
};
/* Defined in jsapi.h under Value definition */
@ -167,7 +170,11 @@ class MutableHandle
MutableHandle(Rooted<S> *root,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
void set(T v) { *ptr = v; }
void set(T v)
{
JS_ASSERT(!RootMethods<T>::poisoned(v));
*ptr = v;
}
T *address() const { return ptr; }
T get() const { return *ptr; }

View File

@ -1990,9 +1990,10 @@ JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj_)
* Check whether we need to bind 'undefined' and define it if so.
* Since ES5 15.1.1.3 undefined can't be deleted.
*/
PropertyName *name = cx->runtime->atomState.typeAtoms[JSTYPE_VOID];
if (!obj->nativeContains(cx, NameToId(name)) &&
!obj->defineProperty(cx, name, UndefinedValue(),
RootedPropertyName undefinedName(cx, cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
RootedId undefinedId(cx, NameToId(undefinedName));
if (!obj->nativeContains(cx, undefinedId) &&
!obj->defineProperty(cx, undefinedName, UndefinedValue(),
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_PERMANENT | JSPROP_READONLY)) {
return false;
@ -2069,7 +2070,8 @@ static JSIdArray *
EnumerateIfResolved(JSContext *cx, JSObject *obj, PropertyName *name, JSIdArray *ida,
int *ip, JSBool *foundp)
{
*foundp = obj->nativeContains(cx, NameToId(name));
RootedId id(cx, NameToId(name));
*foundp = obj->nativeContains(cx, id);
if (*foundp)
ida = AddNameToArray(cx, name, ida, ip);
return ida;
@ -3357,7 +3359,8 @@ JS_NewObjectForConstructor(JSContext *cx, JSClass *clasp, const jsval *vp)
CHECK_REQUEST(cx);
assertSameCompartment(cx, *vp);
return js_CreateThis(cx, Valueify(clasp), JSVAL_TO_OBJECT(*vp));
RootedObject obj(cx, JSVAL_TO_OBJECT(*vp));
return js_CreateThis(cx, Valueify(clasp), obj);
}
JS_PUBLIC_API(JSBool)
@ -5979,12 +5982,15 @@ JS_PUBLIC_API(JSBool)
JS_Stringify(JSContext *cx, jsval *vp, JSObject *replacer, jsval space,
JSONWriteCallback callback, void *data)
{
RootedValue value(cx, *vp);
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, replacer, space);
StringBuffer sb(cx);
if (!js_Stringify(cx, vp, replacer, space, sb))
if (!js_Stringify(cx, &value, replacer, space, sb))
return false;
*vp = value;
if (sb.empty()) {
JSAtom *nullAtom = cx->runtime->atomState.nullAtom;
return callback(nullAtom->chars(), nullAtom->length(), data);

View File

@ -3726,14 +3726,14 @@ NewArray(JSContext *cx, uint32_t length, JSObject *proto_)
NewObjectCache::EntryIndex entry = -1;
if (cache.lookupGlobal(&ArrayClass, parent_, kind, &entry)) {
JSObject *obj = cache.newObjectFromHit(cx, entry);
if (!obj)
return NULL;
/* Fixup the elements pointer and length, which may be incorrect. */
obj->setFixedElements();
obj->setArrayLength(cx, length);
if (allocateCapacity && !EnsureNewArrayElements(cx, obj, length))
return NULL;
return obj;
if (obj) {
/* Fixup the elements pointer and length, which may be incorrect. */
obj->setFixedElements();
obj->setArrayLength(cx, length);
if (allocateCapacity && !EnsureNewArrayElements(cx, obj, length))
return NULL;
return obj;
}
}
Rooted<GlobalObject*> parent(cx, parent_);

View File

@ -293,7 +293,7 @@ struct JSAtomState
extern bool
AtomIsInterned(JSContext *cx, JSAtom *atom);
#define ATOM(name) cx->runtime->atomState.name##Atom
#define ATOM(name) js::HandlePropertyName::fromMarkedLocation(&cx->runtime->atomState.name##Atom)
#define COMMON_ATOM_INDEX(name) \
((offsetof(JSAtomState, name##Atom) - JSAtomState::commonAtomsOffset) \

View File

@ -41,6 +41,10 @@ ReadStructuredClone(JSContext *cx, const uint64_t *data, size_t nbytes, Value *v
const JSStructuredCloneCallbacks *cb, void *cbClosure)
{
SCInput in(cx, data, nbytes);
/* XXX disallow callers from using internal pointers to GC things. */
SkipRoot skip(cx, &in);
JSStructuredCloneReader r(in, cb, cbClosure);
return r.read(vp);
}

View File

@ -327,7 +327,7 @@ AutoResolving::alreadyStartedSlow() const
AutoResolving *cursor = link;
do {
JS_ASSERT(this != cursor);
if (object == cursor->object && id == cursor->id && kind == cursor->kind)
if (object.get() == cursor->object && id.get() == cursor->id && kind == cursor->kind)
return true;
} while (!!(cursor = cursor->link));
return false;

View File

@ -280,7 +280,11 @@ class NewObjectCache
inline bool lookupGlobal(Class *clasp, js::GlobalObject *global, gc::AllocKind kind, EntryIndex *pentry);
inline bool lookupType(Class *clasp, js::types::TypeObject *type, gc::AllocKind kind, EntryIndex *pentry);
/* Return a new object from a cache hit produced by a lookup method. */
/*
* Return a new object from a cache hit produced by a lookup method, or
* NULL if returning the object could possibly trigger GC (does not
* indicate failure).
*/
inline JSObject *newObjectFromHit(JSContext *cx, EntryIndex entry);
/* Fill an entry after a cache miss. */
@ -1377,7 +1381,7 @@ struct AutoResolving {
WATCH
};
AutoResolving(JSContext *cx, JSObject *obj, jsid id, Kind kind = LOOKUP
AutoResolving(JSContext *cx, HandleObject obj, HandleId id, Kind kind = LOOKUP
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: context(cx), object(obj), id(id), kind(kind), link(cx->resolvingList)
{
@ -1399,8 +1403,8 @@ struct AutoResolving {
bool alreadyStartedSlow() const;
JSContext *const context;
JSObject *const object;
jsid const id;
HandleObject object;
HandleId id;
Kind const kind;
AutoResolving *const link;
JS_DECL_USE_GUARD_OBJECT_NOTIFIER

View File

@ -112,21 +112,6 @@ NewObjectCache::newObjectFromHit(JSContext *cx, EntryIndex entry_)
return obj;
}
/* Copy the entry to the stack first in case it is purged by a GC. */
size_t nbytes = entry->nbytes;
char stackObject[sizeof(JSObject_Slots16)];
JS_ASSERT(nbytes <= sizeof(stackObject));
js_memcpy(&stackObject, &entry->templateObject, nbytes);
JSObject *baseobj = (JSObject *) stackObject;
obj = js_NewGCObject(cx, entry->kind);
if (obj) {
copyCachedToObject(obj, baseobj);
Probes::createObject(cx, obj);
return obj;
}
return NULL;
}

View File

@ -561,6 +561,9 @@ Exception(JSContext *cx, unsigned argc, Value *vp)
/* Find the scripted caller. */
ScriptFrameIter iter(cx);
/* XXX StackIter should not point directly to scripts. */
SkipRoot skip(cx, &iter);
/* Set the 'fileName' property. */
RootedString filename(cx);
if (args.length() > 1) {
@ -610,11 +613,11 @@ exn_toString(JSContext *cx, unsigned argc, Value *vp)
}
/* Step 1. */
JSObject &obj = args.thisv().toObject();
RootedObject obj(cx, &args.thisv().toObject());
/* Step 3. */
Value nameVal;
if (!obj.getProperty(cx, cx->runtime->atomState.nameAtom, &nameVal))
if (!obj->getProperty(cx, cx->runtime->atomState.nameAtom, &nameVal))
return false;
/* Step 4. */
@ -629,7 +632,7 @@ exn_toString(JSContext *cx, unsigned argc, Value *vp)
/* Step 5. */
Value msgVal;
if (!obj.getProperty(cx, cx->runtime->atomState.messageAtom, &msgVal))
if (!obj->getProperty(cx, cx->runtime->atomState.messageAtom, &msgVal))
return false;
/* Step 6. */
@ -682,12 +685,12 @@ exn_toSource(JSContext *cx, unsigned argc, Value *vp)
JS_CHECK_RECURSION(cx, return false);
CallArgs args = CallArgsFromVp(argc, vp);
JSObject *obj = ToObject(cx, &args.thisv());
RootedObject obj(cx, ToObject(cx, &args.thisv()));
if (!obj)
return false;
Value nameVal;
JSString *name;
RootedString name(cx);
if (!obj->getProperty(cx, cx->runtime->atomState.nameAtom, &nameVal) ||
!(name = ToString(cx, nameVal)))
{
@ -695,7 +698,7 @@ exn_toSource(JSContext *cx, unsigned argc, Value *vp)
}
Value messageVal;
JSString *message;
RootedString message(cx);
if (!obj->getProperty(cx, cx->runtime->atomState.messageAtom, &messageVal) ||
!(message = js_ValueToSource(cx, messageVal)))
{
@ -703,7 +706,7 @@ exn_toSource(JSContext *cx, unsigned argc, Value *vp)
}
Value filenameVal;
JSString *filename;
RootedString filename(cx);
if (!obj->getProperty(cx, cx->runtime->atomState.fileNameAtom, &filenameVal) ||
!(filename = js_ValueToSource(cx, filenameVal)))
{

View File

@ -339,7 +339,6 @@ bool
js::XDRInterpretedFunction(XDRState<mode> *xdr, JSObject **objp, JSScript *parentScript)
{
/* NB: Keep this in sync with CloneInterpretedFunction. */
JSFunction *fun;
JSAtom *atom;
uint32_t firstword; /* flag telling whether fun->atom is non-null,
plus for fun->u.i.skipmin, fun->u.i.wrapper,
@ -347,6 +346,7 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, JSObject **objp, JSScript *paren
uint32_t flagsword; /* word for argument count and fun->flags */
JSContext *cx = xdr->cx();
RootedFunction fun(cx);
JSScript *script;
if (mode == XDR_ENCODE) {
fun = (*objp)->toFunction();
@ -367,9 +367,9 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, JSObject **objp, JSScript *paren
fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, parent, NULL);
if (!fun)
return false;
if (!fun->clearParent(cx))
if (!JSObject::clearParent(cx, fun))
return false;
if (!fun->clearType(cx))
if (!JSObject::clearType(cx, fun))
return false;
atom = NULL;
script = NULL;
@ -409,17 +409,17 @@ template bool
js::XDRInterpretedFunction(XDRState<XDR_DECODE> *xdr, JSObject **objp, JSScript *parentScript);
JSObject *
js::CloneInterpretedFunction(JSContext *cx, JSFunction *srcFun)
js::CloneInterpretedFunction(JSContext *cx, HandleFunction srcFun)
{
/* NB: Keep this in sync with XDRInterpretedFunction. */
RootedObject parent(cx, NULL);
JSFunction *clone = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, parent, NULL);
RootedFunction clone(cx, js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, parent, NULL));
if (!clone)
return NULL;
if (!clone->clearParent(cx))
if (!JSObject::clearParent(cx, clone))
return NULL;
if (!clone->clearType(cx))
if (!JSObject::clearType(cx, clone))
return NULL;
Rooted<JSScript*> srcScript(cx, srcFun->script());

View File

@ -263,7 +263,7 @@ bool
XDRInterpretedFunction(XDRState<mode> *xdr, JSObject **objp, JSScript *parentScript);
extern JSObject *
CloneInterpretedFunction(JSContext *cx, JSFunction *fun);
CloneInterpretedFunction(JSContext *cx, HandleFunction fun);
} /* namespace js */

View File

@ -1517,6 +1517,8 @@ js::analyze::ScriptAnalysis::addPushedType(JSContext *cx, uint32_t offset, uint3
inline js::types::TypeObject *
JSCompartment::getEmptyType(JSContext *cx)
{
JS::MaybeCheckStackRoots(cx);
if (!emptyTypeObject) {
JS::RootedObject nullproto(cx, NULL);
emptyTypeObject = types.newTypeObject(cx, NULL, JSProto_Object, nullproto, true);

View File

@ -2833,7 +2833,10 @@ BEGIN_CASE(JSOP_DEFVAR)
RootedObject &obj = rootObject0;
obj = &regs.fp()->varObj();
if (!DefVarOrConstOperation(cx, obj, script->getName(regs.pc), attrs))
RootedPropertyName &name = rootName0;
name = script->getName(regs.pc);
if (!DefVarOrConstOperation(cx, obj, name, attrs))
goto error;
}
END_CASE(JSOP_DEFVAR)
@ -2967,9 +2970,11 @@ BEGIN_CASE(JSOP_SETTER)
{
JSOp op2 = JSOp(*++regs.pc);
RootedId &id = rootId0;
Value rval;
RootedValue &rval_ = rootValue0;
Value &rval = rval_.get();
int i;
JSObject *obj;
RootedObject &obj = rootObject0;
switch (op2) {
case JSOP_SETNAME:
case JSOP_SETPROP:
@ -3121,7 +3126,8 @@ BEGIN_CASE(JSOP_INITPROP)
{
/* Load the property's initial value into rval. */
JS_ASSERT(regs.stackDepth() >= 2);
Value rval = regs.sp[-1];
RootedValue &rval = rootValue0;
rval = regs.sp[-1];
/* Load the object being initialized into lval/obj. */
RootedObject &obj = rootObject0;
@ -3134,7 +3140,7 @@ BEGIN_CASE(JSOP_INITPROP)
id = NameToId(name);
if (JS_UNLIKELY(name == cx->runtime->atomState.protoAtom)
? !baseops::SetPropertyHelper(cx, obj, obj, id, 0, &rval, script->strictModeCode)
? !baseops::SetPropertyHelper(cx, obj, obj, id, 0, rval.address(), script->strictModeCode)
: !DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
JSPROP_ENUMERATE, 0, 0, 0)) {
goto error;

View File

@ -313,9 +313,9 @@ SetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, const Val
((obj2 = obj->getProto()) && obj2->lastProperty() == entry->pshape)) {
#ifdef DEBUG
if (entry->isOwnPropertyHit()) {
JS_ASSERT(obj->nativeLookupNoAllocation(cx, shape->propid()) == shape);
JS_ASSERT(obj->nativeLookupNoAllocation(shape->propid()) == shape);
} else {
JS_ASSERT(obj2->nativeLookupNoAllocation(cx, shape->propid()) == shape);
JS_ASSERT(obj2->nativeLookupNoAllocation(shape->propid()) == shape);
JS_ASSERT(entry->isPrototypePropertyHit());
JS_ASSERT(entry->kshape != entry->pshape);
JS_ASSERT(!shape->hasSlot());
@ -418,7 +418,7 @@ NameOperation(JSContext *cx, JSScript *script, jsbytecode *pc, Value *vp)
}
inline bool
DefVarOrConstOperation(JSContext *cx, HandleObject varobj, PropertyName *dn, unsigned attrs)
DefVarOrConstOperation(JSContext *cx, HandleObject varobj, HandlePropertyName dn, unsigned attrs)
{
JS_ASSERT(varobj->isVarObj());
JS_ASSERT(!varobj->getOps()->defineProperty || varobj->isDebugScope());

View File

@ -615,7 +615,7 @@ VectorToValueIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVec
types::MarkTypeObjectFlags(cx, obj, types::OBJECT_FLAG_ITERATED);
}
JSObject *iterobj = NewIteratorObject(cx, flags);
RootedObject iterobj(cx, NewIteratorObject(cx, flags));
if (!iterobj)
return false;

View File

@ -126,12 +126,20 @@ GetPrefixInteger(JSContext *cx, const jschar *start, const jschar *end, int base
JS_ALWAYS_INLINE bool
ToNumber(JSContext *cx, Value *vp)
{
#ifdef DEBUG
{
SkipRoot skip(cx, vp);
MaybeCheckStackRoots(cx);
}
#endif
if (vp->isNumber())
return true;
double d;
extern bool ToNumberSlow(JSContext *cx, js::Value v, double *dp);
if (!ToNumberSlow(cx, *vp, &d))
return false;
vp->setNumber(d);
return true;
}
@ -145,6 +153,13 @@ ToNumber(JSContext *cx, Value *vp)
JS_ALWAYS_INLINE bool
ToUint32(JSContext *cx, const js::Value &v, uint32_t *out)
{
#ifdef DEBUG
{
SkipRoot skip(cx, &v);
MaybeCheckStackRoots(cx);
}
#endif
if (v.isInt32()) {
*out = (uint32_t)v.toInt32();
return true;
@ -161,6 +176,13 @@ ToUint32(JSContext *cx, const js::Value &v, uint32_t *out)
JS_ALWAYS_INLINE bool
ValueToUint16(JSContext *cx, const js::Value &v, uint16_t *out)
{
#ifdef DEBUG
{
SkipRoot skip(cx, &v);
MaybeCheckStackRoots(cx);
}
#endif
if (v.isInt32()) {
*out = uint16_t(v.toInt32());
return true;
@ -233,6 +255,13 @@ IsDefinitelyIndex(const Value &v, uint32_t *indexp)
static inline bool
ToInteger(JSContext *cx, const js::Value &v, double *dp)
{
#ifdef DEBUG
{
SkipRoot skip(cx, &v);
MaybeCheckStackRoots(cx);
}
#endif
if (v.isInt32()) {
*dp = v.toInt32();
return true;

View File

@ -457,7 +457,7 @@ obj_toSource(JSContext *cx, unsigned argc, Value *vp)
for (int i = 0; i < ida->length; i++) {
/* Get strings for id and value and GC-root them via vp. */
id = ida->vector[i];
JSLinearString *idstr;
Rooted<JSLinearString*> idstr(cx);
RootedObject obj2(cx);
RootedShape prop(cx);
@ -703,9 +703,12 @@ obj_valueOf(JSContext *cx, unsigned argc, Value *vp)
#if JS_HAS_OBJ_WATCHPOINT
static JSBool
obj_watch_handler(JSContext *cx, JSObject *obj, jsid id, jsval old,
obj_watch_handler(JSContext *cx, JSObject *obj_, jsid id_, jsval old,
jsval *nvp, void *closure)
{
RootedObject obj(cx, obj_);
RootedId id(cx, id_);
JSObject *callable = (JSObject *) closure;
if (JSSubsumePrincipalsOp subsume = cx->runtime->securityCallbacks->subsumePrincipals) {
if (JSPrincipals *watcher = callable->principals(cx)) {
@ -1906,7 +1909,7 @@ obj_defineProperty(JSContext *cx, unsigned argc, Value *vp)
namespace js {
bool
ReadPropertyDescriptors(JSContext *cx, JSObject *props, bool checkAccessors,
ReadPropertyDescriptors(JSContext *cx, HandleObject props, bool checkAccessors,
AutoIdVector *ids, AutoPropDescArrayRooter *descs)
{
if (!GetPropertyNames(cx, props, JSITER_OWNONLY, ids))
@ -1926,7 +1929,7 @@ ReadPropertyDescriptors(JSContext *cx, JSObject *props, bool checkAccessors,
} /* namespace js */
static bool
DefineProperties(JSContext *cx, HandleObject obj, JSObject *props)
DefineProperties(JSContext *cx, HandleObject obj, HandleObject props)
{
AutoIdVector ids(cx);
AutoPropDescArrayRooter descs(cx);
@ -1943,7 +1946,7 @@ DefineProperties(JSContext *cx, HandleObject obj, JSObject *props)
}
extern JSBool
js_PopulateObject(JSContext *cx, HandleObject newborn, JSObject *props)
js_PopulateObject(JSContext *cx, HandleObject newborn, HandleObject props)
{
return DefineProperties(cx, newborn, props);
}
@ -1964,7 +1967,7 @@ obj_defineProperties(JSContext *cx, unsigned argc, Value *vp)
"Object.defineProperties", "0", "s");
return false;
}
JSObject *props = ToObject(cx, &vp[3]);
RootedObject props(cx, ToObject(cx, &vp[3]));
if (!props)
return false;
@ -2020,7 +2023,8 @@ obj_create(JSContext *cx, unsigned argc, Value *vp)
return false;
}
if (!DefineProperties(cx, obj, &args[1].toObject()))
RootedObject props(cx, &args[1].toObject());
if (!DefineProperties(cx, obj, props))
return false;
}
@ -2389,8 +2393,11 @@ js::NewObjectWithGivenProto(JSContext *cx, js::Class *clasp, JSObject *proto_, J
NewObjectCache::EntryIndex entry = -1;
if (proto && (!parent || parent == proto->getParent()) && !proto->isGlobal()) {
if (cache.lookupProto(clasp, proto, kind, &entry))
return cache.newObjectFromHit(cx, entry);
if (cache.lookupProto(clasp, proto, kind, &entry)) {
JSObject *obj = cache.newObjectFromHit(cx, entry);
if (obj)
return obj;
}
}
types::TypeObject *type = proto ? proto->getNewType(cx) : cx->compartment->getEmptyType(cx);
@ -2445,8 +2452,11 @@ js::NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *proto_, J
NewObjectCache::EntryIndex entry = -1;
if (parent->isGlobal() && protoKey != JSProto_Null) {
if (cache.lookupGlobal(clasp, &parent->asGlobal(), kind, &entry))
return cache.newObjectFromHit(cx, entry);
if (cache.lookupGlobal(clasp, &parent->asGlobal(), kind, &entry)) {
JSObject *obj = cache.newObjectFromHit(cx, entry);
if (obj)
return obj;
}
}
if (!FindProto(cx, clasp, parent, &proto))
@ -2480,8 +2490,11 @@ js::NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc
NewObjectCache::EntryIndex entry = -1;
if (parent == type->proto->getParent()) {
if (cache.lookupType(&ObjectClass, type, kind, &entry))
return cache.newObjectFromHit(cx, entry);
if (cache.lookupType(&ObjectClass, type, kind, &entry)) {
JSObject *obj = cache.newObjectFromHit(cx, entry);
if (obj)
return obj;
}
}
JSObject *obj = NewObject(cx, &ObjectClass, type, parent, kind);
@ -2532,7 +2545,7 @@ js::NewReshapedObject(JSContext *cx, HandleTypeObject type, JSObject *parent,
}
JSObject*
js_CreateThis(JSContext *cx, Class *newclasp, JSObject *callee)
js_CreateThis(JSContext *cx, Class *newclasp, HandleObject callee)
{
Value protov;
if (!callee->getProperty(cx, cx->runtime->atomState.classPrototypeAtom, &protov))
@ -3823,7 +3836,8 @@ js_GetClassObject(JSContext *cx, HandleObject obj, JSProtoKey key,
return true;
}
AutoResolving resolving(cx, global, NameToId(cx->runtime->atomState.classAtoms[key]));
RootedId name(cx, NameToId(cx->runtime->atomState.classAtoms[key]));
AutoResolving resolving(cx, global, name);
if (resolving.alreadyStarted()) {
/* Already caching id in global -- suppress recursion. */
objp.set(NULL);
@ -4250,18 +4264,20 @@ CallResolveOp(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
JS_ASSERT(obj2 != obj);
return obj2->lookupGeneric(cx, id, objp, propp);
}
obj = obj2;
objp.set(obj2);
} else {
if (!resolve(cx, obj, id))
return false;
objp.set(obj);
}
if (!obj->nativeEmpty()) {
if (Shape *shape = obj->nativeLookup(cx, id)) {
objp.set(obj);
propp.set(shape);
}
}
Shape *shape;
if (!objp->nativeEmpty() && (shape = objp->nativeLookup(cx, id)))
propp.set(shape);
else
objp.set(NULL);
return true;
}
@ -4296,7 +4312,7 @@ LookupPropertyWithFlagsInline(JSContext *cx, HandleObject obj, HandleId id, unsi
}
}
JSObject *proto = current->getProto();
RootedObject proto(cx, current->getProto());
if (!proto)
break;
if (!proto->isNative()) {
@ -4552,7 +4568,7 @@ js_NativeGetInline(JSContext *cx, Handle<JSObject*> receiver, JSObject *obj, JSO
return false;
/* Update slotful shapes according to the value produced by the getter. */
if (shapeRoot->hasSlot() && pobjRoot->nativeContains(cx, *shapeRoot))
if (shapeRoot->hasSlot() && pobjRoot->nativeContains(cx, shapeRoot))
pobjRoot->nativeSetSlot(shapeRoot->slot(), *vp);
return true;
@ -4604,7 +4620,7 @@ js_NativeSet(JSContext *cx, Handle<JSObject*> obj, Handle<JSObject*> receiver,
*/
if (shapeRoot->hasSlot() &&
(JS_LIKELY(cx->runtime->propertyRemovals == sample) ||
obj->nativeContains(cx, *shapeRoot))) {
obj->nativeContains(cx, shapeRoot))) {
obj->setSlot(shapeRoot->slot(), *vp);
}

View File

@ -307,8 +307,11 @@ struct JSObject : public js::ObjectImpl
*/
bool setSlotSpan(JSContext *cx, uint32_t span);
inline bool nativeContains(JSContext *cx, jsid id);
inline bool nativeContains(JSContext *cx, const js::Shape &shape);
inline bool nativeContains(JSContext *cx, js::HandleId id);
inline bool nativeContains(JSContext *cx, js::HandleShape shape);
inline bool nativeContainsNoAllocation(jsid id);
inline bool nativeContainsNoAllocation(const js::Shape &shape);
/* Upper bound on the number of elements in an object. */
static const uint32_t NELEMENTS_LIMIT = JS_BIT(28);
@ -510,8 +513,8 @@ struct JSObject : public js::ObjectImpl
inline JSPrincipals *principals(JSContext *cx);
/* Remove the type (and prototype) or parent from a new object. */
inline bool clearType(JSContext *cx);
bool clearParent(JSContext *cx);
static inline bool clearType(JSContext *cx, js::HandleObject obj);
static bool clearParent(JSContext *cx, js::HandleObject obj);
/*
* ES5 meta-object properties and operations.
@ -1089,7 +1092,7 @@ extern const char js_lookupSetter_str[];
#endif
extern JSBool
js_PopulateObject(JSContext *cx, js::HandleObject newborn, JSObject *props);
js_PopulateObject(JSContext *cx, js::HandleObject newborn, js::HandleObject props);
/*
* Fast access to immutable standard objects (constructors and prototypes).
@ -1117,7 +1120,7 @@ js_CreateThisForFunction(JSContext *cx, js::HandleObject callee, bool newType);
// Generic call for constructing |this|.
extern JSObject *
js_CreateThis(JSContext *cx, js::Class *clasp, JSObject *callee);
js_CreateThis(JSContext *cx, js::Class *clasp, js::HandleObject callee);
/*
* Find or create a property named by id in obj's scope, with the given getter
@ -1195,7 +1198,7 @@ DefineProperty(JSContext *cx, js::HandleObject obj,
* ES5 15.2.3.7 steps 3-5.
*/
extern bool
ReadPropertyDescriptors(JSContext *cx, JSObject *props, bool checkAccessors,
ReadPropertyDescriptors(JSContext *cx, HandleObject props, bool checkAccessors,
AutoIdVector *ids, AutoPropDescArrayRooter *descs);
/*

View File

@ -691,16 +691,16 @@ JSObject::getType(JSContext *cx)
return self->type_;
}
inline bool
JSObject::clearType(JSContext *cx)
/* static */ inline bool
JSObject::clearType(JSContext *cx, js::HandleObject obj)
{
JS_ASSERT(!hasSingletonType());
JS_ASSERT(!obj->hasSingletonType());
js::types::TypeObject *type = cx->compartment->getEmptyType(cx);
if (!type)
return false;
type_ = type;
obj->type_ = type;
return true;
}
@ -965,15 +965,27 @@ JSObject::nativeSetSlotWithType(JSContext *cx, js::Shape *shape, const js::Value
}
inline bool
JSObject::nativeContains(JSContext *cx, jsid id)
JSObject::nativeContains(JSContext *cx, js::HandleId id)
{
return nativeLookup(cx, id) != NULL;
}
inline bool
JSObject::nativeContains(JSContext *cx, const js::Shape &shape)
JSObject::nativeContains(JSContext *cx, js::HandleShape shape)
{
return nativeLookup(cx, shape.propid()) == &shape;
return nativeLookup(cx, shape->propid()) == shape;
}
inline bool
JSObject::nativeContainsNoAllocation(jsid id)
{
return nativeLookupNoAllocation(id) != NULL;
}
inline bool
JSObject::nativeContainsNoAllocation(const js::Shape &shape)
{
return nativeLookupNoAllocation(shape.propid()) == &shape;
}
inline bool
@ -1604,7 +1616,7 @@ DefineConstructorAndPrototype(JSContext *cx, GlobalObject *global,
JS_ASSERT(proto);
jsid id = NameToId(cx->runtime->atomState.classAtoms[key]);
JS_ASSERT(!global->nativeLookupNoAllocation(cx, id));
JS_ASSERT(!global->nativeLookupNoAllocation(id));
/* Set these first in case AddTypePropertyId looks for this class. */
global->setSlot(key, ObjectValue(*ctor));

View File

@ -80,14 +80,14 @@ js_json_parse(JSContext *cx, unsigned argc, Value *vp)
JSBool
js_json_stringify(JSContext *cx, unsigned argc, Value *vp)
{
*vp = (argc >= 1) ? vp[2] : UndefinedValue();
JSObject *replacer = (argc >= 2 && vp[3].isObject())
? &vp[3].toObject()
: NULL;
Value space = (argc >= 3) ? vp[4] : UndefinedValue();
RootedObject replacer(cx, (argc >= 2 && vp[3].isObject())
? &vp[3].toObject()
: NULL);
RootedValue value(cx, (argc >= 1) ? vp[2] : UndefinedValue());
RootedValue space(cx, (argc >= 3) ? vp[4] : UndefinedValue());
StringBuffer sb(cx);
if (!js_Stringify(cx, vp, replacer, space, sb))
if (!js_Stringify(cx, &value, replacer, space, sb))
return false;
// XXX This can never happen to nsJSON.cpp, but the JSON object
@ -272,15 +272,15 @@ class KeyStringifier<jsid> {
*/
template<typename KeyType>
static bool
PreprocessValue(JSContext *cx, JSObject *holder, KeyType key, Value *vp, StringifyContext *scx)
PreprocessValue(JSContext *cx, JSObject *holder, KeyType key, MutableHandleValue vp, StringifyContext *scx)
{
JSString *keyStr = NULL;
/* Step 2. */
if (vp->isObject()) {
if (vp.get().isObject()) {
Value toJSON;
RootedId id(cx, NameToId(cx->runtime->atomState.toJSONAtom));
Rooted<JSObject*> obj(cx, &vp->toObject());
Rooted<JSObject*> obj(cx, &vp.get().toObject());
if (!GetMethod(cx, obj, id, 0, &toJSON))
return false;
@ -294,12 +294,12 @@ PreprocessValue(JSContext *cx, JSObject *holder, KeyType key, Value *vp, Stringi
return false;
args.calleev() = toJSON;
args.thisv() = *vp;
args.thisv() = vp;
args[0] = StringValue(keyStr);
if (!Invoke(cx, args))
return false;
*vp = args.rval();
vp.set(args.rval());
}
}
@ -318,30 +318,30 @@ PreprocessValue(JSContext *cx, JSObject *holder, KeyType key, Value *vp, Stringi
args.calleev() = ObjectValue(*scx->replacer);
args.thisv() = ObjectValue(*holder);
args[0] = StringValue(keyStr);
args[1] = *vp;
args[1] = vp;
if (!Invoke(cx, args))
return false;
*vp = args.rval();
vp.set(args.rval());
}
/* Step 4. */
if (vp->isObject()) {
JSObject &obj = vp->toObject();
if (vp.get().isObject()) {
JSObject &obj = vp.get().toObject();
if (ObjectClassIs(obj, ESClass_Number, cx)) {
double d;
if (!ToNumber(cx, *vp, &d))
if (!ToNumber(cx, vp, &d))
return false;
vp->setNumber(d);
vp.set(NumberValue(d));
} else if (ObjectClassIs(obj, ESClass_String, cx)) {
JSString *str = ToStringSlow(cx, *vp);
JSString *str = ToStringSlow(cx, vp);
if (!str)
return false;
vp->setString(str);
vp.set(StringValue(str));
} else if (ObjectClassIs(obj, ESClass_Boolean, cx)) {
if (!BooleanGetPrimitiveValue(cx, obj, vp))
if (!BooleanGetPrimitiveValue(cx, obj, vp.address()))
return false;
JS_ASSERT(vp->isBoolean());
JS_ASSERT(vp.get().isBoolean());
}
}
@ -412,8 +412,8 @@ JO(JSContext *cx, HandleObject obj, StringifyContext *scx)
* which pass the filter.
*/
id = propertyList[i];
Value outputValue;
if (!obj->getGeneric(cx, id, &outputValue))
RootedValue outputValue(cx);
if (!obj->getGeneric(cx, id, outputValue.address()))
return false;
if (!PreprocessValue(cx, obj, id.get(), &outputValue, scx))
return false;
@ -481,7 +481,7 @@ JA(JSContext *cx, HandleObject obj, StringifyContext *scx)
return JS_FALSE;
/* Steps 7-10. */
Value outputValue;
RootedValue outputValue(cx);
for (uint32_t i = 0; i < length; i++) {
/*
* Steps 8a-8c. Again note how the call to the spec's Str method
@ -489,7 +489,7 @@ JA(JSContext *cx, HandleObject obj, StringifyContext *scx)
* and the replacer and maybe unboxing, and interpreting some
* values as |null| in separate steps.
*/
if (!obj->getElement(cx, i, &outputValue))
if (!obj->getElement(cx, i, outputValue.address()))
return JS_FALSE;
if (!PreprocessValue(cx, obj, i, &outputValue, scx))
return JS_FALSE;
@ -582,7 +582,8 @@ Str(JSContext *cx, const Value &v, StringifyContext *scx)
/* ES5 15.12.3. */
JSBool
js_Stringify(JSContext *cx, Value *vp, JSObject *replacer_, Value space_, StringBuffer &sb)
js_Stringify(JSContext *cx, MutableHandleValue vp, JSObject *replacer_, Value space_,
StringBuffer &sb)
{
RootedObject replacer(cx, replacer_);
RootedValue spaceRoot(cx, space_);
@ -723,7 +724,7 @@ js_Stringify(JSContext *cx, Value *vp, JSObject *replacer_, Value space_, String
/* Step 10. */
RootedId emptyId(cx, NameToId(cx->runtime->atomState.emptyAtom));
if (!DefineNativeProperty(cx, wrapper, emptyId, *vp, JS_PropertyStub, JS_StrictPropertyStub,
if (!DefineNativeProperty(cx, wrapper, emptyId, vp, JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE, 0, 0))
{
return false;
@ -736,10 +737,10 @@ js_Stringify(JSContext *cx, Value *vp, JSObject *replacer_, Value space_, String
if (!PreprocessValue(cx, wrapper, emptyId.get(), vp, &scx))
return false;
if (IsFilteredValue(*vp))
if (IsFilteredValue(vp))
return true;
return Str(cx, *vp, &scx);
return Str(cx, vp, &scx);
}
/* ES5 15.12.2 Walk. */

View File

@ -17,7 +17,8 @@ extern JSObject *
js_InitJSONClass(JSContext *cx, JSObject *obj);
extern JSBool
js_Stringify(JSContext *cx, js::Value *vp, JSObject *replacer, js::Value space,
js_Stringify(JSContext *cx, js::MutableHandleValue vp,
JSObject *replacer, js::Value space,
js::StringBuffer &sb);
// Avoid build errors on certain platforms that define these names as constants

View File

@ -192,7 +192,7 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject
if (pobj->lastProperty() == entry->pshape) {
#ifdef DEBUG
PropertyName *name = GetNameFromBytecode(cx, script, pc, op);
JS_ASSERT(pobj->nativeContains(cx, NameToId(name)));
JS_ASSERT(pobj->nativeContainsNoAllocation(NameToId(name)));
#endif
*pobjp = pobj;
return NULL;

View File

@ -31,6 +31,8 @@ JS_ALWAYS_INLINE void
js::PropertyCache::test(JSContext *cx, jsbytecode *pc, JSObject *&obj,
JSObject *&pobj, PropertyCacheEntry *&entry, PropertyName *&name)
{
AssertRootingUnnecessary assert(cx);
JS_ASSERT(this == &JS_PROPERTY_CACHE(cx));
Shape *kshape = obj->lastProperty();

View File

@ -145,10 +145,10 @@ BaseProxyHandler::getElementIfPresent(JSContext *cx, JSObject *proxy_, JSObject
}
bool
BaseProxyHandler::set(JSContext *cx, JSObject *proxy, JSObject *receiver_, jsid id_, bool strict,
BaseProxyHandler::set(JSContext *cx, JSObject *proxy_, JSObject *receiver_, jsid id_, bool strict,
Value *vp)
{
RootedObject receiver(cx, receiver_);
RootedObject proxy(cx, proxy_), receiver(cx, receiver_);
RootedId id(cx, id_);
JS_ASSERT(OperationInProgress(cx, proxy));
@ -593,16 +593,15 @@ DirectProxyHandler::iterate(JSContext *cx, JSObject *proxy, unsigned flags,
}
static bool
GetTrap(JSContext *cx, JSObject *handler, PropertyName *name, Value *fvalp)
GetTrap(JSContext *cx, HandleObject handler, HandlePropertyName name, Value *fvalp)
{
JS_CHECK_RECURSION(cx, return false);
Rooted<PropertyName*> propname(cx, name);
return handler->getProperty(cx, propname, fvalp);
return handler->getProperty(cx, name, fvalp);
}
static bool
GetFundamentalTrap(JSContext *cx, JSObject *handler, PropertyName *name, Value *fvalp)
GetFundamentalTrap(JSContext *cx, HandleObject handler, HandlePropertyName name, Value *fvalp)
{
if (!GetTrap(cx, handler, name, fvalp))
return false;
@ -618,7 +617,7 @@ GetFundamentalTrap(JSContext *cx, JSObject *handler, PropertyName *name, Value *
}
static bool
GetDerivedTrap(JSContext *cx, JSObject *handler, PropertyName *name, Value *fvalp)
GetDerivedTrap(JSContext *cx, HandleObject handler, HandlePropertyName name, Value *fvalp)
{
JS_ASSERT(name == ATOM(has) ||
name == ATOM(hasOwn) ||
@ -637,7 +636,7 @@ Trap(JSContext *cx, HandleObject handler, HandleValue fval, unsigned argc, Value
}
static bool
Trap1(JSContext *cx, HandleObject handler, HandleValue fval, jsid id, Value *rval)
Trap1(JSContext *cx, HandleObject handler, HandleValue fval, HandleId id, Value *rval)
{
JSString *str = ToString(cx, IdToValue(id));
if (!str)
@ -647,18 +646,20 @@ Trap1(JSContext *cx, HandleObject handler, HandleValue fval, jsid id, Value *rva
}
static bool
Trap2(JSContext *cx, HandleObject handler, HandleValue fval, jsid id, Value v, Value *rval)
Trap2(JSContext *cx, HandleObject handler, HandleValue fval, HandleId id, Value v_, Value *rval)
{
RootedValue v(cx, v_);
JSString *str = ToString(cx, IdToValue(id));
if (!str)
return false;
rval->setString(str);
Value argv[2] = { *rval, v };
AutoValueArray ava(cx, argv, 2);
return Trap(cx, handler, fval, 2, argv, rval);
}
static bool
ParsePropertyDescriptorObject(JSContext *cx, JSObject *obj, jsid id, const Value &v,
ParsePropertyDescriptorObject(JSContext *cx, HandleObject obj, const Value &v,
PropertyDescriptor *desc)
{
AutoPropDescArrayRooter descs(cx);
@ -793,7 +794,7 @@ ScriptedProxyHandler::getPropertyDescriptor(JSContext *cx, JSObject *proxy_, jsi
Trap1(cx, handler, fval, id, value.address()) &&
((value.get().isUndefined() && IndicatePropertyNotFound(cx, desc)) ||
(ReturnedValueMustNotBePrimitive(cx, proxy, ATOM(getPropertyDescriptor), value) &&
ParsePropertyDescriptorObject(cx, proxy, id, value, desc)));
ParsePropertyDescriptorObject(cx, proxy, value, desc)));
}
bool
@ -808,7 +809,7 @@ ScriptedProxyHandler::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy_,
Trap1(cx, handler, fval, id, value.address()) &&
((value.get().isUndefined() && IndicatePropertyNotFound(cx, desc)) ||
(ReturnedValueMustNotBePrimitive(cx, proxy, ATOM(getPropertyDescriptor), value) &&
ParsePropertyDescriptorObject(cx, proxy, id, value, desc)));
ParsePropertyDescriptorObject(cx, proxy, value, desc)));
}
bool
@ -834,9 +835,10 @@ ScriptedProxyHandler::getOwnPropertyNames(JSContext *cx, JSObject *proxy, AutoId
}
bool
ScriptedProxyHandler::delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
ScriptedProxyHandler::delete_(JSContext *cx, JSObject *proxy, jsid id_, bool *bp)
{
RootedObject handler(cx, GetProxyHandlerObject(cx, proxy));
RootedId id(cx, id_);
RootedValue fval(cx), value(cx);
return GetFundamentalTrap(cx, handler, ATOM(delete), fval.address()) &&
Trap1(cx, handler, fval, id, value.address()) &&
@ -854,9 +856,10 @@ ScriptedProxyHandler::enumerate(JSContext *cx, JSObject *proxy, AutoIdVector &pr
}
bool
ScriptedProxyHandler::has(JSContext *cx, JSObject *proxy_, jsid id, bool *bp)
ScriptedProxyHandler::has(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
{
RootedObject proxy(cx, proxy_);
RootedId id(cx, id_);
RootedObject handler(cx, GetProxyHandlerObject(cx, proxy));
RootedValue fval(cx), value(cx);
if (!GetDerivedTrap(cx, handler, ATOM(has), fval.address()))
@ -868,9 +871,10 @@ ScriptedProxyHandler::has(JSContext *cx, JSObject *proxy_, jsid id, bool *bp)
}
bool
ScriptedProxyHandler::hasOwn(JSContext *cx, JSObject *proxy_, jsid id, bool *bp)
ScriptedProxyHandler::hasOwn(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
{
RootedObject proxy(cx, proxy_);
RootedId id(cx, id_);
RootedObject handler(cx, GetProxyHandlerObject(cx, proxy));
RootedValue fval(cx), value(cx);
if (!GetDerivedTrap(cx, handler, ATOM(hasOwn), fval.address()))
@ -882,16 +886,17 @@ ScriptedProxyHandler::hasOwn(JSContext *cx, JSObject *proxy_, jsid id, bool *bp)
}
bool
ScriptedProxyHandler::get(JSContext *cx, JSObject *proxy_, JSObject *receiver, jsid id_, Value *vp)
ScriptedProxyHandler::get(JSContext *cx, JSObject *proxy_, JSObject *receiver_, jsid id_, Value *vp)
{
RootedId id(cx, id_);
RootedObject proxy(cx, proxy_);
RootedObject proxy(cx, proxy_), receiver(cx, receiver_);
RootedObject handler(cx, GetProxyHandlerObject(cx, proxy));
JSString *str = ToString(cx, IdToValue(id));
if (!str)
return false;
RootedValue value(cx, StringValue(str));
Value argv[] = { ObjectOrNullValue(receiver), value };
AutoValueArray ava(cx, argv, 2);
RootedValue fval(cx);
if (!GetDerivedTrap(cx, handler, ATOM(get), fval.address()))
return false;
@ -901,17 +906,18 @@ ScriptedProxyHandler::get(JSContext *cx, JSObject *proxy_, JSObject *receiver, j
}
bool
ScriptedProxyHandler::set(JSContext *cx, JSObject *proxy_, JSObject *receiver, jsid id_, bool strict,
ScriptedProxyHandler::set(JSContext *cx, JSObject *proxy_, JSObject *receiver_, jsid id_, bool strict,
Value *vp)
{
RootedId id(cx, id_);
RootedObject proxy(cx, proxy_);
RootedObject proxy(cx, proxy_), receiver(cx, receiver_);
RootedObject handler(cx, GetProxyHandlerObject(cx, proxy));
JSString *str = ToString(cx, IdToValue(id));
if (!str)
return false;
RootedValue value(cx, StringValue(str));
Value argv[] = { ObjectOrNullValue(receiver), value, *vp };
AutoValueArray ava(cx, argv, 3);
RootedValue fval(cx);
if (!GetDerivedTrap(cx, handler, ATOM(set), fval.address()))
return false;
@ -1036,12 +1042,14 @@ Proxy::defineProperty(JSContext *cx, JSObject *proxy, jsid id, PropertyDescripto
}
bool
Proxy::defineProperty(JSContext *cx, JSObject *proxy, jsid id, const Value &v)
Proxy::defineProperty(JSContext *cx, JSObject *proxy_, jsid id_, const Value &v)
{
JS_CHECK_RECURSION(cx, return false);
RootedObject proxy(cx, proxy_);
RootedId id(cx, id_);
AutoPendingProxyOperation pending(cx, proxy);
AutoPropertyDescriptorRooter desc(cx);
return ParsePropertyDescriptorObject(cx, proxy, id, v, &desc) &&
return ParsePropertyDescriptorObject(cx, proxy, v, &desc) &&
Proxy::defineProperty(cx, proxy, id, &desc);
}

View File

@ -760,7 +760,7 @@ Shape *
JSObject::changeProperty(JSContext *cx, Shape *shape, unsigned attrs, unsigned mask,
PropertyOp getter, StrictPropertyOp setter)
{
JS_ASSERT(nativeContains(cx, *shape));
JS_ASSERT(nativeContainsNoAllocation(*shape));
attrs |= shape->attrs & mask;
@ -878,7 +878,7 @@ JSObject::removeProperty(JSContext *cx, jsid id_)
*/
Shape *aprop = self->lastProperty();
for (int n = 50; --n >= 0 && aprop->parent; aprop = aprop->parent)
JS_ASSERT_IF(aprop != shape, self->nativeContains(cx, *aprop));
JS_ASSERT_IF(aprop != shape, self->nativeContainsNoAllocation(*aprop));
#endif
}
@ -952,7 +952,7 @@ JSObject::replaceWithNewEquivalentShape(JSContext *cx, Shape *oldShape, Shape *n
{
JS_ASSERT_IF(oldShape != lastProperty(),
inDictionaryMode() &&
nativeLookup(cx, oldShape->propidRef()) == oldShape);
nativeLookupNoAllocation(oldShape->propidRef()) == oldShape);
JSObject *self = this;
@ -1006,12 +1006,10 @@ JSObject::shadowingShapeChange(JSContext *cx, const Shape &shape)
return generateOwnShape(cx);
}
bool
JSObject::clearParent(JSContext *cx)
/* static */ bool
JSObject::clearParent(JSContext *cx, HandleObject obj)
{
Rooted<JSObject*> obj(cx, this);
Rooted<JSObject*> newParent(cx, NULL);
return setParent(cx, obj, newParent);
return setParent(cx, obj, NullPtr());
}
/* static */ bool

View File

@ -506,9 +506,7 @@ struct Shape : public js::gc::Cell
static inline Shape *search(JSContext *cx, Shape *start, jsid id,
Shape ***pspp, bool adding = false);
#ifdef DEBUG
static inline Shape *searchNoAllocation(JSContext *cx, Shape *start, jsid id);
#endif
static inline Shape *searchNoAllocation(Shape *start, jsid id);
inline void removeFromDictionary(JSObject *obj);
inline void insertIntoDictionary(HeapPtrShape *dictp);
@ -918,7 +916,10 @@ class AutoRooterGetterSetter
: AutoGCRooter(cx, GETTERSETTER), attrs(attrs),
pgetter(pgetter_), psetter(psetter_),
getterRoot(cx, pgetter_), setterRoot(cx, psetter_)
{}
{
JS_ASSERT_IF(attrs & JSPROP_GETTER, !IsPoisonedPtr(*pgetter));
JS_ASSERT_IF(attrs & JSPROP_SETTER, !IsPoisonedPtr(*psetter));
}
friend void AutoGCRooter::trace(JSTracer *trc);
@ -1104,6 +1105,14 @@ namespace js {
inline Shape *
Shape::search(JSContext *cx, Shape *start, jsid id, Shape ***pspp, bool adding)
{
#ifdef DEBUG
{
SkipRoot skip0(cx, &start);
SkipRoot skip1(cx, &id);
MaybeCheckStackRoots(cx);
}
#endif
if (start->inDictionary()) {
*pspp = start->table().search(id, adding);
return SHAPE_FETCH(*pspp);
@ -1121,7 +1130,7 @@ Shape::search(JSContext *cx, Shape *start, jsid id, Shape ***pspp, bool adding)
RootedShape startRoot(cx, start);
RootedId idRoot(cx, id);
if (startRoot->hashify(cx)) {
Shape **spp = startRoot->table().search(id, adding);
Shape **spp = startRoot->table().search(idRoot, adding);
return SHAPE_FETCH(spp);
}
start = startRoot;
@ -1144,9 +1153,8 @@ Shape::search(JSContext *cx, Shape *start, jsid id, Shape ***pspp, bool adding)
return NULL;
}
#ifdef DEBUG
/* static */ inline Shape *
Shape::searchNoAllocation(JSContext *cx, Shape *start, jsid id)
Shape::searchNoAllocation(Shape *start, jsid id)
{
if (start->hasTable()) {
Shape **spp = start->table().search(id, false);
@ -1160,7 +1168,6 @@ Shape::searchNoAllocation(JSContext *cx, Shape *start, jsid id)
return NULL;
}
#endif /* DEBUG */
void
MarkNonNativePropertyFound(HandleObject obj, MutableHandleShape propp);

View File

@ -122,10 +122,14 @@ StackBaseShape::updateGetterSetter(uint8_t attrs,
StrictPropertyOp rawSetter)
{
flags &= ~(BaseShape::HAS_GETTER_OBJECT | BaseShape::HAS_SETTER_OBJECT);
if ((attrs & JSPROP_GETTER) && rawGetter)
if ((attrs & JSPROP_GETTER) && rawGetter) {
JS_ASSERT(!IsPoisonedPtr(rawGetter));
flags |= BaseShape::HAS_GETTER_OBJECT;
if ((attrs & JSPROP_SETTER) && rawSetter)
}
if ((attrs & JSPROP_SETTER) && rawSetter) {
JS_ASSERT(!IsPoisonedPtr(rawSetter));
flags |= BaseShape::HAS_SETTER_OBJECT;
}
this->rawGetter = rawGetter;
this->rawSetter = rawSetter;

View File

@ -368,7 +368,7 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
uint32_t scriptBits = 0;
JSContext *cx = xdr->cx();
JSScript *script;
Rooted<JSScript*> script(cx);
nsrcnotes = ntrynotes = natoms = nobjects = nregexps = nconsts = nClosedArgs = nClosedVars = 0;
jssrcnote *notes = NULL;
@ -572,9 +572,10 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
/* globalObject = */ NULL,
version_,
/* staticLevel = */ 0);
if (!script || !script->partiallyInit(cx, length, nsrcnotes, natoms, nobjects,
nregexps, ntrynotes, nconsts, nClosedArgs,
nClosedVars, nTypeSets))
if (!script || !JSScript::partiallyInit(cx, script,
length, nsrcnotes, natoms, nobjects,
nregexps, ntrynotes, nconsts, nClosedArgs,
nClosedVars, nTypeSets))
return JS_FALSE;
script->bindings.transfer(&bindings);
@ -1129,13 +1130,12 @@ AllocScriptData(JSContext *cx, size_t size)
return data;
}
bool
JSScript::partiallyInit(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t natoms,
/* static */ bool
JSScript::partiallyInit(JSContext *cx, Handle<JSScript*> script,
uint32_t length, uint32_t nsrcnotes, uint32_t natoms,
uint32_t nobjects, uint32_t nregexps, uint32_t ntrynotes, uint32_t nconsts,
uint16_t nClosedArgs, uint16_t nClosedVars, uint32_t nTypeSets)
{
JSScript *script = this;
size_t size = ScriptDataSize(length, nsrcnotes, natoms, nobjects, nregexps,
ntrynotes, nconsts, nClosedArgs, nClosedVars);
script->data = AllocScriptData(cx, size);
@ -1146,7 +1146,7 @@ JSScript::partiallyInit(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint
new (&script->bindings) Bindings;
uint8_t *cursor = data;
uint8_t *cursor = script->data;
if (nconsts != 0) {
script->setHasArray(CONSTS);
cursor += sizeof(ConstArray);
@ -1223,17 +1223,15 @@ JSScript::partiallyInit(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint
script->nTypeSets = uint16_t(nTypeSets);
script->code = (jsbytecode *)cursor;
JS_ASSERT(cursor + length * sizeof(jsbytecode) + nsrcnotes * sizeof(jssrcnote) == data + size);
JS_ASSERT(cursor + length * sizeof(jsbytecode) + nsrcnotes * sizeof(jssrcnote) == script->data + size);
return true;
}
bool
JSScript::fullyInitTrivial(JSContext *cx)
/* static */ bool
JSScript::fullyInitTrivial(JSContext *cx, Handle<JSScript*> script)
{
JSScript *script = this;
if (!script->partiallyInit(cx, /* length = */ 1, /* nsrcnotes = */ 1, 0, 0, 0, 0, 0, 0, 0, 0))
if (!partiallyInit(cx, script, /* length = */ 1, /* nsrcnotes = */ 1, 0, 0, 0, 0, 0, 0, 0, 0))
return false;
script->code[0] = JSOP_STOP;
@ -1242,11 +1240,9 @@ JSScript::fullyInitTrivial(JSContext *cx)
return true;
}
bool
JSScript::fullyInitFromEmitter(JSContext *cx, BytecodeEmitter *bce)
/* static */ bool
JSScript::fullyInitFromEmitter(JSContext *cx, Handle<JSScript*> script, BytecodeEmitter *bce)
{
JSScript *script = this;
/* The counts of indexed things must be checked during code generation. */
JS_ASSERT(bce->atomIndices->count() <= INDEX_LIMIT);
JS_ASSERT(bce->objectList.length <= INDEX_LIMIT);
@ -1263,10 +1259,10 @@ JSScript::fullyInitFromEmitter(JSContext *cx, BytecodeEmitter *bce)
JS_ASSERT(nClosedArgs == bce->closedArgs.length());
uint16_t nClosedVars = uint16_t(bce->closedVars.length());
JS_ASSERT(nClosedVars == bce->closedVars.length());
if (!script->partiallyInit(cx, prologLength + mainLength, nsrcnotes, bce->atomIndices->count(),
bce->objectList.length, bce->regexpList.length, bce->ntrynotes,
bce->constList.length(), nClosedArgs, nClosedVars,
bce->typesetCount))
if (!partiallyInit(cx, script, prologLength + mainLength, nsrcnotes, bce->atomIndices->count(),
bce->objectList.length, bce->regexpList.length, bce->ntrynotes,
bce->constList.length(), nClosedArgs, nClosedVars,
bce->typesetCount))
return false;
JS_ASSERT(script->mainOffset == 0);
@ -1703,9 +1699,14 @@ js::CloneScript(JSContext *cx, HandleScript src)
if (nobjects != 0) {
HeapPtrObject *vector = src->objects()->vector;
for (unsigned i = 0; i < nobjects; i++) {
JSObject *clone = vector[i]->isStaticBlock()
? CloneStaticBlockObject(cx, vector[i]->asStaticBlock(), objects, src)
: CloneInterpretedFunction(cx, vector[i]->toFunction());
JSObject *clone;
if (vector[i]->isStaticBlock()) {
Rooted<StaticBlockObject*> block(cx, &vector[i]->asStaticBlock());
clone = CloneStaticBlockObject(cx, block, objects, src);
} else {
RootedFunction fun(cx, vector[i]->toFunction());
clone = CloneInterpretedFunction(cx, fun);
}
if (!clone || !objects.append(clone))
return NULL;
}

View File

@ -552,11 +552,12 @@ struct JSScript : public js::gc::Cell
// and fullyInitTrivial() are responsible for notifying the debugger after
// successfully creating any kind (function or other) of new JSScript.
// However, callers of fullyInitFromEmitter() do not need to do this.
bool partiallyInit(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t natoms,
uint32_t nobjects, uint32_t nregexps, uint32_t ntrynotes, uint32_t nconsts,
uint16_t nClosedArgs, uint16_t nClosedVars, uint32_t nTypeSets);
bool fullyInitTrivial(JSContext *cx); // inits a JSOP_STOP-only script
bool fullyInitFromEmitter(JSContext *cx, js::BytecodeEmitter *bce);
static bool partiallyInit(JSContext *cx, JS::Handle<JSScript*> script,
uint32_t length, uint32_t nsrcnotes, uint32_t natoms,
uint32_t nobjects, uint32_t nregexps, uint32_t ntrynotes, uint32_t nconsts,
uint16_t nClosedArgs, uint16_t nClosedVars, uint32_t nTypeSets);
static bool fullyInitTrivial(JSContext *cx, JS::Handle<JSScript*> script); // inits a JSOP_STOP-only script
static bool fullyInitFromEmitter(JSContext *cx, JS::Handle<JSScript*> script, js::BytecodeEmitter *bce);
void setVersion(JSVersion v) { version = v; }

View File

@ -721,7 +721,7 @@ static JSBool
str_localeCompare(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;
@ -757,7 +757,7 @@ js_str_charAt(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
JSString *str;
RootedString str(cx);
size_t i;
if (args.thisv().isString() && args.length() != 0 && args[0].isInt32()) {
str = args.thisv().toString();
@ -794,7 +794,7 @@ js_str_charCodeAt(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
JSString *str;
RootedString str(cx);
size_t i;
if (args.thisv().isString() && args.length() != 0 && args[0].isInt32()) {
str = args.thisv().toString();
@ -1106,7 +1106,7 @@ static JSBool
str_indexOf(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;
@ -2717,7 +2717,7 @@ str_slice(JSContext *cx, unsigned argc, Value *vp)
}
}
JSString *str = ThisToStringForStringProto(cx, args);
RootedString str(cx, ThisToStringForStringProto(cx, args));
if (!str)
return false;
@ -3284,7 +3284,7 @@ js_ValueToSource(JSContext *cx, const Value &v)
if (!GetMethod(cx, obj, id, 0, &fval))
return NULL;
if (js_IsCallable(fval)) {
if (!Invoke(cx, v, fval, 0, NULL, &rval))
if (!Invoke(cx, ObjectValue(*obj), fval, 0, NULL, &rval))
return NULL;
}

View File

@ -123,6 +123,13 @@ ToStringSlow(JSContext *cx, const Value &v);
static JS_ALWAYS_INLINE JSString *
ToString(JSContext *cx, const js::Value &v)
{
#ifdef DEBUG
{
SkipRoot skip(cx, &v);
MaybeCheckStackRoots(cx);
}
#endif
if (v.isString())
return v.toString();
return ToStringSlow(cx, v);

View File

@ -1110,7 +1110,7 @@ class TypedArrayTemplate
}
static bool
setElementTail(JSContext *cx, JSObject *tarray, uint32_t index, Value *vp, JSBool strict)
setElementTail(JSContext *cx, HandleObject tarray, uint32_t index, Value *vp, JSBool strict)
{
JS_ASSERT(tarray);
JS_ASSERT(index < length(tarray));
@ -2342,21 +2342,20 @@ DataViewObject::class_constructor(JSContext *cx, unsigned argc, Value *vp)
return construct(cx, bufobj, args, NULL);
}
bool
DataViewObject::getDataPointer(JSContext *cx, CallArgs args, size_t typeSize, uint8_t **data)
/* static */ bool
DataViewObject::getDataPointer(JSContext *cx, Handle<DataViewObject*> obj,
CallArgs args, size_t typeSize, uint8_t **data)
{
JS_ASSERT(isDataView());
uint32_t offset;
JS_ASSERT(args.length() > 0);
if (!ToUint32(cx, args[0], &offset))
return false;
if (offset > UINT32_MAX - typeSize || offset + typeSize > byteLength()) {
if (offset > UINT32_MAX - typeSize || offset + typeSize > obj->byteLength()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_ARG_INDEX_OUT_OF_RANGE, "1");
return false;
}
*data = static_cast<uint8_t*>(dataPointer()) + offset;
*data = static_cast<uint8_t*>(obj->dataPointer()) + offset;
return true;
}
@ -2435,8 +2434,9 @@ struct DataViewIO
};
template<typename NativeType>
bool
DataViewObject::read(JSContext *cx, CallArgs &args, NativeType *val, const char *method)
/* static */ bool
DataViewObject::read(JSContext *cx, Handle<DataViewObject*> obj,
CallArgs &args, NativeType *val, const char *method)
{
if (args.length() < 1) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
@ -2445,7 +2445,7 @@ DataViewObject::read(JSContext *cx, CallArgs &args, NativeType *val, const char
}
uint8_t *data;
if (!getDataPointer(cx, args, sizeof(NativeType), &data))
if (!getDataPointer(cx, obj, args, sizeof(NativeType), &data))
return false;
bool fromLittleEndian = args.length() >= 2 && js_ValueToBoolean(args[1]);
@ -2486,8 +2486,9 @@ WebIDLCast<double>(JSContext *cx, const Value &value, double *out)
}
template<typename NativeType>
bool
DataViewObject::write(JSContext *cx, CallArgs &args, const char *method)
/* static */ bool
DataViewObject::write(JSContext *cx, Handle<DataViewObject*> obj,
CallArgs &args, const char *method)
{
if (args.length() < 2) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
@ -2496,7 +2497,7 @@ DataViewObject::write(JSContext *cx, CallArgs &args, const char *method)
}
uint8_t *data;
if (!getDataPointer(cx, args, sizeof(NativeType), &data))
if (!getDataPointer(cx, obj, args, sizeof(NativeType), &data))
return false;
NativeType value;
@ -2519,8 +2520,10 @@ DataViewObject::fun_getInt8(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
int8_t val;
if (!thisObj->asDataView().read(cx, args, &val, "getInt8"))
if (!read(cx, thisView, args, &val, "getInt8"))
return false;
args.rval().setInt32(val);
return true;
@ -2537,8 +2540,10 @@ DataViewObject::fun_getUint8(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
uint8_t val;
if (!thisObj->asDataView().read(cx, args, &val, "getUint8"))
if (!read(cx, thisView, args, &val, "getUint8"))
return false;
args.rval().setInt32(val);
return true;
@ -2555,8 +2560,10 @@ DataViewObject::fun_getInt16(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
int16_t val;
if (!thisObj->asDataView().read(cx, args, &val, "getInt16"))
if (!read(cx, thisView, args, &val, "getInt16"))
return false;
args.rval().setInt32(val);
return true;
@ -2573,8 +2580,10 @@ DataViewObject::fun_getUint16(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
uint16_t val;
if (!thisObj->asDataView().read(cx, args, &val, "getUint16"))
if (!read(cx, thisView, args, &val, "getUint16"))
return false;
args.rval().setInt32(val);
return true;
@ -2591,8 +2600,10 @@ DataViewObject::fun_getInt32(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
int32_t val;
if (!thisObj->asDataView().read(cx, args, &val, "getInt32"))
if (!read(cx, thisView, args, &val, "getInt32"))
return false;
args.rval().setInt32(val);
return true;
@ -2609,8 +2620,10 @@ DataViewObject::fun_getUint32(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
uint32_t val;
if (!thisObj->asDataView().read(cx, args, &val, "getUint32"))
if (!read(cx, thisView, args, &val, "getUint32"))
return false;
args.rval().setNumber(val);
return true;
@ -2627,8 +2640,10 @@ DataViewObject::fun_getFloat32(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
float val;
if (!thisObj->asDataView().read(cx, args, &val, "getFloat32"))
if (!read(cx, thisView, args, &val, "getFloat32"))
return false;
args.rval().setDouble(JS_CANONICALIZE_NAN(val));
@ -2646,8 +2661,10 @@ DataViewObject::fun_getFloat64(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
double val;
if (!thisObj->asDataView().read(cx, args, &val, "getFloat64"))
if (!read(cx, thisView, args, &val, "getFloat64"))
return false;
args.rval().setDouble(JS_CANONICALIZE_NAN(val));
@ -2665,7 +2682,9 @@ DataViewObject::fun_setInt8(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
if (!thisObj->asDataView().write<int8_t>(cx, args, "setInt8"))
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
if (!write<int8_t>(cx, thisView, args, "setInt8"))
return false;
args.rval().setUndefined();
return true;
@ -2682,7 +2701,9 @@ DataViewObject::fun_setUint8(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
if (!thisObj->asDataView().write<uint8_t>(cx, args, "setUint8"))
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
if (!write<uint8_t>(cx, thisView, args, "setUint8"))
return false;
args.rval().setUndefined();
return true;
@ -2699,7 +2720,9 @@ DataViewObject::fun_setInt16(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
if (!thisObj->asDataView().write<int16_t>(cx, args, "setInt16"))
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
if (!write<int16_t>(cx, thisView, args, "setInt16"))
return false;
args.rval().setUndefined();
return true;
@ -2716,7 +2739,9 @@ DataViewObject::fun_setUint16(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
if (!thisObj->asDataView().write<uint16_t>(cx, args, "setUint16"))
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
if (!write<uint16_t>(cx, thisView, args, "setUint16"))
return false;
args.rval().setUndefined();
return true;
@ -2733,7 +2758,9 @@ DataViewObject::fun_setInt32(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
if (!thisObj->asDataView().write<int32_t>(cx, args, "setInt32"))
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
if (!write<int32_t>(cx, thisView, args, "setInt32"))
return false;
args.rval().setUndefined();
return true;
@ -2750,7 +2777,9 @@ DataViewObject::fun_setUint32(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
if (!thisObj->asDataView().write<uint32_t>(cx, args, "setUint32"))
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
if (!write<uint32_t>(cx, thisView, args, "setUint32"))
return false;
args.rval().setUndefined();
return true;
@ -2767,7 +2796,9 @@ DataViewObject::fun_setFloat32(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
if (!thisObj->asDataView().write<float>(cx, args, "setFloat32"))
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
if (!write<float>(cx, thisView, args, "setFloat32"))
return false;
args.rval().setUndefined();
return true;
@ -2784,7 +2815,9 @@ DataViewObject::fun_setFloat64(JSContext *cx, unsigned argc, Value *vp)
if (!thisObj)
return true;
if (!thisObj->asDataView().write<double>(cx, args, "setFloat64"))
Rooted<DataViewObject*> thisView(cx, &thisObj->asDataView());
if (!write<double>(cx, thisView, args, "setFloat64"))
return false;
args.rval().setUndefined();
return true;

View File

@ -308,11 +308,14 @@ class DataViewObject : public JSObject
inline void *dataPointer();
inline bool hasBuffer() const;
static JSObject *initClass(JSContext *cx);
bool getDataPointer(JSContext *cx, CallArgs args, size_t typeSize, uint8_t **data);
static bool getDataPointer(JSContext *cx, Handle<DataViewObject*> obj,
CallArgs args, size_t typeSize, uint8_t **data);
template<typename NativeType>
bool read(JSContext *cx, CallArgs &args, NativeType *val, const char *method);
static bool read(JSContext *cx, Handle<DataViewObject*> obj,
CallArgs &args, NativeType *val, const char *method);
template<typename NativeType>
bool write(JSContext *cx, CallArgs &args, const char *method);
static bool write(JSContext *cx, Handle<DataViewObject*> obj,
CallArgs &args, const char *method);
private:
static JSFunctionSpec jsfuncs[];
};

View File

@ -7552,7 +7552,7 @@ GlobalObject::getFunctionNamespace(JSContext *cx, Value *vp)
JSRuntime *rt = cx->runtime;
JSLinearString *prefix = rt->atomState.typeAtoms[JSTYPE_FUNCTION];
JSLinearString *uri = rt->atomState.functionNamespaceURIAtom;
JSObject *obj = NewXMLNamespace(cx, prefix, uri, JS_FALSE);
RootedObject obj(cx, NewXMLNamespace(cx, prefix, uri, JS_FALSE));
if (!obj)
return false;
@ -7563,7 +7563,7 @@ GlobalObject::getFunctionNamespace(JSContext *cx, Value *vp)
* names, its prefix and uri references are copied to the QName.
* The parent remains set and links back to global.
*/
if (!obj->clearType(cx))
if (!JSObject::clearType(cx, obj))
return false;
v.set(this, FUNCTION_NS, ObjectValue(*obj));

View File

@ -1402,7 +1402,9 @@ stubs::DefVarOrConst(VMFrame &f, PropertyName *dn)
attrs |= JSPROP_READONLY;
Rooted<JSObject*> varobj(f.cx, &f.fp()->varObj());
if (!DefVarOrConstOperation(f.cx, varobj, dn, attrs))
RootedPropertyName name(f.cx, dn);
if (!DefVarOrConstOperation(f.cx, varobj, name, attrs))
THROW();
}

View File

@ -494,7 +494,9 @@ ReferenceFinder::addReferrer(jsval referrer_, Path *path)
AutoReleasePtr releasePathName(context, pathName);
/* Find the property of the results object named |pathName|. */
JS::Value v;
JS::RootedValue valRoot(context);
Value &v = valRoot.get();
if (!JS_GetProperty(context, result, pathName, &v))
return false;
if (v.isUndefined()) {

View File

@ -25,8 +25,7 @@ using namespace js::gc;
ArgumentsObject *
ArgumentsObject::create(JSContext *cx, StackFrame *fp)
{
JSFunction &callee = fp->callee();
RootedObject proto(cx, callee.global().getOrCreateObjectPrototype(cx));
RootedObject proto(cx, fp->callee().global().getOrCreateObjectPrototype(cx));
if (!proto)
return NULL;
@ -34,7 +33,7 @@ ArgumentsObject::create(JSContext *cx, StackFrame *fp)
if (!type)
return NULL;
bool strict = callee.inStrictMode();
bool strict = fp->callee().inStrictMode();
Class *clasp = strict ? &StrictArgumentsObjectClass : &NormalArgumentsObjectClass;
RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, proto,
@ -56,7 +55,7 @@ ArgumentsObject::create(JSContext *cx, StackFrame *fp)
return NULL;
data->numArgs = numArgs;
data->callee.init(ObjectValue(callee));
data->callee.init(ObjectValue(fp->callee()));
data->script = fp->script();
/* Copy [0, numArgs) into data->slots. */

View File

@ -1127,6 +1127,7 @@ Debugger::onTrap(JSContext *cx, Value *vp)
return JSTRAP_ERROR;
Value argv[1];
AutoValueArray ava(cx, argv, 1);
if (!dbg->getScriptFrame(cx, fp, &argv[0]))
return dbg->handleUncaughtException(ac, vp, false);
Value rv;
@ -1985,7 +1986,7 @@ class Debugger::ScriptQuery {
public:
/* Construct a ScriptQuery to use matching scripts for |dbg|. */
ScriptQuery(JSContext *cx, Debugger *dbg):
cx(cx), debugger(dbg), compartments(cx), innermostForGlobal(cx) {}
cx(cx), debugger(dbg), compartments(cx), urlRoot(cx), url(urlRoot.get()), innermostForGlobal(cx) {}
/*
* Initialize this ScriptQuery. Raise an error and return false if we
@ -2007,7 +2008,7 @@ class Debugger::ScriptQuery {
* Parse the query object |query|, and prepare to match only the scripts
* it specifies.
*/
bool parseQuery(JSObject *query) {
bool parseQuery(HandleObject query) {
/*
* Check for a 'global' property, which limits the results to those
* scripts scoped to a particular global object.
@ -2166,7 +2167,8 @@ class Debugger::ScriptQuery {
CompartmentSet compartments;
/* If this is a string, matching scripts have urls equal to it. */
Value url;
RootedValue urlRoot;
Value &url;
/* url as a C string. */
JSAutoByteString urlCString;
@ -2309,7 +2311,7 @@ Debugger::findScripts(JSContext *cx, unsigned argc, Value *vp)
return false;
if (argc >= 1) {
JSObject *queryObject = NonNullObject(cx, args[0]);
RootedObject queryObject(cx, NonNullObject(cx, args[0]));
if (!queryObject || !query.parseQuery(queryObject))
return false;
} else {
@ -2609,8 +2611,8 @@ class BytecodeRangeWithLineNumbers : private BytecodeRange
using BytecodeRange::frontOpcode;
using BytecodeRange::frontOffset;
BytecodeRangeWithLineNumbers(JSScript *script)
: BytecodeRange(script), lineno(script->lineno), sn(script->notes()), snpc(script->code)
BytecodeRangeWithLineNumbers(JSContext *cx, JSScript *script)
: BytecodeRange(script), lineno(script->lineno), sn(script->notes()), snpc(script->code), skip(cx, this)
{
if (!SN_IS_TERMINATOR(sn))
snpc += SN_DELTA(sn);
@ -2648,6 +2650,8 @@ class BytecodeRangeWithLineNumbers : private BytecodeRange
size_t lineno;
jssrcnote *sn;
jsbytecode *snpc;
SkipRoot skip;
};
static const size_t NoEdges = -1;
@ -2700,7 +2704,7 @@ class FlowGraphSummary : public Vector<size_t> {
size_t prevLine = script->lineno;
JSOp prevOp = JSOP_NOP;
for (BytecodeRangeWithLineNumbers r(script); !r.empty(); r.popFront()) {
for (BytecodeRangeWithLineNumbers r(cx, script); !r.empty(); r.popFront()) {
size_t lineno = r.frontLineNumber();
JSOp op = r.frontOpcode();
@ -2760,10 +2764,10 @@ DebuggerScript_getAllOffsets(JSContext *cx, unsigned argc, Value *vp)
return false;
/* Second pass: build the result array. */
JSObject *result = NewDenseEmptyArray(cx);
RootedObject result(cx, NewDenseEmptyArray(cx));
if (!result)
return false;
for (BytecodeRangeWithLineNumbers r(script); !r.empty(); r.popFront()) {
for (BytecodeRangeWithLineNumbers r(cx, script); !r.empty(); r.popFront()) {
size_t offset = r.frontOffset();
size_t lineno = r.frontLineNumber();
@ -2835,7 +2839,7 @@ DebuggerScript_getLineOffsets(JSContext *cx, unsigned argc, Value *vp)
RootedObject result(cx, NewDenseEmptyArray(cx));
if (!result)
return false;
for (BytecodeRangeWithLineNumbers r(script); !r.empty(); r.popFront()) {
for (BytecodeRangeWithLineNumbers r(cx, script); !r.empty(); r.popFront()) {
size_t offset = r.frontOffset();
/* If the op at offset is an entry point, append offset to result. */
@ -3909,7 +3913,7 @@ 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);
JSObject *props = ToObject(cx, &args[0]);
RootedObject props(cx, ToObject(cx, &args[0]));
if (!props)
return false;

View File

@ -122,7 +122,7 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
/* globalObject = */ NULL,
JSVERSION_DEFAULT,
/* staticLevel = */ 0));
if (!script || !script->fullyInitTrivial(cx))
if (!script || !JSScript::fullyInitTrivial(cx, script))
return NULL;
functionProto->initScript(script);

View File

@ -52,19 +52,17 @@ js::ObjectImpl::nativeLookup(JSContext *cx, PropertyName *name)
return nativeLookup(cx, PropertyId(name));
}
#ifdef DEBUG
inline js::Shape *
js::ObjectImpl::nativeLookupNoAllocation(JSContext *cx, PropertyId pid)
js::ObjectImpl::nativeLookupNoAllocation(PropertyId pid)
{
return nativeLookupNoAllocation(cx, pid.asId());
return nativeLookupNoAllocation(pid.asId());
}
inline js::Shape *
js::ObjectImpl::nativeLookupNoAllocation(JSContext *cx, PropertyName *name)
js::ObjectImpl::nativeLookupNoAllocation(PropertyName *name)
{
return nativeLookupNoAllocation(cx, PropertyId(name));
return nativeLookupNoAllocation(PropertyId(name));
}
#endif
inline bool
js::ObjectImpl::isExtensible() const

View File

@ -265,14 +265,12 @@ js::ObjectImpl::nativeLookup(JSContext *cx, jsid id)
return Shape::search(cx, lastProperty(), id, &spp);
}
#ifdef DEBUG
Shape *
js::ObjectImpl::nativeLookupNoAllocation(JSContext *cx, jsid id)
js::ObjectImpl::nativeLookupNoAllocation(jsid id)
{
MOZ_ASSERT(isNative());
return Shape::searchNoAllocation(cx, lastProperty(), id);
return Shape::searchNoAllocation(lastProperty(), id);
}
#endif
void
js::ObjectImpl::markChildren(JSTracer *trc)

View File

@ -1142,11 +1142,9 @@ class ObjectImpl : public gc::Cell
inline Shape * nativeLookup(JSContext *cx, PropertyId pid);
inline Shape * nativeLookup(JSContext *cx, PropertyName *name);
#ifdef DEBUG
Shape * nativeLookupNoAllocation(JSContext *cx, jsid id);
inline Shape * nativeLookupNoAllocation(JSContext *cx, PropertyId pid);
inline Shape * nativeLookupNoAllocation(JSContext *cx, PropertyName *name);
#endif
Shape * nativeLookupNoAllocation(jsid id);
inline Shape * nativeLookupNoAllocation(PropertyId pid);
inline Shape * nativeLookupNoAllocation(PropertyName *name);
inline Class *getClass() const;
inline JSClass *getJSClass() const;

View File

@ -57,12 +57,6 @@ RegExpObject::setShared(JSContext *cx, RegExpShared &shared)
JSObject::setPrivate(&shared);
}
inline void
RegExpObject::setLastIndex(const Value &v)
{
setSlot(LAST_INDEX_SLOT, v);
}
inline void
RegExpObject::setLastIndex(double d)
{

View File

@ -374,17 +374,17 @@ RegExpObject::init(JSContext *cx, HandleAtom source, RegExpFlag flags)
}
DebugOnly<JSAtomState *> atomState = &cx->runtime->atomState;
JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->lastIndexAtom))->slot() ==
JS_ASSERT(self->nativeLookupNoAllocation(NameToId(atomState->lastIndexAtom))->slot() ==
LAST_INDEX_SLOT);
JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->sourceAtom))->slot() ==
JS_ASSERT(self->nativeLookupNoAllocation(NameToId(atomState->sourceAtom))->slot() ==
SOURCE_SLOT);
JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->globalAtom))->slot() ==
JS_ASSERT(self->nativeLookupNoAllocation(NameToId(atomState->globalAtom))->slot() ==
GLOBAL_FLAG_SLOT);
JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->ignoreCaseAtom))->slot() ==
JS_ASSERT(self->nativeLookupNoAllocation(NameToId(atomState->ignoreCaseAtom))->slot() ==
IGNORE_CASE_FLAG_SLOT);
JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->multilineAtom))->slot() ==
JS_ASSERT(self->nativeLookupNoAllocation(NameToId(atomState->multilineAtom))->slot() ==
MULTILINE_FLAG_SLOT);
JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->stickyAtom))->slot() ==
JS_ASSERT(self->nativeLookupNoAllocation(NameToId(atomState->stickyAtom))->slot() ==
STICKY_FLAG_SLOT);
/*
@ -684,13 +684,13 @@ js::XDRScriptRegExpObject(XDRState<mode> *xdr, HeapPtrObject *objp)
return false;
if (mode == XDR_DECODE) {
RegExpFlag flags = RegExpFlag(flagsword);
RegExpObject *reobj = RegExpObject::createNoStatics(xdr->cx(), source, flags, NULL);
Rooted<RegExpObject*> reobj(xdr->cx(), RegExpObject::createNoStatics(xdr->cx(), source, flags, NULL));
if (!reobj)
return false;
if (!reobj->clearParent(xdr->cx()))
if (!JSObject::clearParent(xdr->cx(), reobj))
return false;
if (!reobj->clearType(xdr->cx()))
if (!JSObject::clearType(xdr->cx(), reobj))
return false;
objp->init(reobj);
}
@ -709,12 +709,12 @@ js::CloneScriptRegExpObject(JSContext *cx, RegExpObject &reobj)
/* NB: Keep this in sync with XDRScriptRegExpObject. */
RootedAtom source(cx, reobj.getSource());
RegExpObject *clone = RegExpObject::createNoStatics(cx, source, reobj.getFlags(), NULL);
Rooted<RegExpObject*> clone(cx, RegExpObject::createNoStatics(cx, source, reobj.getFlags(), NULL));
if (!clone)
return NULL;
if (!clone->clearParent(cx))
if (!JSObject::clearParent(cx, clone))
return NULL;
if (!clone->clearType(cx))
if (!JSObject::clearType(cx, clone))
return NULL;
return clone;
}

View File

@ -341,7 +341,6 @@ class RegExpObject : public JSObject
const Value &getLastIndex() const {
return getSlot(LAST_INDEX_SLOT);
}
inline void setLastIndex(const Value &v);
inline void setLastIndex(double d);
inline void zeroLastIndex();

View File

@ -652,8 +652,9 @@ StaticBlockObject::create(JSContext *cx)
return &obj->asStaticBlock();
}
Shape *
StaticBlockObject::addVar(JSContext *cx, jsid id, int index, bool *redeclared)
/* static */ Shape *
StaticBlockObject::addVar(JSContext *cx, Handle<StaticBlockObject*> block, HandleId id,
int index, bool *redeclared)
{
JS_ASSERT(JSID_IS_ATOM(id) || (JSID_IS_INT(id) && JSID_TO_INT(id) == index));
@ -661,7 +662,7 @@ StaticBlockObject::addVar(JSContext *cx, jsid id, int index, bool *redeclared)
/* Inline JSObject::addProperty in order to trap the redefinition case. */
Shape **spp;
if (Shape::search(cx, lastProperty(), id, &spp, true)) {
if (Shape::search(cx, block->lastProperty(), id, &spp, true)) {
*redeclared = true;
return NULL;
}
@ -671,10 +672,10 @@ StaticBlockObject::addVar(JSContext *cx, jsid id, int index, bool *redeclared)
* block's shape later.
*/
uint32_t slot = JSSLOT_FREE(&BlockClass) + index;
return addPropertyInternal(cx, id, /* getter = */ NULL, /* setter = */ NULL,
slot, JSPROP_ENUMERATE | JSPROP_PERMANENT,
Shape::HAS_SHORTID, index, spp,
/* allowDictionary = */ false);
return block->addPropertyInternal(cx, id, /* getter = */ NULL, /* setter = */ NULL,
slot, JSPROP_ENUMERATE | JSPROP_PERMANENT,
Shape::HAS_SHORTID, index, spp,
/* allowDictionary = */ false);
}
Class js::BlockClass = {
@ -723,7 +724,7 @@ js::XDRStaticBlockObject(XDRState<mode> *xdr, JSScript *script, StaticBlockObjec
JSContext *cx = xdr->cx();
StaticBlockObject *obj = NULL;
Rooted<StaticBlockObject*> obj(cx);
uint32_t parentId = 0;
uint32_t count = 0;
uint32_t depthAndCount = 0;
@ -772,12 +773,12 @@ js::XDRStaticBlockObject(XDRState<mode> *xdr, JSScript *script, StaticBlockObjec
return false;
/* The empty string indicates an int id. */
jsid id = atom != cx->runtime->emptyString
? AtomToId(atom)
: INT_TO_JSID(i);
RootedId id(cx, atom != cx->runtime->emptyString
? AtomToId(atom)
: INT_TO_JSID(i));
bool redeclared;
if (!obj->addVar(cx, id, i, &redeclared)) {
if (!StaticBlockObject::addVar(cx, obj, id, i, &redeclared)) {
JS_ASSERT(!redeclared);
return false;
}
@ -834,40 +835,40 @@ template bool
js::XDRStaticBlockObject(XDRState<XDR_DECODE> *xdr, JSScript *script, StaticBlockObject **objp);
JSObject *
js::CloneStaticBlockObject(JSContext *cx, StaticBlockObject &srcBlock,
js::CloneStaticBlockObject(JSContext *cx, Handle<StaticBlockObject*> srcBlock,
const AutoObjectVector &objects, JSScript *src)
{
/* NB: Keep this in sync with XDRStaticBlockObject. */
StaticBlockObject *clone = StaticBlockObject::create(cx);
Rooted<StaticBlockObject*> clone(cx, StaticBlockObject::create(cx));
if (!clone)
return NULL;
uint32_t parentId = FindObjectIndex(src, srcBlock.enclosingBlock());
uint32_t parentId = FindObjectIndex(src, srcBlock->enclosingBlock());
clone->setEnclosingBlock(parentId == NO_PARENT_INDEX
? NULL
: &objects[parentId]->asStaticBlock());
clone->setStackDepth(srcBlock.stackDepth());
clone->setStackDepth(srcBlock->stackDepth());
/* Shape::Range is reverse order, so build a list in forward order. */
AutoShapeVector shapes(cx);
if (!shapes.growBy(srcBlock.slotCount()))
if (!shapes.growBy(srcBlock->slotCount()))
return NULL;
for (Shape::Range r = srcBlock.lastProperty()->all(); !r.empty(); r.popFront())
for (Shape::Range r = srcBlock->lastProperty()->all(); !r.empty(); r.popFront())
shapes[r.front().shortid()] = &r.front();
for (Shape **p = shapes.begin(); p != shapes.end(); ++p) {
jsid id = (*p)->propid();
RootedId id(cx, (*p)->propid());
unsigned i = (*p)->shortid();
bool redeclared;
if (!clone->addVar(cx, id, i, &redeclared)) {
if (!StaticBlockObject::addVar(cx, clone, id, i, &redeclared)) {
JS_ASSERT(!redeclared);
return NULL;
}
clone->setAliased(i, srcBlock.isAliased(i));
clone->setAliased(i, srcBlock->isAliased(i));
}
return clone;
@ -1126,16 +1127,16 @@ class DebugScopeProxy : public BaseProxyHandler
* handleUnaliasedAccess returns 'true' if the access was unaliased and
* completed by handleUnaliasedAccess.
*/
bool handleUnaliasedAccess(JSContext *cx, ScopeObject &scope, jsid id, Action action, Value *vp)
bool handleUnaliasedAccess(JSContext *cx, Handle<ScopeObject*> scope, jsid id, Action action, Value *vp)
{
Shape *shape = scope.lastProperty()->search(cx, id);
Shape *shape = scope->lastProperty()->search(cx, id);
if (!shape)
return false;
StackFrame *maybefp = cx->runtime->debugScopes->hasLiveFrame(scope);
StackFrame *maybefp = cx->runtime->debugScopes->hasLiveFrame(*scope);
if (scope.isCall() && !scope.asCall().isForEval()) {
CallObject &callobj = scope.asCall();
if (scope->isCall() && !scope->asCall().isForEval()) {
CallObject &callobj = scope->asCall();
JSScript *script = callobj.callee().script();
if (!script->ensureHasTypes(cx))
return false;
@ -1196,8 +1197,8 @@ class DebugScopeProxy : public BaseProxyHandler
return false;
}
if (scope.isClonedBlock()) {
ClonedBlockObject &block = scope.asClonedBlock();
if (scope->isClonedBlock()) {
ClonedBlockObject &block = scope->asClonedBlock();
unsigned i = shape->shortid();
if (block.staticBlock().isAliased(i))
return false;
@ -1220,7 +1221,7 @@ class DebugScopeProxy : public BaseProxyHandler
return true;
}
JS_ASSERT(scope.isDeclEnv() || scope.isWith() || scope.asCall().isForEval());
JS_ASSERT(scope->isDeclEnv() || scope->isWith() || scope->asCall().isForEval());
return false;
}
@ -1287,13 +1288,14 @@ class DebugScopeProxy : public BaseProxyHandler
return getOwnPropertyDescriptor(cx, proxy, id, set, desc);
}
bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set,
bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id_, bool set,
PropertyDescriptor *desc) MOZ_OVERRIDE
{
ScopeObject &scope = proxy->asDebugScope().scope();
Rooted<ScopeObject*> scope(cx, &proxy->asDebugScope().scope());
RootedId id(cx, id_);
ArgumentsObject *maybeArgsObj;
if (!checkForMissingArguments(cx, id, scope, &maybeArgsObj))
if (!checkForMissingArguments(cx, id, *scope, &maybeArgsObj))
return false;
if (maybeArgsObj) {
@ -1313,15 +1315,16 @@ class DebugScopeProxy : public BaseProxyHandler
return true;
}
return JS_GetPropertyDescriptorById(cx, &scope, id, JSRESOLVE_QUALIFIED, desc);
return JS_GetPropertyDescriptorById(cx, scope, id, JSRESOLVE_QUALIFIED, desc);
}
bool get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, Value *vp) MOZ_OVERRIDE
bool get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id_, Value *vp) MOZ_OVERRIDE
{
ScopeObject &scope = proxy->asDebugScope().scope();
Rooted<ScopeObject*> scope(cx, &proxy->asDebugScope().scope());
RootedId id(cx, id_);
ArgumentsObject *maybeArgsObj;
if (!checkForMissingArguments(cx, id, scope, &maybeArgsObj))
if (!checkForMissingArguments(cx, id, *scope, &maybeArgsObj))
return false;
if (maybeArgsObj) {
@ -1332,33 +1335,33 @@ class DebugScopeProxy : public BaseProxyHandler
if (handleUnaliasedAccess(cx, scope, id, GET, vp))
return true;
Rooted<ScopeObject*> scopeObj(cx, &scope);
Rooted<jsid> idRoot(cx, id);
return scope.getGeneric(cx, scopeObj, idRoot, vp);
return scope->getGeneric(cx, scope, id, vp);
}
bool set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id_, bool strict,
Value *vp) MOZ_OVERRIDE
{
Rooted<ScopeObject*> scope(cx, &proxy->asDebugScope().scope());
RootedId id(cx, id_);
if (handleUnaliasedAccess(cx, *scope, id_, SET, vp))
if (handleUnaliasedAccess(cx, scope, id, SET, vp))
return true;
Rooted<jsid> id(cx, id_);
return scope->setGeneric(cx, scope, id, vp, strict);
}
bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, PropertyDescriptor *desc) MOZ_OVERRIDE
bool defineProperty(JSContext *cx, JSObject *proxy, jsid id_, PropertyDescriptor *desc) MOZ_OVERRIDE
{
Rooted<ScopeObject*> scope(cx, &proxy->asDebugScope().scope());
RootedId id(cx, id_);
bool found;
if (!has(cx, proxy, id, &found))
return false;
if (found)
return Throw(cx, id, JSMSG_CANT_REDEFINE_PROP);
ScopeObject &scope = proxy->asDebugScope().scope();
return JS_DefinePropertyById(cx, &scope, id, desc->value, desc->getter, desc->setter,
return JS_DefinePropertyById(cx, scope, id, desc->value, desc->getter, desc->setter,
desc->attrs);
}
@ -1770,29 +1773,29 @@ static JSObject *
GetDebugScope(JSContext *cx, const ScopeIter &si);
static DebugScopeObject *
GetDebugScopeForScope(JSContext *cx, ScopeObject &scope, const ScopeIter &enclosing)
GetDebugScopeForScope(JSContext *cx, Handle<ScopeObject*> scope, const ScopeIter &enclosing)
{
DebugScopes &debugScopes = *cx->runtime->debugScopes;
if (DebugScopeObject *debugScope = debugScopes.hasDebugScope(cx, scope))
if (DebugScopeObject *debugScope = debugScopes.hasDebugScope(cx, *scope))
return debugScope;
RootedObject enclosingDebug(cx, GetDebugScope(cx, enclosing));
if (!enclosingDebug)
return NULL;
JSObject &maybeDecl = scope.enclosingScope();
JSObject &maybeDecl = scope->enclosingScope();
if (maybeDecl.isDeclEnv()) {
JS_ASSERT(CallObjectLambdaName(scope.asCall().callee()));
JS_ASSERT(CallObjectLambdaName(scope->asCall().callee()));
enclosingDebug = DebugScopeObject::create(cx, maybeDecl.asDeclEnv(), enclosingDebug);
if (!enclosingDebug)
return NULL;
}
DebugScopeObject *debugScope = DebugScopeObject::create(cx, scope, enclosingDebug);
DebugScopeObject *debugScope = DebugScopeObject::create(cx, *scope, enclosingDebug);
if (!debugScope)
return NULL;
if (!debugScopes.addDebugScope(cx, scope, *debugScope))
if (!debugScopes.addDebugScope(cx, *scope, *debugScope))
return NULL;
return debugScope;
@ -1819,7 +1822,7 @@ GetDebugScopeForMissing(JSContext *cx, const ScopeIter &si)
DebugScopeObject *debugScope = NULL;
switch (si.type()) {
case ScopeIter::Call: {
CallObject *callobj = CallObject::createForFunction(cx, si.fp());
Rooted<CallObject*> callobj(cx, CallObject::createForFunction(cx, si.fp()));
if (!callobj)
return NULL;
@ -1874,12 +1877,12 @@ GetDebugScope(JSContext *cx, JSObject &obj)
return &obj;
}
ScopeObject &scope = obj.asScope();
if (StackFrame *fp = cx->runtime->debugScopes->hasLiveFrame(scope)) {
ScopeIter si(fp, scope, cx);
Rooted<ScopeObject*> scope(cx, &obj.asScope());
if (StackFrame *fp = cx->runtime->debugScopes->hasLiveFrame(*scope)) {
ScopeIter si(fp, *scope, cx);
return GetDebugScope(cx, si);
}
ScopeIter si(scope.enclosingScope(), cx);
ScopeIter si(scope->enclosingScope(), cx);
return GetDebugScopeForScope(cx, scope, si);
}
@ -1894,8 +1897,10 @@ GetDebugScope(JSContext *cx, const ScopeIter &si)
if (!si.hasScopeObject())
return GetDebugScopeForMissing(cx, si);
Rooted<ScopeObject*> scope(cx, &si.scope());
ScopeIter copy(si, cx);
return GetDebugScopeForScope(cx, si.scope(), ++copy);
return GetDebugScopeForScope(cx, scope, ++copy);
}
JSObject *

View File

@ -262,7 +262,8 @@ class StaticBlockObject : public BlockObject
*/
bool needsClone();
Shape *addVar(JSContext *cx, jsid id, int index, bool *redeclared);
static Shape *addVar(JSContext *cx, Handle<StaticBlockObject*> block, HandleId id,
int index, bool *redeclared);
};
class ClonedBlockObject : public BlockObject
@ -287,7 +288,7 @@ bool
XDRStaticBlockObject(XDRState<mode> *xdr, JSScript *script, StaticBlockObject **objp);
extern JSObject *
CloneStaticBlockObject(JSContext *cx, StaticBlockObject &srcBlock,
CloneStaticBlockObject(JSContext *cx, Handle<StaticBlockObject*> srcBlock,
const AutoObjectVector &objects, JSScript *src);
/*****************************************************************************/

View File

@ -346,10 +346,13 @@ StackFrame::pushBlock(JSContext *cx, StaticBlockObject &block)
return false;
pushOnScopeChain(*clone);
blockChain_ = blockHandle;
} else {
blockChain_ = &block;
}
flags_ |= HAS_BLOCKCHAIN;
blockChain_ = &block;
return true;
}

View File

@ -38,7 +38,7 @@ StringObject::init(JSContext *cx, HandleString str)
}
}
JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(cx->runtime->atomState.lengthAtom))->slot()
JS_ASSERT(self->nativeLookupNoAllocation(NameToId(cx->runtime->atomState.lengthAtom))->slot()
== LENGTH_SLOT);
self->setStringThis(str);