зеркало из https://github.com/mozilla/gecko-dev.git
Add most handles and stack rooters needed for exact scanning on shell benchmarks, bug 714647. r=billm
This commit is contained in:
Родитель
ecd67863cd
Коммит
5fe350f0a8
|
@ -226,6 +226,7 @@ EXPORTS_ds = \
|
|||
EXPORTS_gc = \
|
||||
Statistics.h \
|
||||
Barrier.h \
|
||||
Root.h \
|
||||
$(NULL)
|
||||
|
||||
######################################################
|
||||
|
|
|
@ -54,7 +54,7 @@ using namespace js::types;
|
|||
class RegExpMatchBuilder
|
||||
{
|
||||
JSContext * const cx;
|
||||
JSObject * const array;
|
||||
RootedVarObject array;
|
||||
|
||||
bool setProperty(JSAtom *name, Value v) {
|
||||
return !!js_DefineProperty(cx, array, ATOM_TO_JSID(name), &v,
|
||||
|
@ -62,7 +62,7 @@ class RegExpMatchBuilder
|
|||
}
|
||||
|
||||
public:
|
||||
RegExpMatchBuilder(JSContext *cx, JSObject *array) : cx(cx), array(array) {}
|
||||
RegExpMatchBuilder(JSContext *cx, JSObject *array) : cx(cx), array(cx, array) {}
|
||||
|
||||
bool append(uint32_t index, Value v) {
|
||||
JS_ASSERT(!array->getOps()->getElement);
|
||||
|
@ -81,9 +81,11 @@ class RegExpMatchBuilder
|
|||
};
|
||||
|
||||
static bool
|
||||
CreateRegExpMatchResult(JSContext *cx, JSString *input, const jschar *chars, size_t length,
|
||||
CreateRegExpMatchResult(JSContext *cx, JSString *input_, const jschar *chars, size_t length,
|
||||
MatchPairs *matchPairs, Value *rval)
|
||||
{
|
||||
RootedVarString input(cx, input_);
|
||||
|
||||
/*
|
||||
* Create the (slow) result array for a match.
|
||||
*
|
||||
|
@ -93,7 +95,7 @@ CreateRegExpMatchResult(JSContext *cx, JSString *input, const jschar *chars, siz
|
|||
* input: input string
|
||||
* index: start index for the match
|
||||
*/
|
||||
JSObject *array = NewSlowEmptyArray(cx);
|
||||
RootedVarObject array(cx, NewSlowEmptyArray(cx));
|
||||
if (!array)
|
||||
return false;
|
||||
|
||||
|
@ -225,7 +227,8 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args)
|
|||
{
|
||||
if (args.length() == 0) {
|
||||
RegExpStatics *res = cx->regExpStatics();
|
||||
RegExpObject *reobj = builder.build(cx->runtime->emptyString, res->getFlags());
|
||||
RegExpObject *reobj = builder.build(RootedVarAtom(cx, cx->runtime->emptyString),
|
||||
res->getFlags());
|
||||
if (!reobj)
|
||||
return false;
|
||||
args.rval() = ObjectValue(*reobj);
|
||||
|
@ -272,7 +275,7 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args)
|
|||
if (!sourceObj.getProperty(cx, cx->runtime->atomState.sourceAtom, &v))
|
||||
return false;
|
||||
|
||||
RegExpObject *reobj = builder.build(&v.toString()->asAtom(), flags);
|
||||
RegExpObject *reobj = builder.build(RootedVarAtom(cx, &v.toString()->asAtom()), flags);
|
||||
if (!reobj)
|
||||
return false;
|
||||
|
||||
|
@ -304,7 +307,7 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args)
|
|||
return false;
|
||||
}
|
||||
|
||||
JSAtom *escapedSourceStr = EscapeNakedForwardSlashes(cx, source);
|
||||
RootedVarAtom escapedSourceStr(cx, EscapeNakedForwardSlashes(cx, source));
|
||||
if (!escapedSourceStr)
|
||||
return false;
|
||||
|
||||
|
@ -482,22 +485,22 @@ js_InitRegExpClass(JSContext *cx, JSObject *obj)
|
|||
{
|
||||
JS_ASSERT(obj->isNative());
|
||||
|
||||
GlobalObject *global = &obj->asGlobal();
|
||||
RootedVar<GlobalObject*> global(cx, &obj->asGlobal());
|
||||
|
||||
JSObject *proto = global->createBlankPrototype(cx, &RegExpClass);
|
||||
RootedVarObject proto(cx, global->createBlankPrototype(cx, &RegExpClass));
|
||||
if (!proto)
|
||||
return NULL;
|
||||
proto->setPrivate(NULL);
|
||||
|
||||
RegExpObject *reproto = &proto->asRegExp();
|
||||
RegExpObjectBuilder builder(cx, reproto);
|
||||
if (!builder.build(cx->runtime->emptyString, RegExpFlag(0)))
|
||||
RegExpObjectBuilder builder(cx, &proto->asRegExp());
|
||||
if (!builder.build(RootedVarAtom(cx, cx->runtime->emptyString), RegExpFlag(0)))
|
||||
return NULL;
|
||||
|
||||
if (!DefinePropertiesAndBrand(cx, proto, NULL, regexp_methods))
|
||||
return NULL;
|
||||
|
||||
JSFunction *ctor = global->createConstructor(cx, regexp_construct, CLASS_ATOM(cx, RegExp), 2);
|
||||
RootedVarFunction ctor(cx);
|
||||
ctor = global->createConstructor(cx, regexp_construct, CLASS_ATOM(cx, RegExp), 2);
|
||||
if (!ctor)
|
||||
return NULL;
|
||||
|
||||
|
@ -575,14 +578,14 @@ ExecuteRegExp(JSContext *cx, Native native, unsigned argc, Value *vp)
|
|||
if (!obj)
|
||||
return ok;
|
||||
|
||||
RegExpObject &reobj = obj->asRegExp();
|
||||
RootedVar<RegExpObject*> reobj(cx, &obj->asRegExp());
|
||||
|
||||
RegExpGuard re;
|
||||
if (StartsWithGreedyStar(reobj.getSource())) {
|
||||
if (!GetSharedForGreedyStar(cx, reobj.getSource(), reobj.getFlags(), &re))
|
||||
if (StartsWithGreedyStar(reobj->getSource())) {
|
||||
if (!GetSharedForGreedyStar(cx, reobj->getSource(), reobj->getFlags(), &re))
|
||||
return false;
|
||||
} else {
|
||||
if (!reobj.getShared(cx, &re))
|
||||
if (!reobj->getShared(cx, &re))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -601,7 +604,7 @@ ExecuteRegExp(JSContext *cx, Native native, unsigned argc, Value *vp)
|
|||
size_t length = input->length();
|
||||
|
||||
/* Step 4. */
|
||||
const Value &lastIndex = reobj.getLastIndex();
|
||||
const Value &lastIndex = reobj->getLastIndex();
|
||||
|
||||
/* Step 5. */
|
||||
double i;
|
||||
|
@ -614,7 +617,7 @@ ExecuteRegExp(JSContext *cx, Native native, unsigned argc, Value *vp)
|
|||
|
||||
/* Step 9a. */
|
||||
if (i < 0 || i > length) {
|
||||
reobj.zeroLastIndex();
|
||||
reobj->zeroLastIndex();
|
||||
args.rval() = NullValue();
|
||||
return true;
|
||||
}
|
||||
|
@ -630,9 +633,9 @@ ExecuteRegExp(JSContext *cx, Native native, unsigned argc, Value *vp)
|
|||
/* Step 11 (with sticky extension). */
|
||||
if (re->global() || (!args.rval().isNull() && re->sticky())) {
|
||||
if (args.rval().isNull())
|
||||
reobj.zeroLastIndex();
|
||||
reobj->zeroLastIndex();
|
||||
else
|
||||
reobj.setLastIndex(lastIndexInt);
|
||||
reobj->setLastIndex(lastIndexInt);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -4155,7 +4155,7 @@ fi
|
|||
dnl ========================================================
|
||||
dnl = Perform moving GC stack rooting analysis
|
||||
dnl ========================================================
|
||||
MOZ_ARG_ENABLE_BOOL(gcrootanalysis,
|
||||
MOZ_ARG_ENABLE_BOOL(root-analysis,
|
||||
[ --enable-root-analysis Enable moving GC stack root analysis],
|
||||
JSGC_ROOT_ANALYSIS=1,
|
||||
JSGC_ROOT_ANALYSIS= )
|
||||
|
|
|
@ -53,9 +53,11 @@ using namespace js;
|
|||
using namespace js::frontend;
|
||||
|
||||
bool
|
||||
DefineGlobals(JSContext *cx, GlobalScope &globalScope, JSScript *script)
|
||||
DefineGlobals(JSContext *cx, GlobalScope &globalScope, JSScript* script)
|
||||
{
|
||||
JSObject *globalObj = globalScope.globalObj;
|
||||
Root<JSScript*> root(cx, &script);
|
||||
|
||||
HandleObject globalObj = globalScope.globalObj;
|
||||
|
||||
/* Define and update global properties. */
|
||||
for (size_t i = 0; i < globalScope.defs.length(); i++) {
|
||||
|
@ -165,7 +167,6 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
|
|||
{
|
||||
TokenKind tt;
|
||||
ParseNode *pn;
|
||||
JSScript *script;
|
||||
bool inDirectivePrologue;
|
||||
|
||||
JS_ASSERT(!(tcflags & ~(TCF_COMPILE_N_GO | TCF_NO_SCRIPT_RVAL | TCF_COMPILE_FOR_EVAL
|
||||
|
@ -199,8 +200,7 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
|
|||
JS_ASSERT_IF(globalObj, globalObj->isNative());
|
||||
JS_ASSERT_IF(globalObj, JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(globalObj->getClass()));
|
||||
|
||||
/* Null script early in case of error, to reduce our code footprint. */
|
||||
script = NULL;
|
||||
RootedVar<JSScript*> script(cx);
|
||||
|
||||
GlobalScope globalScope(cx, globalObj, &bce);
|
||||
bce.flags |= tcflags;
|
||||
|
|
|
@ -49,8 +49,9 @@ namespace js {
|
|||
inline
|
||||
TreeContext::TreeContext(Parser *prs)
|
||||
: flags(0), bodyid(0), blockidGen(0), parenDepth(0), yieldCount(0),
|
||||
topStmt(NULL), topScopeStmt(NULL), blockChain(NULL), blockNode(NULL),
|
||||
decls(prs->context), parser(prs), yieldNode(NULL), argumentsNode(NULL), scopeChain_(NULL),
|
||||
topStmt(NULL), topScopeStmt(NULL), blockChain(prs->context), blockNode(NULL),
|
||||
decls(prs->context), parser(prs), yieldNode(NULL), argumentsNode(NULL),
|
||||
fun_(prs->context), scopeChain_(prs->context),
|
||||
lexdeps(prs->context), parent(prs->tc), staticLevel(0), funbox(NULL), functionList(NULL),
|
||||
innermostWith(NULL), bindings(prs->context), bindingsRoot(prs->context, &bindings),
|
||||
funcStmts(NULL)
|
||||
|
|
|
@ -423,7 +423,7 @@ frontend::PushStatement(TreeContext *tc, StmtInfo *stmt, StmtType type, ptrdiff_
|
|||
stmt->blockid = tc->blockid();
|
||||
SET_STATEMENT_TOP(stmt, top);
|
||||
stmt->label = NULL;
|
||||
JS_ASSERT(!stmt->blockObj);
|
||||
stmt->blockObj = NULL;
|
||||
stmt->down = tc->topStmt;
|
||||
tc->topStmt = stmt;
|
||||
if (STMT_LINKS_SCOPE(stmt)) {
|
||||
|
@ -1360,7 +1360,6 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
{
|
||||
Definition *dn;
|
||||
JSOp op;
|
||||
JSAtom *atom;
|
||||
Definition::Kind dn_kind;
|
||||
|
||||
JS_ASSERT(pn->isKind(PNK_NAME));
|
||||
|
@ -1394,7 +1393,7 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
return JS_TRUE;
|
||||
|
||||
JS_ASSERT(JOF_OPTYPE(op) == JOF_ATOM);
|
||||
atom = pn->pn_atom;
|
||||
RootedVarAtom atom(cx, pn->pn_atom);
|
||||
UpvarCookie cookie = dn->pn_cookie;
|
||||
dn_kind = dn->kind();
|
||||
|
||||
|
@ -2369,7 +2368,7 @@ EmitSwitch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
int noteIndex;
|
||||
size_t switchSize, tableSize;
|
||||
jsbytecode *pc, *savepc;
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(cx);
|
||||
|
||||
/* Try for most optimal, fall back if not dense ints, and per ECMAv2. */
|
||||
switchOp = JSOP_TABLESWITCH;
|
||||
|
@ -3982,7 +3981,7 @@ ParseNode::getConstantValue(JSContext *cx, bool strictChecks, Value *vp)
|
|||
JS_ASSERT(isOp(JSOP_NEWINIT) && !(pn_xflags & PNX_NONCONST));
|
||||
|
||||
gc::AllocKind kind = GuessObjectGCKind(pn_count);
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
|
||||
RootedVarObject obj(cx, NewBuiltinClassInstance(cx, &ObjectClass, kind));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
|
@ -4141,7 +4140,7 @@ EmitCatch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
MOZ_NEVER_INLINE static bool
|
||||
EmitTry(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(cx);
|
||||
ptrdiff_t catchJump = -1;
|
||||
|
||||
/*
|
||||
|
@ -4373,7 +4372,7 @@ EmitTry(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
static bool
|
||||
EmitIf(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(cx);
|
||||
|
||||
/* Initialize so we can detect else-if chains and avoid recursion. */
|
||||
stmtInfo.type = STMT_IF;
|
||||
|
@ -4530,7 +4529,7 @@ EmitLet(JSContext *cx, BytecodeEmitter *bce, ParseNode *pnLet)
|
|||
return false;
|
||||
}
|
||||
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(cx);
|
||||
PushBlockScope(bce, &stmtInfo, blockObj, bce->offset());
|
||||
|
||||
if (!letNotes.update(cx, bce, bce->offset()))
|
||||
|
@ -4656,7 +4655,7 @@ EmitLexicalScope(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
JS_ASSERT(pn->isKind(PNK_LEXICALSCOPE));
|
||||
JS_ASSERT(pn->getOp() == JSOP_LEAVEBLOCK);
|
||||
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(cx);
|
||||
ObjectBox *objbox = pn->pn_objbox;
|
||||
StaticBlockObject &blockObj = objbox->object->asStaticBlock();
|
||||
PushBlockScope(bce, &stmtInfo, blockObj, bce->offset());
|
||||
|
@ -4705,7 +4704,7 @@ EmitLexicalScope(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
static bool
|
||||
EmitWith(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(cx);
|
||||
if (!EmitTree(cx, bce, pn->pn_left))
|
||||
return false;
|
||||
PushStatement(bce, &stmtInfo, STMT_WITH, bce->offset());
|
||||
|
@ -4722,7 +4721,7 @@ EmitWith(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
static bool
|
||||
EmitForIn(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
{
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(cx);
|
||||
PushStatement(bce, &stmtInfo, STMT_FOR_IN_LOOP, top);
|
||||
|
||||
ParseNode *forHead = pn->pn_left;
|
||||
|
@ -4788,7 +4787,7 @@ EmitForIn(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
|||
return false;
|
||||
|
||||
/* Enter the block before the loop body, after evaluating the obj. */
|
||||
StmtInfo letStmt;
|
||||
StmtInfo letStmt(cx);
|
||||
if (letDecl) {
|
||||
PushBlockScope(bce, &letStmt, *blockObj, bce->offset());
|
||||
letStmt.flags |= SIF_FOR_BLOCK;
|
||||
|
@ -4898,7 +4897,7 @@ EmitForIn(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
|||
static bool
|
||||
EmitNormalFor(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
{
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(cx);
|
||||
PushStatement(bce, &stmtInfo, STMT_FOR_LOOP, top);
|
||||
|
||||
ParseNode *forHead = pn->pn_left;
|
||||
|
@ -5055,7 +5054,7 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
return Emit1(cx, bce, JSOP_GETFUNNS) >= 0;
|
||||
#endif
|
||||
|
||||
JSFunction *fun = pn->pn_funbox->function();
|
||||
RootedVarFunction fun(cx, pn->pn_funbox->function());
|
||||
JS_ASSERT(fun->isInterpreted());
|
||||
if (fun->script()) {
|
||||
/*
|
||||
|
@ -5178,7 +5177,7 @@ EmitDo(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
if (!EmitLoopEntry(cx, bce, NULL))
|
||||
return false;
|
||||
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(cx);
|
||||
PushStatement(bce, &stmtInfo, STMT_DO_LOOP, top);
|
||||
if (!EmitTree(cx, bce, pn->pn_left))
|
||||
return false;
|
||||
|
@ -5231,7 +5230,7 @@ EmitWhile(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
|||
* . . .
|
||||
* N N*(ifeq-fail; goto); ifeq-pass goto; N*ifne-pass; ifne-fail
|
||||
*/
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(cx);
|
||||
PushStatement(bce, &stmtInfo, STMT_WHILE_LOOP, top);
|
||||
|
||||
ptrdiff_t noteIndex = NewSrcNote(cx, bce, SRC_WHILE);
|
||||
|
@ -5369,7 +5368,7 @@ EmitStatementList(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t
|
|||
return false;
|
||||
}
|
||||
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(cx);
|
||||
PushStatement(bce, &stmtInfo, STMT_BLOCK, top);
|
||||
|
||||
ParseNode *pnchild = pn->pn_head;
|
||||
|
@ -5850,7 +5849,7 @@ EmitLabel(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
return false;
|
||||
|
||||
/* Emit code for the labeled statement. */
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(cx);
|
||||
PushStatement(bce, &stmtInfo, STMT_LABEL, bce->offset());
|
||||
stmtInfo.label = atom;
|
||||
if (!EmitTree(cx, bce, pn2))
|
||||
|
@ -5874,7 +5873,7 @@ static bool
|
|||
EmitSyntheticStatements(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
{
|
||||
JS_ASSERT(pn->isArity(PN_LIST));
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(cx);
|
||||
PushStatement(bce, &stmtInfo, STMT_SEQ, top);
|
||||
for (ParseNode *pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
|
||||
if (!EmitTree(cx, bce, pn2))
|
||||
|
@ -5950,7 +5949,7 @@ EmitObject(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
* Try to construct the shape of the object as we go, so we can emit a
|
||||
* JSOP_NEWOBJECT with the final shape instead.
|
||||
*/
|
||||
JSObject *obj = NULL;
|
||||
RootedVarObject obj(cx);
|
||||
if (bce->compileAndGo()) {
|
||||
gc::AllocKind kind = GuessObjectGCKind(pn->pn_count);
|
||||
obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
#include "frontend/Parser.h"
|
||||
#include "frontend/ParseMaps.h"
|
||||
|
||||
#include "vm/ScopeObject.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
typedef HashSet<JSAtom *> FuncStmtSet;
|
||||
|
@ -136,12 +138,12 @@ struct StmtInfo {
|
|||
ptrdiff_t update; /* loop update offset (top if none) */
|
||||
ptrdiff_t breaks; /* offset of last break in loop */
|
||||
ptrdiff_t continues; /* offset of last continue in loop */
|
||||
union {
|
||||
JSAtom *label; /* name of LABEL */
|
||||
StaticBlockObject *blockObj;/* block scope object */
|
||||
};
|
||||
RootedVarAtom label; /* name of LABEL */
|
||||
RootedVar<StaticBlockObject *> blockObj; /* block scope object */
|
||||
StmtInfo *down; /* info for enclosing statement */
|
||||
StmtInfo *downScope; /* next enclosing lexical scope */
|
||||
|
||||
StmtInfo(JSContext *cx) : label(cx), blockObj(cx) {}
|
||||
};
|
||||
|
||||
#define SIF_SCOPE 0x0001 /* statement has its own lexical scope */
|
||||
|
@ -336,7 +338,8 @@ struct TreeContext { /* tree context for semantic checks */
|
|||
non-zero depth in current paren tree */
|
||||
StmtInfo *topStmt; /* top of statement info stack */
|
||||
StmtInfo *topScopeStmt; /* top lexical scope statement */
|
||||
StaticBlockObject *blockChain; /* compile block scope chain (NB: one
|
||||
RootedVar<StaticBlockObject *> blockChain;
|
||||
/* compile time block scope chain (NB: one
|
||||
deeper than the topScopeStmt/downScope
|
||||
chain when in head of let block/expr) */
|
||||
ParseNode *blockNode; /* parse node for a block with let declarations
|
||||
|
@ -351,11 +354,9 @@ struct TreeContext { /* tree context for semantic checks */
|
|||
inside a generator expression */
|
||||
|
||||
private:
|
||||
union {
|
||||
JSFunction *fun_; /* function to store argument and variable
|
||||
RootedVarFunction fun_; /* function to store argument and variable
|
||||
names when flags & TCF_IN_FUNCTION */
|
||||
JSObject *scopeChain_; /* scope chain object for the script */
|
||||
};
|
||||
RootedVarObject scopeChain_; /* scope chain object for the script */
|
||||
|
||||
public:
|
||||
JSFunction *fun() const {
|
||||
|
@ -544,7 +545,8 @@ class GCConstList {
|
|||
|
||||
struct GlobalScope {
|
||||
GlobalScope(JSContext *cx, JSObject *globalObj, BytecodeEmitter *bce)
|
||||
: globalObj(globalObj), bce(bce), defs(cx), names(cx)
|
||||
: globalObj(cx, globalObj), bce(bce), defs(cx), names(cx),
|
||||
defsRoot(cx, &defs), namesRoot(cx, &names)
|
||||
{ }
|
||||
|
||||
struct GlobalDef {
|
||||
|
@ -558,7 +560,7 @@ struct GlobalScope {
|
|||
GlobalDef(JSAtom *atom, FunctionBox *box) : atom(atom), funbox(box) { }
|
||||
};
|
||||
|
||||
JSObject *globalObj;
|
||||
RootedVarObject globalObj;
|
||||
BytecodeEmitter *bce;
|
||||
|
||||
/*
|
||||
|
@ -571,6 +573,13 @@ struct GlobalScope {
|
|||
*/
|
||||
Vector<GlobalDef, 16> defs;
|
||||
AtomIndexMap names;
|
||||
|
||||
/*
|
||||
* Protect the inline elements within defs/names from being clobbered by
|
||||
* root analysis. The atoms in this structure must be separately rooted.
|
||||
*/
|
||||
JS::SkipRoot defsRoot;
|
||||
JS::SkipRoot namesRoot;
|
||||
};
|
||||
|
||||
struct BytecodeEmitter : public TreeContext
|
||||
|
|
|
@ -230,8 +230,8 @@ FoldXMLConstants(JSContext *cx, ParseNode *pn, TreeContext *tc)
|
|||
ParseNodeKind kind = pn->getKind();
|
||||
ParseNode **pnp = &pn->pn_head;
|
||||
ParseNode *pn1 = *pnp;
|
||||
JSString *accum = NULL;
|
||||
JSString *str = NULL;
|
||||
RootedVarString accum(cx);
|
||||
RootedVarString str(cx);
|
||||
if ((pn->pn_xflags & PNX_CANTFOLD) == 0) {
|
||||
if (kind == PNK_XMLETAGO)
|
||||
accum = cx->runtime->atomState.etagoAtom;
|
||||
|
@ -745,15 +745,13 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
|
|||
/* Handle a binary string concatenation. */
|
||||
JS_ASSERT(pn->isArity(PN_BINARY));
|
||||
if (pn1->isKind(PNK_STRING) || pn2->isKind(PNK_STRING)) {
|
||||
JSString *left, *right, *str;
|
||||
|
||||
if (!FoldType(cx, !pn1->isKind(PNK_STRING) ? pn1 : pn2, PNK_STRING))
|
||||
return false;
|
||||
if (!pn1->isKind(PNK_STRING) || !pn2->isKind(PNK_STRING))
|
||||
return true;
|
||||
left = pn1->pn_atom;
|
||||
right = pn2->pn_atom;
|
||||
str = js_ConcatStrings(cx, left, right);
|
||||
RootedVarString left(cx, pn1->pn_atom);
|
||||
RootedVarString right(cx, pn2->pn_atom);
|
||||
RootedVarString str(cx, js_ConcatStrings(cx, left, right));
|
||||
if (!str)
|
||||
return false;
|
||||
pn->pn_atom = js_AtomizeString(cx, str);
|
||||
|
|
|
@ -174,6 +174,8 @@ Parser::setPrincipals(JSPrincipals *prin, JSPrincipals *originPrin)
|
|||
ObjectBox *
|
||||
Parser::newObjectBox(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj && !IsPoisonedPtr(obj));
|
||||
|
||||
/*
|
||||
* We use JSContext.tempLifoAlloc to allocate parsed objects and place them
|
||||
* on a list in this Parser to ensure GC safety. Thus the tempLifoAlloc
|
||||
|
@ -197,7 +199,7 @@ Parser::newObjectBox(JSObject *obj)
|
|||
FunctionBox *
|
||||
Parser::newFunctionBox(JSObject *obj, ParseNode *fn, TreeContext *tc)
|
||||
{
|
||||
JS_ASSERT(obj);
|
||||
JS_ASSERT(obj && !IsPoisonedPtr(obj));
|
||||
JS_ASSERT(obj->isFunction());
|
||||
|
||||
/*
|
||||
|
@ -583,7 +585,7 @@ BindLocalVariable(JSContext *cx, TreeContext *tc, ParseNode *pn, BindingKind kin
|
|||
JS_ASSERT(kind == VARIABLE || kind == CONSTANT);
|
||||
|
||||
unsigned index = tc->bindings.numVars();
|
||||
if (!tc->bindings.add(cx, pn->pn_atom, kind))
|
||||
if (!tc->bindings.add(cx, RootedVarAtom(cx, pn->pn_atom), kind))
|
||||
return false;
|
||||
|
||||
pn->pn_cookie.set(tc->staticLevel, index);
|
||||
|
@ -596,7 +598,7 @@ Parser::functionBody(FunctionBodyType type)
|
|||
{
|
||||
JS_ASSERT(tc->inFunction());
|
||||
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(context);
|
||||
PushStatement(tc, &stmtInfo, STMT_BLOCK, -1);
|
||||
stmtInfo.flags = SIF_BODY_BLOCK;
|
||||
|
||||
|
@ -646,7 +648,7 @@ Parser::functionBody(FunctionBodyType type)
|
|||
if (!CheckStrictParameters(context, tc))
|
||||
return NULL;
|
||||
|
||||
PropertyName * const arguments = context->runtime->atomState.argumentsAtom;
|
||||
RootedVar<PropertyName*> const arguments(context, context->runtime->atomState.argumentsAtom);
|
||||
|
||||
/*
|
||||
* Non-top-level functions use JSOP_DEFFUN which is a dynamic scope
|
||||
|
@ -1354,7 +1356,7 @@ Parser::functionArguments(TreeContext &funtc, FunctionBox *funbox, ParseNode **l
|
|||
|
||||
case TOK_NAME:
|
||||
{
|
||||
PropertyName *name = tokenStream.currentToken().name();
|
||||
RootedVar<PropertyName*> name(context, tokenStream.currentToken().name());
|
||||
|
||||
#ifdef JS_HAS_DESTRUCTURING
|
||||
/*
|
||||
|
@ -1414,7 +1416,7 @@ Parser::functionArguments(TreeContext &funtc, FunctionBox *funbox, ParseNode **l
|
|||
}
|
||||
|
||||
ParseNode *
|
||||
Parser::functionDef(PropertyName *funName, FunctionType type, FunctionSyntaxKind kind)
|
||||
Parser::functionDef(HandlePropertyName funName, FunctionType type, FunctionSyntaxKind kind)
|
||||
{
|
||||
JS_ASSERT_IF(kind == Statement, funName);
|
||||
|
||||
|
@ -1537,7 +1539,7 @@ Parser::functionDef(PropertyName *funName, FunctionType type, FunctionSyntaxKind
|
|||
if (!funbox)
|
||||
return NULL;
|
||||
|
||||
JSFunction *fun = funbox->function();
|
||||
RootedVarFunction fun(context, funbox->function());
|
||||
|
||||
/* Now parse formal argument list and compute fun->nargs. */
|
||||
ParseNode *prelude = NULL;
|
||||
|
@ -1727,7 +1729,7 @@ Parser::functionDef(PropertyName *funName, FunctionType type, FunctionSyntaxKind
|
|||
ParseNode *
|
||||
Parser::functionStmt()
|
||||
{
|
||||
PropertyName *name = NULL;
|
||||
RootedVarPropertyName name(context);
|
||||
if (tokenStream.getToken(TSF_KEYWORD_IS_NAME) == TOK_NAME) {
|
||||
name = tokenStream.currentToken().name();
|
||||
} else {
|
||||
|
@ -1748,7 +1750,7 @@ Parser::functionStmt()
|
|||
ParseNode *
|
||||
Parser::functionExpr()
|
||||
{
|
||||
PropertyName *name = NULL;
|
||||
RootedVarPropertyName name(context);
|
||||
if (tokenStream.getToken(TSF_KEYWORD_IS_NAME) == TOK_NAME)
|
||||
name = tokenStream.currentToken().name();
|
||||
else
|
||||
|
@ -1968,8 +1970,8 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, TreeContext *tc)
|
|||
if (!CheckStrictBinding(cx, tc, atom->asPropertyName(), pn))
|
||||
return false;
|
||||
|
||||
StaticBlockObject &blockObj = *data->let.blockObj;
|
||||
unsigned blockCount = blockObj.slotCount();
|
||||
RootedVar<StaticBlockObject *> blockObj(cx, data->let.blockObj);
|
||||
unsigned blockCount = blockObj->slotCount();
|
||||
if (blockCount == JS_BIT(16)) {
|
||||
ReportCompileErrorNumber(cx, TS(tc->parser), pn,
|
||||
JSREPORT_ERROR, data->let.overflow);
|
||||
|
@ -2006,7 +2008,7 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, TreeContext *tc)
|
|||
*/
|
||||
bool redeclared;
|
||||
jsid id = ATOM_TO_JSID(atom);
|
||||
const Shape *shape = blockObj.addVar(cx, id, blockCount, &redeclared);
|
||||
const Shape *shape = blockObj->addVar(cx, id, blockCount, &redeclared);
|
||||
if (!shape) {
|
||||
if (redeclared)
|
||||
ReportRedeclaration(cx, tc, pn, false, atom);
|
||||
|
@ -2014,7 +2016,7 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, TreeContext *tc)
|
|||
}
|
||||
|
||||
/* Store pn in the static block object. */
|
||||
blockObj.setDefinitionParseNode(blockCount, reinterpret_cast<Definition *>(pn));
|
||||
blockObj->setDefinitionParseNode(blockCount, reinterpret_cast<Definition *>(pn));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2085,11 +2087,12 @@ static bool
|
|||
DefineGlobal(ParseNode *pn, BytecodeEmitter *bce, PropertyName *name)
|
||||
{
|
||||
GlobalScope *globalScope = bce->globalScope;
|
||||
JSObject *globalObj = globalScope->globalObj;
|
||||
HandleObject globalObj = globalScope->globalObj;
|
||||
|
||||
if (!bce->compileAndGo() || !globalObj || bce->compilingForEval())
|
||||
return true;
|
||||
|
||||
JS_ASSERT(!IsPoisonedPtr(name));
|
||||
AtomIndexAddPtr p = globalScope->names.lookupForAdd(name);
|
||||
if (!p) {
|
||||
JSContext *cx = bce->parser->context;
|
||||
|
@ -2127,6 +2130,8 @@ DefineGlobal(ParseNode *pn, BytecodeEmitter *bce, PropertyName *name)
|
|||
if (!globalScope->defs.append(def))
|
||||
return false;
|
||||
|
||||
JS_ASSERT(!IsPoisonedPtr(name));
|
||||
|
||||
jsatomid index = globalScope->names.count();
|
||||
if (!globalScope->names.add(p, name, index))
|
||||
return false;
|
||||
|
@ -2591,7 +2596,8 @@ CheckDestructuring(JSContext *cx, BindData *data, ParseNode *left, TreeContext *
|
|||
return false;
|
||||
}
|
||||
|
||||
StaticBlockObject *blockObj = data && data->binder == BindLet ? data->let.blockObj : NULL;
|
||||
RootedVar<StaticBlockObject *> blockObj(cx);
|
||||
blockObj = data && data->binder == BindLet ? data->let.blockObj : NULL;
|
||||
uint32_t blockCountBefore = blockObj ? blockObj->slotCount() : 0;
|
||||
|
||||
if (left->isKind(PNK_RB)) {
|
||||
|
@ -2902,7 +2908,7 @@ Parser::letBlock(LetContext letContext)
|
|||
|
||||
MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_LET);
|
||||
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(context);
|
||||
ParseNode *block = PushLetScope(context, tc, *blockObj, &stmtInfo);
|
||||
if (!block)
|
||||
return NULL;
|
||||
|
@ -3037,7 +3043,7 @@ Parser::switchStatement()
|
|||
* NB: we must push stmtInfo before calling GenerateBlockIdForStmtNode
|
||||
* because that function states tc->topStmt->blockid.
|
||||
*/
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(context);
|
||||
PushStatement(tc, &stmtInfo, STMT_SWITCH, -1);
|
||||
|
||||
/* pn2 is a list of case nodes. The default case has pn_left == NULL */
|
||||
|
@ -3159,7 +3165,7 @@ Parser::forStatement()
|
|||
if (!pn)
|
||||
return NULL;
|
||||
|
||||
StmtInfo forStmt;
|
||||
StmtInfo forStmt(context);
|
||||
PushStatement(tc, &forStmt, STMT_FOR_LOOP, -1);
|
||||
|
||||
pn->setOp(JSOP_ITER);
|
||||
|
@ -3251,9 +3257,9 @@ Parser::forStatement()
|
|||
* as we've excluded 'in' from being parsed in RelExpr by setting
|
||||
* the TCF_IN_FOR_INIT flag in our TreeContext.
|
||||
*/
|
||||
ParseNode *forHead; /* initialized by both branches. */
|
||||
StmtInfo letStmt; /* used if blockObj != NULL. */
|
||||
ParseNode *pn2, *pn3; /* forHead->pn_kid1 and pn_kid2. */
|
||||
ParseNode *forHead; /* initialized by both branches. */
|
||||
StmtInfo letStmt(context); /* used if blockObj != NULL. */
|
||||
ParseNode *pn2, *pn3; /* forHead->pn_kid1 and pn_kid2. */
|
||||
bool forOf;
|
||||
if (pn1 && matchInOrOf(&forOf)) {
|
||||
/*
|
||||
|
@ -3552,7 +3558,7 @@ Parser::tryStatement()
|
|||
pn->setOp(JSOP_NOP);
|
||||
|
||||
MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_TRY);
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(context);
|
||||
if (!PushBlocklikeStatement(&stmtInfo, STMT_TRY, tc))
|
||||
return NULL;
|
||||
pn->pn_kid1 = statements();
|
||||
|
@ -3719,7 +3725,7 @@ Parser::withStatement()
|
|||
ParseNode *oldWith = tc->innermostWith;
|
||||
tc->innermostWith = pn;
|
||||
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(context);
|
||||
PushStatement(tc, &stmtInfo, STMT_WITH, -1);
|
||||
pn2 = statement();
|
||||
if (!pn2)
|
||||
|
@ -3890,7 +3896,7 @@ Parser::expressionStatement()
|
|||
(void) tokenStream.getToken();
|
||||
|
||||
/* Push a label struct and parse the statement. */
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(context);
|
||||
PushStatement(tc, &stmtInfo, STMT_LABEL, -1);
|
||||
stmtInfo.label = label;
|
||||
ParseNode *pn = statement();
|
||||
|
@ -3971,7 +3977,7 @@ Parser::statement()
|
|||
if (!pn1)
|
||||
return NULL;
|
||||
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(context);
|
||||
PushStatement(tc, &stmtInfo, STMT_IF, -1);
|
||||
ParseNode *pn2 = statement();
|
||||
if (!pn2)
|
||||
|
@ -4010,7 +4016,7 @@ Parser::statement()
|
|||
pn = BinaryNode::create(PNK_WHILE, tc);
|
||||
if (!pn)
|
||||
return NULL;
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(context);
|
||||
PushStatement(tc, &stmtInfo, STMT_WHILE_LOOP, -1);
|
||||
ParseNode *pn2 = condition();
|
||||
if (!pn2)
|
||||
|
@ -4030,7 +4036,7 @@ Parser::statement()
|
|||
pn = BinaryNode::create(PNK_DOWHILE, tc);
|
||||
if (!pn)
|
||||
return NULL;
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(context);
|
||||
PushStatement(tc, &stmtInfo, STMT_DO_LOOP, -1);
|
||||
ParseNode *pn2 = statement();
|
||||
if (!pn2)
|
||||
|
@ -4207,7 +4213,7 @@ Parser::statement()
|
|||
|
||||
oldflags = tc->flags;
|
||||
tc->flags = oldflags & ~TCF_HAS_FUNCTION_STMT;
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(context);
|
||||
if (!PushBlocklikeStatement(&stmtInfo, STMT_BLOCK, tc))
|
||||
return NULL;
|
||||
pn = statements();
|
||||
|
@ -5308,7 +5314,7 @@ Parser::comprehensionTail(ParseNode *kid, unsigned blockid, bool isGenexp,
|
|||
{
|
||||
unsigned adjust;
|
||||
ParseNode *pn, *pn2, *pn3, **pnp;
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(context);
|
||||
BindData data;
|
||||
TokenKind tt;
|
||||
|
||||
|
@ -5757,7 +5763,7 @@ Parser::memberExpr(JSBool allowCallSyntax)
|
|||
tc->flags |= TCF_FUN_HEAVYWEIGHT;
|
||||
tc->noteBindingsAccessedDynamically();
|
||||
|
||||
StmtInfo stmtInfo;
|
||||
StmtInfo stmtInfo(context);
|
||||
ParseNode *oldWith = tc->innermostWith;
|
||||
tc->innermostWith = lhs;
|
||||
PushStatement(tc, &stmtInfo, STMT_WITH, -1);
|
||||
|
@ -6934,7 +6940,8 @@ Parser::primaryExpr(TokenKind tt, bool afterDoubleDot)
|
|||
pn->pn_xflags |= PNX_NONCONST;
|
||||
|
||||
/* NB: Getter function in { get x(){} } is unnamed. */
|
||||
pn2 = functionDef(NULL, op == JSOP_GETTER ? Getter : Setter, Expression);
|
||||
pn2 = functionDef(RootedVarPropertyName(context, NULL),
|
||||
op == JSOP_GETTER ? Getter : Setter, Expression);
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
TokenPos pos = {begin, pn2->pn_pos.end};
|
||||
|
@ -7147,7 +7154,7 @@ Parser::primaryExpr(TokenKind tt, bool afterDoubleDot)
|
|||
RegExpFlag flags = tokenStream.currentToken().regExpFlags();
|
||||
RegExpStatics *res = context->regExpStatics();
|
||||
|
||||
RegExpObject *reobj;
|
||||
RootedVar<RegExpObject*> reobj(context);
|
||||
if (context->hasfp())
|
||||
reobj = RegExpObject::create(context, res, chars, length, flags, &tokenStream);
|
||||
else
|
||||
|
|
|
@ -243,7 +243,7 @@ struct Parser : private AutoGCRooter
|
|||
enum FunctionType { Getter, Setter, Normal };
|
||||
bool functionArguments(TreeContext &funtc, FunctionBox *funbox, ParseNode **list);
|
||||
|
||||
ParseNode *functionDef(PropertyName *name, FunctionType type, FunctionSyntaxKind kind);
|
||||
ParseNode *functionDef(HandlePropertyName name, FunctionType type, FunctionSyntaxKind kind);
|
||||
|
||||
ParseNode *unaryOpExpr(ParseNodeKind kind, JSOp op);
|
||||
|
||||
|
|
|
@ -154,7 +154,8 @@ js::IsIdentifier(JSLinearString *str)
|
|||
|
||||
/* Initialize members that aren't initialized in |init|. */
|
||||
TokenStream::TokenStream(JSContext *cx, JSPrincipals *prin, JSPrincipals *originPrin)
|
||||
: tokens(), cursor(), lookahead(), flags(), listenerTSData(), tokenbuf(cx),
|
||||
: tokens(), tokensRoot(cx, &tokens),
|
||||
cursor(), lookahead(), flags(), userbufRoot(cx, &userbuf), listenerTSData(), tokenbuf(cx),
|
||||
cx(cx), originPrincipals(JSScript::normalizeOriginPrincipals(prin, originPrin))
|
||||
{
|
||||
if (originPrincipals)
|
||||
|
|
|
@ -336,12 +336,14 @@ struct Token {
|
|||
|
||||
void setName(JSOp op, PropertyName *name) {
|
||||
JS_ASSERT(op == JSOP_NAME);
|
||||
JS_ASSERT(!IsPoisonedPtr(name));
|
||||
u.s.op = op;
|
||||
u.s.n.name = name;
|
||||
}
|
||||
|
||||
void setAtom(JSOp op, JSAtom *atom) {
|
||||
JS_ASSERT(op == JSOP_STRING || op == JSOP_XMLCOMMENT || JSOP_XMLCDATA);
|
||||
JS_ASSERT(!IsPoisonedPtr(atom));
|
||||
u.s.op = op;
|
||||
u.s.n.atom = atom;
|
||||
}
|
||||
|
@ -350,6 +352,8 @@ struct Token {
|
|||
JS_ASSERT(target);
|
||||
JS_ASSERT(data);
|
||||
JS_ASSERT(!target->empty());
|
||||
JS_ASSERT(!IsPoisonedPtr(target));
|
||||
JS_ASSERT(!IsPoisonedPtr(data));
|
||||
u.xmlpi.target = target;
|
||||
u.xmlpi.data = data;
|
||||
}
|
||||
|
@ -808,13 +812,15 @@ class TokenStream
|
|||
void updateFlagsForEOL();
|
||||
|
||||
Token tokens[ntokens];/* circular token buffer */
|
||||
unsigned cursor; /* index of last parsed token */
|
||||
unsigned lookahead; /* count of lookahead tokens */
|
||||
unsigned lineno; /* current line number */
|
||||
unsigned flags; /* flags -- see above */
|
||||
JS::SkipRoot tokensRoot; /* prevent overwriting of token buffer */
|
||||
unsigned cursor; /* index of last parsed token */
|
||||
unsigned lookahead; /* count of lookahead tokens */
|
||||
unsigned lineno; /* current line number */
|
||||
unsigned flags; /* flags -- see above */
|
||||
const jschar *linebase; /* start of current line; points into userbuf */
|
||||
const jschar *prevLinebase; /* start of previous line; NULL if on the first line */
|
||||
TokenBuf userbuf; /* user input buffer */
|
||||
JS::SkipRoot userbufRoot; /* prevent overwriting of char pointers within userbuf */
|
||||
const char *filename; /* input filename or null */
|
||||
jschar *sourceMap; /* source map's filename or null */
|
||||
void *listenerTSData;/* listener data for this TokenStream */
|
||||
|
|
|
@ -124,6 +124,7 @@ HeapValue::init(const Value &v)
|
|||
inline void
|
||||
HeapValue::init(JSCompartment *comp, const Value &v)
|
||||
{
|
||||
JS_ASSERT(!IsPoisonedValue(v));
|
||||
value = v;
|
||||
post(comp);
|
||||
}
|
||||
|
|
159
js/src/gc/Root.h
159
js/src/gc/Root.h
|
@ -40,10 +40,11 @@
|
|||
#ifndef jsgc_root_h__
|
||||
#define jsgc_root_h__
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jspubtd.h"
|
||||
|
||||
namespace js {
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace JS {
|
||||
|
||||
/*
|
||||
* Moving GC Stack Rooting
|
||||
|
@ -92,33 +93,55 @@ namespace js {
|
|||
* fix than when relying on a separate rooting analysis.
|
||||
*/
|
||||
|
||||
template <> struct RootMethods<const jsid>
|
||||
template <typename T> class Root;
|
||||
template <typename T> class RootedVar;
|
||||
|
||||
template <typename T>
|
||||
struct RootMethods { };
|
||||
|
||||
/*
|
||||
* Reference to a stack location rooted for GC. See "Moving GC Stack Rooting"
|
||||
* comment in jscntxt.h.
|
||||
*/
|
||||
template <typename T>
|
||||
class Handle
|
||||
{
|
||||
static jsid initial() { return JSID_VOID; }
|
||||
static ThingRootKind kind() { return THING_ROOT_ID; }
|
||||
static bool poisoned(jsid id) { return IsPoisonedId(id); }
|
||||
public:
|
||||
/* Copy handles of different types, with implicit coercion. */
|
||||
template <typename S> Handle(Handle<S> handle) {
|
||||
testAssign<S>();
|
||||
ptr = reinterpret_cast<const T *>(handle.address());
|
||||
}
|
||||
|
||||
/* Get a handle from a rooted stack location, with implicit coercion. */
|
||||
template <typename S> inline Handle(const Root<S> &root);
|
||||
template <typename S> inline Handle(const RootedVar<S> &root);
|
||||
|
||||
const T *address() { return ptr; }
|
||||
|
||||
operator T () { return value(); }
|
||||
T operator ->() { return value(); }
|
||||
|
||||
private:
|
||||
const T *ptr;
|
||||
T value() { return *ptr; }
|
||||
|
||||
template <typename S>
|
||||
void testAssign() {
|
||||
#ifdef DEBUG
|
||||
T a = RootMethods<T>::initial();
|
||||
S b = RootMethods<S>::initial();
|
||||
a = b;
|
||||
(void)a;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct RootMethods<jsid>
|
||||
{
|
||||
static jsid initial() { return JSID_VOID; }
|
||||
static ThingRootKind kind() { return THING_ROOT_ID; }
|
||||
static bool poisoned(jsid id) { return IsPoisonedId(id); }
|
||||
};
|
||||
|
||||
template <> struct RootMethods<const Value>
|
||||
{
|
||||
static Value initial() { return UndefinedValue(); }
|
||||
static ThingRootKind kind() { return THING_ROOT_VALUE; }
|
||||
static bool poisoned(const Value &v) { return IsPoisonedValue(v); }
|
||||
};
|
||||
|
||||
template <> struct RootMethods<Value>
|
||||
{
|
||||
static Value initial() { return UndefinedValue(); }
|
||||
static ThingRootKind kind() { return THING_ROOT_VALUE; }
|
||||
static bool poisoned(const Value &v) { return IsPoisonedValue(v); }
|
||||
};
|
||||
typedef Handle<JSObject*> HandleObject;
|
||||
typedef Handle<JSFunction*> HandleFunction;
|
||||
typedef Handle<JSString*> HandleString;
|
||||
typedef Handle<jsid> HandleId;
|
||||
typedef Handle<Value> HandleValue;
|
||||
|
||||
template <typename T>
|
||||
struct RootMethods<T *>
|
||||
|
@ -142,10 +165,12 @@ template <typename T>
|
|||
class Root
|
||||
{
|
||||
public:
|
||||
Root(JSContext *cx, const T *ptr
|
||||
Root(JSContext *cx_, const T *ptr
|
||||
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
#ifdef JSGC_ROOT_ANALYSIS
|
||||
ContextFriendFields *cx = ContextFriendFields::get(cx_);
|
||||
|
||||
ThingRootKind kind = RootMethods<T>::kind();
|
||||
this->stack = reinterpret_cast<Root<T>**>(&cx->thingGCRooters[kind]);
|
||||
this->prev = *stack;
|
||||
|
@ -191,53 +216,58 @@ Handle<T>::Handle(const Root<S> &root)
|
|||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
typedef Root<JSObject*> RootObject;
|
||||
typedef Root<JSFunction*> RootFunction;
|
||||
typedef Root<Shape*> RootShape;
|
||||
typedef Root<BaseShape*> RootBaseShape;
|
||||
typedef Root<types::TypeObject*> RootTypeObject;
|
||||
typedef Root<JSString*> RootString;
|
||||
typedef Root<JSAtom*> RootAtom;
|
||||
typedef Root<jsid> RootId;
|
||||
typedef Root<Value> RootValue;
|
||||
typedef Root<JSObject*> RootObject;
|
||||
typedef Root<JSFunction*> RootFunction;
|
||||
typedef Root<JSString*> RootString;
|
||||
typedef Root<jsid> RootId;
|
||||
typedef Root<Value> RootValue;
|
||||
|
||||
/* Mark a stack location as a root for a rooting analysis. */
|
||||
class CheckRoot
|
||||
/*
|
||||
* Mark a stack location as a root for the rooting analysis, without actually
|
||||
* rooting it in release builds. This should only be used for stack locations
|
||||
* of GC things that cannot be relocated by a garbage collection, and that
|
||||
* are definitely reachable via another path.
|
||||
*/
|
||||
class SkipRoot
|
||||
{
|
||||
#if defined(DEBUG) && defined(JSGC_ROOT_ANALYSIS)
|
||||
|
||||
CheckRoot **stack, *prev;
|
||||
const uint8_t *ptr;
|
||||
SkipRoot **stack, *prev;
|
||||
const uint8_t *start;
|
||||
const uint8_t *end;
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
CheckRoot(JSContext *cx, const T *ptr
|
||||
SkipRoot(JSContext *cx_, const T *ptr
|
||||
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
this->stack = &cx->checkGCRooters;
|
||||
ContextFriendFields *cx = ContextFriendFields::get(cx_);
|
||||
|
||||
this->stack = &cx->skipGCRooters;
|
||||
this->prev = *stack;
|
||||
*stack = this;
|
||||
this->ptr = static_cast<const uint8_t*>(ptr);
|
||||
this->start = (const uint8_t *) ptr;
|
||||
this->end = this->start + sizeof(T);
|
||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
~CheckRoot()
|
||||
~SkipRoot()
|
||||
{
|
||||
JS_ASSERT(*stack == this);
|
||||
*stack = prev;
|
||||
}
|
||||
|
||||
CheckRoot *previous() { return prev; }
|
||||
SkipRoot *previous() { return prev; }
|
||||
|
||||
bool contains(const uint8_t *v, size_t len) {
|
||||
return ptr >= v && ptr < v + len;
|
||||
return v >= start && v + len <= end;
|
||||
}
|
||||
|
||||
#else /* DEBUG && JSGC_ROOT_ANALYSIS */
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
CheckRoot(JSContext *cx, const T *ptr
|
||||
SkipRoot(JSContext *cx, const T *ptr
|
||||
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
@ -261,10 +291,14 @@ class RootedVar
|
|||
: ptr(initial), root(cx, &ptr)
|
||||
{}
|
||||
|
||||
operator T () { return ptr; }
|
||||
T operator ->() { return ptr; }
|
||||
RootedVar() MOZ_DELETE;
|
||||
RootedVar(const RootedVar &) MOZ_DELETE;
|
||||
|
||||
operator T () const { return ptr; }
|
||||
T operator ->() const { return ptr; }
|
||||
T * address() { return &ptr; }
|
||||
const T * address() const { return &ptr; }
|
||||
T & reference() { return ptr; }
|
||||
T raw() { return ptr; }
|
||||
|
||||
T & operator =(T value)
|
||||
|
@ -274,6 +308,12 @@ class RootedVar
|
|||
return ptr;
|
||||
}
|
||||
|
||||
T & operator =(const RootedVar &value)
|
||||
{
|
||||
ptr = value;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
T ptr;
|
||||
Root<T> root;
|
||||
|
@ -286,15 +326,14 @@ Handle<T>::Handle(const RootedVar<S> &root)
|
|||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
typedef RootedVar<JSObject*> RootedVarObject;
|
||||
typedef RootedVar<JSFunction*> RootedVarFunction;
|
||||
typedef RootedVar<Shape*> RootedVarShape;
|
||||
typedef RootedVar<BaseShape*> RootedVarBaseShape;
|
||||
typedef RootedVar<types::TypeObject*> RootedVarTypeObject;
|
||||
typedef RootedVar<JSString*> RootedVarString;
|
||||
typedef RootedVar<JSAtom*> RootedVarAtom;
|
||||
typedef RootedVar<jsid> RootedVarId;
|
||||
typedef RootedVar<Value> RootedVarValue;
|
||||
typedef RootedVar<JSObject*> RootedVarObject;
|
||||
typedef RootedVar<JSFunction*> RootedVarFunction;
|
||||
typedef RootedVar<JSString*> RootedVarString;
|
||||
typedef RootedVar<jsid> RootedVarId;
|
||||
typedef RootedVar<Value> RootedVarValue;
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
} /* namespace js */
|
||||
#endif /* jsgc_root_h___ */
|
||||
|
|
|
@ -3079,7 +3079,7 @@ JS_ConvertStub(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
|||
{
|
||||
JS_ASSERT(type != JSTYPE_OBJECT && type != JSTYPE_FUNCTION);
|
||||
JS_ASSERT(obj);
|
||||
return DefaultValue(cx, obj, type, vp);
|
||||
return DefaultValue(cx, RootedVarObject(cx, obj), type, vp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
|
@ -3619,7 +3619,7 @@ JS_AlreadyHasOwnUCProperty(JSContext *cx, JSObject *obj, const jschar *name, siz
|
|||
}
|
||||
|
||||
static JSBool
|
||||
DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, const Value &value,
|
||||
DefinePropertyById(JSContext *cx, HandleObject obj, jsid id, const Value &value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
unsigned flags, int tinyid)
|
||||
{
|
||||
|
@ -3679,16 +3679,18 @@ DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, const Value &value,
|
|||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, jsval value,
|
||||
JS_DefinePropertyById(JSContext *cx, JSObject *obj_, jsid id, jsval value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
RootedVarObject obj(cx, obj_);
|
||||
return DefinePropertyById(cx, obj, id, value, getter, setter, attrs, 0, 0);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_DefineElement(JSContext *cx, JSObject *obj, uint32_t index, jsval value,
|
||||
JS_DefineElement(JSContext *cx, JSObject *obj_, uint32_t index, jsval value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
RootedVarObject obj(cx, obj_);
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
jsid id;
|
||||
|
@ -3698,15 +3700,15 @@ JS_DefineElement(JSContext *cx, JSObject *obj, uint32_t index, jsval value,
|
|||
}
|
||||
|
||||
static JSBool
|
||||
DefineProperty(JSContext *cx, JSObject *obj, const char *name, const Value &value,
|
||||
DefineProperty(JSContext *cx, JSObject *obj_, const char *name, const Value &value_,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
unsigned flags, int tinyid)
|
||||
{
|
||||
jsid id;
|
||||
JSAtom *atom;
|
||||
|
||||
RootObject objRoot(cx, &obj);
|
||||
RootValue valueRoot(cx, &value);
|
||||
RootedVarObject obj(cx, obj_);
|
||||
RootedVarValue value(cx, value_);
|
||||
|
||||
if (attrs & JSPROP_INDEX) {
|
||||
id = INT_TO_JSID(intptr_t(name));
|
||||
|
@ -3737,10 +3739,11 @@ JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name, int8
|
|||
}
|
||||
|
||||
static JSBool
|
||||
DefineUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen,
|
||||
DefineUCProperty(JSContext *cx, JSObject *obj_, const jschar *name, size_t namelen,
|
||||
const Value &value, PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
unsigned flags, int tinyid)
|
||||
{
|
||||
RootObject obj(cx, &obj_);
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && DefinePropertyById(cx, obj, ATOM_TO_JSID(atom), value, getter, setter, attrs,
|
||||
flags, tinyid);
|
||||
|
@ -3768,7 +3771,7 @@ JS_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, jsval descriptor, JS
|
|||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, id, descriptor);
|
||||
return js_DefineOwnProperty(cx, obj, id, descriptor, bp);
|
||||
return js_DefineOwnProperty(cx, RootedVarObject(cx, obj), RootedVarId(cx, id), descriptor, bp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
|
@ -3797,8 +3800,10 @@ JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *jsclasp
|
|||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds)
|
||||
JS_DefineConstDoubles(JSContext *cx, JSObject *obj_, JSConstDoubleSpec *cds)
|
||||
{
|
||||
RootedVarObject obj(cx, obj_);
|
||||
|
||||
JSBool ok;
|
||||
unsigned attrs;
|
||||
|
||||
|
@ -3945,7 +3950,7 @@ JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return GetOwnPropertyDescriptor(cx, obj, id, vp);
|
||||
return GetOwnPropertyDescriptor(cx, RootedVarObject(cx, obj), RootedVarId(cx, id), vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -4005,7 +4010,7 @@ JS_ForwardGetPropertyTo(JSContext *cx, JSObject *obj, jsid id, JSObject *onBehal
|
|||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetPropertyByIdDefault(JSContext *cx, JSObject *obj, jsid id, jsval def, jsval *vp)
|
||||
{
|
||||
return GetPropertyDefault(cx, obj, id, def, vp);
|
||||
return GetPropertyDefault(cx, RootedVarObject(cx, obj), RootedVarId(cx, id), def, vp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
|
@ -4065,7 +4070,7 @@ JS_GetMethodById(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, jsval *
|
|||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, id);
|
||||
if (!js_GetMethod(cx, obj, id, 0, vp))
|
||||
if (!js_GetMethod(cx, RootedVarObject(cx, obj), id, 0, vp))
|
||||
return JS_FALSE;
|
||||
if (objp)
|
||||
*objp = obj;
|
||||
|
@ -4520,11 +4525,14 @@ JS_NewFunctionById(JSContext *cx, JSNative native, unsigned nargs, unsigned flag
|
|||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent)
|
||||
JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent_)
|
||||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, parent); // XXX no funobj for now
|
||||
assertSameCompartment(cx, parent_); // XXX no funobj for now
|
||||
|
||||
RootedVarObject parent(cx, parent_);
|
||||
|
||||
if (!parent) {
|
||||
if (cx->hasfp())
|
||||
parent = &cx->fp()->scopeChain();
|
||||
|
@ -4543,7 +4551,7 @@ JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
JSFunction *fun = funobj->toFunction();
|
||||
RootedVarFunction fun(cx, funobj->toFunction());
|
||||
if (fun->isInterpreted() && fun->script()->compileAndGo) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_CLONE_FUNOBJ_SCOPE);
|
||||
|
@ -5061,10 +5069,8 @@ CompileUCFunctionForPrincipalsCommon(JSContext *cx, JSObject *obj,
|
|||
assertSameCompartment(cx, obj, principals);
|
||||
AutoLastFrameCheck lfc(cx);
|
||||
|
||||
JSAtom *funAtom;
|
||||
if (!name) {
|
||||
funAtom = NULL;
|
||||
} else {
|
||||
RootedVarAtom funAtom(cx);
|
||||
if (name) {
|
||||
funAtom = js_Atomize(cx, name, strlen(name));
|
||||
if (!funAtom)
|
||||
return NULL;
|
||||
|
@ -5073,7 +5079,7 @@ CompileUCFunctionForPrincipalsCommon(JSContext *cx, JSObject *obj,
|
|||
Bindings bindings(cx);
|
||||
for (unsigned i = 0; i < nargs; i++) {
|
||||
uint16_t dummy;
|
||||
JSAtom *argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]));
|
||||
RootedVarAtom argAtom(cx, js_Atomize(cx, argnames[i], strlen(argnames[i])));
|
||||
if (!argAtom || !bindings.addArgument(cx, argAtom, &dummy))
|
||||
return NULL;
|
||||
}
|
||||
|
@ -5254,7 +5260,7 @@ JS_ExecuteScriptVersion(JSContext *cx, JSObject *obj, JSScript *script, jsval *r
|
|||
}
|
||||
|
||||
bool
|
||||
EvaluateUCScriptForPrincipalsCommon(JSContext *cx, JSObject *obj,
|
||||
EvaluateUCScriptForPrincipalsCommon(JSContext *cx, JSObject *obj_,
|
||||
JSPrincipals *principals, JSPrincipals *originPrincipals,
|
||||
const jschar *chars, unsigned length,
|
||||
const char *filename, unsigned lineno,
|
||||
|
@ -5262,6 +5268,8 @@ EvaluateUCScriptForPrincipalsCommon(JSContext *cx, JSObject *obj,
|
|||
{
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
|
||||
RootedVarObject obj(cx, obj_);
|
||||
|
||||
uint32_t flags = TCF_COMPILE_N_GO | TCF_NEED_SCRIPT_GLOBAL;
|
||||
if (!rval)
|
||||
flags |= TCF_NO_SCRIPT_RVAL;
|
||||
|
@ -5373,15 +5381,17 @@ JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, unsigned argc, js
|
|||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, unsigned argc, jsval *argv,
|
||||
JS_CallFunctionName(JSContext *cx, JSObject *obj_, const char *name, unsigned argc, jsval *argv,
|
||||
jsval *rval)
|
||||
{
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, JSValueArray(argv, argc));
|
||||
assertSameCompartment(cx, obj_, JSValueArray(argv, argc));
|
||||
AutoLastFrameCheck lfc(cx);
|
||||
|
||||
RootedVarObject obj(cx, obj_);
|
||||
|
||||
Value v;
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom &&
|
||||
|
@ -5755,7 +5765,7 @@ JS_ConcatStrings(JSContext *cx, JSString *left, JSString *right)
|
|||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return js_ConcatStrings(cx, left, right);
|
||||
return js_ConcatStrings(cx, RootedVarString(cx, left), RootedVarString(cx, right));
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(const jschar *)
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "jsval.h"
|
||||
|
||||
#include "js/Utility.h"
|
||||
#include "gc/Root.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "jsalloc.h"
|
||||
|
@ -769,6 +770,20 @@ SameType(const Value &lhs, const Value &rhs)
|
|||
return JSVAL_SAME_TYPE_IMPL(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
template <> struct RootMethods<const Value>
|
||||
{
|
||||
static Value initial() { return UndefinedValue(); }
|
||||
static ThingRootKind kind() { return THING_ROOT_VALUE; }
|
||||
static bool poisoned(const Value &v) { return IsPoisonedValue(v); }
|
||||
};
|
||||
|
||||
template <> struct RootMethods<Value>
|
||||
{
|
||||
static Value initial() { return UndefinedValue(); }
|
||||
static ThingRootKind kind() { return THING_ROOT_VALUE; }
|
||||
static bool poisoned(const Value &v) { return IsPoisonedValue(v); }
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
@ -1052,7 +1067,7 @@ class AutoVectorRooter : protected AutoGCRooter
|
|||
public:
|
||||
explicit AutoVectorRooter(JSContext *cx, ptrdiff_t tag
|
||||
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoGCRooter(cx, tag), vector(cx)
|
||||
: AutoGCRooter(cx, tag), vector(cx), vectorRoot(cx, &vector)
|
||||
{
|
||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
@ -1115,6 +1130,10 @@ class AutoVectorRooter : protected AutoGCRooter
|
|||
|
||||
typedef js::Vector<T, 8> VectorImpl;
|
||||
VectorImpl vector;
|
||||
|
||||
/* Prevent overwriting of inline elements in vector. */
|
||||
SkipRoot vectorRoot;
|
||||
|
||||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
|
@ -2457,6 +2476,8 @@ JS_IsInSuspendedRequest(JSRuntime *rt);
|
|||
#ifdef __cplusplus
|
||||
JS_END_EXTERN_C
|
||||
|
||||
namespace JS {
|
||||
|
||||
inline bool
|
||||
IsPoisonedId(jsid iden)
|
||||
{
|
||||
|
@ -2467,6 +2488,22 @@ IsPoisonedId(jsid iden)
|
|||
return false;
|
||||
}
|
||||
|
||||
template <> struct RootMethods<const jsid>
|
||||
{
|
||||
static jsid initial() { return JSID_VOID; }
|
||||
static ThingRootKind kind() { return THING_ROOT_ID; }
|
||||
static bool poisoned(jsid id) { return IsPoisonedId(id); }
|
||||
};
|
||||
|
||||
template <> struct RootMethods<jsid>
|
||||
{
|
||||
static jsid initial() { return JSID_VOID; }
|
||||
static ThingRootKind kind() { return THING_ROOT_ID; }
|
||||
static bool poisoned(jsid id) { return IsPoisonedId(id); }
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
class JSAutoRequest {
|
||||
public:
|
||||
JSAutoRequest(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
|
|
|
@ -481,7 +481,7 @@ GetElements(JSContext *cx, JSObject *aobj, uint32_t length, Value *vp)
|
|||
* Set the value of the property at the given index to v assuming v is rooted.
|
||||
*/
|
||||
static JSBool
|
||||
SetArrayElement(JSContext *cx, JSObject *obj, double index, const Value &v)
|
||||
SetArrayElement(JSContext *cx, HandleObject obj, double index, const Value &v)
|
||||
{
|
||||
JS_ASSERT(index >= 0);
|
||||
|
||||
|
@ -504,7 +504,7 @@ SetArrayElement(JSContext *cx, JSObject *obj, double index, const Value &v)
|
|||
if (result == JSObject::ED_FAILED)
|
||||
return false;
|
||||
JS_ASSERT(result == JSObject::ED_SPARSE);
|
||||
if (!obj->makeDenseArraySlow(cx))
|
||||
if (!JSObject::makeDenseArraySlow(cx, obj))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -532,7 +532,7 @@ SetArrayElement(JSContext *cx, JSObject *obj, double index, const Value &v)
|
|||
* - Return -1 if an exception occurs (that is, [[Delete]] would throw).
|
||||
*/
|
||||
static int
|
||||
DeleteArrayElement(JSContext *cx, JSObject *obj, double index, bool strict)
|
||||
DeleteArrayElement(JSContext *cx, HandleObject obj, double index, bool strict)
|
||||
{
|
||||
JS_ASSERT(index >= 0);
|
||||
JS_ASSERT(floor(index) == index);
|
||||
|
@ -567,7 +567,7 @@ DeleteArrayElement(JSContext *cx, JSObject *obj, double index, bool strict)
|
|||
* its value to v assuming v is rooted.
|
||||
*/
|
||||
static JSBool
|
||||
SetOrDeleteArrayElement(JSContext *cx, JSObject *obj, double index,
|
||||
SetOrDeleteArrayElement(JSContext *cx, HandleObject obj, double index,
|
||||
JSBool hole, const Value &v)
|
||||
{
|
||||
if (hole) {
|
||||
|
@ -606,8 +606,10 @@ array_length_getter(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
|||
}
|
||||
|
||||
static JSBool
|
||||
array_length_setter(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp)
|
||||
array_length_setter(JSContext *cx, JSObject *obj_, jsid id, JSBool strict, Value *vp)
|
||||
{
|
||||
RootedVarObject obj(cx, obj_);
|
||||
|
||||
if (!obj->isArray()) {
|
||||
return obj->defineProperty(cx, cx->runtime->atomState.lengthAtom, *vp,
|
||||
NULL, NULL, JSPROP_ENUMERATE);
|
||||
|
@ -803,7 +805,13 @@ array_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName
|
|||
}
|
||||
|
||||
if (!obj->isDenseArray())
|
||||
return js_GetProperty(cx, obj, receiver, ATOM_TO_JSID(name), vp);
|
||||
{
|
||||
return js_GetProperty(cx,
|
||||
RootedVarObject(cx, obj),
|
||||
RootedVarObject(cx, receiver),
|
||||
ATOM_TO_JSID(name),
|
||||
vp);
|
||||
}
|
||||
|
||||
JSObject *proto = obj->getProto();
|
||||
if (!proto) {
|
||||
|
@ -818,7 +826,13 @@ static JSBool
|
|||
array_getElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index, Value *vp)
|
||||
{
|
||||
if (!obj->isDenseArray())
|
||||
return js_GetElement(cx, obj, receiver, index, vp);
|
||||
{
|
||||
return js_GetElement(cx,
|
||||
RootedVarObject(cx, obj),
|
||||
RootedVarObject(cx, receiver),
|
||||
index,
|
||||
vp);
|
||||
}
|
||||
|
||||
if (index < obj->getDenseArrayInitializedLength()) {
|
||||
*vp = obj->getDenseArrayElement(index);
|
||||
|
@ -848,7 +862,11 @@ array_getSpecial(JSContext *cx, JSObject *obj, JSObject *receiver, SpecialId sid
|
|||
return true;
|
||||
}
|
||||
|
||||
return js_GetProperty(cx, obj, receiver, SPECIALID_TO_JSID(sid), vp);
|
||||
return js_GetProperty(cx,
|
||||
RootedVarObject(cx, obj),
|
||||
RootedVarObject(cx, receiver),
|
||||
SPECIALID_TO_JSID(sid),
|
||||
vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -894,9 +912,10 @@ array_typeOf(JSContext *cx, JSObject *obj)
|
|||
}
|
||||
|
||||
static JSBool
|
||||
array_setGeneric(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
|
||||
array_setGeneric(JSContext *cx, JSObject *obj_, jsid id_, Value *vp, JSBool strict)
|
||||
{
|
||||
uint32_t i;
|
||||
RootedVarObject obj(cx, obj_);
|
||||
RootedVarId id(cx, id_);
|
||||
|
||||
if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom))
|
||||
return array_length_setter(cx, obj, id, strict, vp);
|
||||
|
@ -905,6 +924,7 @@ array_setGeneric(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict
|
|||
return js_SetPropertyHelper(cx, obj, id, 0, vp, strict);
|
||||
|
||||
do {
|
||||
uint32_t i;
|
||||
if (!js_IdIsIndex(id, &i))
|
||||
break;
|
||||
if (js_PrototypeHasIndexedProperties(cx, obj))
|
||||
|
@ -924,7 +944,7 @@ array_setGeneric(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict
|
|||
return true;
|
||||
} while (false);
|
||||
|
||||
if (!obj->makeDenseArraySlow(cx))
|
||||
if (!JSObject::makeDenseArraySlow(cx, obj))
|
||||
return false;
|
||||
return js_SetPropertyHelper(cx, obj, id, 0, vp, strict);
|
||||
}
|
||||
|
@ -936,8 +956,10 @@ array_setProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *vp, J
|
|||
}
|
||||
|
||||
static JSBool
|
||||
array_setElement(JSContext *cx, JSObject *obj, uint32_t index, Value *vp, JSBool strict)
|
||||
array_setElement(JSContext *cx, JSObject *obj_, uint32_t index, Value *vp, JSBool strict)
|
||||
{
|
||||
RootedVarObject obj(cx, obj_);
|
||||
|
||||
jsid id;
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
|
@ -969,7 +991,7 @@ array_setElement(JSContext *cx, JSObject *obj, uint32_t index, Value *vp, JSBool
|
|||
return true;
|
||||
} while (false);
|
||||
|
||||
if (!obj->makeDenseArraySlow(cx))
|
||||
if (!JSObject::makeDenseArraySlow(cx, obj))
|
||||
return false;
|
||||
return js_SetPropertyHelper(cx, obj, id, 0, vp, strict);
|
||||
}
|
||||
|
@ -1003,9 +1025,11 @@ js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj)
|
|||
}
|
||||
|
||||
static JSBool
|
||||
array_defineGeneric(JSContext *cx, JSObject *obj, jsid id, const Value *value,
|
||||
array_defineGeneric(JSContext *cx, JSObject *obj_, jsid id, const Value *value,
|
||||
JSPropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
RootedVarObject obj(cx, obj_);
|
||||
|
||||
if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom))
|
||||
return JS_TRUE;
|
||||
|
||||
|
@ -1032,7 +1056,7 @@ array_defineGeneric(JSContext *cx, JSObject *obj, jsid id, const Value *value,
|
|||
return true;
|
||||
} while (false);
|
||||
|
||||
if (!obj->makeDenseArraySlow(cx))
|
||||
if (!JSObject::makeDenseArraySlow(cx, obj))
|
||||
return false;
|
||||
return js_DefineProperty(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
@ -1048,9 +1072,11 @@ namespace js {
|
|||
|
||||
/* non-static for direct definition of array elements within the engine */
|
||||
JSBool
|
||||
array_defineElement(JSContext *cx, JSObject *obj, uint32_t index, const Value *value,
|
||||
array_defineElement(JSContext *cx, JSObject *obj_, uint32_t index, const Value *value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
RootedVarObject obj(cx, obj_);
|
||||
|
||||
if (!obj->isDenseArray())
|
||||
return js_DefineElement(cx, obj, index, value, getter, setter, attrs);
|
||||
|
||||
|
@ -1080,7 +1106,7 @@ array_defineElement(JSContext *cx, JSObject *obj, uint32_t index, const Value *v
|
|||
return true;
|
||||
} while (false);
|
||||
|
||||
if (!obj->makeDenseArraySlow(cx))
|
||||
if (!JSObject::makeDenseArraySlow(cx, obj))
|
||||
return false;
|
||||
return js_DefineElement(cx, obj, index, value, getter, setter, attrs);
|
||||
}
|
||||
|
@ -1211,15 +1237,17 @@ array_trace(JSTracer *trc, JSObject *obj)
|
|||
}
|
||||
|
||||
static JSBool
|
||||
array_fix(JSContext *cx, JSObject *obj, bool *success, AutoIdVector *props)
|
||||
array_fix(JSContext *cx, JSObject *obj_, bool *success, AutoIdVector *props)
|
||||
{
|
||||
RootedVarObject obj(cx, obj_);
|
||||
|
||||
JS_ASSERT(obj->isDenseArray());
|
||||
|
||||
/*
|
||||
* We must slowify dense arrays; otherwise, we'd need to detect assignments to holes,
|
||||
* since that is effectively adding a new property to the array.
|
||||
*/
|
||||
if (!obj->makeDenseArraySlow(cx) ||
|
||||
if (!JSObject::makeDenseArraySlow(cx, obj) ||
|
||||
!GetPropertyNames(cx, obj, JSITER_HIDDEN | JSITER_OWNONLY, props))
|
||||
return false;
|
||||
|
||||
|
@ -1352,26 +1380,26 @@ AddLengthProperty(JSContext *cx, JSObject *obj)
|
|||
/*
|
||||
* Convert an array object from fast-and-dense to slow-and-flexible.
|
||||
*/
|
||||
JSBool
|
||||
JSObject::makeDenseArraySlow(JSContext *cx)
|
||||
/* static */ bool
|
||||
JSObject::makeDenseArraySlow(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
JS_ASSERT(isDenseArray());
|
||||
JS_ASSERT(obj->isDenseArray());
|
||||
|
||||
MarkTypeObjectFlags(cx, this,
|
||||
MarkTypeObjectFlags(cx, obj,
|
||||
OBJECT_FLAG_NON_PACKED_ARRAY |
|
||||
OBJECT_FLAG_NON_DENSE_ARRAY);
|
||||
|
||||
uint32_t arrayCapacity = getDenseArrayCapacity();
|
||||
uint32_t arrayInitialized = getDenseArrayInitializedLength();
|
||||
uint32_t arrayCapacity = obj->getDenseArrayCapacity();
|
||||
uint32_t arrayInitialized = obj->getDenseArrayInitializedLength();
|
||||
|
||||
/*
|
||||
* Get an allocated array of the existing elements, evicting from the fixed
|
||||
* slots if necessary.
|
||||
*/
|
||||
if (!hasDynamicElements()) {
|
||||
if (!growElements(cx, arrayCapacity))
|
||||
if (!obj->hasDynamicElements()) {
|
||||
if (!obj->growElements(cx, arrayCapacity))
|
||||
return false;
|
||||
JS_ASSERT(hasDynamicElements());
|
||||
JS_ASSERT(obj->hasDynamicElements());
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1379,19 +1407,19 @@ JSObject::makeDenseArraySlow(JSContext *cx)
|
|||
* on error. This is gross, but a better way is not obvious. Note: the
|
||||
* exact contents of the array are not preserved on error.
|
||||
*/
|
||||
js::Shape *oldShape = lastProperty();
|
||||
js::Shape *oldShape = obj->lastProperty();
|
||||
|
||||
/* Create a native scope. */
|
||||
gc::AllocKind kind = getAllocKind();
|
||||
Shape *shape = EmptyShape::getInitialShape(cx, &SlowArrayClass, getProto(),
|
||||
gc::AllocKind kind = obj->getAllocKind();
|
||||
Shape *shape = EmptyShape::getInitialShape(cx, &SlowArrayClass, obj->getProto(),
|
||||
oldShape->getObjectParent(), kind);
|
||||
if (!shape)
|
||||
return false;
|
||||
this->shape_ = shape;
|
||||
obj->shape_ = shape;
|
||||
|
||||
/* Take ownership of the dense elements, reset to an empty dense array. */
|
||||
HeapSlot *elems = elements;
|
||||
elements = emptyObjectElements;
|
||||
HeapSlot *elems = obj->elements;
|
||||
obj->elements = emptyObjectElements;
|
||||
|
||||
/* Root all values in the array during conversion. */
|
||||
AutoValueArray autoArray(cx, (Value *) elems, arrayInitialized);
|
||||
|
@ -1400,11 +1428,11 @@ JSObject::makeDenseArraySlow(JSContext *cx)
|
|||
* Begin with the length property to share more of the property tree.
|
||||
* The getter/setter here will directly access the object's private value.
|
||||
*/
|
||||
if (!AddLengthProperty(cx, this)) {
|
||||
this->shape_ = oldShape;
|
||||
if (elements != emptyObjectElements)
|
||||
cx->free_(getElementsHeader());
|
||||
elements = elems;
|
||||
if (!AddLengthProperty(cx, obj)) {
|
||||
obj->shape_ = oldShape;
|
||||
if (obj->elements != emptyObjectElements)
|
||||
cx->free_(obj->getElementsHeader());
|
||||
obj->elements = elems;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1421,21 +1449,21 @@ JSObject::makeDenseArraySlow(JSContext *cx)
|
|||
if (elems[i].isMagic(JS_ARRAY_HOLE))
|
||||
continue;
|
||||
|
||||
if (!addDataProperty(cx, id, next, JSPROP_ENUMERATE)) {
|
||||
this->shape_ = oldShape;
|
||||
cx->free_(getElementsHeader());
|
||||
elements = elems;
|
||||
if (!obj->addDataProperty(cx, id, next, JSPROP_ENUMERATE)) {
|
||||
obj->shape_ = oldShape;
|
||||
cx->free_(obj->getElementsHeader());
|
||||
obj->elements = elems;
|
||||
return false;
|
||||
}
|
||||
|
||||
initSlot(next, elems[i]);
|
||||
obj->initSlot(next, elems[i]);
|
||||
|
||||
next++;
|
||||
}
|
||||
|
||||
ObjectElements *oldheader = ObjectElements::fromElements(elems);
|
||||
|
||||
getElementsHeader()->length = oldheader->length;
|
||||
obj->getElementsHeader()->length = oldheader->length;
|
||||
cx->free_(oldheader);
|
||||
|
||||
return true;
|
||||
|
@ -1706,7 +1734,7 @@ array_toString(JSContext *cx, unsigned argc, Value *vp)
|
|||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JSObject *obj = ToObject(cx, &args.thisv());
|
||||
RootedVarObject obj(cx, ToObject(cx, &args.thisv()));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
|
@ -1780,7 +1808,7 @@ enum ShouldUpdateTypes
|
|||
};
|
||||
|
||||
static bool
|
||||
InitArrayElements(JSContext *cx, JSObject *obj, uint32_t start, uint32_t count, const Value *vector, ShouldUpdateTypes updateTypes)
|
||||
InitArrayElements(JSContext *cx, HandleObject obj, uint32_t start, uint32_t count, const Value *vector, ShouldUpdateTypes updateTypes)
|
||||
{
|
||||
JS_ASSERT(count <= MAX_ARRAY_INDEX);
|
||||
|
||||
|
@ -1829,7 +1857,7 @@ InitArrayElements(JSContext *cx, JSObject *obj, uint32_t start, uint32_t count,
|
|||
return true;
|
||||
|
||||
/* Finish out any remaining elements past the max array index. */
|
||||
if (obj->isDenseArray() && !obj->makeDenseArraySlow(cx))
|
||||
if (obj->isDenseArray() && !JSObject::makeDenseArraySlow(cx, obj))
|
||||
return false;
|
||||
|
||||
JS_ASSERT(start == MAX_ARRAY_INDEX + 1);
|
||||
|
@ -1908,7 +1936,7 @@ static JSBool
|
|||
array_reverse(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JSObject *obj = ToObject(cx, &args.thisv());
|
||||
RootedVarObject obj(cx, ToObject(cx, &args.thisv()));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
|
@ -2212,7 +2240,7 @@ js::array_sort(JSContext *cx, unsigned argc, Value *vp)
|
|||
fval.setNull();
|
||||
}
|
||||
|
||||
JSObject *obj = ToObject(cx, &args.thisv());
|
||||
RootedVarObject obj(cx, ToObject(cx, &args.thisv()));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
|
@ -2378,7 +2406,7 @@ js::array_sort(JSContext *cx, unsigned argc, Value *vp)
|
|||
* Perl-inspired push, pop, shift, unshift, and splice methods.
|
||||
*/
|
||||
static bool
|
||||
array_push_slowly(JSContext *cx, JSObject *obj, CallArgs &args)
|
||||
array_push_slowly(JSContext *cx, HandleObject obj, CallArgs &args)
|
||||
{
|
||||
uint32_t length;
|
||||
|
||||
|
@ -2394,7 +2422,7 @@ array_push_slowly(JSContext *cx, JSObject *obj, CallArgs &args)
|
|||
}
|
||||
|
||||
static bool
|
||||
array_push1_dense(JSContext* cx, JSObject* obj, CallArgs &args)
|
||||
array_push1_dense(JSContext* cx, HandleObject obj, CallArgs &args)
|
||||
{
|
||||
JS_ASSERT(args.length() == 1);
|
||||
|
||||
|
@ -2404,7 +2432,7 @@ array_push1_dense(JSContext* cx, JSObject* obj, CallArgs &args)
|
|||
if (result == JSObject::ED_FAILED)
|
||||
return false;
|
||||
JS_ASSERT(result == JSObject::ED_SPARSE);
|
||||
if (!obj->makeDenseArraySlow(cx))
|
||||
if (!JSObject::makeDenseArraySlow(cx, obj))
|
||||
return false;
|
||||
return array_push_slowly(cx, obj, args);
|
||||
}
|
||||
|
@ -2450,7 +2478,7 @@ JSBool
|
|||
js::array_push(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JSObject *obj = ToObject(cx, &args.thisv());
|
||||
RootedVarObject obj(cx, ToObject(cx, &args.thisv()));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
|
@ -2462,7 +2490,7 @@ js::array_push(JSContext *cx, unsigned argc, Value *vp)
|
|||
}
|
||||
|
||||
static JSBool
|
||||
array_pop_slowly(JSContext *cx, JSObject* obj, CallArgs &args)
|
||||
array_pop_slowly(JSContext *cx, HandleObject obj, CallArgs &args)
|
||||
{
|
||||
uint32_t index;
|
||||
if (!js_GetLengthProperty(cx, obj, &index))
|
||||
|
@ -2488,7 +2516,7 @@ array_pop_slowly(JSContext *cx, JSObject* obj, CallArgs &args)
|
|||
}
|
||||
|
||||
static JSBool
|
||||
array_pop_dense(JSContext *cx, JSObject* obj, CallArgs &args)
|
||||
array_pop_dense(JSContext *cx, HandleObject obj, CallArgs &args)
|
||||
{
|
||||
uint32_t index = obj->getArrayLength();
|
||||
if (index == 0) {
|
||||
|
@ -2518,7 +2546,7 @@ JSBool
|
|||
js::array_pop(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JSObject *obj = ToObject(cx, &args.thisv());
|
||||
RootedVarObject obj(cx, ToObject(cx, &args.thisv()));
|
||||
if (!obj)
|
||||
return false;
|
||||
if (obj->isDenseArray())
|
||||
|
@ -2547,7 +2575,7 @@ JSBool
|
|||
js::array_shift(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JSObject *obj = ToObject(cx, &args.thisv());
|
||||
RootedVarObject obj(cx, ToObject(cx, &args.thisv()));
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -2599,7 +2627,7 @@ static JSBool
|
|||
array_unshift(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JSObject *obj = ToObject(cx, &args.thisv());
|
||||
RootedVarObject obj(cx, ToObject(cx, &args.thisv()));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
|
@ -2721,7 +2749,7 @@ array_splice(JSContext *cx, unsigned argc, Value *vp)
|
|||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
/* Step 1. */
|
||||
JSObject *obj = ToObject(cx, &args.thisv());
|
||||
RootedVarObject obj(cx, ToObject(cx, &args.thisv()));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
|
@ -2852,7 +2880,7 @@ array_splice(JSContext *cx, unsigned argc, Value *vp)
|
|||
return false;
|
||||
|
||||
if (res == JSObject::ED_SPARSE) {
|
||||
if (!obj->makeDenseArraySlow(cx))
|
||||
if (!JSObject::makeDenseArraySlow(cx, obj))
|
||||
return false;
|
||||
} else {
|
||||
JS_ASSERT(res == JSObject::ED_OK);
|
||||
|
@ -2944,11 +2972,11 @@ js::array_concat(JSContext *cx, unsigned argc, Value *vp)
|
|||
Value *p = JS_ARGV(cx, vp) - 1;
|
||||
|
||||
/* Create a new Array object and root it using *vp. */
|
||||
JSObject *aobj = ToObject(cx, &vp[1]);
|
||||
RootedVarObject aobj(cx, ToObject(cx, &vp[1]));
|
||||
if (!aobj)
|
||||
return false;
|
||||
|
||||
JSObject *nobj;
|
||||
RootedVarObject nobj(cx);
|
||||
uint32_t length;
|
||||
if (aobj->isDenseArray()) {
|
||||
length = aobj->getArrayLength();
|
||||
|
@ -3012,7 +3040,6 @@ js::array_concat(JSContext *cx, unsigned argc, Value *vp)
|
|||
static JSBool
|
||||
array_slice(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
JSObject *nobj;
|
||||
uint32_t length, begin, end, slot;
|
||||
JSBool hole;
|
||||
|
||||
|
@ -3057,6 +3084,8 @@ array_slice(JSContext *cx, unsigned argc, Value *vp)
|
|||
if (begin > end)
|
||||
begin = end;
|
||||
|
||||
RootedVarObject nobj(cx);
|
||||
|
||||
if (obj->isDenseArray() && end <= obj->getDenseArrayInitializedLength() &&
|
||||
!js_PrototypeHasIndexedProperties(cx, obj)) {
|
||||
nobj = NewDenseCopiedArray(cx, end - begin, obj->getDenseArrayElements() + begin);
|
||||
|
@ -3336,7 +3365,7 @@ array_map(JSContext *cx, unsigned argc, Value *vp)
|
|||
Value thisv = args.length() >= 2 ? args[1] : UndefinedValue();
|
||||
|
||||
/* Step 6. */
|
||||
JSObject *arr = NewDenseAllocatedArray(cx, len);
|
||||
RootedVarObject arr(cx, NewDenseAllocatedArray(cx, len));
|
||||
if (!arr)
|
||||
return false;
|
||||
TypeObject *newtype = GetTypeCallerInitObject(cx, JSProto_Array);
|
||||
|
@ -3412,7 +3441,7 @@ array_filter(JSContext *cx, unsigned argc, Value *vp)
|
|||
Value thisv = args.length() >= 2 ? args[1] : UndefinedValue();
|
||||
|
||||
/* Step 6. */
|
||||
JSObject *arr = NewDenseAllocatedArray(cx, 0);
|
||||
RootedVarObject arr(cx, NewDenseAllocatedArray(cx, 0));
|
||||
if (!arr)
|
||||
return false;
|
||||
TypeObject *newtype = GetTypeCallerInitObject(cx, JSProto_Array);
|
||||
|
@ -3651,7 +3680,7 @@ JSBool
|
|||
js_Array(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
TypeObject *type = GetTypeCallerInitObject(cx, JSProto_Array);
|
||||
RootedVarTypeObject type(cx, GetTypeCallerInitObject(cx, JSProto_Array));
|
||||
if (!type)
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -3792,7 +3821,7 @@ NewArray(JSContext *cx, uint32_t length, JSObject *proto)
|
|||
return obj;
|
||||
}
|
||||
|
||||
Root<GlobalObject*> parentRoot(cx, &parent);
|
||||
JS::Root<GlobalObject*> parentRoot(cx, &parent);
|
||||
|
||||
if (!proto && !FindProto(cx, &ArrayClass, parentRoot, &proto))
|
||||
return NULL;
|
||||
|
@ -3885,7 +3914,7 @@ NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *vp, JSObject *p
|
|||
JSObject *
|
||||
NewSlowEmptyArray(JSContext *cx)
|
||||
{
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, &SlowArrayClass);
|
||||
RootedVarObject obj(cx, NewBuiltinClassInstance(cx, &SlowArrayClass));
|
||||
if (!obj || !AddLengthProperty(cx, obj))
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -73,28 +73,6 @@ js_IdIsIndex(jsid id, uint32_t *indexp)
|
|||
return js::StringIsArrayIndex(JSID_TO_ATOM(id), indexp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dense arrays are not native -- aobj->isNative() for a dense array aobj
|
||||
* results in false, meaning aobj->map does not point to a js::Shape.
|
||||
*
|
||||
* But Array methods are called via aobj.sort(), e.g., and the interpreter and
|
||||
* the trace recorder must consult the property cache in order to perform well.
|
||||
* The cache works only for native objects.
|
||||
*
|
||||
* Therefore the interpreter (js_Interpret in JSOP_GETPROP and JSOP_CALLPROP)
|
||||
* and js_GetPropertyHelper use this inline function to skip up one link in the
|
||||
* prototype chain when obj is a dense array, in order to find a native object
|
||||
* (to wit, Array.prototype) in which to probe for cached methods.
|
||||
*
|
||||
* Note that setting aobj.__proto__ for a dense array aobj turns aobj into a
|
||||
* slow array, avoiding the neede to skip.
|
||||
*
|
||||
* Callers of js_GetProtoIfDenseArray must take care to use the original object
|
||||
* (obj) for the |this| value of a getter, setter, or method call (bug 476447).
|
||||
*/
|
||||
inline JSObject *
|
||||
js_GetProtoIfDenseArray(JSObject *obj);
|
||||
|
||||
extern JSObject *
|
||||
js_InitArrayClass(JSContext *cx, JSObject *obj);
|
||||
|
||||
|
|
|
@ -156,14 +156,15 @@ js_InitBooleanClass(JSContext *cx, JSObject *obj)
|
|||
{
|
||||
JS_ASSERT(obj->isNative());
|
||||
|
||||
GlobalObject *global = &obj->asGlobal();
|
||||
RootedVar<GlobalObject*> global(cx, &obj->asGlobal());
|
||||
|
||||
JSObject *booleanProto = global->createBlankPrototype(cx, &BooleanClass);
|
||||
RootedVarObject booleanProto (cx, global->createBlankPrototype(cx, &BooleanClass));
|
||||
if (!booleanProto)
|
||||
return NULL;
|
||||
booleanProto->setFixedSlot(BooleanObject::PRIMITIVE_VALUE_SLOT, BooleanValue(false));
|
||||
|
||||
JSFunction *ctor = global->createConstructor(cx, Boolean, CLASS_ATOM(cx, Boolean), 1);
|
||||
RootedVarFunction ctor(cx);
|
||||
ctor = global->createConstructor(cx, Boolean, CLASS_ATOM(cx, Boolean), 1);
|
||||
if (!ctor)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -606,7 +606,7 @@ JSStructuredCloneWriter::write(const Value &v)
|
|||
return false;
|
||||
|
||||
while (!counts.empty()) {
|
||||
JSObject *obj = &objs.back().toObject();
|
||||
RootedVarObject obj(context(), &objs.back().toObject());
|
||||
|
||||
// The objects in |obj| can live in other compartments.
|
||||
AutoEnterCompartmentAndPushPrincipal ac;
|
||||
|
@ -615,7 +615,7 @@ JSStructuredCloneWriter::write(const Value &v)
|
|||
|
||||
if (counts.back()) {
|
||||
counts.back()--;
|
||||
jsid id = ids.back();
|
||||
RootedVarId id(context(), ids.back());
|
||||
ids.popBack();
|
||||
checkStack();
|
||||
if (JSID_IS_STRING(id) || JSID_IS_INT(id)) {
|
||||
|
|
|
@ -965,7 +965,7 @@ JSContext::JSContext(JSRuntime *rt)
|
|||
#ifdef JSGC_ROOT_ANALYSIS
|
||||
PodArrayZero(thingGCRooters);
|
||||
#ifdef DEBUG
|
||||
checkGCRooters = NULL;
|
||||
skipGCRooters = NULL;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -742,9 +742,6 @@ struct JSArgumentFormatMap {
|
|||
|
||||
namespace js {
|
||||
|
||||
template <typename T> class Root;
|
||||
class CheckRoot;
|
||||
|
||||
struct AutoResolving;
|
||||
|
||||
static inline bool
|
||||
|
@ -1021,29 +1018,6 @@ struct JSContext : js::ContextFriendFields
|
|||
JS_EndRequest. */
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef JSGC_ROOT_ANALYSIS
|
||||
|
||||
/*
|
||||
* Stack allocated GC roots for stack GC heap pointers, which may be
|
||||
* overwritten if moved during a GC.
|
||||
*/
|
||||
js::Root<js::gc::Cell*> *thingGCRooters[js::THING_ROOT_COUNT];
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Stack allocated list of stack locations which hold non-relocatable
|
||||
* GC heap pointers (where the target is rooted somewhere else) or integer
|
||||
* values which may be confused for GC heap pointers. These are used to
|
||||
* suppress false positives which occur when a rooting analysis treats the
|
||||
* location as holding a relocatable pointer, but have no other effect on
|
||||
* GC behavior.
|
||||
*/
|
||||
js::CheckRoot *checkGCRooters;
|
||||
#endif
|
||||
|
||||
#endif /* JSGC_ROOT_ANALYSIS */
|
||||
|
||||
/* Stored here to avoid passing it around as a parameter. */
|
||||
unsigned resolveFlags;
|
||||
|
||||
|
|
|
@ -326,7 +326,7 @@ JS_ALWAYS_INLINE bool
|
|||
CallJSNativeConstructor(JSContext *cx, Native native, const CallArgs &args)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
JSObject &callee = args.callee();
|
||||
RootedVarObject callee(cx, &args.callee());
|
||||
#endif
|
||||
|
||||
JS_ASSERT(args.thisv().isMagic());
|
||||
|
@ -351,8 +351,8 @@ CallJSNativeConstructor(JSContext *cx, Native native, const CallArgs &args)
|
|||
JS_ASSERT_IF(native != FunctionProxyClass.construct &&
|
||||
native != CallableObjectClass.construct &&
|
||||
native != js::CallOrConstructBoundFunction &&
|
||||
(!callee.isFunction() || callee.toFunction()->native() != js_Object),
|
||||
!args.rval().isPrimitive() && callee != args.rval().toObject());
|
||||
(!callee->isFunction() || callee->toFunction()->native() != js_Object),
|
||||
!args.rval().isPrimitive() && callee != &args.rval().toObject());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -502,7 +502,8 @@ date_convert(JSContext *cx, JSObject *obj, JSType hint, Value *vp)
|
|||
JS_ASSERT(hint == JSTYPE_NUMBER || hint == JSTYPE_STRING || hint == JSTYPE_VOID);
|
||||
JS_ASSERT(obj->isDate());
|
||||
|
||||
return DefaultValue(cx, obj, (hint == JSTYPE_VOID) ? JSTYPE_STRING : hint, vp);
|
||||
return DefaultValue(cx, RootedVarObject(cx, obj),
|
||||
(hint == JSTYPE_VOID) ? JSTYPE_STRING : hint, vp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2664,14 +2665,15 @@ js_InitDateClass(JSContext *cx, JSObject *obj)
|
|||
/* Set the static LocalTZA. */
|
||||
LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond);
|
||||
|
||||
GlobalObject *global = &obj->asGlobal();
|
||||
RootedVar<GlobalObject*> global(cx, &obj->asGlobal());
|
||||
|
||||
JSObject *dateProto = global->createBlankPrototype(cx, &DateClass);
|
||||
RootedVarObject dateProto(cx, global->createBlankPrototype(cx, &DateClass));
|
||||
if (!dateProto)
|
||||
return NULL;
|
||||
SetDateToNaN(cx, dateProto);
|
||||
|
||||
JSFunction *ctor = global->createConstructor(cx, js_Date, CLASS_ATOM(cx, Date), MAXARGS);
|
||||
RootedVarFunction ctor(cx);
|
||||
ctor = global->createConstructor(cx, js_Date, CLASS_ATOM(cx, Date), MAXARGS);
|
||||
if (!ctor)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -797,13 +797,15 @@ JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp)
|
|||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
|
||||
JS_GetPropertyDesc(JSContext *cx, JSObject *obj_, JSScopeProperty *sprop,
|
||||
JSPropertyDesc *pd)
|
||||
{
|
||||
assertSameCompartment(cx, obj);
|
||||
assertSameCompartment(cx, obj_);
|
||||
Shape *shape = (Shape *) sprop;
|
||||
pd->id = IdToJsval(shape->propid());
|
||||
|
||||
RootedVarObject obj(cx, obj_);
|
||||
|
||||
JSBool wasThrowing = cx->isExceptionPending();
|
||||
Value lastException = UndefinedValue();
|
||||
if (wasThrowing)
|
||||
|
|
|
@ -333,8 +333,8 @@ static void
|
|||
SetExnPrivate(JSContext *cx, JSObject *exnObject, JSExnPrivate *priv);
|
||||
|
||||
static bool
|
||||
InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
|
||||
JSString *filename, unsigned lineno, JSErrorReport *report, int exnType)
|
||||
InitExnPrivate(JSContext *cx, HandleObject exnObject, HandleString message,
|
||||
HandleString filename, unsigned lineno, JSErrorReport *report, int exnType)
|
||||
{
|
||||
JS_ASSERT(exnObject->isError());
|
||||
JS_ASSERT(!exnObject->getPrivate());
|
||||
|
@ -502,7 +502,7 @@ exn_finalize(FreeOp *fop, JSObject *obj)
|
|||
}
|
||||
|
||||
static JSBool
|
||||
exn_resolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
|
||||
exn_resolve(JSContext *cx, JSObject *obj_, jsid id, unsigned flags,
|
||||
JSObject **objp)
|
||||
{
|
||||
JSExnPrivate *priv;
|
||||
|
@ -513,6 +513,8 @@ exn_resolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
|
|||
jsval v;
|
||||
unsigned attrs;
|
||||
|
||||
RootedVarObject obj(cx, obj_);
|
||||
|
||||
*objp = NULL;
|
||||
priv = GetExnPrivate(obj);
|
||||
if (priv && JSID_IS_ATOM(id)) {
|
||||
|
@ -779,12 +781,12 @@ Exception(JSContext *cx, unsigned argc, Value *vp)
|
|||
}
|
||||
|
||||
JSObject *errProto = &protov.toObject();
|
||||
JSObject *obj = NewObjectWithGivenProto(cx, &ErrorClass, errProto, NULL);
|
||||
RootedVarObject obj(cx, NewObjectWithGivenProto(cx, &ErrorClass, errProto, NULL));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
/* Set the 'message' property. */
|
||||
JSString *message;
|
||||
RootedVarString message(cx);
|
||||
if (args.hasDefined(0)) {
|
||||
message = ToString(cx, args[0]);
|
||||
if (!message)
|
||||
|
@ -800,7 +802,7 @@ Exception(JSContext *cx, unsigned argc, Value *vp)
|
|||
++iter;
|
||||
|
||||
/* Set the 'fileName' property. */
|
||||
JSString *filename;
|
||||
RootedVarString filename(cx);
|
||||
if (args.length() > 1) {
|
||||
filename = ToString(cx, args[1]);
|
||||
if (!filename)
|
||||
|
@ -855,7 +857,7 @@ exn_toString(JSContext *cx, unsigned argc, Value *vp)
|
|||
return false;
|
||||
|
||||
/* Step 4. */
|
||||
JSString *name;
|
||||
RootedVarString name(cx);
|
||||
if (nameVal.isUndefined()) {
|
||||
name = CLASS_ATOM(cx, Error);
|
||||
} else {
|
||||
|
@ -1008,19 +1010,19 @@ JS_STATIC_ASSERT(JSProto_Error + JSEXN_TYPEERR == JSProto_TypeError);
|
|||
JS_STATIC_ASSERT(JSProto_Error + JSEXN_URIERR == JSProto_URIError);
|
||||
|
||||
static JSObject *
|
||||
InitErrorClass(JSContext *cx, GlobalObject *global, int type, JSObject &proto)
|
||||
InitErrorClass(JSContext *cx, Handle<GlobalObject*> global, int type, HandleObject proto)
|
||||
{
|
||||
JSProtoKey key = GetExceptionProtoKey(type);
|
||||
JSAtom *name = cx->runtime->atomState.classAtoms[key];
|
||||
JSObject *errorProto = global->createBlankPrototypeInheriting(cx, &ErrorClass, proto);
|
||||
RootedVarAtom name(cx, cx->runtime->atomState.classAtoms[key]);
|
||||
RootedVarObject errorProto(cx, global->createBlankPrototypeInheriting(cx, &ErrorClass, *proto));
|
||||
if (!errorProto)
|
||||
return NULL;
|
||||
|
||||
Value empty = StringValue(cx->runtime->emptyString);
|
||||
jsid nameId = ATOM_TO_JSID(cx->runtime->atomState.nameAtom);
|
||||
jsid messageId = ATOM_TO_JSID(cx->runtime->atomState.messageAtom);
|
||||
jsid fileNameId = ATOM_TO_JSID(cx->runtime->atomState.fileNameAtom);
|
||||
jsid lineNumberId = ATOM_TO_JSID(cx->runtime->atomState.lineNumberAtom);
|
||||
RootedVarValue empty(cx, StringValue(cx->runtime->emptyString));
|
||||
RootedVarId nameId(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom));
|
||||
RootedVarId messageId(cx, ATOM_TO_JSID(cx->runtime->atomState.messageAtom));
|
||||
RootedVarId fileNameId(cx, ATOM_TO_JSID(cx->runtime->atomState.fileNameAtom));
|
||||
RootedVarId lineNumberId(cx, ATOM_TO_JSID(cx->runtime->atomState.lineNumberAtom));
|
||||
if (!DefineNativeProperty(cx, errorProto, nameId, StringValue(name),
|
||||
JS_PropertyStub, JS_StrictPropertyStub, 0, 0, 0) ||
|
||||
!DefineNativeProperty(cx, errorProto, messageId, empty,
|
||||
|
@ -1034,8 +1036,9 @@ InitErrorClass(JSContext *cx, GlobalObject *global, int type, JSObject &proto)
|
|||
}
|
||||
|
||||
/* Create the corresponding constructor. */
|
||||
JSFunction *ctor = global->createConstructor(cx, Exception, name, 1,
|
||||
JSFunction::ExtendedFinalizeKind);
|
||||
RootedVarFunction ctor(cx);
|
||||
ctor = global->createConstructor(cx, Exception, name, 1,
|
||||
JSFunction::ExtendedFinalizeKind);
|
||||
if (!ctor)
|
||||
return NULL;
|
||||
ctor->setExtendedSlot(0, Int32Value(int32_t(type)));
|
||||
|
@ -1057,14 +1060,15 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj)
|
|||
JS_ASSERT(obj->isGlobal());
|
||||
JS_ASSERT(obj->isNative());
|
||||
|
||||
GlobalObject *global = &obj->asGlobal();
|
||||
RootedVar<GlobalObject*> global(cx, &obj->asGlobal());
|
||||
|
||||
JSObject *objectProto = global->getOrCreateObjectPrototype(cx);
|
||||
RootedVarObject objectProto(cx, global->getOrCreateObjectPrototype(cx));
|
||||
if (!objectProto)
|
||||
return NULL;
|
||||
|
||||
/* Initialize the base Error class first. */
|
||||
JSObject *errorProto = InitErrorClass(cx, global, JSEXN_ERR, *objectProto);
|
||||
RootedVarObject errorProto(cx);
|
||||
errorProto = InitErrorClass(cx, global, JSEXN_ERR, objectProto);
|
||||
if (!errorProto)
|
||||
return NULL;
|
||||
|
||||
|
@ -1074,7 +1078,7 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj)
|
|||
|
||||
/* Define all remaining *Error constructors. */
|
||||
for (int i = JSEXN_ERR + 1; i < JSEXN_LIMIT; i++) {
|
||||
if (!InitErrorClass(cx, global, i, *errorProto))
|
||||
if (!InitErrorClass(cx, global, i, errorProto))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1127,6 +1131,24 @@ static struct exnname { char *name; char *exception; } errortoexnname[] = {
|
|||
};
|
||||
#endif /* DEBUG */
|
||||
|
||||
struct AutoSetGeneratingError
|
||||
{
|
||||
JSContext *cx;
|
||||
|
||||
AutoSetGeneratingError(JSContext *cx)
|
||||
: cx(cx)
|
||||
{
|
||||
JS_ASSERT(!cx->generatingError);
|
||||
cx->generatingError = true;
|
||||
}
|
||||
|
||||
~AutoSetGeneratingError()
|
||||
{
|
||||
JS_ASSERT(cx->generatingError);
|
||||
cx->generatingError = false;
|
||||
}
|
||||
};
|
||||
|
||||
JSBool
|
||||
js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
|
||||
JSErrorCallback callback, void *userRef)
|
||||
|
@ -1135,8 +1157,7 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
|
|||
const JSErrorFormatString *errorString;
|
||||
JSExnType exn;
|
||||
jsval tv[4];
|
||||
JSObject *errProto, *errObject;
|
||||
JSString *messageStr, *filenameStr;
|
||||
JSObject *errProto;
|
||||
|
||||
/*
|
||||
* Tell our caller to report immediately if this report is just a warning.
|
||||
|
@ -1186,15 +1207,18 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
|
|||
return false;
|
||||
tv[0] = OBJECT_TO_JSVAL(errProto);
|
||||
|
||||
if (!(errObject = NewObjectWithGivenProto(cx, &ErrorClass, errProto, NULL)))
|
||||
RootedVarObject errObject(cx, NewObjectWithGivenProto(cx, &ErrorClass, errProto, NULL));
|
||||
if (!errObject)
|
||||
return false;
|
||||
tv[1] = OBJECT_TO_JSVAL(errObject);
|
||||
|
||||
if (!(messageStr = JS_NewStringCopyZ(cx, message)))
|
||||
RootedVarString messageStr(cx, JS_NewStringCopyZ(cx, message));
|
||||
if (!messageStr)
|
||||
return false;
|
||||
tv[2] = STRING_TO_JSVAL(messageStr);
|
||||
|
||||
if (!(filenameStr = JS_NewStringCopyZ(cx, reportp->filename)))
|
||||
RootedVarString filenameStr(cx, JS_NewStringCopyZ(cx, reportp->filename));
|
||||
if (!filenameStr)
|
||||
return false;
|
||||
tv[3] = STRING_TO_JSVAL(filenameStr);
|
||||
|
||||
|
@ -1235,7 +1259,6 @@ IsDuckTypedErrorObject(JSContext *cx, JSObject *exnObject, const char **filename
|
|||
JSBool
|
||||
js_ReportUncaughtException(JSContext *cx)
|
||||
{
|
||||
jsval exn;
|
||||
JSObject *exnObject;
|
||||
jsval roots[6];
|
||||
JSErrorReport *reportp, report;
|
||||
|
@ -1244,7 +1267,8 @@ js_ReportUncaughtException(JSContext *cx)
|
|||
if (!JS_IsExceptionPending(cx))
|
||||
return true;
|
||||
|
||||
if (!JS_GetPendingException(cx, &exn))
|
||||
RootedVarValue exn(cx);
|
||||
if (!JS_GetPendingException(cx, exn.address()))
|
||||
return false;
|
||||
|
||||
PodArrayZero(roots);
|
||||
|
|
|
@ -189,17 +189,6 @@ JS_END_EXTERN_C
|
|||
|
||||
namespace js {
|
||||
|
||||
struct ContextFriendFields {
|
||||
JSRuntime *const runtime;
|
||||
|
||||
ContextFriendFields(JSRuntime *rt)
|
||||
: runtime(rt) { }
|
||||
|
||||
static const ContextFriendFields *get(const JSContext *cx) {
|
||||
return reinterpret_cast<const ContextFriendFields *>(cx);
|
||||
}
|
||||
};
|
||||
|
||||
struct RuntimeFriendFields {
|
||||
/*
|
||||
* If non-zero, we were been asked to call the operation callback as soon
|
||||
|
|
|
@ -244,7 +244,7 @@ fun_enumerate(JSContext *cx, JSObject *obj)
|
|||
}
|
||||
|
||||
static JSObject *
|
||||
ResolveInterpretedFunctionPrototype(JSContext *cx, JSObject *obj)
|
||||
ResolveInterpretedFunctionPrototype(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
JSFunction *fun = obj->toFunction();
|
||||
|
@ -267,7 +267,7 @@ ResolveInterpretedFunctionPrototype(JSContext *cx, JSObject *obj)
|
|||
JSObject *objProto = obj->global().getOrCreateObjectPrototype(cx);
|
||||
if (!objProto)
|
||||
return NULL;
|
||||
JSObject *proto = NewObjectWithGivenProto(cx, &ObjectClass, objProto, NULL);
|
||||
RootedVarObject proto(cx, NewObjectWithGivenProto(cx, &ObjectClass, objProto, NULL));
|
||||
if (!proto || !proto->setSingletonType(cx))
|
||||
return NULL;
|
||||
|
||||
|
@ -1078,7 +1078,7 @@ Function(JSContext *cx, unsigned argc, Value *vp)
|
|||
return OnBadFormal(cx, tt);
|
||||
|
||||
/* Check for a duplicate parameter name. */
|
||||
PropertyName *name = ts.currentToken().name();
|
||||
RootedVar<PropertyName*> name(cx, ts.currentToken().name());
|
||||
if (bindings.hasBinding(cx, name)) {
|
||||
JSAutoByteString bytes;
|
||||
if (!js_AtomToPrintableString(cx, name, &bytes))
|
||||
|
@ -1150,7 +1150,7 @@ IsBuiltinFunctionConstructor(JSFunction *fun)
|
|||
}
|
||||
|
||||
const Shape *
|
||||
LookupInterpretedFunctionPrototype(JSContext *cx, JSObject *funobj)
|
||||
LookupInterpretedFunctionPrototype(JSContext *cx, RootedVarObject funobj)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
JSFunction *fun = funobj->toFunction();
|
||||
|
@ -1160,10 +1160,11 @@ LookupInterpretedFunctionPrototype(JSContext *cx, JSObject *funobj)
|
|||
#endif
|
||||
|
||||
jsid id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
|
||||
const Shape *shape = funobj->nativeLookup(cx, id);
|
||||
RootedVar<const Shape*> shape(cx, funobj->nativeLookup(cx, id));
|
||||
if (!shape) {
|
||||
if (!ResolveInterpretedFunctionPrototype(cx, funobj))
|
||||
return NULL;
|
||||
id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
|
||||
shape = funobj->nativeLookup(cx, id);
|
||||
}
|
||||
JS_ASSERT(!shape->configurable());
|
||||
|
@ -1176,12 +1177,14 @@ LookupInterpretedFunctionPrototype(JSContext *cx, JSObject *funobj)
|
|||
|
||||
JSFunction *
|
||||
js_NewFunction(JSContext *cx, JSObject *funobj, Native native, unsigned nargs,
|
||||
unsigned flags, HandleObject parent, JSAtom *atom, js::gc::AllocKind kind)
|
||||
unsigned flags, HandleObject parent, JSAtom *atom_, js::gc::AllocKind kind)
|
||||
{
|
||||
JS_ASSERT(kind == JSFunction::FinalizeKind || kind == JSFunction::ExtendedFinalizeKind);
|
||||
JS_ASSERT(sizeof(JSFunction) <= gc::Arena::thingSize(JSFunction::FinalizeKind));
|
||||
JS_ASSERT(sizeof(FunctionExtended) <= gc::Arena::thingSize(JSFunction::ExtendedFinalizeKind));
|
||||
|
||||
RootedVarAtom atom(cx, atom_);
|
||||
|
||||
JSFunction *fun;
|
||||
|
||||
if (funobj) {
|
||||
|
@ -1218,8 +1221,8 @@ js_NewFunction(JSContext *cx, JSObject *funobj, Native native, unsigned nargs,
|
|||
}
|
||||
|
||||
JSFunction * JS_FASTCALL
|
||||
js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent,
|
||||
JSObject *proto, gc::AllocKind kind)
|
||||
js_CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
|
||||
HandleObject proto, gc::AllocKind kind)
|
||||
{
|
||||
JS_ASSERT(parent);
|
||||
JS_ASSERT(proto);
|
||||
|
|
|
@ -245,7 +245,8 @@ js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, unsigned nargs,
|
|||
js::gc::AllocKind kind = JSFunction::FinalizeKind);
|
||||
|
||||
extern JSFunction * JS_FASTCALL
|
||||
js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent, JSObject *proto,
|
||||
js_CloneFunctionObject(JSContext *cx, js::HandleFunction fun,
|
||||
js::HandleObject parent, js::HandleObject proto,
|
||||
js::gc::AllocKind kind = JSFunction::FinalizeKind);
|
||||
|
||||
extern JSFunction *
|
||||
|
|
|
@ -145,13 +145,13 @@ IsNativeFunction(const js::Value &v, JSNative native)
|
|||
* TODO: a per-thread shape-based cache would be faster and simpler.
|
||||
*/
|
||||
static JS_ALWAYS_INLINE bool
|
||||
ClassMethodIsNative(JSContext *cx, JSObject *obj, Class *clasp, jsid methodid, JSNative native)
|
||||
ClassMethodIsNative(JSContext *cx, HandleObject obj, Class *clasp, HandleId methodid, JSNative native)
|
||||
{
|
||||
JS_ASSERT(obj->getClass() == clasp);
|
||||
|
||||
Value v;
|
||||
if (!HasDataProperty(cx, obj, methodid, &v)) {
|
||||
JSObject *proto = obj->getProto();
|
||||
RootedVarObject proto(cx, obj->getProto());
|
||||
if (!proto || proto->getClass() != clasp || !HasDataProperty(cx, proto, methodid, &v))
|
||||
return false;
|
||||
}
|
||||
|
@ -205,21 +205,6 @@ Function(JSContext *cx, unsigned argc, Value *vp);
|
|||
extern bool
|
||||
IsBuiltinFunctionConstructor(JSFunction *fun);
|
||||
|
||||
/*
|
||||
* Preconditions: funobj->isInterpreted() && !funobj->isFunctionPrototype() &&
|
||||
* !funobj->isBoundFunction(). This is sufficient to establish that funobj has
|
||||
* a non-configurable non-method .prototype data property, thought it might not
|
||||
* have been resolved yet, and its value could be anything.
|
||||
*
|
||||
* Return the shape of the .prototype property of funobj, resolving it if
|
||||
* needed. On error, return NULL.
|
||||
*
|
||||
* This is not safe to call on trace because it defines properties, which can
|
||||
* trigger lookups that could reenter.
|
||||
*/
|
||||
const Shape *
|
||||
LookupInterpretedFunctionPrototype(JSContext *cx, JSObject *funobj);
|
||||
|
||||
static inline JSObject *
|
||||
SkipScopeParent(JSObject *parent)
|
||||
{
|
||||
|
@ -231,11 +216,11 @@ SkipScopeParent(JSObject *parent)
|
|||
}
|
||||
|
||||
inline JSFunction *
|
||||
CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent,
|
||||
CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
|
||||
gc::AllocKind kind = JSFunction::FinalizeKind)
|
||||
{
|
||||
JS_ASSERT(parent);
|
||||
JSObject *proto = parent->global().getOrCreateFunctionPrototype(cx);
|
||||
RootedVarObject proto(cx, parent->global().getOrCreateFunctionPrototype(cx));
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
|
@ -243,7 +228,7 @@ CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent,
|
|||
}
|
||||
|
||||
inline JSFunction *
|
||||
CloneFunctionObjectIfNotSingleton(JSContext *cx, JSFunction *fun, JSObject *parent)
|
||||
CloneFunctionObjectIfNotSingleton(JSContext *cx, HandleFunction fun, HandleObject parent)
|
||||
{
|
||||
/*
|
||||
* For attempts to clone functions at a function definition opcode,
|
||||
|
@ -263,7 +248,7 @@ CloneFunctionObjectIfNotSingleton(JSContext *cx, JSFunction *fun, JSObject *pare
|
|||
}
|
||||
|
||||
inline JSFunction *
|
||||
CloneFunctionObject(JSContext *cx, JSFunction *fun)
|
||||
CloneFunctionObject(JSContext *cx, HandleFunction fun)
|
||||
{
|
||||
/*
|
||||
* Variant which makes an exact clone of fun, preserving parent and proto.
|
||||
|
@ -277,7 +262,9 @@ CloneFunctionObject(JSContext *cx, JSFunction *fun)
|
|||
if (fun->hasSingletonType())
|
||||
return fun;
|
||||
|
||||
return js_CloneFunctionObject(cx, fun, fun->environment(), fun->getProto(),
|
||||
return js_CloneFunctionObject(cx, fun,
|
||||
RootedVarObject(cx, fun->environment()),
|
||||
RootedVarObject(cx, fun->getProto()),
|
||||
JSFunction::ExtendedFinalizeKind);
|
||||
}
|
||||
|
||||
|
|
|
@ -3945,25 +3945,27 @@ CheckStackRoot(JSTracer *trc, uintptr_t *w)
|
|||
VALGRIND_MAKE_MEM_DEFINED(&w, sizeof(w));
|
||||
#endif
|
||||
|
||||
ConservativeGCTest test = MarkIfGCThingWord(trc, *w, DONT_MARK_THING);
|
||||
ConservativeGCTest test = MarkIfGCThingWord(trc, *w);
|
||||
|
||||
if (test == CGCT_VALID) {
|
||||
JSContext *iter = NULL;
|
||||
bool matched = false;
|
||||
JSRuntime *rt = trc->runtime;
|
||||
for (unsigned i = 0; i < THING_ROOT_COUNT; i++) {
|
||||
Root<Cell*> *rooter = rt->thingGCRooters[i];
|
||||
while (rooter) {
|
||||
if (rooter->address() == (Cell **) w)
|
||||
matched = true;
|
||||
rooter = rooter->previous();
|
||||
for (ContextIter cx(rt); !cx.done(); cx.next()) {
|
||||
for (unsigned i = 0; i < THING_ROOT_LIMIT; i++) {
|
||||
Root<void*> *rooter = cx->thingGCRooters[i];
|
||||
while (rooter) {
|
||||
if (rooter->address() == static_cast<void*>(w))
|
||||
matched = true;
|
||||
rooter = rooter->previous();
|
||||
}
|
||||
}
|
||||
SkipRoot *skip = cx->skipGCRooters;
|
||||
while (skip) {
|
||||
if (skip->contains(reinterpret_cast<uint8_t*>(w), sizeof(w)))
|
||||
matched = true;
|
||||
skip = skip->previous();
|
||||
}
|
||||
}
|
||||
CheckRoot *check = rt->checkGCRooters;
|
||||
while (check) {
|
||||
if (check->contains(static_cast<uint8_t*>(w), sizeof(w)))
|
||||
matched = true;
|
||||
check = check->previous();
|
||||
}
|
||||
if (!matched) {
|
||||
/*
|
||||
|
@ -4001,17 +4003,17 @@ CheckStackRoots(JSContext *cx)
|
|||
JS_ASSERT(ctd->hasStackToScan());
|
||||
uintptr_t *stackMin, *stackEnd;
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
stackMin = td->nativeStackBase;
|
||||
stackEnd = ctd->nativeStackTop;
|
||||
stackMin = rt->nativeStackBase;
|
||||
stackEnd = cgcd->nativeStackTop;
|
||||
#else
|
||||
stackMin = ctd->nativeStackTop + 1;
|
||||
stackEnd = td->nativeStackBase;
|
||||
stackMin = cgcd->nativeStackTop + 1;
|
||||
stackEnd = reinterpret_cast<uintptr_t *>(rt->nativeStackBase);
|
||||
#endif
|
||||
|
||||
JS_ASSERT(stackMin <= stackEnd);
|
||||
CheckStackRootsRange(&checker, stackMin, stackEnd);
|
||||
CheckStackRootsRange(&checker, ctd->registerSnapshot.words,
|
||||
ArrayEnd(ctd->registerSnapshot.words));
|
||||
CheckStackRootsRange(&checker, cgcd->registerSnapshot.words,
|
||||
ArrayEnd(cgcd->registerSnapshot.words));
|
||||
}
|
||||
|
||||
#endif /* DEBUG && JSGC_ROOT_ANALYSIS && !JS_THREADSAFE */
|
||||
|
|
|
@ -1697,7 +1697,7 @@ public:
|
|||
};
|
||||
|
||||
static void
|
||||
CheckNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun);
|
||||
CheckNewScriptProperties(JSContext *cx, HandleTypeObject type, JSFunction *fun);
|
||||
|
||||
bool
|
||||
TypeSet::isOwnProperty(JSContext *cx, TypeObject *object, bool configurable)
|
||||
|
@ -1710,7 +1710,8 @@ TypeSet::isOwnProperty(JSContext *cx, TypeObject *object, bool configurable)
|
|||
*/
|
||||
if (object->flags & OBJECT_FLAG_NEW_SCRIPT_REGENERATE) {
|
||||
if (object->newScript) {
|
||||
CheckNewScriptProperties(cx, object, object->newScript->fun);
|
||||
CheckNewScriptProperties(cx, RootedVarTypeObject(cx, object),
|
||||
object->newScript->fun);
|
||||
} else {
|
||||
JS_ASSERT(object->flags & OBJECT_FLAG_NEW_SCRIPT_CLEARED);
|
||||
object->flags &= ~OBJECT_FLAG_NEW_SCRIPT_REGENERATE;
|
||||
|
@ -4382,7 +4383,7 @@ AnalyzeNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun, JSO
|
|||
pc = script->code + uses->offset;
|
||||
op = JSOp(*pc);
|
||||
|
||||
JSObject *obj = *pbaseobj;
|
||||
RootedVarObject obj(cx, *pbaseobj);
|
||||
|
||||
if (op == JSOP_SETPROP && uses->u.which == 1) {
|
||||
/*
|
||||
|
@ -4532,13 +4533,14 @@ AnalyzeNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun, JSO
|
|||
* newScript on the type after they were cleared by a GC.
|
||||
*/
|
||||
static void
|
||||
CheckNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun)
|
||||
CheckNewScriptProperties(JSContext *cx, HandleTypeObject type, JSFunction *fun)
|
||||
{
|
||||
if (type->unknownProperties() || fun->script()->isInnerFunction)
|
||||
return;
|
||||
|
||||
/* Strawman object to add properties to and watch for duplicates. */
|
||||
JSObject *baseobj = NewBuiltinClassInstance(cx, &ObjectClass, gc::FINALIZE_OBJECT16);
|
||||
RootedVarObject baseobj(cx);
|
||||
baseobj = NewBuiltinClassInstance(cx, &ObjectClass, gc::FINALIZE_OBJECT16);
|
||||
if (!baseobj) {
|
||||
if (type->newScript)
|
||||
type->clearNewScript(cx);
|
||||
|
@ -4546,7 +4548,7 @@ CheckNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun)
|
|||
}
|
||||
|
||||
Vector<TypeNewScript::Initializer> initializerList(cx);
|
||||
AnalyzeNewScriptProperties(cx, type, fun, &baseobj, &initializerList);
|
||||
AnalyzeNewScriptProperties(cx, type, fun, baseobj.address(), &initializerList);
|
||||
if (!baseobj || baseobj->slotSpan() == 0 || !!(type->flags & OBJECT_FLAG_NEW_SCRIPT_CLEARED)) {
|
||||
if (type->newScript)
|
||||
type->clearNewScript(cx);
|
||||
|
@ -5365,10 +5367,12 @@ JSScript::makeAnalysis(JSContext *cx)
|
|||
if (!types->analysis)
|
||||
return false;
|
||||
|
||||
RootedVar<JSScript*> self(cx, this);
|
||||
|
||||
types->analysis->analyzeBytecode(cx);
|
||||
|
||||
if (types->analysis->OOM()) {
|
||||
types->analysis = NULL;
|
||||
if (self->types->analysis->OOM()) {
|
||||
self->types->analysis = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -5654,12 +5658,12 @@ JSObject::getNewType(JSContext *cx, JSFunction *fun)
|
|||
|
||||
bool markUnknown = self->lastProperty()->hasObjectFlag(BaseShape::NEW_TYPE_UNKNOWN);
|
||||
|
||||
TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL,
|
||||
JSProto_Object, self, markUnknown);
|
||||
RootedVarTypeObject type(cx);
|
||||
type = cx->compartment->types.newTypeObject(cx, NULL, JSProto_Object, self, markUnknown);
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
if (!table.relookupOrAdd(p, self, type))
|
||||
if (!table.relookupOrAdd(p, self, type.raw()))
|
||||
return NULL;
|
||||
|
||||
if (!cx->typeInferenceEnabled())
|
||||
|
|
|
@ -1427,11 +1427,11 @@ inline bool
|
|||
JSScript::ensureRanAnalysis(JSContext *cx, JSObject *scope)
|
||||
{
|
||||
JSScript *self = this;
|
||||
JS::SkipRoot root(cx, &self);
|
||||
|
||||
if (!self->ensureHasTypes(cx))
|
||||
return false;
|
||||
if (!self->types->hasScope()) {
|
||||
js::CheckRoot root(cx, &self);
|
||||
js::RootObject objRoot(cx, &scope);
|
||||
if (!js::types::TypeScript::SetScope(cx, self, scope))
|
||||
return false;
|
||||
|
|
|
@ -208,7 +208,8 @@ js::GetScopeChain(JSContext *cx, StackFrame *fp)
|
|||
*
|
||||
* create() leaves the clone's enclosingScope unset. We set it below.
|
||||
*/
|
||||
ClonedBlockObject *innermostNewChild = ClonedBlockObject::create(cx, *sharedBlock, fp);
|
||||
RootedVar<ClonedBlockObject *> innermostNewChild(cx);
|
||||
innermostNewChild = ClonedBlockObject::create(cx, *sharedBlock, fp);
|
||||
if (!innermostNewChild)
|
||||
return NULL;
|
||||
|
||||
|
@ -216,7 +217,7 @@ js::GetScopeChain(JSContext *cx, StackFrame *fp)
|
|||
* Clone our way towards outer scopes until we reach the innermost
|
||||
* enclosing function, or the innermost block we've already cloned.
|
||||
*/
|
||||
ClonedBlockObject *newChild = innermostNewChild;
|
||||
RootedVar<ClonedBlockObject *> newChild(cx, innermostNewChild);
|
||||
for (;;) {
|
||||
JS_ASSERT(newChild->getProto() == sharedBlock);
|
||||
sharedBlock = sharedBlock->enclosingBlock();
|
||||
|
@ -226,18 +227,17 @@ js::GetScopeChain(JSContext *cx, StackFrame *fp)
|
|||
break;
|
||||
|
||||
/* As in the call above, we don't know the real parent yet. */
|
||||
ClonedBlockObject *clone = ClonedBlockObject::create(cx, *sharedBlock, fp);
|
||||
RootedVar<ClonedBlockObject *> clone(cx, ClonedBlockObject::create(cx, *sharedBlock, fp));
|
||||
if (!clone)
|
||||
return NULL;
|
||||
|
||||
if (!newChild->setEnclosingScope(cx, *clone))
|
||||
if (!newChild->setEnclosingScope(cx, clone))
|
||||
return NULL;
|
||||
newChild = clone;
|
||||
}
|
||||
if (!newChild->setEnclosingScope(cx, fp->scopeChain()))
|
||||
if (!newChild->setEnclosingScope(cx, RootedVarObject(cx, &fp->scopeChain())))
|
||||
return NULL;
|
||||
|
||||
|
||||
/*
|
||||
* If we found a limit block belonging to this frame, then we should have
|
||||
* found it in blockChain.
|
||||
|
@ -365,7 +365,7 @@ Class js_NoSuchMethodClass = {
|
|||
* parameters.
|
||||
*/
|
||||
bool
|
||||
js::OnUnknownMethod(JSContext *cx, JSObject *obj, Value idval, Value *vp)
|
||||
js::OnUnknownMethod(JSContext *cx, HandleObject obj, Value idval, Value *vp)
|
||||
{
|
||||
jsid id = ATOM_TO_JSID(cx->runtime->atomState.noSuchMethodAtom);
|
||||
AutoValueRooter tvr(cx);
|
||||
|
@ -379,13 +379,13 @@ js::OnUnknownMethod(JSContext *cx, JSObject *obj, Value idval, Value *vp)
|
|||
#if JS_HAS_XML_SUPPORT
|
||||
/* Extract the function name from function::name qname. */
|
||||
if (idval.isObject()) {
|
||||
obj = &idval.toObject();
|
||||
JSObject *obj = &idval.toObject();
|
||||
if (js_GetLocalNameFromFunctionQName(obj, &id, cx))
|
||||
idval = IdToValue(id);
|
||||
}
|
||||
#endif
|
||||
|
||||
obj = NewObjectWithClassProto(cx, &js_NoSuchMethodClass, NULL, NULL);
|
||||
JSObject *obj = NewObjectWithClassProto(cx, &js_NoSuchMethodClass, NULL, NULL);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
|
@ -644,7 +644,7 @@ js::ExecuteKernel(JSContext *cx, JSScript *script, JSObject &scopeChain, const V
|
|||
{
|
||||
JS_ASSERT_IF(evalInFrame, type == EXECUTE_DEBUG);
|
||||
|
||||
Root<JSScript*> scriptRoot(cx, &script);
|
||||
JS::Root<JSScript*> scriptRoot(cx, &script);
|
||||
|
||||
if (script->isEmpty()) {
|
||||
if (result)
|
||||
|
@ -924,7 +924,7 @@ EnterWith(JSContext *cx, int stackIndex)
|
|||
JS_ASSERT(stackIndex < 0);
|
||||
JS_ASSERT(fp->base() <= sp + stackIndex);
|
||||
|
||||
JSObject *obj;
|
||||
RootedVarObject obj(cx);
|
||||
if (sp[-1].isObject()) {
|
||||
obj = &sp[-1].toObject();
|
||||
} else {
|
||||
|
@ -934,11 +934,11 @@ EnterWith(JSContext *cx, int stackIndex)
|
|||
sp[-1].setObject(*obj);
|
||||
}
|
||||
|
||||
JSObject *parent = GetScopeChain(cx, fp);
|
||||
RootedVarObject parent(cx, GetScopeChain(cx, fp));
|
||||
if (!parent)
|
||||
return JS_FALSE;
|
||||
|
||||
JSObject *withobj = WithObject::create(cx, fp, *obj, *parent,
|
||||
JSObject *withobj = WithObject::create(cx, fp, obj, parent,
|
||||
sp + stackIndex - fp->base());
|
||||
if (!withobj)
|
||||
return JS_FALSE;
|
||||
|
@ -1222,10 +1222,10 @@ inline InterpreterFrames::~InterpreterFrames()
|
|||
context->runtime->interpreterFrames = older;
|
||||
}
|
||||
|
||||
#if defined(DEBUG) && !defined(JS_THREADSAFE)
|
||||
#if defined(DEBUG) && !defined(JS_THREADSAFE) && !defined(JSGC_ROOT_ANALYSIS)
|
||||
void
|
||||
js::AssertValidPropertyCacheHit(JSContext *cx,
|
||||
JSObject *start, JSObject *found,
|
||||
JSObject *start_, JSObject *found,
|
||||
PropertyCacheEntry *entry)
|
||||
{
|
||||
jsbytecode *pc;
|
||||
|
@ -1234,7 +1234,8 @@ js::AssertValidPropertyCacheHit(JSContext *cx,
|
|||
uint64_t sample = cx->runtime->gcNumber;
|
||||
PropertyCacheEntry savedEntry = *entry;
|
||||
|
||||
PropertyName *name = GetNameFromBytecode(cx, pc, JSOp(*pc), js_CodeSpec[*pc]);
|
||||
RootedVarPropertyName name(cx, GetNameFromBytecode(cx, pc, JSOp(*pc), js_CodeSpec[*pc]));
|
||||
RootedVarObject start(cx, start_);
|
||||
|
||||
JSObject *obj, *pobj;
|
||||
JSProperty *prop;
|
||||
|
@ -1294,7 +1295,7 @@ IteratorMore(JSContext *cx, JSObject *iterobj, bool *cond, Value *rval)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
if (!js_IteratorMore(cx, iterobj, rval))
|
||||
if (!js_IteratorMore(cx, RootedVarObject(cx, iterobj), rval))
|
||||
return false;
|
||||
*cond = rval->isTrue();
|
||||
return true;
|
||||
|
@ -1544,11 +1545,25 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
|
|||
|
||||
/* Copy in hot values that change infrequently. */
|
||||
JSRuntime *const rt = cx->runtime;
|
||||
JSScript *script;
|
||||
RootedVar<JSScript*> script(cx);
|
||||
SET_SCRIPT(regs.fp()->script());
|
||||
Value *argv = regs.fp()->maybeFormalArgs();
|
||||
CHECK_INTERRUPT_HANDLER();
|
||||
|
||||
/*
|
||||
* Pool of rooters for use in this interpreter frame. References to these
|
||||
* are used for local variables within interpreter cases. This avoids
|
||||
* creating new rooters each time an interpreter case is entered, and also
|
||||
* correctness pitfalls due to incorrect compilation of destructor calls
|
||||
* around computed gotos.
|
||||
*/
|
||||
RootedVarValue rootValue0(cx), rootValue1(cx);
|
||||
RootedVarString rootString0(cx), rootString1(cx);
|
||||
RootedVarObject rootObject0(cx), rootObject1(cx);
|
||||
RootedVarFunction rootFunction0(cx);
|
||||
RootedVarTypeObject rootType0(cx);
|
||||
RootedVarPropertyName rootName0(cx);
|
||||
|
||||
if (rt->profilingScripts)
|
||||
ENABLE_INTERRUPTS();
|
||||
|
||||
|
@ -2481,11 +2496,15 @@ END_CASE(JSOP_POS)
|
|||
|
||||
BEGIN_CASE(JSOP_DELNAME)
|
||||
{
|
||||
PropertyName *name;
|
||||
RootedVarPropertyName &name = rootName0;
|
||||
LOAD_NAME(0, name);
|
||||
|
||||
RootedVarObject &scopeObj = rootObject0;
|
||||
scopeObj = cx->stack.currentScriptedScopeChain();
|
||||
|
||||
JSObject *obj, *obj2;
|
||||
JSProperty *prop;
|
||||
if (!FindProperty(cx, name, cx->stack.currentScriptedScopeChain(), &obj, &obj2, &prop))
|
||||
if (!FindProperty(cx, name, scopeObj, &obj, &obj2, &prop))
|
||||
goto error;
|
||||
|
||||
/* Strict mode code should never contain JSOP_DELNAME opcodes. */
|
||||
|
@ -2724,10 +2743,10 @@ BEGIN_CASE(JSOP_FUNCALL)
|
|||
|
||||
bool construct = (*regs.pc == JSOP_NEW);
|
||||
|
||||
JSFunction *fun;
|
||||
RootedVarFunction &fun = rootFunction0;
|
||||
|
||||
/* Don't bother trying to fast-path calls to scripted non-constructors. */
|
||||
if (!IsFunctionObject(args.calleev(), &fun) || !fun->isInterpretedConstructor()) {
|
||||
if (!IsFunctionObject(args.calleev(), fun.address()) || !fun->isInterpretedConstructor()) {
|
||||
if (construct) {
|
||||
if (!InvokeConstructorKernel(cx, args))
|
||||
goto error;
|
||||
|
@ -2821,12 +2840,15 @@ END_CASE(JSOP_SETCALL)
|
|||
|
||||
BEGIN_CASE(JSOP_IMPLICITTHIS)
|
||||
{
|
||||
PropertyName *name;
|
||||
RootedVarPropertyName &name = rootName0;
|
||||
LOAD_NAME(0, name);
|
||||
|
||||
RootedVarObject &scopeObj = rootObject0;
|
||||
scopeObj = cx->stack.currentScriptedScopeChain();
|
||||
|
||||
JSObject *obj, *obj2;
|
||||
JSProperty *prop;
|
||||
if (!FindPropertyHelper(cx, name, false, cx->stack.currentScriptedScopeChain(), &obj, &obj2, &prop))
|
||||
if (!FindPropertyHelper(cx, name, false, scopeObj, &obj, &obj2, &prop))
|
||||
goto error;
|
||||
|
||||
Value v;
|
||||
|
@ -2841,8 +2863,9 @@ BEGIN_CASE(JSOP_CALLGNAME)
|
|||
BEGIN_CASE(JSOP_NAME)
|
||||
BEGIN_CASE(JSOP_CALLNAME)
|
||||
{
|
||||
Value rval;
|
||||
if (!NameOperation(cx, regs.pc, &rval))
|
||||
RootedVarValue &rval = rootValue0;
|
||||
|
||||
if (!NameOperation(cx, regs.pc, rval.address()))
|
||||
goto error;
|
||||
|
||||
PUSH_COPY(rval);
|
||||
|
@ -3115,7 +3138,8 @@ BEGIN_CASE(JSOP_DEFVAR)
|
|||
attrs |= JSPROP_READONLY;
|
||||
|
||||
/* Step 8b. */
|
||||
JSObject &obj = regs.fp()->varObj();
|
||||
RootedVarObject &obj = rootObject0;
|
||||
obj = ®s.fp()->varObj();
|
||||
|
||||
if (!DefVarOrConstOperation(cx, obj, dn, attrs))
|
||||
goto error;
|
||||
|
@ -3130,10 +3154,11 @@ BEGIN_CASE(JSOP_DEFFUN)
|
|||
* a compound statement (not at the top statement level of global code, or
|
||||
* at the top level of a function body).
|
||||
*/
|
||||
JSFunction *fun = script->getFunction(GET_UINT32_INDEX(regs.pc));
|
||||
RootedVarFunction &fun = rootFunction0;
|
||||
fun = script->getFunction(GET_UINT32_INDEX(regs.pc));
|
||||
JSObject *obj = fun;
|
||||
|
||||
JSObject *obj2;
|
||||
RootedVarObject &obj2 = rootObject0;
|
||||
if (fun->isNullClosure()) {
|
||||
/*
|
||||
* Even a null closure needs a parent for principals finding.
|
||||
|
@ -3238,12 +3263,13 @@ END_CASE(JSOP_DEFFUN)
|
|||
BEGIN_CASE(JSOP_LAMBDA)
|
||||
{
|
||||
/* Load the specified function object literal. */
|
||||
JSFunction *fun = script->getFunction(GET_UINT32_INDEX(regs.pc));
|
||||
RootedVarFunction &fun = rootFunction0;
|
||||
fun = script->getFunction(GET_UINT32_INDEX(regs.pc));
|
||||
JSObject *obj = fun;
|
||||
|
||||
/* do-while(0) so we can break instead of using a goto. */
|
||||
do {
|
||||
JSObject *parent;
|
||||
RootedVarObject &parent = rootObject0;
|
||||
if (fun->isNullClosure()) {
|
||||
parent = ®s.fp()->scopeChain();
|
||||
} else {
|
||||
|
@ -3405,9 +3431,11 @@ END_CASE(JSOP_NEWARRAY)
|
|||
|
||||
BEGIN_CASE(JSOP_NEWOBJECT)
|
||||
{
|
||||
JSObject *baseobj = script->getObject(GET_UINT32_INDEX(regs.pc));
|
||||
RootedVarObject &baseobj = rootObject0;
|
||||
baseobj = script->getObject(GET_UINT32_INDEX(regs.pc));
|
||||
|
||||
JSObject *obj = CopyInitializerObject(cx, baseobj);
|
||||
RootedVarObject &obj = rootObject1;
|
||||
obj = CopyInitializerObject(cx, baseobj);
|
||||
if (!obj || !SetInitializerObjectType(cx, script, regs.pc, obj))
|
||||
goto error;
|
||||
|
||||
|
@ -3431,7 +3459,8 @@ BEGIN_CASE(JSOP_INITPROP)
|
|||
Value rval = regs.sp[-1];
|
||||
|
||||
/* Load the object being initialized into lval/obj. */
|
||||
JSObject *obj = ®s.sp[-2].toObject();
|
||||
RootedVarObject &obj = rootObject0;
|
||||
obj = ®s.sp[-2].toObject();
|
||||
JS_ASSERT(obj->isObject());
|
||||
|
||||
JSAtom *atom;
|
||||
|
|
|
@ -322,7 +322,7 @@ extern void
|
|||
UnwindForUncatchableException(JSContext *cx, const FrameRegs ®s);
|
||||
|
||||
extern bool
|
||||
OnUnknownMethod(JSContext *cx, JSObject *obj, Value idval, Value *vp);
|
||||
OnUnknownMethod(JSContext *cx, HandleObject obj, Value idval, Value *vp);
|
||||
|
||||
extern bool
|
||||
IsActiveWithOrBlock(JSContext *cx, JSObject &obj, uint32_t stackDepth);
|
||||
|
|
|
@ -171,7 +171,7 @@ NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, const Shape *shape, unsi
|
|||
return true;
|
||||
}
|
||||
|
||||
#if defined(DEBUG) && !defined(JS_THREADSAFE)
|
||||
#if defined(DEBUG) && !defined(JS_THREADSAFE) && !defined(JSGC_ROOT_ANALYSIS)
|
||||
extern void
|
||||
AssertValidPropertyCacheHit(JSContext *cx, JSObject *start, JSObject *found,
|
||||
PropertyCacheEntry *entry);
|
||||
|
@ -183,7 +183,7 @@ AssertValidPropertyCacheHit(JSContext *cx, JSObject *start, JSObject *found,
|
|||
#endif
|
||||
|
||||
inline bool
|
||||
GetPropertyGenericMaybeCallXML(JSContext *cx, JSOp op, JSObject *obj, jsid id, Value *vp)
|
||||
GetPropertyGenericMaybeCallXML(JSContext *cx, JSOp op, HandleObject obj, jsid id, Value *vp)
|
||||
{
|
||||
/*
|
||||
* Various XML properties behave differently when accessed in a
|
||||
|
@ -255,13 +255,15 @@ GetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, Value *vp
|
|||
return true;
|
||||
}
|
||||
|
||||
RootObject objRoot(cx, &obj);
|
||||
|
||||
jsid id = ATOM_TO_JSID(name);
|
||||
|
||||
if (obj->getOps()->getProperty) {
|
||||
if (!GetPropertyGenericMaybeCallXML(cx, op, obj, id, vp))
|
||||
if (!GetPropertyGenericMaybeCallXML(cx, op, objRoot, id, vp))
|
||||
return false;
|
||||
} else {
|
||||
if (!GetPropertyHelper(cx, obj, id, JSGET_CACHE_RESULT, vp))
|
||||
if (!GetPropertyHelper(cx, objRoot, id, JSGET_CACHE_RESULT, vp))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -270,7 +272,7 @@ GetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, Value *vp
|
|||
JS_UNLIKELY(vp->isPrimitive()) &&
|
||||
lval.isObject())
|
||||
{
|
||||
if (!OnUnknownMethod(cx, obj, IdToValue(id), vp))
|
||||
if (!OnUnknownMethod(cx, objRoot, IdToValue(id), vp))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
@ -308,9 +310,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->nativeContains(cx, *shape));
|
||||
JS_ASSERT(obj->nativeLookupNoAllocation(cx, shape->propid()) == shape);
|
||||
} else {
|
||||
JS_ASSERT(obj2->nativeContains(cx, *shape));
|
||||
JS_ASSERT(obj2->nativeLookupNoAllocation(cx, shape->propid()) == shape);
|
||||
JS_ASSERT(entry->isPrototypePropertyHit());
|
||||
JS_ASSERT(entry->kshape != entry->pshape);
|
||||
JS_ASSERT(!shape->hasSlot());
|
||||
|
@ -333,19 +335,21 @@ SetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, const Val
|
|||
}
|
||||
|
||||
bool strict = cx->stack.currentScript()->strictModeCode;
|
||||
Value rref = rval;
|
||||
RootedVarValue rref(cx, rval);
|
||||
|
||||
JSOp op = JSOp(*pc);
|
||||
|
||||
RootObject objRoot(cx, &obj);
|
||||
|
||||
jsid id = ATOM_TO_JSID(name);
|
||||
if (JS_LIKELY(!obj->getOps()->setProperty)) {
|
||||
unsigned defineHow = (op == JSOP_SETNAME)
|
||||
? DNP_CACHE_RESULT | DNP_UNQUALIFIED
|
||||
: DNP_CACHE_RESULT;
|
||||
if (!js_SetPropertyHelper(cx, obj, id, defineHow, &rref, strict))
|
||||
if (!js_SetPropertyHelper(cx, objRoot, id, defineHow, rref.address(), strict))
|
||||
return false;
|
||||
} else {
|
||||
if (!obj->setGeneric(cx, id, &rref, strict))
|
||||
if (!obj->setGeneric(cx, id, rref.address(), strict))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -382,8 +386,11 @@ NameOperation(JSContext *cx, jsbytecode *pc, Value *vp)
|
|||
|
||||
jsid id = ATOM_TO_JSID(name);
|
||||
|
||||
RootPropertyName nameRoot(cx, &name);
|
||||
RootObject objRoot(cx, &obj);
|
||||
|
||||
JSProperty *prop;
|
||||
if (!FindPropertyHelper(cx, name, true, obj, &obj, &obj2, &prop))
|
||||
if (!FindPropertyHelper(cx, nameRoot, true, objRoot, &obj, &obj2, &prop))
|
||||
return false;
|
||||
if (!prop) {
|
||||
/* Kludge to allow (typeof foo == "undefined") tests. */
|
||||
|
@ -415,19 +422,19 @@ NameOperation(JSContext *cx, jsbytecode *pc, Value *vp)
|
|||
}
|
||||
|
||||
inline bool
|
||||
DefVarOrConstOperation(JSContext *cx, JSObject &varobj, PropertyName *dn, unsigned attrs)
|
||||
DefVarOrConstOperation(JSContext *cx, HandleObject varobj, PropertyName *dn, unsigned attrs)
|
||||
{
|
||||
JS_ASSERT(varobj.isVarObj());
|
||||
JS_ASSERT(!varobj.getOps()->defineProperty);
|
||||
JS_ASSERT(varobj->isVarObj());
|
||||
JS_ASSERT(!varobj->getOps()->defineProperty);
|
||||
|
||||
JSProperty *prop;
|
||||
JSObject *obj2;
|
||||
if (!varobj.lookupProperty(cx, dn, &obj2, &prop))
|
||||
if (!varobj->lookupProperty(cx, dn, &obj2, &prop))
|
||||
return false;
|
||||
|
||||
/* Steps 8c, 8d. */
|
||||
if (!prop || (obj2 != &varobj && varobj.isGlobal())) {
|
||||
if (!DefineNativeProperty(cx, &varobj, dn, UndefinedValue(),
|
||||
if (!prop || (obj2 != varobj && varobj->isGlobal())) {
|
||||
if (!DefineNativeProperty(cx, varobj, dn, UndefinedValue(),
|
||||
JS_PropertyStub, JS_StrictPropertyStub, attrs, 0, 0))
|
||||
{
|
||||
return false;
|
||||
|
@ -438,7 +445,7 @@ DefVarOrConstOperation(JSContext *cx, JSObject &varobj, PropertyName *dn, unsign
|
|||
* see a redeclaration that's |const|, we consider it a conflict.
|
||||
*/
|
||||
unsigned oldAttrs;
|
||||
if (!varobj.getPropertyAttributes(cx, dn, &oldAttrs))
|
||||
if (!varobj->getPropertyAttributes(cx, dn, &oldAttrs))
|
||||
return false;
|
||||
if (attrs & JSPROP_READONLY) {
|
||||
JSAutoByteString bytes;
|
||||
|
@ -478,7 +485,7 @@ ScriptPrologue(JSContext *cx, StackFrame *fp, bool newType)
|
|||
JS_ASSERT_IF(fp->isNonEvalFunctionFrame() && fp->fun()->isHeavyweight(), fp->hasCallObj());
|
||||
|
||||
if (fp->isConstructing()) {
|
||||
JSObject *obj = js_CreateThisForFunction(cx, &fp->callee(), newType);
|
||||
JSObject *obj = js_CreateThisForFunction(cx, RootedVarObject(cx, &fp->callee()), newType);
|
||||
if (!obj)
|
||||
return false;
|
||||
fp->functionThis().setObject(*obj);
|
||||
|
@ -532,11 +539,8 @@ InterpreterFrames::enableInterruptsIfRunning(JSScript *script)
|
|||
static JS_ALWAYS_INLINE bool
|
||||
AddOperation(JSContext *cx, const Value &lhs, const Value &rhs, Value *res)
|
||||
{
|
||||
Value lval = lhs;
|
||||
Value rval = rhs;
|
||||
|
||||
if (lval.isInt32() && rval.isInt32()) {
|
||||
int32_t l = lval.toInt32(), r = rval.toInt32();
|
||||
if (lhs.isInt32() && rhs.isInt32()) {
|
||||
int32_t l = lhs.toInt32(), r = rhs.toInt32();
|
||||
int32_t sum = l + r;
|
||||
if (JS_UNLIKELY(bool((l ^ sum) & (r ^ sum) & 0x80000000))) {
|
||||
res->setDouble(double(l) + double(r));
|
||||
|
@ -546,13 +550,18 @@ AddOperation(JSContext *cx, const Value &lhs, const Value &rhs, Value *res)
|
|||
}
|
||||
} else
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
if (IsXML(lval) && IsXML(rval)) {
|
||||
if (!js_ConcatenateXML(cx, &lval.toObject(), &rval.toObject(), res))
|
||||
if (IsXML(lhs) && IsXML(rhs)) {
|
||||
if (!js_ConcatenateXML(cx, &lhs.toObject(), &rhs.toObject(), res))
|
||||
return false;
|
||||
types::TypeScript::MonitorUnknown(cx);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
RootedVarValue lval_(cx, lhs);
|
||||
RootedVarValue rval_(cx, rhs);
|
||||
Value &lval = lval_.reference();
|
||||
Value &rval = rval_.reference();
|
||||
|
||||
/*
|
||||
* If either operand is an object, any non-integer result must be
|
||||
* reported to inference.
|
||||
|
@ -565,22 +574,22 @@ AddOperation(JSContext *cx, const Value &lhs, const Value &rhs, Value *res)
|
|||
return false;
|
||||
bool lIsString, rIsString;
|
||||
if ((lIsString = lval.isString()) | (rIsString = rval.isString())) {
|
||||
js::AutoStringRooter lstr(cx), rstr(cx);
|
||||
RootedVarString lstr(cx), rstr(cx);
|
||||
if (lIsString) {
|
||||
lstr.setString(lval.toString());
|
||||
lstr = lval.toString();
|
||||
} else {
|
||||
lstr.setString(ToString(cx, lval));
|
||||
if (!lstr.string())
|
||||
lstr = ToString(cx, lval);
|
||||
if (!lstr)
|
||||
return false;
|
||||
}
|
||||
if (rIsString) {
|
||||
rstr.setString(rval.toString());
|
||||
rstr = rval.toString();
|
||||
} else {
|
||||
rstr.setString(ToString(cx, rval));
|
||||
if (!rstr.string())
|
||||
rstr = ToString(cx, rval);
|
||||
if (!rstr)
|
||||
return false;
|
||||
}
|
||||
JSString *str = js_ConcatStrings(cx, lstr.string(), rstr.string());
|
||||
JSString *str = js_ConcatStrings(cx, lstr, rstr);
|
||||
if (!str)
|
||||
return false;
|
||||
if (lIsObject || rIsObject)
|
||||
|
@ -693,7 +702,7 @@ ToIdOperation(JSContext *cx, const Value &objval, const Value &idval, Value *res
|
|||
}
|
||||
|
||||
static JS_ALWAYS_INLINE bool
|
||||
GetObjectElementOperation(JSContext *cx, JSOp op, JSObject *obj, const Value &rref, Value *res)
|
||||
GetObjectElementOperation(JSContext *cx, JSOp op, HandleObject obj, const Value &rref, Value *res)
|
||||
{
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
if (op == JSOP_CALLELEM && JS_UNLIKELY(obj->isXML())) {
|
||||
|
@ -773,7 +782,7 @@ GetElementOperation(JSContext *cx, JSOp op, const Value &lref, const Value &rref
|
|||
return NormalArgumentsObject::optimizedGetElem(cx, cx->fp(), rref, res);
|
||||
|
||||
bool isObject = lref.isObject();
|
||||
JSObject *obj = ValueToObject(cx, lref);
|
||||
RootedVarObject obj(cx, ValueToObject(cx, lref));
|
||||
if (!obj)
|
||||
return false;
|
||||
if (!GetObjectElementOperation(cx, op, obj, rref, res))
|
||||
|
@ -817,8 +826,8 @@ SetObjectElementOperation(JSContext *cx, JSObject *obj, jsid id, const Value &va
|
|||
}
|
||||
} while (0);
|
||||
|
||||
Value tmp = value;
|
||||
return obj->setGeneric(cx, id, &tmp, strict);
|
||||
RootedVarValue tmp(cx, value);
|
||||
return obj->setGeneric(cx, id, tmp.address(), strict);
|
||||
}
|
||||
|
||||
#define RELATIONAL_OP(OP) \
|
||||
|
|
|
@ -443,7 +443,7 @@ js::GetPropertyNames(JSContext *cx, JSObject *obj, unsigned flags, AutoIdVector
|
|||
size_t sCustomIteratorCount = 0;
|
||||
|
||||
static inline bool
|
||||
GetCustomIterator(JSContext *cx, JSObject *obj, unsigned flags, Value *vp)
|
||||
GetCustomIterator(JSContext *cx, HandleObject obj, unsigned flags, Value *vp)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
||||
|
@ -584,7 +584,7 @@ RegisterEnumerator(JSContext *cx, JSObject *iterobj, NativeIterator *ni)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
VectorToKeyIterator(JSContext *cx, JSObject *obj, unsigned flags, AutoIdVector &keys,
|
||||
VectorToKeyIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &keys,
|
||||
uint32_t slength, uint32_t key, Value *vp)
|
||||
{
|
||||
JS_ASSERT(!(flags & JSITER_FOREACH));
|
||||
|
@ -595,7 +595,7 @@ VectorToKeyIterator(JSContext *cx, JSObject *obj, unsigned flags, AutoIdVector &
|
|||
types::MarkTypeObjectFlags(cx, obj, types::OBJECT_FLAG_ITERATED);
|
||||
}
|
||||
|
||||
JSObject *iterobj = NewIteratorObject(cx, flags);
|
||||
RootedVarObject iterobj(cx, NewIteratorObject(cx, flags));
|
||||
if (!iterobj)
|
||||
return false;
|
||||
|
||||
|
@ -631,13 +631,13 @@ VectorToKeyIterator(JSContext *cx, JSObject *obj, unsigned flags, AutoIdVector &
|
|||
namespace js {
|
||||
|
||||
bool
|
||||
VectorToKeyIterator(JSContext *cx, JSObject *obj, unsigned flags, AutoIdVector &props, Value *vp)
|
||||
VectorToKeyIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &props, Value *vp)
|
||||
{
|
||||
return VectorToKeyIterator(cx, obj, flags, props, 0, 0, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
VectorToValueIterator(JSContext *cx, JSObject *obj, unsigned flags, AutoIdVector &keys,
|
||||
VectorToValueIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &keys,
|
||||
Value *vp)
|
||||
{
|
||||
JS_ASSERT(flags & JSITER_FOREACH);
|
||||
|
@ -665,7 +665,7 @@ VectorToValueIterator(JSContext *cx, JSObject *obj, unsigned flags, AutoIdVector
|
|||
}
|
||||
|
||||
bool
|
||||
EnumeratedIdVectorToIterator(JSContext *cx, JSObject *obj, unsigned flags, AutoIdVector &props, Value *vp)
|
||||
EnumeratedIdVectorToIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &props, Value *vp)
|
||||
{
|
||||
if (!(flags & JSITER_FOREACH))
|
||||
return VectorToKeyIterator(cx, obj, flags, props, vp);
|
||||
|
@ -682,7 +682,7 @@ UpdateNativeIterator(NativeIterator *ni, JSObject *obj)
|
|||
}
|
||||
|
||||
bool
|
||||
GetIterator(JSContext *cx, JSObject *obj, unsigned flags, Value *vp)
|
||||
GetIterator(JSContext *cx, HandleObject obj, unsigned flags, Value *vp)
|
||||
{
|
||||
Vector<const Shape *, 8> shapes(cx);
|
||||
uint32_t key = 0;
|
||||
|
@ -849,7 +849,7 @@ iterator_next(JSContext *cx, unsigned argc, Value *vp)
|
|||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
bool ok;
|
||||
JSObject *obj = NonGenericMethodGuard(cx, args, iterator_next, &IteratorClass, &ok);
|
||||
RootedVarObject obj(cx, NonGenericMethodGuard(cx, args, iterator_next, &IteratorClass, &ok));
|
||||
if (!obj)
|
||||
return ok;
|
||||
|
||||
|
@ -893,7 +893,7 @@ js::ValueToIterator(JSContext *cx, unsigned flags, Value *vp)
|
|||
*/
|
||||
cx->iterValue.setMagic(JS_NO_ITER_VALUE);
|
||||
|
||||
JSObject *obj;
|
||||
RootedVarObject obj(cx);
|
||||
if (vp->isObject()) {
|
||||
/* Common case. */
|
||||
obj = &vp->toObject();
|
||||
|
@ -906,7 +906,7 @@ js::ValueToIterator(JSContext *cx, unsigned flags, Value *vp)
|
|||
* standard.
|
||||
*/
|
||||
if ((flags & JSITER_ENUMERATE)) {
|
||||
if (!js_ValueToObjectOrNull(cx, *vp, &obj))
|
||||
if (!js_ValueToObjectOrNull(cx, *vp, obj.address()))
|
||||
return false;
|
||||
/* fall through */
|
||||
} else {
|
||||
|
@ -1154,7 +1154,7 @@ bool
|
|||
ElementIteratorObject::iteratorNext(JSContext *cx, Value *vp)
|
||||
{
|
||||
uint32_t i, length;
|
||||
JSObject *obj = getTargetObject();
|
||||
RootedVarObject obj(cx, getTargetObject());
|
||||
if (!js_GetLengthProperty(cx, obj, &length))
|
||||
goto error;
|
||||
|
||||
|
@ -1186,7 +1186,7 @@ JSObject::asElementIterator()
|
|||
}
|
||||
|
||||
JSBool
|
||||
js_IteratorMore(JSContext *cx, JSObject *iterobj, Value *rval)
|
||||
js_IteratorMore(JSContext *cx, HandleObject iterobj, Value *rval)
|
||||
{
|
||||
/* Fast path for native iterators */
|
||||
NativeIterator *ni = NULL;
|
||||
|
|
|
@ -163,23 +163,23 @@ class ElementIteratorObject : public JSObject {
|
|||
};
|
||||
|
||||
bool
|
||||
VectorToIdArray(JSContext *cx, js::AutoIdVector &props, JSIdArray **idap);
|
||||
VectorToIdArray(JSContext *cx, AutoIdVector &props, JSIdArray **idap);
|
||||
|
||||
bool
|
||||
GetIterator(JSContext *cx, JSObject *obj, unsigned flags, js::Value *vp);
|
||||
GetIterator(JSContext *cx, HandleObject obj, unsigned flags, Value *vp);
|
||||
|
||||
bool
|
||||
VectorToKeyIterator(JSContext *cx, JSObject *obj, unsigned flags, js::AutoIdVector &props, js::Value *vp);
|
||||
VectorToKeyIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &props, Value *vp);
|
||||
|
||||
bool
|
||||
VectorToValueIterator(JSContext *cx, JSObject *obj, unsigned flags, js::AutoIdVector &props, js::Value *vp);
|
||||
VectorToValueIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &props, Value *vp);
|
||||
|
||||
/*
|
||||
* Creates either a key or value iterator, depending on flags. For a value
|
||||
* iterator, performs value-lookup to convert the given list of jsids.
|
||||
*/
|
||||
bool
|
||||
EnumeratedIdVectorToIterator(JSContext *cx, JSObject *obj, unsigned flags, js::AutoIdVector &props, js::Value *vp);
|
||||
EnumeratedIdVectorToIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &props, Value *vp);
|
||||
|
||||
/*
|
||||
* Convert the value stored in *vp to its iteration object. The flags should
|
||||
|
@ -188,7 +188,7 @@ EnumeratedIdVectorToIterator(JSContext *cx, JSObject *obj, unsigned flags, js::A
|
|||
* iterator will never be exposed to scripts.
|
||||
*/
|
||||
extern JSBool
|
||||
ValueToIterator(JSContext *cx, unsigned flags, js::Value *vp);
|
||||
ValueToIterator(JSContext *cx, unsigned flags, Value *vp);
|
||||
|
||||
extern bool
|
||||
CloseIterator(JSContext *cx, JSObject *iterObj);
|
||||
|
@ -216,7 +216,7 @@ js_SuppressDeletedElements(JSContext *cx, JSObject *obj, uint32_t begin, uint32_
|
|||
* picked up by IteratorNext(). The value is cached in the current context.
|
||||
*/
|
||||
extern JSBool
|
||||
js_IteratorMore(JSContext *cx, JSObject *iterobj, js::Value *rval);
|
||||
js_IteratorMore(JSContext *cx, js::HandleObject iterobj, js::Value *rval);
|
||||
|
||||
extern JSBool
|
||||
js_IteratorNext(JSContext *cx, JSObject *iterobj, js::Value *rval);
|
||||
|
@ -233,7 +233,7 @@ namespace js {
|
|||
* more values, store the magic value JS_NO_ITER_VALUE in *vp and return true.
|
||||
*/
|
||||
inline bool
|
||||
Next(JSContext *cx, JSObject *iter, Value *vp)
|
||||
Next(JSContext *cx, HandleObject iter, Value *vp)
|
||||
{
|
||||
if (!js_IteratorMore(cx, iter, vp))
|
||||
return false;
|
||||
|
@ -262,7 +262,7 @@ ForOf(JSContext *cx, const Value &iterable, Op op)
|
|||
Value iterv(iterable);
|
||||
if (!ValueToIterator(cx, JSITER_FOR_OF, &iterv))
|
||||
return false;
|
||||
JSObject *iter = &iterv.toObject();
|
||||
RootedVarObject iter(cx, &iterv.toObject());
|
||||
|
||||
bool ok = true;
|
||||
while (ok) {
|
||||
|
|
|
@ -711,9 +711,11 @@ js_IsMathFunction(Native native)
|
|||
}
|
||||
|
||||
JSObject *
|
||||
js_InitMathClass(JSContext *cx, JSObject *obj)
|
||||
js_InitMathClass(JSContext *cx, JSObject *obj_)
|
||||
{
|
||||
JSObject *Math = NewObjectWithClassProto(cx, &MathClass, NULL, obj);
|
||||
RootedVarObject obj(cx, obj_);
|
||||
|
||||
RootedVarObject Math(cx, NewObjectWithClassProto(cx, &MathClass, NULL, obj));
|
||||
if (!Math || !Math->setSingletonType(cx))
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -1014,14 +1014,15 @@ js_InitNumberClass(JSContext *cx, JSObject *obj)
|
|||
/* XXX must do at least once per new thread, so do it per JSContext... */
|
||||
FIX_FPU();
|
||||
|
||||
GlobalObject *global = &obj->asGlobal();
|
||||
RootedVar<GlobalObject*> global(cx, &obj->asGlobal());
|
||||
|
||||
JSObject *numberProto = global->createBlankPrototype(cx, &NumberClass);
|
||||
RootedVarObject numberProto(cx, global->createBlankPrototype(cx, &NumberClass));
|
||||
if (!numberProto)
|
||||
return NULL;
|
||||
numberProto->asNumber().setPrimitiveValue(0);
|
||||
|
||||
JSFunction *ctor = global->createConstructor(cx, Number, CLASS_ATOM(cx, Number), 1);
|
||||
RootedVarFunction ctor(cx);
|
||||
ctor = global->createConstructor(cx, Number, CLASS_ATOM(cx, Number), 1);
|
||||
if (!ctor)
|
||||
return NULL;
|
||||
|
||||
|
|
218
js/src/jsobj.cpp
218
js/src/jsobj.cpp
|
@ -846,13 +846,13 @@ class EvalScriptGuard
|
|||
JSContext *cx_;
|
||||
JSLinearString *str_;
|
||||
JSScript **bucket_;
|
||||
JSScript *script_;
|
||||
RootedVar<JSScript*> script_;
|
||||
|
||||
public:
|
||||
EvalScriptGuard(JSContext *cx, JSLinearString *str)
|
||||
: cx_(cx),
|
||||
str_(str),
|
||||
script_(NULL) {
|
||||
script_(cx) {
|
||||
bucket_ = EvalCacheHash(cx, str);
|
||||
}
|
||||
|
||||
|
@ -909,12 +909,12 @@ enum EvalType { DIRECT_EVAL = EXECUTE_DIRECT_EVAL, INDIRECT_EVAL = EXECUTE_INDIR
|
|||
*/
|
||||
static bool
|
||||
EvalKernel(JSContext *cx, const CallArgs &args, EvalType evalType, StackFrame *caller,
|
||||
JSObject &scopeobj)
|
||||
HandleObject scopeobj)
|
||||
{
|
||||
JS_ASSERT((evalType == INDIRECT_EVAL) == (caller == NULL));
|
||||
AssertInnerizedScopeChain(cx, scopeobj);
|
||||
AssertInnerizedScopeChain(cx, *scopeobj);
|
||||
|
||||
if (!scopeobj.global().isRuntimeCodeGenEnabled(cx)) {
|
||||
if (!scopeobj->global().isRuntimeCodeGenEnabled(cx)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CSP_BLOCKED_EVAL);
|
||||
return false;
|
||||
}
|
||||
|
@ -956,11 +956,11 @@ EvalKernel(JSContext *cx, const CallArgs &args, EvalType evalType, StackFrame *c
|
|||
JS_ASSERT(callerPC && JSOp(*callerPC) == JSOP_EVAL);
|
||||
#endif
|
||||
} else {
|
||||
JS_ASSERT(args.callee().global() == scopeobj);
|
||||
JS_ASSERT(args.callee().global() == *scopeobj);
|
||||
staticLevel = 0;
|
||||
|
||||
/* Use the global as 'this', modulo outerization. */
|
||||
JSObject *thisobj = scopeobj.thisObject(cx);
|
||||
JSObject *thisobj = scopeobj->thisObject(cx);
|
||||
if (!thisobj)
|
||||
return false;
|
||||
thisv = ObjectValue(*thisobj);
|
||||
|
@ -1020,7 +1020,7 @@ EvalKernel(JSContext *cx, const CallArgs &args, EvalType evalType, StackFrame *c
|
|||
JSPrincipals *principals = PrincipalsForCompiledCode(args, cx);
|
||||
|
||||
if (evalType == DIRECT_EVAL && caller->isNonEvalFunctionFrame())
|
||||
esg.lookupInEvalCache(caller, staticLevel, principals, scopeobj);
|
||||
esg.lookupInEvalCache(caller, staticLevel, principals, *scopeobj);
|
||||
|
||||
if (!esg.foundScript()) {
|
||||
unsigned lineno;
|
||||
|
@ -1030,7 +1030,7 @@ EvalKernel(JSContext *cx, const CallArgs &args, EvalType evalType, StackFrame *c
|
|||
evalType == DIRECT_EVAL ? CALLED_FROM_JSOP_EVAL
|
||||
: NOT_CALLED_FROM_JSOP_EVAL);
|
||||
uint32_t tcflags = TCF_COMPILE_N_GO | TCF_COMPILE_FOR_EVAL;
|
||||
JSScript *compiled = frontend::CompileScript(cx, &scopeobj, caller,
|
||||
JSScript *compiled = frontend::CompileScript(cx, scopeobj, caller,
|
||||
principals, originPrincipals,
|
||||
tcflags, chars, length, filename,
|
||||
lineno, cx->findVersion(), linearStr,
|
||||
|
@ -1041,7 +1041,7 @@ EvalKernel(JSContext *cx, const CallArgs &args, EvalType evalType, StackFrame *c
|
|||
esg.setNewScript(compiled);
|
||||
}
|
||||
|
||||
return ExecuteKernel(cx, esg.script(), scopeobj, thisv, ExecuteType(evalType),
|
||||
return ExecuteKernel(cx, esg.script(), *scopeobj, thisv, ExecuteType(evalType),
|
||||
NULL /* evalInFrame */, &args.rval());
|
||||
}
|
||||
|
||||
|
@ -1086,7 +1086,8 @@ eval(JSContext *cx, unsigned argc, Value *vp)
|
|||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return WarnOnTooManyArgs(cx, args) &&
|
||||
EvalKernel(cx, args, INDIRECT_EVAL, NULL, args.callee().global());
|
||||
EvalKernel(cx, args, INDIRECT_EVAL, NULL,
|
||||
RootedVarObject(cx, &args.callee().global()));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1100,14 +1101,14 @@ DirectEval(JSContext *cx, const CallArgs &args)
|
|||
|
||||
AutoFunctionCallProbe callProbe(cx, args.callee().toFunction(), caller->script());
|
||||
|
||||
JSObject *scopeChain = GetScopeChain(cx, caller);
|
||||
RootedVarObject scopeChain(cx, GetScopeChain(cx, caller));
|
||||
if (!scopeChain)
|
||||
return false;
|
||||
|
||||
if (!WarnOnTooManyArgs(cx, args))
|
||||
return false;
|
||||
|
||||
return EvalKernel(cx, args, DIRECT_EVAL, caller, *scopeChain);
|
||||
return EvalKernel(cx, args, DIRECT_EVAL, caller, scopeChain);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1194,7 +1195,7 @@ obj_watch(JSContext *cx, unsigned argc, Value *vp)
|
|||
if (!ValueToId(cx, vp[2], &propid))
|
||||
return false;
|
||||
|
||||
JSObject *obj = ToObject(cx, &vp[1]);
|
||||
RootedVarObject obj(cx, ToObject(cx, &vp[1]));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
|
@ -1205,7 +1206,7 @@ obj_watch(JSContext *cx, unsigned argc, Value *vp)
|
|||
|
||||
vp->setUndefined();
|
||||
|
||||
if (obj->isDenseArray() && !obj->makeDenseArraySlow(cx))
|
||||
if (obj->isDenseArray() && !JSObject::makeDenseArraySlow(cx, obj))
|
||||
return false;
|
||||
return JS_SetWatchPoint(cx, obj, propid, obj_watch_handler, callable);
|
||||
}
|
||||
|
@ -1252,7 +1253,7 @@ js_HasOwnPropertyHelper(JSContext *cx, LookupGenericOp lookup, unsigned argc,
|
|||
if (!ValueToId(cx, argc != 0 ? vp[2] : UndefinedValue(), &id))
|
||||
return JS_FALSE;
|
||||
|
||||
JSObject *obj = ToObject(cx, &vp[1]);
|
||||
RootedVarObject obj(cx, ToObject(cx, &vp[1]));
|
||||
if (!obj)
|
||||
return false;
|
||||
JSObject *obj2;
|
||||
|
@ -1271,7 +1272,7 @@ js_HasOwnPropertyHelper(JSContext *cx, LookupGenericOp lookup, unsigned argc,
|
|||
}
|
||||
|
||||
JSBool
|
||||
js_HasOwnProperty(JSContext *cx, LookupGenericOp lookup, JSObject *obj, jsid id,
|
||||
js_HasOwnProperty(JSContext *cx, LookupGenericOp lookup, HandleObject obj, jsid id,
|
||||
JSObject **objp, JSProperty **propp)
|
||||
{
|
||||
JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_DETECTING);
|
||||
|
@ -1410,8 +1411,13 @@ DefineAccessor(JSContext *cx, unsigned argc, Value *vp)
|
|||
return false;
|
||||
|
||||
JSBool dummy;
|
||||
if (!js_DefineOwnProperty(cx, &args.thisv().toObject(), id, ObjectValue(*descObj), &dummy))
|
||||
if (!js_DefineOwnProperty(cx,
|
||||
RootedVarObject(cx, &args.thisv().toObject()),
|
||||
RootedVarId(cx, id),
|
||||
ObjectValue(*descObj), &dummy))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
@ -1583,7 +1589,7 @@ PropDesc::makeObject(JSContext *cx)
|
|||
}
|
||||
|
||||
bool
|
||||
GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, PropertyDescriptor *desc)
|
||||
GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, PropertyDescriptor *desc)
|
||||
{
|
||||
if (obj->isProxy())
|
||||
return Proxy::getOwnPropertyDescriptor(cx, obj, id, false, desc);
|
||||
|
@ -1621,7 +1627,7 @@ GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, PropertyDescript
|
|||
}
|
||||
|
||||
bool
|
||||
GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, Value *vp)
|
||||
{
|
||||
AutoPropertyDescriptorRooter desc(cx);
|
||||
return GetOwnPropertyDescriptor(cx, obj, id, &desc) &&
|
||||
|
@ -1657,13 +1663,13 @@ GetFirstArgumentAsObject(JSContext *cx, unsigned argc, Value *vp, const char *me
|
|||
static JSBool
|
||||
obj_getOwnPropertyDescriptor(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
JSObject *obj;
|
||||
if (!GetFirstArgumentAsObject(cx, argc, vp, "Object.getOwnPropertyDescriptor", &obj))
|
||||
RootedVarObject obj(cx);
|
||||
if (!GetFirstArgumentAsObject(cx, argc, vp, "Object.getOwnPropertyDescriptor", obj.address()))
|
||||
return JS_FALSE;
|
||||
AutoIdRooter nameidr(cx);
|
||||
if (!ValueToId(cx, argc >= 2 ? vp[3] : UndefinedValue(), nameidr.addr()))
|
||||
RootedVarId id(cx);
|
||||
if (!ValueToId(cx, argc >= 2 ? vp[3] : UndefinedValue(), id.address()))
|
||||
return JS_FALSE;
|
||||
return GetOwnPropertyDescriptor(cx, obj, nameidr.id(), vp);
|
||||
return GetOwnPropertyDescriptor(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -1884,14 +1890,14 @@ Reject(JSContext *cx, JSObject *obj, unsigned errorNumber, bool throwError, bool
|
|||
}
|
||||
|
||||
static JSBool
|
||||
DefinePropertyOnObject(JSContext *cx, JSObject *obj, const jsid &id, const PropDesc &desc,
|
||||
DefinePropertyOnObject(JSContext *cx, HandleObject obj, HandleId id, const PropDesc &desc,
|
||||
bool throwError, bool *rval)
|
||||
{
|
||||
/* 8.12.9 step 1. */
|
||||
JSProperty *current;
|
||||
JSObject *obj2;
|
||||
RootedVarObject obj2(cx);
|
||||
JS_ASSERT(!obj->getOps()->lookupGeneric);
|
||||
if (!js_HasOwnProperty(cx, NULL, obj, id, &obj2, ¤t))
|
||||
if (!js_HasOwnProperty(cx, NULL, obj, id, obj2.address(), ¤t))
|
||||
return JS_FALSE;
|
||||
|
||||
JS_ASSERT(!obj->getOps()->defineProperty);
|
||||
|
@ -2184,7 +2190,7 @@ DefinePropertyOnObject(JSContext *cx, JSObject *obj, const jsid &id, const PropD
|
|||
}
|
||||
|
||||
static JSBool
|
||||
DefinePropertyOnArray(JSContext *cx, JSObject *obj, const jsid &id, const PropDesc &desc,
|
||||
DefinePropertyOnArray(JSContext *cx, HandleObject obj, HandleId id, const PropDesc &desc,
|
||||
bool throwError, bool *rval)
|
||||
{
|
||||
/*
|
||||
|
@ -2194,7 +2200,7 @@ DefinePropertyOnArray(JSContext *cx, JSObject *obj, const jsid &id, const PropDe
|
|||
* attributes). Such definitions are probably unlikely, so we don't bother
|
||||
* for now.
|
||||
*/
|
||||
if (obj->isDenseArray() && !obj->makeDenseArraySlow(cx))
|
||||
if (obj->isDenseArray() && !JSObject::makeDenseArraySlow(cx, obj))
|
||||
return JS_FALSE;
|
||||
|
||||
uint32_t oldLen = obj->getArrayLength();
|
||||
|
@ -2238,7 +2244,7 @@ DefinePropertyOnArray(JSContext *cx, JSObject *obj, const jsid &id, const PropDe
|
|||
namespace js {
|
||||
|
||||
bool
|
||||
DefineProperty(JSContext *cx, JSObject *obj, const jsid &id, const PropDesc &desc, bool throwError,
|
||||
DefineProperty(JSContext *cx, HandleObject obj, HandleId id, const PropDesc &desc, bool throwError,
|
||||
bool *rval)
|
||||
{
|
||||
if (obj->isArray())
|
||||
|
@ -2256,7 +2262,7 @@ DefineProperty(JSContext *cx, JSObject *obj, const jsid &id, const PropDesc &des
|
|||
} /* namespace js */
|
||||
|
||||
JSBool
|
||||
js_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, const Value &descriptor, JSBool *bp)
|
||||
js_DefineOwnProperty(JSContext *cx, HandleObject obj, HandleId id, const Value &descriptor, JSBool *bp)
|
||||
{
|
||||
AutoPropDescArrayRooter descs(cx);
|
||||
PropDesc *desc = descs.append();
|
||||
|
@ -2274,12 +2280,12 @@ js_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, const Value &descrip
|
|||
static JSBool
|
||||
obj_defineProperty(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
JSObject *obj;
|
||||
if (!GetFirstArgumentAsObject(cx, argc, vp, "Object.defineProperty", &obj))
|
||||
RootedVarObject obj(cx);
|
||||
if (!GetFirstArgumentAsObject(cx, argc, vp, "Object.defineProperty", obj.address()))
|
||||
return false;
|
||||
|
||||
jsid id;
|
||||
if (!ValueToId(cx, argc >= 2 ? vp[3] : UndefinedValue(), &id))
|
||||
RootedVarId id(cx);
|
||||
if (!ValueToId(cx, argc >= 2 ? vp[3] : UndefinedValue(), id.address()))
|
||||
return JS_FALSE;
|
||||
|
||||
const Value descval = argc >= 3 ? vp[4] : UndefinedValue();
|
||||
|
@ -2314,7 +2320,7 @@ ReadPropertyDescriptors(JSContext *cx, JSObject *props, bool checkAccessors,
|
|||
} /* namespace js */
|
||||
|
||||
static bool
|
||||
DefineProperties(JSContext *cx, JSObject *obj, JSObject *props)
|
||||
DefineProperties(JSContext *cx, HandleObject obj, JSObject *props)
|
||||
{
|
||||
AutoIdVector ids(cx);
|
||||
AutoPropDescArrayRooter descs(cx);
|
||||
|
@ -2323,7 +2329,7 @@ DefineProperties(JSContext *cx, JSObject *obj, JSObject *props)
|
|||
|
||||
bool dummy;
|
||||
for (size_t i = 0, len = ids.length(); i < len; i++) {
|
||||
if (!DefineProperty(cx, obj, ids[i], descs[i], true, &dummy))
|
||||
if (!DefineProperty(cx, obj, RootedVarId(cx, ids[i]), descs[i], true, &dummy))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2331,7 +2337,7 @@ DefineProperties(JSContext *cx, JSObject *obj, JSObject *props)
|
|||
}
|
||||
|
||||
extern JSBool
|
||||
js_PopulateObject(JSContext *cx, JSObject *newborn, JSObject *props)
|
||||
js_PopulateObject(JSContext *cx, HandleObject newborn, JSObject *props)
|
||||
{
|
||||
return DefineProperties(cx, newborn, props);
|
||||
}
|
||||
|
@ -2341,8 +2347,8 @@ static JSBool
|
|||
obj_defineProperties(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
/* Steps 1 and 7. */
|
||||
JSObject *obj;
|
||||
if (!GetFirstArgumentAsObject(cx, argc, vp, "Object.defineProperties", &obj))
|
||||
RootedVarObject obj(cx);
|
||||
if (!GetFirstArgumentAsObject(cx, argc, vp, "Object.defineProperties", obj.address()))
|
||||
return false;
|
||||
vp->setObject(*obj);
|
||||
|
||||
|
@ -2392,7 +2398,8 @@ obj_create(JSContext *cx, unsigned argc, Value *vp)
|
|||
* Use the callee's global as the parent of the new object to avoid dynamic
|
||||
* scoping (i.e., using the caller's global).
|
||||
*/
|
||||
JSObject *obj = NewObjectWithGivenProto(cx, &ObjectClass, proto, &args.callee().global());
|
||||
RootedVarObject obj(cx);
|
||||
obj = NewObjectWithGivenProto(cx, &ObjectClass, proto, &args.callee().global());
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
|
@ -2507,7 +2514,7 @@ JSObject::sealOrFreeze(JSContext *cx, ImmutabilityType it)
|
|||
/* preventExtensions must slowify dense arrays, so we can assign to holes without checks. */
|
||||
JS_ASSERT(!self->isDenseArray());
|
||||
|
||||
if (isNative() && !inDictionaryMode()) {
|
||||
if (self->isNative() && !self->inDictionaryMode()) {
|
||||
/*
|
||||
* Seal/freeze non-dictionary objects by constructing a new shape
|
||||
* hierarchy mirroring the original one, which can be shared if many
|
||||
|
@ -2544,7 +2551,7 @@ JSObject::sealOrFreeze(JSContext *cx, ImmutabilityType it)
|
|||
}
|
||||
|
||||
JS_ASSERT(self->lastProperty()->slotSpan() == last->slotSpan());
|
||||
JS_ALWAYS_TRUE(setLastProperty(cx, last));
|
||||
JS_ALWAYS_TRUE(self->setLastProperty(cx, last));
|
||||
} else {
|
||||
for (size_t i = 0; i < props.length(); i++) {
|
||||
jsid id = props[i];
|
||||
|
@ -2858,7 +2865,7 @@ js::NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *proto, JS
|
|||
}
|
||||
|
||||
JSObject *
|
||||
js::NewObjectWithType(JSContext *cx, types::TypeObject *type, JSObject *parent, gc::AllocKind kind)
|
||||
js::NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc::AllocKind kind)
|
||||
{
|
||||
JS_ASSERT(type->proto->hasNewType(type));
|
||||
JS_ASSERT(parent);
|
||||
|
@ -2885,10 +2892,10 @@ js::NewObjectWithType(JSContext *cx, types::TypeObject *type, JSObject *parent,
|
|||
}
|
||||
|
||||
JSObject *
|
||||
js::NewReshapedObject(JSContext *cx, TypeObject *type, JSObject *parent,
|
||||
js::NewReshapedObject(JSContext *cx, HandleTypeObject type, JSObject *parent,
|
||||
gc::AllocKind kind, const Shape *shape)
|
||||
{
|
||||
JSObject *res = NewObjectWithType(cx, type, parent, kind);
|
||||
RootedVarObject res(cx, NewObjectWithType(cx, type, parent, kind));
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
|
@ -2933,7 +2940,7 @@ js_CreateThis(JSContext *cx, Class *newclasp, JSObject *callee)
|
|||
}
|
||||
|
||||
static inline JSObject *
|
||||
CreateThisForFunctionWithType(JSContext *cx, types::TypeObject *type, JSObject *parent)
|
||||
CreateThisForFunctionWithType(JSContext *cx, HandleTypeObject type, JSObject *parent)
|
||||
{
|
||||
if (type->newScript) {
|
||||
/*
|
||||
|
@ -2953,12 +2960,12 @@ CreateThisForFunctionWithType(JSContext *cx, types::TypeObject *type, JSObject *
|
|||
}
|
||||
|
||||
JSObject *
|
||||
js_CreateThisForFunctionWithProto(JSContext *cx, JSObject *callee, JSObject *proto)
|
||||
js_CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject *proto)
|
||||
{
|
||||
JSObject *res;
|
||||
|
||||
if (proto) {
|
||||
types::TypeObject *type = proto->getNewType(cx, callee->toFunction());
|
||||
RootedVarTypeObject type(cx, proto->getNewType(cx, callee->toFunction()));
|
||||
if (!type)
|
||||
return NULL;
|
||||
res = CreateThisForFunctionWithType(cx, type, callee->getParent());
|
||||
|
@ -2974,7 +2981,7 @@ js_CreateThisForFunctionWithProto(JSContext *cx, JSObject *callee, JSObject *pro
|
|||
}
|
||||
|
||||
JSObject *
|
||||
js_CreateThisForFunction(JSContext *cx, JSObject *callee, bool newType)
|
||||
js_CreateThisForFunction(JSContext *cx, HandleObject callee, bool newType)
|
||||
{
|
||||
Value protov;
|
||||
if (!callee->getProperty(cx, cx->runtime->atomState.classPrototypeAtom, &protov))
|
||||
|
@ -3191,15 +3198,19 @@ CopySlots(JSContext *cx, JSObject *from, JSObject *to)
|
|||
}
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
JS_CloneObject(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent)
|
||||
JS_CloneObject(JSContext *cx, JSObject *obj_, JSObject *proto_, JSObject *parent_)
|
||||
{
|
||||
RootedVarObject obj(cx, obj_);
|
||||
RootedVarObject proto(cx, proto_);
|
||||
RootedVarObject parent(cx, parent_);
|
||||
|
||||
/*
|
||||
* We can only clone native objects and proxies. Dense arrays are slowified if
|
||||
* we try to clone them.
|
||||
*/
|
||||
if (!obj->isNative()) {
|
||||
if (obj->isDenseArray()) {
|
||||
if (!obj->makeDenseArraySlow(cx))
|
||||
if (!JSObject::makeDenseArraySlow(cx, obj))
|
||||
return NULL;
|
||||
} else if (!obj->isProxy()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
|
@ -3632,7 +3643,7 @@ DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey key, H
|
|||
if (!proto->setSingletonType(cx))
|
||||
return NULL;
|
||||
|
||||
if (clasp == &ArrayClass && !proto->makeDenseArraySlow(cx))
|
||||
if (clasp == &ArrayClass && !JSObject::makeDenseArraySlow(cx, proto))
|
||||
return NULL;
|
||||
|
||||
/* After this point, control must exit via label bad or out. */
|
||||
|
@ -3903,7 +3914,8 @@ JSObject::growSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount)
|
|||
gc::AllocKind kind = type()->newScript->allocKind;
|
||||
unsigned newScriptSlots = gc::GetGCKindSlots(kind);
|
||||
if (newScriptSlots == numFixedSlots() && gc::TryIncrementAllocKind(&kind)) {
|
||||
JSObject *obj = NewReshapedObject(cx, type(), getParent(), kind,
|
||||
JSObject *obj = NewReshapedObject(cx, RootedVarTypeObject(cx, type()),
|
||||
getParent(), kind,
|
||||
type()->newScript->shape);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
@ -4421,16 +4433,18 @@ js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id,
|
|||
}
|
||||
|
||||
JSBool
|
||||
js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, const Value *value,
|
||||
js_DefineProperty(JSContext *cx, JSObject *obj_, jsid id, const Value *value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
RootObject obj(cx, &obj_);
|
||||
return !!DefineNativeProperty(cx, obj, id, *value, getter, setter, attrs, 0, 0);
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_DefineElement(JSContext *cx, JSObject *obj, uint32_t index, const Value *value,
|
||||
js_DefineElement(JSContext *cx, JSObject *obj_, uint32_t index, const Value *value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
RootObject obj(cx, &obj_);
|
||||
jsid id;
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
|
@ -4462,7 +4476,7 @@ CallAddPropertyHook(JSContext *cx, Class *clasp, JSObject *obj, const Shape *sha
|
|||
namespace js {
|
||||
|
||||
const Shape *
|
||||
DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &value_,
|
||||
DefineNativeProperty(JSContext *cx, HandleObject obj, jsid id, const Value &value_,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
unsigned flags, int shortid, unsigned defineHow /* = 0 */)
|
||||
{
|
||||
|
@ -4470,7 +4484,6 @@ DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &value_,
|
|||
DNP_SKIP_TYPE)) == 0);
|
||||
JS_ASSERT(!(attrs & JSPROP_NATIVE_ACCESSORS));
|
||||
|
||||
RootObject objRoot(cx, &obj);
|
||||
RootId idRoot(cx, &id);
|
||||
|
||||
/* Make a local copy of value so addProperty can mutate its inout parameter. */
|
||||
|
@ -4654,17 +4667,17 @@ CallResolveOp(JSContext *cx, JSObject *start, HandleObject obj, HandleId id, uns
|
|||
}
|
||||
|
||||
static JS_ALWAYS_INLINE bool
|
||||
LookupPropertyWithFlagsInline(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
|
||||
LookupPropertyWithFlagsInline(JSContext *cx, JSObject *obj_, jsid id_, unsigned flags,
|
||||
JSObject **objp, JSProperty **propp)
|
||||
{
|
||||
/* We should not get string indices which aren't already integers here. */
|
||||
JS_ASSERT(id == js_CheckForStringIndex(id));
|
||||
RootedVarObject obj(cx, obj_);
|
||||
RootedVarId id(cx, id_);
|
||||
|
||||
RootObject objRoot(cx, &obj);
|
||||
RootId idRoot(cx, &id);
|
||||
/* We should not get string indices which aren't already integers here. */
|
||||
JS_ASSERT(id.raw() == js_CheckForStringIndex(id));
|
||||
|
||||
/* Search scopes starting with obj and following the prototype link. */
|
||||
JSObject *start = obj;
|
||||
RootedVarObject start(cx, obj);
|
||||
while (true) {
|
||||
const Shape *shape = obj->nativeLookup(cx, id);
|
||||
if (shape) {
|
||||
|
@ -4676,7 +4689,7 @@ LookupPropertyWithFlagsInline(JSContext *cx, JSObject *obj, jsid id, unsigned fl
|
|||
/* Try obj's class resolve hook if id was not found in obj's scope. */
|
||||
if (obj->getClass()->resolve != JS_ResolveStub) {
|
||||
bool recursed;
|
||||
if (!CallResolveOp(cx, start, objRoot, idRoot, flags, objp, propp, &recursed))
|
||||
if (!CallResolveOp(cx, start, obj, id, flags, objp, propp, &recursed))
|
||||
return false;
|
||||
if (recursed)
|
||||
break;
|
||||
|
@ -4752,17 +4765,19 @@ js::LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, unsigned flag
|
|||
}
|
||||
|
||||
bool
|
||||
js::FindPropertyHelper(JSContext *cx, PropertyName *name, bool cacheResult, JSObject *scopeChain,
|
||||
js::FindPropertyHelper(JSContext *cx,
|
||||
HandlePropertyName name, bool cacheResult, HandleObject scopeChain,
|
||||
JSObject **objp, JSObject **pobjp, JSProperty **propp)
|
||||
{
|
||||
jsid id = ATOM_TO_JSID(name);
|
||||
JSObject *obj, *parent, *pobj;
|
||||
RootedVarId id(cx, ATOM_TO_JSID(name));
|
||||
|
||||
JSObject *pobj;
|
||||
int scopeIndex;
|
||||
JSProperty *prop;
|
||||
|
||||
/* Scan entries on the scope chain that we can cache across. */
|
||||
obj = scopeChain;
|
||||
parent = obj->enclosingScope();
|
||||
RootedVarObject obj(cx, scopeChain);
|
||||
RootedVarObject parent(cx, obj->enclosingScope());
|
||||
for (scopeIndex = 0;
|
||||
parent
|
||||
? IsCacheableNonGlobalScope(obj)
|
||||
|
@ -4844,7 +4859,7 @@ js::FindPropertyHelper(JSContext *cx, PropertyName *name, bool cacheResult, JSOb
|
|||
* Otherwise, its type and meaning depends on the host object's implementation.
|
||||
*/
|
||||
bool
|
||||
js::FindProperty(JSContext *cx, PropertyName *name, JSObject *scopeChain,
|
||||
js::FindProperty(JSContext *cx, HandlePropertyName name, HandleObject scopeChain,
|
||||
JSObject **objp, JSObject **pobjp, JSProperty **propp)
|
||||
{
|
||||
return !!FindPropertyHelper(cx, name, false, scopeChain, objp, pobjp, propp);
|
||||
|
@ -4940,6 +4955,9 @@ js_NativeGetInline(JSContext *cx, JSObject *receiver, JSObject *obj, JSObject *p
|
|||
code->accessGetter = true;
|
||||
}
|
||||
|
||||
Root<const Shape*> rootShape(cx, &shape);
|
||||
RootObject pobjRoot(cx, &pobj);
|
||||
|
||||
if (!shape->get(cx, receiver, obj, pobj, vp))
|
||||
return false;
|
||||
|
||||
|
@ -4983,6 +5001,9 @@ js_NativeSet(JSContext *cx, JSObject *obj, const Shape *shape, bool added, bool
|
|||
return js_ReportGetterOnlyAssignment(cx);
|
||||
}
|
||||
|
||||
RootObject objRoot(cx, &obj);
|
||||
Root<const Shape *> shapeRoot(cx, &shape);
|
||||
|
||||
int32_t sample = cx->runtime->propertyRemovals;
|
||||
if (!shape->set(cx, obj, strict, vp))
|
||||
return false;
|
||||
|
@ -5001,19 +5022,19 @@ js_NativeSet(JSContext *cx, JSObject *obj, const Shape *shape, bool added, bool
|
|||
}
|
||||
|
||||
static JS_ALWAYS_INLINE JSBool
|
||||
js_GetPropertyHelperInline(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id,
|
||||
js_GetPropertyHelperInline(JSContext *cx, HandleObject obj, HandleObject receiver, jsid id_,
|
||||
uint32_t getHow, Value *vp)
|
||||
{
|
||||
JSObject *aobj, *obj2;
|
||||
JSProperty *prop;
|
||||
const Shape *shape;
|
||||
|
||||
RootedVarId id(cx, id_);
|
||||
|
||||
/* Convert string indices to integers if appropriate. */
|
||||
id = js_CheckForStringIndex(id);
|
||||
|
||||
aobj = js_GetProtoIfDenseArray(obj);
|
||||
/* This call site is hot -- use the always-inlined variant of LookupPropertyWithFlags(). */
|
||||
if (!LookupPropertyWithFlagsInline(cx, aobj, id, cx->resolveFlags, &obj2, &prop))
|
||||
RootedVarObject obj2(cx);
|
||||
if (!LookupPropertyWithFlagsInline(cx, obj, id, cx->resolveFlags, obj2.address(), &prop))
|
||||
return false;
|
||||
|
||||
if (!prop) {
|
||||
|
@ -5084,10 +5105,10 @@ js_GetPropertyHelperInline(JSContext *cx, JSObject *obj, JSObject *receiver, jsi
|
|||
: obj2->getGeneric(cx, id, vp);
|
||||
}
|
||||
|
||||
shape = (Shape *) prop;
|
||||
Shape *shape = (Shape *) prop;
|
||||
|
||||
if (getHow & JSGET_CACHE_RESULT)
|
||||
JS_PROPERTY_CACHE(cx).fill(cx, aobj, 0, obj2, shape);
|
||||
JS_PROPERTY_CACHE(cx).fill(cx, obj, 0, obj2, shape);
|
||||
|
||||
/* This call site is hot -- use the always-inlined variant of js_NativeGet(). */
|
||||
if (!js_NativeGetInline(cx, receiver, obj, obj2, shape, getHow, vp))
|
||||
|
@ -5097,20 +5118,20 @@ js_GetPropertyHelperInline(JSContext *cx, JSObject *obj, JSObject *receiver, jsi
|
|||
}
|
||||
|
||||
bool
|
||||
js::GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uint32_t getHow, Value *vp)
|
||||
js::GetPropertyHelper(JSContext *cx, HandleObject obj, jsid id, uint32_t getHow, Value *vp)
|
||||
{
|
||||
return !!js_GetPropertyHelperInline(cx, obj, obj, id, getHow, vp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
|
||||
js_GetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, jsid id, Value *vp)
|
||||
{
|
||||
/* This call site is hot -- use the always-inlined variant of js_GetPropertyHelper(). */
|
||||
return js_GetPropertyHelperInline(cx, obj, receiver, id, 0, vp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_GetElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index, Value *vp)
|
||||
js_GetElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index, Value *vp)
|
||||
{
|
||||
jsid id;
|
||||
if (!IndexToId(cx, index, &id))
|
||||
|
@ -5121,11 +5142,11 @@ js_GetElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index,
|
|||
}
|
||||
|
||||
JSBool
|
||||
js::GetPropertyDefault(JSContext *cx, JSObject *obj, jsid id, const Value &def, Value *vp)
|
||||
js::GetPropertyDefault(JSContext *cx, HandleObject obj, HandleId id, const Value &def, Value *vp)
|
||||
{
|
||||
JSProperty *prop;
|
||||
JSObject *obj2;
|
||||
if (!LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_QUALIFIED, &obj2, &prop))
|
||||
RootedVarObject obj2(cx);
|
||||
if (!LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_QUALIFIED, obj2.address(), &prop))
|
||||
return false;
|
||||
|
||||
if (!prop) {
|
||||
|
@ -5137,7 +5158,7 @@ js::GetPropertyDefault(JSContext *cx, JSObject *obj, jsid id, const Value &def,
|
|||
}
|
||||
|
||||
JSBool
|
||||
js_GetMethod(JSContext *cx, JSObject *obj, jsid id, unsigned getHow, Value *vp)
|
||||
js_GetMethod(JSContext *cx, HandleObject obj, jsid id, unsigned getHow, Value *vp)
|
||||
{
|
||||
JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
|
||||
|
||||
|
@ -5205,17 +5226,16 @@ bool
|
|||
JSObject::callMethod(JSContext *cx, jsid id, unsigned argc, Value *argv, Value *vp)
|
||||
{
|
||||
Value fval;
|
||||
return js_GetMethod(cx, this, id, 0, &fval) &&
|
||||
return js_GetMethod(cx, RootedVarObject(cx, this), id, 0, &fval) &&
|
||||
Invoke(cx, ObjectValue(*this), fval, argc, argv, vp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, unsigned defineHow,
|
||||
js_SetPropertyHelper(JSContext *cx, HandleObject obj, jsid id, unsigned defineHow,
|
||||
Value *vp, JSBool strict)
|
||||
{
|
||||
JSObject *pobj;
|
||||
JSProperty *prop;
|
||||
const Shape *shape;
|
||||
unsigned attrs, flags;
|
||||
int shortid;
|
||||
Class *clasp;
|
||||
|
@ -5224,6 +5244,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, unsigned defineHow,
|
|||
bool added;
|
||||
|
||||
JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_UNQUALIFIED)) == 0);
|
||||
RootId idRoot(cx, &id);
|
||||
|
||||
/* Convert string indices to integers if appropriate. */
|
||||
id = js_CheckForStringIndex(id);
|
||||
|
@ -5270,7 +5291,8 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, unsigned defineHow,
|
|||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
shape = (Shape *) prop;
|
||||
|
||||
RootedVarShape shape(cx, (Shape *) prop);
|
||||
|
||||
/*
|
||||
* Now either shape is null, meaning id was not found in obj or one of its
|
||||
|
@ -5398,7 +5420,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, unsigned defineHow,
|
|||
}
|
||||
|
||||
JSBool
|
||||
js_SetElementHelper(JSContext *cx, JSObject *obj, uint32_t index, unsigned defineHow,
|
||||
js_SetElementHelper(JSContext *cx, HandleObject obj, uint32_t index, unsigned defineHow,
|
||||
Value *vp, JSBool strict)
|
||||
{
|
||||
jsid id;
|
||||
|
@ -5536,7 +5558,7 @@ js_DeleteSpecial(JSContext *cx, JSObject *obj, SpecialId sid, Value *rval, JSBoo
|
|||
namespace js {
|
||||
|
||||
bool
|
||||
HasDataProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
HasDataProperty(JSContext *cx, HandleObject obj, jsid id, Value *vp)
|
||||
{
|
||||
JS_ASSERT(id == js_CheckForStringIndex(id));
|
||||
if (const Shape *shape = obj->nativeLookup(cx, id)) {
|
||||
|
@ -5558,7 +5580,7 @@ HasDataProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
|||
* or steps 3-4.
|
||||
*/
|
||||
static bool
|
||||
MaybeCallMethod(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
MaybeCallMethod(JSContext *cx, HandleObject obj, jsid id, Value *vp)
|
||||
{
|
||||
if (!js_GetMethod(cx, obj, id, 0, vp))
|
||||
return false;
|
||||
|
@ -5570,7 +5592,7 @@ MaybeCallMethod(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
|||
}
|
||||
|
||||
JSBool
|
||||
DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp)
|
||||
DefaultValue(JSContext *cx, HandleObject obj, JSType hint, Value *vp)
|
||||
{
|
||||
JS_ASSERT(hint == JSTYPE_NUMBER || hint == JSTYPE_STRING || hint == JSTYPE_VOID);
|
||||
JS_ASSERT(!obj->isXML());
|
||||
|
@ -5581,7 +5603,7 @@ DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp)
|
|||
if (clasp == &StringClass &&
|
||||
ClassMethodIsNative(cx, obj,
|
||||
&StringClass,
|
||||
ATOM_TO_JSID(cx->runtime->atomState.toStringAtom),
|
||||
RootedVarId(cx, ATOM_TO_JSID(cx->runtime->atomState.toStringAtom)),
|
||||
js_str_toString)) {
|
||||
*vp = StringValue(obj->asString().unbox());
|
||||
return true;
|
||||
|
@ -5600,11 +5622,11 @@ DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp)
|
|||
/* Optimize (new String(...)).valueOf(). */
|
||||
if ((clasp == &StringClass &&
|
||||
ClassMethodIsNative(cx, obj, &StringClass,
|
||||
ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom),
|
||||
RootedVarId(cx, ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom)),
|
||||
js_str_toString)) ||
|
||||
(clasp == &NumberClass &&
|
||||
ClassMethodIsNative(cx, obj, &NumberClass,
|
||||
ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom),
|
||||
RootedVarId(cx, ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom)),
|
||||
js_num_valueOf))) {
|
||||
*vp = obj->isString()
|
||||
? StringValue(obj->asString().unbox())
|
||||
|
@ -5814,7 +5836,7 @@ JSObject *
|
|||
PrimitiveToObject(JSContext *cx, const Value &v)
|
||||
{
|
||||
if (v.isString())
|
||||
return StringObject::create(cx, v.toString());
|
||||
return StringObject::create(cx, RootedVarString(cx, v.toString()));
|
||||
if (v.isNumber())
|
||||
return NumberObject::create(cx, v.toNumber());
|
||||
|
||||
|
|
|
@ -273,19 +273,19 @@ js_DefineElement(JSContext *cx, JSObject *obj, uint32_t index, const js::Value *
|
|||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
|
||||
|
||||
extern JSBool
|
||||
js_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, js::Value *vp);
|
||||
js_GetProperty(JSContext *cx, js::HandleObject obj, js::HandleObject receiver, jsid id, js::Value *vp);
|
||||
|
||||
extern JSBool
|
||||
js_GetElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t, js::Value *vp);
|
||||
js_GetElement(JSContext *cx, js::HandleObject obj, js::HandleObject receiver, uint32_t, js::Value *vp);
|
||||
|
||||
inline JSBool
|
||||
js_GetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp)
|
||||
js_GetProperty(JSContext *cx, js::HandleObject obj, jsid id, js::Value *vp)
|
||||
{
|
||||
return js_GetProperty(cx, obj, obj, id, vp);
|
||||
}
|
||||
|
||||
inline JSBool
|
||||
js_GetElement(JSContext *cx, JSObject *obj, uint32_t index, js::Value *vp)
|
||||
js_GetElement(JSContext *cx, js::HandleObject obj, uint32_t index, js::Value *vp)
|
||||
{
|
||||
return js_GetElement(cx, obj, obj, index, vp);
|
||||
}
|
||||
|
@ -293,18 +293,18 @@ js_GetElement(JSContext *cx, JSObject *obj, uint32_t index, js::Value *vp)
|
|||
namespace js {
|
||||
|
||||
extern JSBool
|
||||
GetPropertyDefault(JSContext *cx, JSObject *obj, jsid id, const Value &def, Value *vp);
|
||||
GetPropertyDefault(JSContext *cx, js::HandleObject obj, js::HandleId id, const Value &def, Value *vp);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern JSBool
|
||||
js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, unsigned defineHow,
|
||||
js_SetPropertyHelper(JSContext *cx, js::HandleObject obj, jsid id, unsigned defineHow,
|
||||
js::Value *vp, JSBool strict);
|
||||
|
||||
namespace js {
|
||||
|
||||
inline bool
|
||||
SetPropertyHelper(JSContext *cx, JSObject *obj, PropertyName *name, unsigned defineHow,
|
||||
SetPropertyHelper(JSContext *cx, HandleObject obj, PropertyName *name, unsigned defineHow,
|
||||
Value *vp, JSBool strict)
|
||||
{
|
||||
return !!js_SetPropertyHelper(cx, obj, ATOM_TO_JSID(name), defineHow, vp, strict);
|
||||
|
@ -313,7 +313,7 @@ SetPropertyHelper(JSContext *cx, JSObject *obj, PropertyName *name, unsigned def
|
|||
} /* namespace js */
|
||||
|
||||
extern JSBool
|
||||
js_SetElementHelper(JSContext *cx, JSObject *obj, uint32_t index, unsigned defineHow,
|
||||
js_SetElementHelper(JSContext *cx, js::HandleObject obj, uint32_t index, unsigned defineHow,
|
||||
js::Value *vp, JSBool strict);
|
||||
|
||||
extern JSBool
|
||||
|
@ -347,7 +347,7 @@ namespace js {
|
|||
|
||||
/* ES5 8.12.8. */
|
||||
extern JSBool
|
||||
DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp);
|
||||
DefaultValue(JSContext *cx, HandleObject obj, JSType hint, Value *vp);
|
||||
|
||||
extern Class ArrayClass;
|
||||
extern Class ArrayBufferClass;
|
||||
|
@ -739,7 +739,7 @@ struct JSObject : public js::ObjectImpl
|
|||
*/
|
||||
bool willBeSparseDenseArray(unsigned requiredCapacity, unsigned newElementsHint);
|
||||
|
||||
JSBool makeDenseArraySlow(JSContext *cx);
|
||||
static bool makeDenseArraySlow(JSContext *cx, js::HandleObject obj);
|
||||
|
||||
/*
|
||||
* If this array object has a data property with index i, set *vp to its
|
||||
|
@ -1180,7 +1180,7 @@ js_HasOwnPropertyHelper(JSContext *cx, js::LookupGenericOp lookup, unsigned argc
|
|||
js::Value *vp);
|
||||
|
||||
extern JSBool
|
||||
js_HasOwnProperty(JSContext *cx, js::LookupGenericOp lookup, JSObject *obj, jsid id,
|
||||
js_HasOwnProperty(JSContext *cx, js::LookupGenericOp lookup, js::HandleObject obj, jsid id,
|
||||
JSObject **objp, JSProperty **propp);
|
||||
|
||||
extern JSBool
|
||||
|
@ -1299,7 +1299,7 @@ extern const char js_lookupSetter_str[];
|
|||
#endif
|
||||
|
||||
extern JSBool
|
||||
js_PopulateObject(JSContext *cx, JSObject *newborn, JSObject *props);
|
||||
js_PopulateObject(JSContext *cx, js::HandleObject newborn, JSObject *props);
|
||||
|
||||
/*
|
||||
* Fast access to immutable standard objects (constructors and prototypes).
|
||||
|
@ -1319,11 +1319,11 @@ js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey key,
|
|||
// Specialized call for constructing |this| with a known function callee,
|
||||
// and a known prototype.
|
||||
extern JSObject *
|
||||
js_CreateThisForFunctionWithProto(JSContext *cx, JSObject *callee, JSObject *proto);
|
||||
js_CreateThisForFunctionWithProto(JSContext *cx, js::HandleObject callee, JSObject *proto);
|
||||
|
||||
// Specialized call for constructing |this| with a known function callee.
|
||||
extern JSObject *
|
||||
js_CreateThisForFunction(JSContext *cx, JSObject *callee, bool newType);
|
||||
js_CreateThisForFunction(JSContext *cx, js::HandleObject callee, bool newType);
|
||||
|
||||
// Generic call for constructing |this|.
|
||||
extern JSObject *
|
||||
|
@ -1342,7 +1342,7 @@ js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id,
|
|||
unsigned attrs, unsigned flags, int shortid);
|
||||
|
||||
extern JSBool
|
||||
js_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id,
|
||||
js_DefineOwnProperty(JSContext *cx, js::HandleObject obj, js::HandleId id,
|
||||
const js::Value &descriptor, JSBool *bp);
|
||||
|
||||
namespace js {
|
||||
|
@ -1361,12 +1361,12 @@ const unsigned DNP_SKIP_TYPE = 8; /* Don't update type information */
|
|||
* Return successfully added or changed shape or NULL on error.
|
||||
*/
|
||||
extern const Shape *
|
||||
DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &value,
|
||||
DefineNativeProperty(JSContext *cx, HandleObject obj, jsid id, const Value &value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
unsigned flags, int shortid, unsigned defineHow = 0);
|
||||
|
||||
inline const Shape *
|
||||
DefineNativeProperty(JSContext *cx, JSObject *obj, PropertyName *name, const Value &value,
|
||||
DefineNativeProperty(JSContext *cx, HandleObject obj, PropertyName *name, const Value &value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
unsigned flags, int shortid, unsigned defineHow = 0)
|
||||
{
|
||||
|
@ -1397,7 +1397,8 @@ LookupPropertyWithFlags(JSContext *cx, JSObject *obj, PropertyName *name, unsign
|
|||
* Otherwise, this reports an error and returns false.
|
||||
*/
|
||||
extern bool
|
||||
DefineProperty(JSContext *cx, JSObject *obj, const jsid &id, const PropDesc &desc, bool throwError,
|
||||
DefineProperty(JSContext *cx, js::HandleObject obj,
|
||||
js::HandleId id, const PropDesc &desc, bool throwError,
|
||||
bool *rval);
|
||||
|
||||
/*
|
||||
|
@ -1418,7 +1419,8 @@ static const unsigned RESOLVE_INFER = 0xffff;
|
|||
* If cacheResult is false, return JS_NO_PROP_CACHE_FILL on success.
|
||||
*/
|
||||
extern bool
|
||||
FindPropertyHelper(JSContext *cx, PropertyName *name, bool cacheResult, JSObject *scopeChain,
|
||||
FindPropertyHelper(JSContext *cx, HandlePropertyName name,
|
||||
bool cacheResult, HandleObject scopeChain,
|
||||
JSObject **objp, JSObject **pobjp, JSProperty **propp);
|
||||
|
||||
/*
|
||||
|
@ -1426,7 +1428,7 @@ FindPropertyHelper(JSContext *cx, PropertyName *name, bool cacheResult, JSObject
|
|||
* global object, per the global parameter.
|
||||
*/
|
||||
extern bool
|
||||
FindProperty(JSContext *cx, PropertyName *name, JSObject *scopeChain,
|
||||
FindProperty(JSContext *cx, HandlePropertyName name, HandleObject scopeChain,
|
||||
JSObject **objp, JSObject **pobjp, JSProperty **propp);
|
||||
|
||||
extern JSObject *
|
||||
|
@ -1457,19 +1459,19 @@ js_NativeSet(JSContext *cx, JSObject *obj, const js::Shape *shape, bool added,
|
|||
namespace js {
|
||||
|
||||
bool
|
||||
GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uint32_t getHow, Value *vp);
|
||||
GetPropertyHelper(JSContext *cx, HandleObject obj, jsid id, uint32_t getHow, Value *vp);
|
||||
|
||||
inline bool
|
||||
GetPropertyHelper(JSContext *cx, JSObject *obj, PropertyName *name, uint32_t getHow, Value *vp)
|
||||
GetPropertyHelper(JSContext *cx, HandleObject obj, PropertyName *name, uint32_t getHow, Value *vp)
|
||||
{
|
||||
return GetPropertyHelper(cx, obj, ATOM_TO_JSID(name), getHow, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, PropertyDescriptor *desc);
|
||||
GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, PropertyDescriptor *desc);
|
||||
|
||||
bool
|
||||
GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, Value *vp);
|
||||
GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, Value *vp);
|
||||
|
||||
bool
|
||||
NewPropertyDescriptorObject(JSContext *cx, const PropertyDescriptor *desc, Value *vp);
|
||||
|
@ -1477,12 +1479,12 @@ NewPropertyDescriptorObject(JSContext *cx, const PropertyDescriptor *desc, Value
|
|||
} /* namespace js */
|
||||
|
||||
extern JSBool
|
||||
js_GetMethod(JSContext *cx, JSObject *obj, jsid id, unsigned getHow, js::Value *vp);
|
||||
js_GetMethod(JSContext *cx, js::HandleObject obj, jsid id, unsigned getHow, js::Value *vp);
|
||||
|
||||
namespace js {
|
||||
|
||||
inline bool
|
||||
GetMethod(JSContext *cx, JSObject *obj, PropertyName *name, unsigned getHow, Value *vp)
|
||||
GetMethod(JSContext *cx, HandleObject obj, PropertyName *name, unsigned getHow, Value *vp)
|
||||
{
|
||||
return js_GetMethod(cx, obj, ATOM_TO_JSID(name), getHow, vp);
|
||||
}
|
||||
|
@ -1497,10 +1499,10 @@ namespace js {
|
|||
* called js_CheckForStringIndex.
|
||||
*/
|
||||
extern bool
|
||||
HasDataProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp);
|
||||
HasDataProperty(JSContext *cx, HandleObject obj, jsid id, Value *vp);
|
||||
|
||||
inline bool
|
||||
HasDataProperty(JSContext *cx, JSObject *obj, JSAtom *atom, Value *vp)
|
||||
HasDataProperty(JSContext *cx, HandleObject obj, JSAtom *atom, Value *vp)
|
||||
{
|
||||
return HasDataProperty(cx, obj, js_CheckForStringIndex(ATOM_TO_JSID(atom)), vp);
|
||||
}
|
||||
|
|
|
@ -96,7 +96,11 @@ inline bool
|
|||
JSObject::defaultValue(JSContext *cx, JSType hint, js::Value *vp)
|
||||
{
|
||||
JSConvertOp op = getClass()->convert;
|
||||
bool ok = (op == JS_ConvertStub ? js::DefaultValue : op)(cx, this, hint, vp);
|
||||
bool ok;
|
||||
if (op == JS_ConvertStub)
|
||||
ok = js::DefaultValue(cx, js::RootedVarObject(cx, this), hint, vp);
|
||||
else
|
||||
ok = op(cx, this, hint, vp);
|
||||
JS_ASSERT_IF(ok, vp->isPrimitive());
|
||||
return ok;
|
||||
}
|
||||
|
@ -120,7 +124,10 @@ JSObject::setGeneric(JSContext *cx, jsid id, js::Value *vp, JSBool strict)
|
|||
{
|
||||
if (getOps()->setGeneric)
|
||||
return nonNativeSetProperty(cx, id, vp, strict);
|
||||
return js_SetPropertyHelper(cx, this, id, 0, vp, strict);
|
||||
return js_SetPropertyHelper(cx,
|
||||
js::RootedVarObject(cx, this),
|
||||
js::RootedVarId(cx, id),
|
||||
0, vp, strict);
|
||||
}
|
||||
|
||||
inline JSBool
|
||||
|
@ -134,7 +141,7 @@ JSObject::setElement(JSContext *cx, uint32_t index, js::Value *vp, JSBool strict
|
|||
{
|
||||
if (getOps()->setElement)
|
||||
return nonNativeSetElement(cx, index, vp, strict);
|
||||
return js_SetElementHelper(cx, this, index, 0, vp, strict);
|
||||
return js_SetElementHelper(cx, js::RootedVarObject(cx, this), index, 0, vp, strict);
|
||||
}
|
||||
|
||||
inline JSBool
|
||||
|
@ -184,7 +191,7 @@ JSObject::getGeneric(JSContext *cx, JSObject *receiver, jsid id, js::Value *vp)
|
|||
if (!op(cx, this, receiver, id, vp))
|
||||
return false;
|
||||
} else {
|
||||
if (!js_GetProperty(cx, this, receiver, id, vp))
|
||||
if (!js_GetProperty(cx, js::RootedVarObject(cx, this), js::RootedVarObject(cx, receiver), id, vp))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -1535,11 +1542,11 @@ FindClassPrototype(JSContext *cx, JSObject *scope, JSProtoKey protoKey, JSObject
|
|||
* avoid losing creation site information for objects made by scripted 'new'.
|
||||
*/
|
||||
JSObject *
|
||||
NewObjectWithType(JSContext *cx, types::TypeObject *type, JSObject *parent, gc::AllocKind kind);
|
||||
NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc::AllocKind kind);
|
||||
|
||||
/* Make an object with pregenerated shape from a NEWOBJECT bytecode. */
|
||||
static inline JSObject *
|
||||
CopyInitializerObject(JSContext *cx, JSObject *baseobj)
|
||||
CopyInitializerObject(JSContext *cx, HandleObject baseobj)
|
||||
{
|
||||
JS_ASSERT(baseobj->getClass() == &ObjectClass);
|
||||
JS_ASSERT(!baseobj->inDictionaryMode());
|
||||
|
@ -1561,7 +1568,7 @@ CopyInitializerObject(JSContext *cx, JSObject *baseobj)
|
|||
}
|
||||
|
||||
JSObject *
|
||||
NewReshapedObject(JSContext *cx, js::types::TypeObject *type, JSObject *parent,
|
||||
NewReshapedObject(JSContext *cx, HandleTypeObject type, JSObject *parent,
|
||||
gc::AllocKind kind, const Shape *shape);
|
||||
|
||||
/*
|
||||
|
@ -1733,12 +1740,6 @@ js_InitClass(JSContext *cx, js::HandleObject obj, JSObject *parent_proto,
|
|||
JSObject **ctorp = NULL,
|
||||
js::gc::AllocKind ctorKind = JSFunction::FinalizeKind);
|
||||
|
||||
inline JSObject *
|
||||
js_GetProtoIfDenseArray(JSObject *obj)
|
||||
{
|
||||
return obj->isDenseArray() ? obj->getProto() : obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* js_PurgeScopeChain does nothing if obj is not itself a prototype or parent
|
||||
* scope, else it reshapes the scope and prototype chains it links. It calls
|
||||
|
|
|
@ -312,7 +312,7 @@ PreprocessValue(JSContext *cx, JSObject *holder, KeyType key, Value *vp, Stringi
|
|||
if (vp->isObject()) {
|
||||
Value toJSON;
|
||||
jsid id = ATOM_TO_JSID(cx->runtime->atomState.toJSONAtom);
|
||||
if (!js_GetMethod(cx, &vp->toObject(), id, 0, &toJSON))
|
||||
if (!js_GetMethod(cx, RootedVarObject(cx, &vp->toObject()), id, 0, &toJSON))
|
||||
return false;
|
||||
|
||||
if (js_IsCallable(toJSON)) {
|
||||
|
@ -745,7 +745,7 @@ js_Stringify(JSContext *cx, Value *vp, JSObject *replacer, Value space, StringBu
|
|||
}
|
||||
|
||||
/* Step 9. */
|
||||
JSObject *wrapper = NewBuiltinClassInstance(cx, &ObjectClass);
|
||||
RootedVarObject wrapper(cx, NewBuiltinClassInstance(cx, &ObjectClass));
|
||||
if (!wrapper)
|
||||
return false;
|
||||
|
||||
|
@ -783,7 +783,7 @@ Walk(JSContext *cx, JSObject *holder, jsid name, const Value &reviver, Value *vp
|
|||
|
||||
/* Step 2. */
|
||||
if (val.isObject()) {
|
||||
JSObject *obj = &val.toObject();
|
||||
RootedVarObject obj(cx, &val.toObject());
|
||||
|
||||
/* 'val' must have been produced by the JSON parser, so not a proxy. */
|
||||
JS_ASSERT(!obj->isProxy());
|
||||
|
|
|
@ -539,7 +539,8 @@ JSONParser::parse(Value *vp)
|
|||
* js_CheckForStringIndex.
|
||||
*/
|
||||
jsid propid = ATOM_TO_JSID(&valueStack.popCopy().toString()->asAtom());
|
||||
if (!DefineNativeProperty(cx, &valueStack.back().toObject(), propid, v,
|
||||
RootedVarObject obj(cx, &valueStack.back().toObject());
|
||||
if (!DefineNativeProperty(cx, obj, propid, v,
|
||||
JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE,
|
||||
0, 0))
|
||||
{
|
||||
|
|
|
@ -54,15 +54,6 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, unsigned scopeIndex, JSObject
|
|||
JS_ASSERT(this == &JS_PROPERTY_CACHE(cx));
|
||||
JS_ASSERT(!cx->runtime->gcRunning);
|
||||
|
||||
/*
|
||||
* Check for fill from js_SetPropertyHelper where the setter removed shape
|
||||
* from pobj (via unwatch or delete, e.g.).
|
||||
*/
|
||||
if (!pobj->nativeContains(cx, *shape)) {
|
||||
PCMETER(oddfills++);
|
||||
return JS_NO_PROP_CACHE_FILL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for overdeep scope and prototype chain. Because resolve, getter,
|
||||
* and setter hooks can change the prototype chain using JS_SetPrototype
|
||||
|
|
|
@ -270,8 +270,10 @@ ProxyHandler::keys(JSContext *cx, JSObject *proxy, AutoIdVector &props)
|
|||
}
|
||||
|
||||
bool
|
||||
ProxyHandler::iterate(JSContext *cx, JSObject *proxy, unsigned flags, Value *vp)
|
||||
ProxyHandler::iterate(JSContext *cx, JSObject *proxy_, unsigned flags, Value *vp)
|
||||
{
|
||||
RootedVarObject proxy(cx, proxy_);
|
||||
|
||||
JS_ASSERT(OperationInProgress(cx, proxy));
|
||||
AutoIdVector props(cx);
|
||||
if ((flags & JSITER_OWNONLY)
|
||||
|
@ -318,7 +320,7 @@ ProxyHandler::regexp_toShared(JSContext *cx, JSObject *proxy, RegExpGuard *g)
|
|||
bool
|
||||
ProxyHandler::defaultValue(JSContext *cx, JSObject *proxy, JSType hint, Value *vp)
|
||||
{
|
||||
return DefaultValue(cx, proxy, hint, vp);
|
||||
return DefaultValue(cx, RootedVarObject(cx, proxy), hint, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1756,7 +1758,8 @@ FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp)
|
|||
* number of fixed slots as the proxy so that we can swap their contents.
|
||||
*/
|
||||
gc::AllocKind kind = proxy->getAllocKind();
|
||||
JSObject *newborn = NewObjectWithGivenProto(cx, clasp, proto, parent, kind);
|
||||
RootedVarObject newborn(cx);
|
||||
newborn = NewObjectWithGivenProto(cx, clasp, proto, parent, kind);
|
||||
if (!newborn)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -129,6 +129,7 @@ class RegExpObjectBuilder;
|
|||
class RegExpShared;
|
||||
class RegExpStatics;
|
||||
class MatchPairs;
|
||||
class PropertyName;
|
||||
|
||||
namespace detail { class RegExpCode; }
|
||||
|
||||
|
@ -249,72 +250,23 @@ struct TypeCompartment;
|
|||
|
||||
} /* namespace types */
|
||||
|
||||
enum ThingRootKind
|
||||
{
|
||||
THING_ROOT_OBJECT,
|
||||
THING_ROOT_SHAPE,
|
||||
THING_ROOT_BASE_SHAPE,
|
||||
THING_ROOT_TYPE_OBJECT,
|
||||
THING_ROOT_STRING,
|
||||
THING_ROOT_SCRIPT,
|
||||
THING_ROOT_ID,
|
||||
THING_ROOT_VALUE,
|
||||
THING_ROOT_LIMIT
|
||||
};
|
||||
typedef JS::Handle<Shape*> HandleShape;
|
||||
typedef JS::Handle<BaseShape*> HandleBaseShape;
|
||||
typedef JS::Handle<types::TypeObject*> HandleTypeObject;
|
||||
typedef JS::Handle<JSAtom*> HandleAtom;
|
||||
typedef JS::Handle<PropertyName*> HandlePropertyName;
|
||||
|
||||
template <typename T> class Root;
|
||||
template <typename T> class RootedVar;
|
||||
typedef JS::Root<Shape*> RootShape;
|
||||
typedef JS::Root<BaseShape*> RootBaseShape;
|
||||
typedef JS::Root<types::TypeObject*> RootTypeObject;
|
||||
typedef JS::Root<JSAtom*> RootAtom;
|
||||
typedef JS::Root<PropertyName*> RootPropertyName;
|
||||
|
||||
template <typename T>
|
||||
struct RootMethods { };
|
||||
|
||||
/*
|
||||
* Reference to a stack location rooted for GC. See "Moving GC Stack Rooting"
|
||||
* comment in jscntxt.h.
|
||||
*/
|
||||
template <typename T>
|
||||
class Handle
|
||||
{
|
||||
public:
|
||||
/* Copy handles of different types, with implicit coercion. */
|
||||
template <typename S> Handle(Handle<S> handle) {
|
||||
testAssign<S>();
|
||||
ptr = reinterpret_cast<const T *>(handle.address());
|
||||
}
|
||||
|
||||
/* Get a handle from a rooted stack location, with implicit coercion. */
|
||||
template <typename S> inline Handle(const Root<S> &root);
|
||||
template <typename S> inline Handle(const RootedVar<S> &root);
|
||||
|
||||
const T *address() { return ptr; }
|
||||
|
||||
operator T () { return value(); }
|
||||
T operator ->() { return value(); }
|
||||
|
||||
private:
|
||||
const T *ptr;
|
||||
T value() { return *ptr; }
|
||||
|
||||
template <typename S>
|
||||
void testAssign() {
|
||||
#ifdef DEBUG
|
||||
T a = RootMethods<T>::initial();
|
||||
S b = RootMethods<S>::initial();
|
||||
a = b;
|
||||
(void)a;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
typedef Handle<JSObject*> HandleObject;
|
||||
typedef Handle<JSFunction*> HandleFunction;
|
||||
typedef Handle<Shape*> HandleShape;
|
||||
typedef Handle<BaseShape*> HandleBaseShape;
|
||||
typedef Handle<types::TypeObject*> HandleTypeObject;
|
||||
typedef Handle<JSString*> HandleString;
|
||||
typedef Handle<JSAtom*> HandleAtom;
|
||||
typedef Handle<jsid> HandleId;
|
||||
typedef Handle<Value> HandleValue;
|
||||
typedef JS::RootedVar<Shape*> RootedVarShape;
|
||||
typedef JS::RootedVar<BaseShape*> RootedVarBaseShape;
|
||||
typedef JS::RootedVar<types::TypeObject*> RootedVarTypeObject;
|
||||
typedef JS::RootedVar<JSAtom*> RootedVarAtom;
|
||||
typedef JS::RootedVar<PropertyName*> RootedVarPropertyName;
|
||||
|
||||
enum XDRMode {
|
||||
XDR_ENCODE,
|
||||
|
|
|
@ -244,4 +244,67 @@ typedef JSBool (*JSInitCallback)(void);
|
|||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace JS {
|
||||
|
||||
template <typename T>
|
||||
class Root;
|
||||
|
||||
class SkipRoot;
|
||||
|
||||
enum ThingRootKind
|
||||
{
|
||||
THING_ROOT_OBJECT,
|
||||
THING_ROOT_SHAPE,
|
||||
THING_ROOT_BASE_SHAPE,
|
||||
THING_ROOT_TYPE_OBJECT,
|
||||
THING_ROOT_STRING,
|
||||
THING_ROOT_SCRIPT,
|
||||
THING_ROOT_ID,
|
||||
THING_ROOT_VALUE,
|
||||
THING_ROOT_LIMIT
|
||||
};
|
||||
|
||||
struct ContextFriendFields {
|
||||
JSRuntime *const runtime;
|
||||
|
||||
ContextFriendFields(JSRuntime *rt)
|
||||
: runtime(rt) { }
|
||||
|
||||
static const ContextFriendFields *get(const JSContext *cx) {
|
||||
return reinterpret_cast<const ContextFriendFields *>(cx);
|
||||
}
|
||||
|
||||
static ContextFriendFields *get(JSContext *cx) {
|
||||
return reinterpret_cast<ContextFriendFields *>(cx);
|
||||
}
|
||||
|
||||
#ifdef JSGC_ROOT_ANALYSIS
|
||||
|
||||
/*
|
||||
* Stack allocated GC roots for stack GC heap pointers, which may be
|
||||
* overwritten if moved during a GC.
|
||||
*/
|
||||
Root<void*> *thingGCRooters[THING_ROOT_LIMIT];
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Stack allocated list of stack locations which hold non-relocatable
|
||||
* GC heap pointers (where the target is rooted somewhere else) or integer
|
||||
* values which may be confused for GC heap pointers. These are used to
|
||||
* suppress false positives which occur when a rooting analysis treats the
|
||||
* location as holding a relocatable pointer, but have no other effect on
|
||||
* GC behavior.
|
||||
*/
|
||||
SkipRoot *skipGCRooters;
|
||||
#endif
|
||||
|
||||
#endif /* JSGC_ROOT_ANALYSIS */
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* jspubtd_h___ */
|
||||
|
|
|
@ -179,7 +179,9 @@ class NodeBuilder
|
|||
: cx(c), saveLoc(l), src(s) {
|
||||
}
|
||||
|
||||
bool init(JSObject *userobj = NULL) {
|
||||
bool init(JSObject *userobj_ = NULL) {
|
||||
RootedVarObject userobj(cx, userobj_);
|
||||
|
||||
if (src) {
|
||||
if (!atomValue(src, &srcval))
|
||||
return false;
|
||||
|
@ -202,7 +204,10 @@ class NodeBuilder
|
|||
|
||||
const char *name = callbackNames[i];
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
if (!atom || !GetPropertyDefault(cx, userobj, ATOM_TO_JSID(atom), NullValue(), &funv))
|
||||
if (!atom)
|
||||
return false;
|
||||
RootedVarId id(cx, ATOM_TO_JSID(atom));
|
||||
if (!GetPropertyDefault(cx, userobj, id, NullValue(), &funv))
|
||||
return false;
|
||||
|
||||
if (funv.isNullOrUndefined()) {
|
||||
|
@ -3123,24 +3128,22 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp)
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSObject *config = &arg.toObject();
|
||||
RootedVarObject config(cx, &arg.toObject());
|
||||
|
||||
Value prop;
|
||||
|
||||
/* config.loc */
|
||||
if (!GetPropertyDefault(cx, config, ATOM_TO_JSID(cx->runtime->atomState.locAtom),
|
||||
BooleanValue(true), &prop)) {
|
||||
RootedVarId locId(cx, ATOM_TO_JSID(cx->runtime->atomState.locAtom));
|
||||
if (!GetPropertyDefault(cx, config, locId, BooleanValue(true), &prop))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
loc = js_ValueToBoolean(prop);
|
||||
|
||||
if (loc) {
|
||||
/* config.source */
|
||||
if (!GetPropertyDefault(cx, config, ATOM_TO_JSID(cx->runtime->atomState.sourceAtom),
|
||||
NullValue(), &prop)) {
|
||||
RootedVarId sourceId(cx, ATOM_TO_JSID(cx->runtime->atomState.sourceAtom));
|
||||
if (!GetPropertyDefault(cx, config, sourceId, NullValue(), &prop))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (!prop.isNullOrUndefined()) {
|
||||
JSString *str = ToString(cx, prop);
|
||||
|
@ -3159,18 +3162,17 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp)
|
|||
}
|
||||
|
||||
/* config.line */
|
||||
if (!GetPropertyDefault(cx, config, ATOM_TO_JSID(cx->runtime->atomState.lineAtom),
|
||||
Int32Value(1), &prop) ||
|
||||
RootedVarId lineId(cx, ATOM_TO_JSID(cx->runtime->atomState.lineAtom));
|
||||
if (!GetPropertyDefault(cx, config, lineId, Int32Value(1), &prop) ||
|
||||
!ToUint32(cx, prop, &lineno)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* config.builder */
|
||||
if (!GetPropertyDefault(cx, config, ATOM_TO_JSID(cx->runtime->atomState.builderAtom),
|
||||
NullValue(), &prop)) {
|
||||
RootedVarId builderId(cx, ATOM_TO_JSID(cx->runtime->atomState.builderAtom));
|
||||
if (!GetPropertyDefault(cx, config, builderId, NullValue(), &prop))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (!prop.isNullOrUndefined()) {
|
||||
if (!prop.isObject()) {
|
||||
|
|
|
@ -312,7 +312,7 @@ Shape::getChildBinding(JSContext *cx, const StackShape &child)
|
|||
|
||||
Shape *shape = JS_PROPERTY_TREE(cx).getChild(cx, this, numFixedSlots(), child);
|
||||
if (shape) {
|
||||
JS_ASSERT(shape->parent == this);
|
||||
//JS_ASSERT(shape->parent == this); // XXX 'this' is not rooted here
|
||||
|
||||
/*
|
||||
* Update the number of fixed slots which bindings of this shape will
|
||||
|
@ -520,12 +520,14 @@ JSObject::addProperty(JSContext *cx, jsid id,
|
|||
|
||||
NormalizeGetterAndSetter(cx, this, id, attrs, flags, getter, setter);
|
||||
|
||||
RootedVarObject self(cx, this);
|
||||
|
||||
Shape **spp = NULL;
|
||||
if (inDictionaryMode())
|
||||
spp = lastProperty()->table().search(id, true);
|
||||
|
||||
return addPropertyInternal(cx, id, getter, setter, slot, attrs, flags, shortid,
|
||||
spp, allowDictionary);
|
||||
return self->addPropertyInternal(cx, id, getter, setter, slot, attrs, flags, shortid,
|
||||
spp, allowDictionary);
|
||||
}
|
||||
|
||||
Shape *
|
||||
|
@ -551,7 +553,7 @@ JSObject::addPropertyInternal(JSContext *cx, jsid id,
|
|||
(!stableSlot || lastProperty()->entryCount() >= PropertyTree::MAX_HEIGHT)) {
|
||||
if (!toDictionaryMode(cx))
|
||||
return NULL;
|
||||
table = &lastProperty()->table();
|
||||
table = &self->lastProperty()->table();
|
||||
spp = table->search(id, true);
|
||||
}
|
||||
} else {
|
||||
|
@ -995,7 +997,7 @@ JSObject::replaceWithNewEquivalentShape(JSContext *cx, Shape *oldShape, Shape *n
|
|||
RootShape newRoot(cx, &newShape);
|
||||
if (!toDictionaryMode(cx))
|
||||
return NULL;
|
||||
oldShape = lastProperty();
|
||||
oldShape = self->lastProperty();
|
||||
}
|
||||
|
||||
if (!newShape) {
|
||||
|
@ -1022,7 +1024,7 @@ JSObject::replaceWithNewEquivalentShape(JSContext *cx, Shape *oldShape, Shape *n
|
|||
JS_ASSERT(newShape->parent == oldShape);
|
||||
oldShape->removeFromDictionary(self);
|
||||
|
||||
if (newShape == lastProperty())
|
||||
if (newShape == self->lastProperty())
|
||||
oldShape->handoffTableTo(newShape);
|
||||
|
||||
if (spp)
|
||||
|
@ -1269,7 +1271,7 @@ Bindings::setParent(JSContext *cx, JSObject *obj)
|
|||
* mark the stack value as non-relocatable for the stack root analysis.
|
||||
*/
|
||||
Bindings *self = this;
|
||||
CheckRoot root(cx, &self);
|
||||
SkipRoot root(cx, &self);
|
||||
|
||||
RootObject rootObj(cx, &obj);
|
||||
|
||||
|
@ -1320,6 +1322,9 @@ EmptyShape::getInitialShape(JSContext *cx, Class *clasp, JSObject *proto, JSObje
|
|||
if (p)
|
||||
return p->shape;
|
||||
|
||||
RootObject protoRoot(cx, &lookup.proto);
|
||||
RootObject parentRoot(cx, &lookup.parent);
|
||||
|
||||
RootedVar<UnownedBaseShape*> nbase(cx);
|
||||
|
||||
StackBaseShape base(clasp, parent, objectFlags);
|
||||
|
@ -1334,7 +1339,7 @@ EmptyShape::getInitialShape(JSContext *cx, Class *clasp, JSObject *proto, JSObje
|
|||
|
||||
InitialShapeEntry entry;
|
||||
entry.shape = shape;
|
||||
entry.proto = proto;
|
||||
entry.proto = lookup.proto;
|
||||
|
||||
if (!table.relookupOrAdd(p, lookup, entry))
|
||||
return NULL;
|
||||
|
|
|
@ -519,6 +519,10 @@ 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
|
||||
|
||||
inline void removeFromDictionary(JSObject *obj);
|
||||
inline void insertIntoDictionary(HeapPtrShape *dictp);
|
||||
|
||||
|
@ -1079,6 +1083,24 @@ 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)
|
||||
{
|
||||
if (start->hasTable()) {
|
||||
Shape **spp = start->table().search(id, false);
|
||||
return SHAPE_FETCH(spp);
|
||||
}
|
||||
|
||||
for (Shape *shape = start; shape; shape = shape->parent) {
|
||||
if (shape->propidRef() == id)
|
||||
return shape;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
} // namespace js
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
|
|
@ -103,7 +103,7 @@ Bindings::lookup(JSContext *cx, JSAtom *name, unsigned *indexp) const
|
|||
}
|
||||
|
||||
bool
|
||||
Bindings::add(JSContext *cx, JSAtom *name, BindingKind kind)
|
||||
Bindings::add(JSContext *cx, HandleAtom name, BindingKind kind)
|
||||
{
|
||||
if (!ensureShape(cx))
|
||||
return false;
|
||||
|
@ -492,10 +492,10 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
|
|||
continue;
|
||||
}
|
||||
|
||||
JSAtom *name;
|
||||
RootedVarAtom name(cx);
|
||||
if (mode == XDR_ENCODE)
|
||||
name = names[i];
|
||||
if (!XDRAtom(xdr, &name))
|
||||
if (!XDRAtom(xdr, name.address()))
|
||||
return false;
|
||||
if (mode == XDR_DECODE) {
|
||||
BindingKind kind = (i < nargs)
|
||||
|
|
|
@ -194,23 +194,23 @@ class Bindings
|
|||
* runtime, by calling an "add" method. All ARGUMENT bindings must be added
|
||||
* before before any VARIABLE or CONSTANT bindings.
|
||||
*/
|
||||
bool add(JSContext *cx, JSAtom *name, BindingKind kind);
|
||||
bool add(JSContext *cx, HandleAtom name, BindingKind kind);
|
||||
|
||||
/* Convenience specializations. */
|
||||
bool addVariable(JSContext *cx, JSAtom *name) {
|
||||
bool addVariable(JSContext *cx, HandleAtom name) {
|
||||
return add(cx, name, VARIABLE);
|
||||
}
|
||||
bool addConstant(JSContext *cx, JSAtom *name) {
|
||||
bool addConstant(JSContext *cx, HandleAtom name) {
|
||||
return add(cx, name, CONSTANT);
|
||||
}
|
||||
bool addArgument(JSContext *cx, JSAtom *name, uint16_t *slotp) {
|
||||
bool addArgument(JSContext *cx, HandleAtom name, uint16_t *slotp) {
|
||||
JS_ASSERT(name != NULL); /* not destructuring */
|
||||
*slotp = nargs;
|
||||
return add(cx, name, ARGUMENT);
|
||||
}
|
||||
bool addDestructuring(JSContext *cx, uint16_t *slotp) {
|
||||
*slotp = nargs;
|
||||
return add(cx, NULL, ARGUMENT);
|
||||
return add(cx, RootedVarAtom(cx), ARGUMENT);
|
||||
}
|
||||
|
||||
void noteDup() { hasDup_ = true; }
|
||||
|
|
125
js/src/jsstr.cpp
125
js/src/jsstr.cpp
|
@ -468,11 +468,11 @@ ThisToStringForStringProto(JSContext *cx, CallReceiver call)
|
|||
return call.thisv().toString();
|
||||
|
||||
if (call.thisv().isObject()) {
|
||||
JSObject *obj = &call.thisv().toObject();
|
||||
RootedVarObject obj(cx, &call.thisv().toObject());
|
||||
if (obj->isString() &&
|
||||
ClassMethodIsNative(cx, obj,
|
||||
&StringClass,
|
||||
ATOM_TO_JSID(cx->runtime->atomState.toStringAtom),
|
||||
RootedVarId(cx, ATOM_TO_JSID(cx->runtime->atomState.toStringAtom)),
|
||||
js_str_toString))
|
||||
{
|
||||
JSString *str = obj->asString().unbox();
|
||||
|
@ -1497,7 +1497,7 @@ class StringRegExpGuard
|
|||
return true;
|
||||
|
||||
/* Build RegExp from pattern string. */
|
||||
JSString *opt;
|
||||
RootedVarString opt(cx);
|
||||
if (optarg < args.length()) {
|
||||
opt = ToString(cx, args[optarg]);
|
||||
if (!opt)
|
||||
|
@ -1550,19 +1550,20 @@ static bool
|
|||
DoMatch(JSContext *cx, RegExpStatics *res, JSString *str, RegExpShared &re,
|
||||
DoMatchCallback callback, void *data, MatchControlFlags flags, Value *rval)
|
||||
{
|
||||
JSLinearString *linearStr = str->ensureLinear(cx);
|
||||
RootedVar<JSLinearString*> linearStr(cx, str->ensureLinear(cx));
|
||||
if (!linearStr)
|
||||
return false;
|
||||
|
||||
const jschar *chars = linearStr->chars();
|
||||
size_t length = linearStr->length();
|
||||
|
||||
if (re.global()) {
|
||||
RegExpExecType type = (flags & TEST_GLOBAL_BIT) ? RegExpTest : RegExpExec;
|
||||
for (size_t count = 0, i = 0, length = str->length(); i <= length; ++count) {
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx))
|
||||
return false;
|
||||
if (!ExecuteRegExp(cx, res, re, linearStr, chars, length, &i, type, rval))
|
||||
|
||||
const jschar *chars = linearStr->chars();
|
||||
size_t charsLen = linearStr->length();
|
||||
|
||||
if (!ExecuteRegExp(cx, res, re, linearStr, chars, charsLen, &i, type, rval))
|
||||
return false;
|
||||
if (!Matched(type, *rval))
|
||||
break;
|
||||
|
@ -1572,10 +1573,13 @@ DoMatch(JSContext *cx, RegExpStatics *res, JSString *str, RegExpShared &re,
|
|||
++i;
|
||||
}
|
||||
} else {
|
||||
const jschar *chars = linearStr->chars();
|
||||
size_t charsLen = linearStr->length();
|
||||
|
||||
RegExpExecType type = (flags & TEST_SINGLE_BIT) ? RegExpTest : RegExpExec;
|
||||
bool callbackOnSingle = !!(flags & CALLBACK_ON_SINGLE_BIT);
|
||||
size_t i = 0;
|
||||
if (!ExecuteRegExp(cx, res, re, linearStr, chars, length, &i, type, rval))
|
||||
if (!ExecuteRegExp(cx, res, re, linearStr, chars, charsLen, &i, type, rval))
|
||||
return false;
|
||||
if (callbackOnSingle && Matched(type, *rval) && !callback(cx, res, 0, data))
|
||||
return false;
|
||||
|
@ -1651,8 +1655,8 @@ js::str_match(JSContext *cx, unsigned argc, Value *vp)
|
|||
if (!g.normalizeRegExp(cx, false, 1, args))
|
||||
return false;
|
||||
|
||||
JSObject *array = NULL;
|
||||
MatchArgType arg = &array;
|
||||
RootedVarObject array(cx);
|
||||
MatchArgType arg = array.address();
|
||||
RegExpStatics *res = cx->regExpStatics();
|
||||
Value rval;
|
||||
if (!DoMatch(cx, res, str, g.regExp(), MatchCallback, arg, MATCH_ARGS, &rval))
|
||||
|
@ -1711,14 +1715,14 @@ js::str_search(JSContext *cx, unsigned argc, Value *vp)
|
|||
struct ReplaceData
|
||||
{
|
||||
ReplaceData(JSContext *cx)
|
||||
: sb(cx)
|
||||
: str(cx), lambda(cx), elembase(cx), repstr(cx), sb(cx)
|
||||
{}
|
||||
|
||||
JSString *str; /* 'this' parameter object as a string */
|
||||
RootedVarString str; /* 'this' parameter object as a string */
|
||||
StringRegExpGuard g; /* regexp parameter object and private data */
|
||||
JSObject *lambda; /* replacement function object or null */
|
||||
JSObject *elembase; /* object for function(a){return b[a]} replace */
|
||||
JSLinearString *repstr; /* replacement string */
|
||||
RootedVarObject lambda; /* replacement function object or null */
|
||||
RootedVarObject elembase; /* object for function(a){return b[a]} replace */
|
||||
RootedVar<JSLinearString*> repstr; /* replacement string */
|
||||
const jschar *dollar; /* null or pointer to first $ in repstr */
|
||||
const jschar *dollarEnd; /* limit pointer for js_strchr_limit */
|
||||
int leftIndex; /* left context index in str->chars */
|
||||
|
@ -1795,7 +1799,8 @@ InterpretDollar(JSContext *cx, RegExpStatics *res, const jschar *dp, const jscha
|
|||
static bool
|
||||
FindReplaceLength(JSContext *cx, RegExpStatics *res, ReplaceData &rdata, size_t *sizep)
|
||||
{
|
||||
if (JSObject *base = rdata.elembase) {
|
||||
RootedVarObject base(cx, rdata.elembase);
|
||||
if (base) {
|
||||
/*
|
||||
* The base object is used when replace was passed a lambda which looks like
|
||||
* 'function(a) { return b[a]; }' for the base object b. b will not change
|
||||
|
@ -1943,9 +1948,7 @@ ReplaceRegExpCallback(JSContext *cx, RegExpStatics *res, size_t count, void *p)
|
|||
ReplaceData &rdata = *static_cast<ReplaceData *>(p);
|
||||
|
||||
rdata.calledBack = true;
|
||||
JSLinearString &str = rdata.str->asLinear(); /* flattened for regexp */
|
||||
size_t leftoff = rdata.leftIndex;
|
||||
const jschar *left = str.chars() + leftoff;
|
||||
size_t leftlen = res->matchStart() - leftoff;
|
||||
rdata.leftIndex = res->matchLimit();
|
||||
|
||||
|
@ -1956,13 +1959,17 @@ ReplaceRegExpCallback(JSContext *cx, RegExpStatics *res, size_t count, void *p)
|
|||
size_t growth = leftlen + replen;
|
||||
if (!rdata.sb.reserve(rdata.sb.length() + growth))
|
||||
return false;
|
||||
|
||||
JSLinearString &str = rdata.str->asLinear(); /* flattened for regexp */
|
||||
const jschar *left = str.chars() + leftoff;
|
||||
|
||||
rdata.sb.infallibleAppend(left, leftlen); /* skipped-over portion of the search value */
|
||||
DoReplace(cx, res, rdata);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
BuildFlatReplacement(JSContext *cx, JSString *textstr, JSString *repstr,
|
||||
BuildFlatReplacement(JSContext *cx, HandleString textstr, HandleString repstr,
|
||||
const FlatMatch &fm, CallArgs *args)
|
||||
{
|
||||
RopeBuilder builder(cx);
|
||||
|
@ -1994,7 +2001,8 @@ BuildFlatReplacement(JSContext *cx, JSString *textstr, JSString *repstr,
|
|||
* the first character in the pattern, so we include the
|
||||
* replacement string here.
|
||||
*/
|
||||
JSString *leftSide = js_NewDependentString(cx, str, 0, match - pos);
|
||||
RootedVarString leftSide(cx);
|
||||
leftSide = js_NewDependentString(cx, str, 0, match - pos);
|
||||
if (!leftSide ||
|
||||
!builder.append(leftSide) ||
|
||||
!builder.append(repstr)) {
|
||||
|
@ -2007,13 +2015,14 @@ BuildFlatReplacement(JSContext *cx, JSString *textstr, JSString *repstr,
|
|||
* last part of str.
|
||||
*/
|
||||
if (strEnd > matchEnd) {
|
||||
JSString *rightSide = js_NewDependentString(cx, str, matchEnd - pos,
|
||||
strEnd - matchEnd);
|
||||
RootedVarString rightSide(cx);
|
||||
rightSide = js_NewDependentString(cx, str, matchEnd - pos,
|
||||
strEnd - matchEnd);
|
||||
if (!rightSide || !builder.append(rightSide))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!builder.append(str))
|
||||
if (!builder.append(RootedVarString(cx, str)))
|
||||
return false;
|
||||
}
|
||||
pos += str->length();
|
||||
|
@ -2021,11 +2030,13 @@ BuildFlatReplacement(JSContext *cx, JSString *textstr, JSString *repstr,
|
|||
return false;
|
||||
}
|
||||
} else {
|
||||
JSString *leftSide = js_NewDependentString(cx, textstr, 0, match);
|
||||
RootedVarString leftSide(cx);
|
||||
leftSide = js_NewDependentString(cx, textstr, 0, match);
|
||||
if (!leftSide)
|
||||
return false;
|
||||
JSString *rightSide = js_NewDependentString(cx, textstr, match + fm.patternLength(),
|
||||
textstr->length() - match - fm.patternLength());
|
||||
RootedVarString rightSide(cx);
|
||||
rightSide = js_NewDependentString(cx, textstr, match + fm.patternLength(),
|
||||
textstr->length() - match - fm.patternLength());
|
||||
if (!rightSide ||
|
||||
!builder.append(leftSide) ||
|
||||
!builder.append(repstr) ||
|
||||
|
@ -2101,15 +2112,15 @@ BuildDollarReplacement(JSContext *cx, JSString *textstrArg, JSLinearString *reps
|
|||
++it; /* We always eat an extra char in the above switch. */
|
||||
}
|
||||
|
||||
JSString *leftSide = js_NewDependentString(cx, textstr, 0, matchStart);
|
||||
RootedVarString leftSide(cx, js_NewDependentString(cx, textstr, 0, matchStart));
|
||||
ENSURE(leftSide);
|
||||
|
||||
JSString *newReplace = newReplaceChars.finishString();
|
||||
RootedVarString newReplace(cx, newReplaceChars.finishString());
|
||||
ENSURE(newReplace);
|
||||
|
||||
JS_ASSERT(textstr->length() >= matchLimit);
|
||||
JSString *rightSide = js_NewDependentString(cx, textstr, matchLimit,
|
||||
textstr->length() - matchLimit);
|
||||
RootedVarString rightSide(cx, js_NewDependentString(cx, textstr, matchLimit,
|
||||
textstr->length() - matchLimit));
|
||||
ENSURE(rightSide);
|
||||
|
||||
RopeBuilder builder(cx);
|
||||
|
@ -2183,17 +2194,17 @@ str_replace_flat_lambda(JSContext *cx, CallArgs outerArgs, ReplaceData &rdata, c
|
|||
if (!Invoke(cx, rdata.args))
|
||||
return false;
|
||||
|
||||
JSString *repstr = ToString(cx, args.rval());
|
||||
RootedVarString repstr(cx, ToString(cx, args.rval()));
|
||||
if (!repstr)
|
||||
return false;
|
||||
|
||||
JSString *leftSide = js_NewDependentString(cx, rdata.str, 0, fm.match());
|
||||
RootedVarString leftSide(cx, js_NewDependentString(cx, rdata.str, 0, fm.match()));
|
||||
if (!leftSide)
|
||||
return false;
|
||||
|
||||
size_t matchLimit = fm.match() + fm.patternLength();
|
||||
JSString *rightSide = js_NewDependentString(cx, rdata.str, matchLimit,
|
||||
rdata.str->length() - matchLimit);
|
||||
RootedVarString rightSide(cx, js_NewDependentString(cx, rdata.str, matchLimit,
|
||||
rdata.str->length() - matchLimit));
|
||||
if (!rightSide)
|
||||
return false;
|
||||
|
||||
|
@ -2382,7 +2393,7 @@ class SplitMatchResult {
|
|||
|
||||
template<class Matcher>
|
||||
static JSObject *
|
||||
SplitHelper(JSContext *cx, JSLinearString *str, uint32_t limit, Matcher splitMatch, TypeObject *type)
|
||||
SplitHelper(JSContext *cx, Handle<JSLinearString*> str, uint32_t limit, Matcher splitMatch, TypeObject *type)
|
||||
{
|
||||
size_t strLength = str->length();
|
||||
SplitMatchResult result;
|
||||
|
@ -2405,8 +2416,8 @@ SplitHelper(JSContext *cx, JSLinearString *str, uint32_t limit, Matcher splitMat
|
|||
if (!result.isFailure())
|
||||
return NewDenseEmptyArray(cx);
|
||||
|
||||
Value v = StringValue(str);
|
||||
return NewDenseCopiedArray(cx, 1, &v);
|
||||
RootedVarValue v(cx, StringValue(str));
|
||||
return NewDenseCopiedArray(cx, 1, v.address());
|
||||
}
|
||||
|
||||
/* Step 12. */
|
||||
|
@ -2544,14 +2555,12 @@ class SplitRegExpMatcher
|
|||
|
||||
class SplitStringMatcher
|
||||
{
|
||||
const jschar *sepChars;
|
||||
size_t sepLength;
|
||||
RootedVar<JSLinearString*> sep;
|
||||
|
||||
public:
|
||||
SplitStringMatcher(JSLinearString *sep) {
|
||||
sepChars = sep->chars();
|
||||
sepLength = sep->length();
|
||||
}
|
||||
SplitStringMatcher(JSContext *cx, JSLinearString *sep)
|
||||
: sep(cx, sep)
|
||||
{}
|
||||
|
||||
static const bool returnsCaptures = false;
|
||||
|
||||
|
@ -2559,11 +2568,12 @@ class SplitStringMatcher
|
|||
{
|
||||
JS_ASSERT(index == 0 || index < str->length());
|
||||
const jschar *chars = str->chars();
|
||||
int match = StringMatch(chars + index, str->length() - index, sepChars, sepLength);
|
||||
int match = StringMatch(chars + index, str->length() - index,
|
||||
sep->chars(), sep->length());
|
||||
if (match == -1)
|
||||
res->setFailure();
|
||||
else
|
||||
res->setResult(sepLength, index + match + sepLength);
|
||||
res->setResult(sep->length(), index + match + sep->length());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -2579,7 +2589,7 @@ js::str_split(JSContext *cx, unsigned argc, Value *vp)
|
|||
if (!str)
|
||||
return false;
|
||||
|
||||
TypeObject *type = GetTypeCallerInitObject(cx, JSProto_Array);
|
||||
RootedVarTypeObject type(cx, GetTypeCallerInitObject(cx, JSProto_Array));
|
||||
if (!type)
|
||||
return false;
|
||||
AddTypeProperty(cx, type, NULL, Type::StringType());
|
||||
|
@ -2630,14 +2640,14 @@ js::str_split(JSContext *cx, unsigned argc, Value *vp)
|
|||
args.rval() = ObjectValue(*aobj);
|
||||
return true;
|
||||
}
|
||||
JSLinearString *strlin = str->ensureLinear(cx);
|
||||
RootedVar<JSLinearString*> strlin(cx, str->ensureLinear(cx));
|
||||
if (!strlin)
|
||||
return false;
|
||||
|
||||
/* Steps 11-15. */
|
||||
JSObject *aobj;
|
||||
if (!re.initialized())
|
||||
aobj = SplitHelper(cx, strlin, limit, SplitStringMatcher(sepstr), type);
|
||||
aobj = SplitHelper(cx, strlin, limit, SplitStringMatcher(cx, sepstr), type);
|
||||
else
|
||||
aobj = SplitHelper(cx, strlin, limit, SplitRegExpMatcher(*re, cx->regExpStatics()), type);
|
||||
if (!aobj)
|
||||
|
@ -2705,12 +2715,12 @@ static JSBool
|
|||
str_concat(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JSString *str = ThisToStringForStringProto(cx, args);
|
||||
RootedVarString str(cx, ThisToStringForStringProto(cx, args));
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
for (unsigned i = 0; i < args.length(); i++) {
|
||||
JSString *argStr = ToString(cx, args[i]);
|
||||
RootedVarString argStr(cx, ToString(cx, args[i]));
|
||||
if (!argStr)
|
||||
return false;
|
||||
|
||||
|
@ -3012,7 +3022,7 @@ js_String(JSContext *cx, unsigned argc, Value *vp)
|
|||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
JSString *str;
|
||||
RootedVarString str(cx);
|
||||
if (args.length() > 0) {
|
||||
str = ToString(cx, args[0]);
|
||||
if (!str)
|
||||
|
@ -3090,14 +3100,15 @@ js_InitStringClass(JSContext *cx, JSObject *obj)
|
|||
{
|
||||
JS_ASSERT(obj->isNative());
|
||||
|
||||
GlobalObject *global = &obj->asGlobal();
|
||||
RootedVar<GlobalObject*> global(cx, &obj->asGlobal());
|
||||
|
||||
JSObject *proto = global->createBlankPrototype(cx, &StringClass);
|
||||
if (!proto || !proto->asString().init(cx, cx->runtime->emptyString))
|
||||
RootedVarObject proto(cx, global->createBlankPrototype(cx, &StringClass));
|
||||
if (!proto || !proto->asString().init(cx, RootedVarString(cx, cx->runtime->emptyString)))
|
||||
return NULL;
|
||||
|
||||
/* Now create the String function. */
|
||||
JSFunction *ctor = global->createConstructor(cx, js_String, CLASS_ATOM(cx, String), 1);
|
||||
RootedVarFunction ctor(cx);
|
||||
ctor = global->createConstructor(cx, js_String, CLASS_ATOM(cx, String), 1);
|
||||
if (!ctor)
|
||||
return NULL;
|
||||
|
||||
|
@ -3312,7 +3323,7 @@ js_ValueToSource(JSContext *cx, const Value &v)
|
|||
Value rval = NullValue();
|
||||
Value fval;
|
||||
jsid id = ATOM_TO_JSID(cx->runtime->atomState.toSourceAtom);
|
||||
if (!js_GetMethod(cx, &v.toObject(), id, 0, &fval))
|
||||
if (!js_GetMethod(cx, RootedVarObject(cx, &v.toObject()), id, 0, &fval))
|
||||
return NULL;
|
||||
if (js_IsCallable(fval)) {
|
||||
if (!Invoke(cx, v, fval, 0, NULL, &rval))
|
||||
|
|
|
@ -74,7 +74,7 @@ class RopeBuilder;
|
|||
} /* namespace js */
|
||||
|
||||
extern JSString * JS_FASTCALL
|
||||
js_ConcatStrings(JSContext *cx, JSString *s1, JSString *s2);
|
||||
js_ConcatStrings(JSContext *cx, js::HandleString s1, js::HandleString s2);
|
||||
|
||||
extern JSString * JS_FASTCALL
|
||||
js_toLowerCase(JSContext *cx, JSString *str);
|
||||
|
|
|
@ -53,17 +53,17 @@ namespace js {
|
|||
|
||||
class RopeBuilder {
|
||||
JSContext *cx;
|
||||
JSString *res;
|
||||
RootedVarString res;
|
||||
|
||||
RopeBuilder(const RopeBuilder &other) MOZ_DELETE;
|
||||
void operator=(const RopeBuilder &other) MOZ_DELETE;
|
||||
|
||||
public:
|
||||
RopeBuilder(JSContext *cx)
|
||||
: cx(cx), res(cx->runtime->emptyString)
|
||||
: cx(cx), res(cx, cx->runtime->emptyString)
|
||||
{}
|
||||
|
||||
inline bool append(JSString *str) {
|
||||
inline bool append(HandleString str) {
|
||||
res = js_ConcatStrings(cx, res, str);
|
||||
return !!res;
|
||||
}
|
||||
|
|
|
@ -473,10 +473,10 @@ ArrayBuffer::obj_getGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, js
|
|||
return true;
|
||||
}
|
||||
|
||||
JSObject *delegate = DelegateObject(cx, obj);
|
||||
RootedVarObject delegate(cx, DelegateObject(cx, obj));
|
||||
if (!delegate)
|
||||
return false;
|
||||
return js_GetProperty(cx, delegate, receiver, id, vp);
|
||||
return js_GetProperty(cx, delegate, RootedVarObject(cx, receiver), id, vp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
|
@ -489,19 +489,19 @@ ArrayBuffer::obj_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, P
|
|||
return true;
|
||||
}
|
||||
|
||||
JSObject *delegate = DelegateObject(cx, obj);
|
||||
RootedVarObject delegate(cx, DelegateObject(cx, obj));
|
||||
if (!delegate)
|
||||
return false;
|
||||
return js_GetProperty(cx, delegate, receiver, ATOM_TO_JSID(name), vp);
|
||||
return js_GetProperty(cx, delegate, RootedVarObject(cx, receiver), ATOM_TO_JSID(name), vp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
ArrayBuffer::obj_getElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index, Value *vp)
|
||||
{
|
||||
JSObject *delegate = DelegateObject(cx, getArrayBuffer(obj));
|
||||
RootedVarObject delegate(cx, DelegateObject(cx, getArrayBuffer(obj)));
|
||||
if (!delegate)
|
||||
return false;
|
||||
return js_GetElement(cx, delegate, receiver, index, vp);
|
||||
return js_GetElement(cx, delegate, RootedVarObject(cx, receiver), index, vp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
|
@ -526,6 +526,10 @@ ArrayBuffer::obj_setGeneric(JSContext *cx, JSObject *obj, jsid id, Value *vp, JS
|
|||
if (JSID_IS_ATOM(id, cx->runtime->atomState.byteLengthAtom))
|
||||
return true;
|
||||
|
||||
RootedVarObject delegate(cx, DelegateObject(cx, obj));
|
||||
if (!delegate)
|
||||
return false;
|
||||
|
||||
if (JSID_IS_ATOM(id, cx->runtime->atomState.protoAtom)) {
|
||||
// setting __proto__ = null
|
||||
// effectively removes the prototype chain.
|
||||
|
@ -545,9 +549,6 @@ ArrayBuffer::obj_setGeneric(JSContext *cx, JSObject *obj, jsid id, Value *vp, JS
|
|||
// and we don't modify our prototype chain
|
||||
// since obj_getProperty will fetch it as a plain
|
||||
// property from the delegate.
|
||||
JSObject *delegate = DelegateObject(cx, obj);
|
||||
if (!delegate)
|
||||
return false;
|
||||
|
||||
JSObject *oldDelegateProto = delegate->getProto();
|
||||
|
||||
|
@ -571,10 +572,6 @@ ArrayBuffer::obj_setGeneric(JSContext *cx, JSObject *obj, jsid id, Value *vp, JS
|
|||
return true;
|
||||
}
|
||||
|
||||
JSObject *delegate = DelegateObject(cx, obj);
|
||||
if (!delegate)
|
||||
return false;
|
||||
|
||||
return js_SetPropertyHelper(cx, delegate, id, 0, vp, strict);
|
||||
}
|
||||
|
||||
|
@ -587,7 +584,7 @@ ArrayBuffer::obj_setProperty(JSContext *cx, JSObject *obj, PropertyName *name, V
|
|||
JSBool
|
||||
ArrayBuffer::obj_setElement(JSContext *cx, JSObject *obj, uint32_t index, Value *vp, JSBool strict)
|
||||
{
|
||||
JSObject *delegate = DelegateObject(cx, obj);
|
||||
RootedVarObject delegate(cx, DelegateObject(cx, obj));
|
||||
if (!delegate)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ Wrapper::iterate(JSContext *cx, JSObject *wrapper, unsigned flags, Value *vp)
|
|||
{
|
||||
vp->setUndefined(); // default result if we refuse to perform this action
|
||||
const jsid id = JSID_VOID;
|
||||
GET(GetIterator(cx, wrappedObject(wrapper), flags, vp));
|
||||
GET(GetIterator(cx, RootedVarObject(cx, wrappedObject(wrapper)), flags, vp));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -366,7 +366,7 @@ Wrapper::defaultValue(JSContext *cx, JSObject *wrapper, JSType hint, Value *vp)
|
|||
bool
|
||||
Wrapper::iteratorNext(JSContext *cx, JSObject *wrapper, Value *vp)
|
||||
{
|
||||
if (!js_IteratorMore(cx, wrappedObject(wrapper), vp))
|
||||
if (!js_IteratorMore(cx, RootedVarObject(cx, wrappedObject(wrapper)), vp))
|
||||
return false;
|
||||
|
||||
if (vp->toBoolean()) {
|
||||
|
@ -692,8 +692,8 @@ Reify(JSContext *cx, JSCompartment *origin, Value *vp)
|
|||
AutoCloseIterator close(cx, iterObj);
|
||||
|
||||
/* Wrap the iteratee. */
|
||||
JSObject *obj = ni->obj;
|
||||
if (!origin->wrap(cx, &obj))
|
||||
RootedVarObject obj(cx, ni->obj);
|
||||
if (!origin->wrap(cx, obj.address()))
|
||||
return false;
|
||||
|
||||
/*
|
||||
|
|
|
@ -156,7 +156,7 @@ const char js_leftcurly_entity_str[] = "{";
|
|||
#define IS_STAR(str) ((str)->length() == 1 && *(str)->chars() == '*')
|
||||
|
||||
static JSBool
|
||||
GetXMLFunction(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
|
||||
GetXMLFunction(JSContext *cx, HandleObject obj, HandleId id, jsval *vp);
|
||||
|
||||
static JSBool
|
||||
IsDeclared(const JSObject *obj)
|
||||
|
@ -405,8 +405,8 @@ static JSString *
|
|||
ConvertQNameToString(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->isQName());
|
||||
JSString *uri = obj->getNameURI();
|
||||
JSString *str;
|
||||
RootedVarString uri(cx, obj->getNameURI());
|
||||
RootedVarString str(cx);
|
||||
if (!uri) {
|
||||
/* No uri means wildcard qualifier. */
|
||||
str = cx->runtime->atomState.starQualifierAtom;
|
||||
|
@ -414,12 +414,12 @@ ConvertQNameToString(JSContext *cx, JSObject *obj)
|
|||
/* Empty string for uri means localName is in no namespace. */
|
||||
str = cx->runtime->emptyString;
|
||||
} else {
|
||||
JSString *qualstr = cx->runtime->atomState.qualifierAtom;
|
||||
RootedVarString qualstr(cx, cx->runtime->atomState.qualifierAtom);
|
||||
str = js_ConcatStrings(cx, uri, qualstr);
|
||||
if (!str)
|
||||
return NULL;
|
||||
}
|
||||
str = js_ConcatStrings(cx, str, obj->getQNameLocalName());
|
||||
str = js_ConcatStrings(cx, str, RootedVarString(cx, obj->getQNameLocalName()));
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
|
@ -3765,13 +3765,15 @@ GetNamedProperty(JSContext *cx, JSXML *xml, JSObject* nameqn, JSXML *list)
|
|||
|
||||
/* ECMA-357 9.1.1.1 XML [[Get]] and 9.2.1.1 XMLList [[Get]]. */
|
||||
static JSBool
|
||||
GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
GetProperty(JSContext *cx, JSObject *obj_, jsid id_, jsval *vp)
|
||||
{
|
||||
JSXML *xml, *list, *kid;
|
||||
uint32_t index;
|
||||
JSObject *kidobj, *listobj;
|
||||
JSObject *nameqn;
|
||||
jsid funid;
|
||||
|
||||
RootedVarObject obj(cx, obj_);
|
||||
RootedVarId id(cx, id_);
|
||||
|
||||
if (!obj->isXML())
|
||||
return true;
|
||||
|
@ -3811,7 +3813,8 @@ GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
/*
|
||||
* ECMA-357 9.2.1.1/9.1.1.1 qname case.
|
||||
*/
|
||||
nameqn = ToXMLName(cx, IdToJsval(id), &funid);
|
||||
RootedVarId funid(cx);
|
||||
nameqn = ToXMLName(cx, IdToJsval(id), funid.address());
|
||||
if (!nameqn)
|
||||
return false;
|
||||
if (!JSID_IS_VOID(funid))
|
||||
|
@ -3880,18 +3883,21 @@ ResolveValue(JSContext *cx, JSXML *list, JSXML **result);
|
|||
|
||||
/* ECMA-357 9.1.1.2 XML [[Put]] and 9.2.1.2 XMLList [[Put]]. */
|
||||
static JSBool
|
||||
PutProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
||||
PutProperty(JSContext *cx, JSObject *obj_, jsid id_, JSBool strict, jsval *vp)
|
||||
{
|
||||
JSBool ok, primitiveAssign;
|
||||
enum { OBJ_ROOT, ID_ROOT, VAL_ROOT };
|
||||
JSXML *xml, *vxml, *rxml, *kid, *attr, *parent, *copy, *kid2, *match;
|
||||
JSObject *vobj, *nameobj, *attrobj, *parentobj, *kidobj, *copyobj;
|
||||
JSObject *vobj, *nameobj, *attrobj, *kidobj, *copyobj;
|
||||
JSObject *targetprop, *nameqn, *attrqn;
|
||||
uint32_t index, i, j, k, n, q, matchIndex;
|
||||
jsval attrval, nsval;
|
||||
jsid funid;
|
||||
JSObject *ns;
|
||||
|
||||
RootedVarObject obj(cx, obj_);
|
||||
RootedVarId id(cx, id_);
|
||||
|
||||
if (!obj->isXML())
|
||||
return JS_TRUE;
|
||||
xml = (JSXML *) obj->getPrivate();
|
||||
|
@ -4094,7 +4100,7 @@ PutProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
|||
|
||||
if (parent) {
|
||||
/* 2(e)(i). */
|
||||
parentobj = js_GetXMLObject(cx, parent);
|
||||
RootedVarObject parentobj(cx, js_GetXMLObject(cx, parent));
|
||||
if (!parentobj)
|
||||
goto bad;
|
||||
ok = PutProperty(cx, parentobj, id, strict, vp);
|
||||
|
@ -4302,16 +4308,16 @@ PutProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
|||
if (n == 0) {
|
||||
*vp = STRING_TO_JSVAL(cx->runtime->emptyString);
|
||||
} else {
|
||||
JSString *left = KidToString(cx, vxml, 0);
|
||||
RootedVarString left(cx, KidToString(cx, vxml, 0));
|
||||
if (!left)
|
||||
goto bad;
|
||||
|
||||
JSString *space = cx->runtime->atomState.spaceAtom;
|
||||
RootedVarString space(cx, cx->runtime->atomState.spaceAtom);
|
||||
for (i = 1; i < n; i++) {
|
||||
left = js_ConcatStrings(cx, left, space);
|
||||
if (!left)
|
||||
goto bad;
|
||||
JSString *right = KidToString(cx, vxml, i);
|
||||
RootedVarString right(cx, KidToString(cx, vxml, i));
|
||||
if (!right)
|
||||
goto bad;
|
||||
left = js_ConcatStrings(cx, left, right);
|
||||
|
@ -4527,7 +4533,6 @@ ResolveValue(JSContext *cx, JSXML *list, JSXML **result)
|
|||
{
|
||||
JSXML *target, *base;
|
||||
JSObject *targetprop;
|
||||
jsid id;
|
||||
jsval tv;
|
||||
|
||||
if (list->xml_class != JSXML_CLASS_LIST || list->xml_kids.length != 0) {
|
||||
|
@ -4558,7 +4563,7 @@ ResolveValue(JSContext *cx, JSXML *list, JSXML **result)
|
|||
if (!js_GetXMLObject(cx, base))
|
||||
return JS_FALSE;
|
||||
|
||||
id = OBJECT_TO_JSID(targetprop);
|
||||
RootedVarId id(cx, OBJECT_TO_JSID(targetprop));
|
||||
if (!GetProperty(cx, base->object, id, &tv))
|
||||
return JS_FALSE;
|
||||
target = (JSXML *) JSVAL_TO_OBJECT(tv)->getPrivate();
|
||||
|
@ -5212,7 +5217,7 @@ again:
|
|||
* 11.2.2.1 Step 3(d) onward.
|
||||
*/
|
||||
JSBool
|
||||
js_GetXMLMethod(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
js_GetXMLMethod(JSContext *cx, HandleObject obj, jsid id, Value *vp)
|
||||
{
|
||||
JS_ASSERT(obj->isXML());
|
||||
|
||||
|
@ -5224,7 +5229,7 @@ js_GetXMLMethod(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
|||
* local value as vp, we use a proper root here.
|
||||
*/
|
||||
AutoValueRooter tvr(cx);
|
||||
JSBool ok = GetXMLFunction(cx, obj, id, tvr.addr());
|
||||
JSBool ok = GetXMLFunction(cx, obj, RootedVarId(cx, id), tvr.addr());
|
||||
*vp = tvr.value();
|
||||
return ok;
|
||||
}
|
||||
|
@ -6337,7 +6342,8 @@ xml_normalize_helper(JSContext *cx, JSObject *obj, JSXML *xml)
|
|||
while (i + 1 < n &&
|
||||
(kid2 = XMLARRAY_MEMBER(&xml->xml_kids, i + 1, JSXML)) &&
|
||||
kid2->xml_class == JSXML_CLASS_TEXT) {
|
||||
str = js_ConcatStrings(cx, kid->xml_value, kid2->xml_value);
|
||||
str = js_ConcatStrings(cx, RootedVarString(cx, kid->xml_value),
|
||||
RootedVarString(cx, kid2->xml_value));
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
NormalizingDelete(cx, xml, i + 1);
|
||||
|
@ -6959,8 +6965,6 @@ xml_text(JSContext *cx, unsigned argc, jsval *vp)
|
|||
static JSString *
|
||||
xml_toString_helper(JSContext *cx, JSXML *xml)
|
||||
{
|
||||
JSString *str, *kidstr;
|
||||
|
||||
if (xml->xml_class == JSXML_CLASS_ATTRIBUTE ||
|
||||
xml->xml_class == JSXML_CLASS_TEXT) {
|
||||
return xml->xml_value;
|
||||
|
@ -6969,14 +6973,14 @@ xml_toString_helper(JSContext *cx, JSXML *xml)
|
|||
if (!HasSimpleContent(xml))
|
||||
return ToXMLString(cx, OBJECT_TO_JSVAL(xml->object), 0);
|
||||
|
||||
str = cx->runtime->emptyString;
|
||||
RootedVarString str(cx, cx->runtime->emptyString);
|
||||
if (!js_EnterLocalRootScope(cx))
|
||||
return NULL;
|
||||
JSXMLArrayCursor<JSXML> cursor(&xml->xml_kids);
|
||||
while (JSXML *kid = cursor.getNext()) {
|
||||
if (kid->xml_class != JSXML_CLASS_COMMENT &&
|
||||
kid->xml_class != JSXML_CLASS_PROCESSING_INSTRUCTION) {
|
||||
kidstr = xml_toString_helper(cx, kid);
|
||||
RootedVarString kidstr(cx, xml_toString_helper(cx, kid));
|
||||
if (!kidstr) {
|
||||
str = NULL;
|
||||
break;
|
||||
|
@ -7795,7 +7799,7 @@ js_FindXMLProperty(JSContext *cx, const Value &nameval, JSObject **objp, jsid *i
|
|||
}
|
||||
|
||||
static JSBool
|
||||
GetXMLFunction(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
GetXMLFunction(JSContext *cx, HandleObject obj, HandleId id, jsval *vp)
|
||||
{
|
||||
JS_ASSERT(obj->isXML());
|
||||
|
||||
|
@ -7803,7 +7807,7 @@ GetXMLFunction(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
* See comments before xml_lookupGeneric about the need for the proto
|
||||
* chain lookup.
|
||||
*/
|
||||
JSObject *target = obj;
|
||||
RootedVarObject target(cx, obj);
|
||||
for (;;) {
|
||||
if (!js_GetProperty(cx, target, id, vp))
|
||||
return false;
|
||||
|
|
|
@ -287,7 +287,7 @@ extern JSBool
|
|||
js_FindXMLProperty(JSContext *cx, const js::Value &nameval, JSObject **objp, jsid *idp);
|
||||
|
||||
extern JSBool
|
||||
js_GetXMLMethod(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
|
||||
js_GetXMLMethod(JSContext *cx, js::HandleObject obj, jsid id, js::Value *vp);
|
||||
|
||||
extern JSBool
|
||||
js_GetXMLDescendants(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
|
||||
|
|
|
@ -6535,7 +6535,7 @@ mjit::Compiler::jsop_newinit()
|
|||
{
|
||||
bool isArray;
|
||||
unsigned count = 0;
|
||||
JSObject *baseobj = NULL;
|
||||
RootedVarObject baseobj(cx);
|
||||
switch (*PC) {
|
||||
case JSOP_NEWINIT:
|
||||
isArray = (GET_UINT8(PC) == JSProto_Array);
|
||||
|
@ -6571,7 +6571,7 @@ mjit::Compiler::jsop_newinit()
|
|||
* Don't bake in types for non-compileAndGo scripts, or at initializers
|
||||
* producing objects with singleton types.
|
||||
*/
|
||||
types::TypeObject *type = NULL;
|
||||
RootedVarTypeObject type(cx);
|
||||
if (globalObj && !types::UseNewTypeForInitializer(cx, script, PC)) {
|
||||
type = types::TypeScript::InitObject(cx, script, PC,
|
||||
isArray ? JSProto_Array : JSProto_Object);
|
||||
|
@ -7008,7 +7008,7 @@ mjit::Compiler::constructThis()
|
|||
{
|
||||
JS_ASSERT(isConstructing);
|
||||
|
||||
JSFunction *fun = script->function();
|
||||
RootedVarFunction fun(cx, script->function());
|
||||
|
||||
do {
|
||||
if (!cx->typeInferenceEnabled() ||
|
||||
|
|
|
@ -641,7 +641,7 @@ stubs::CreateThis(VMFrame &f, JSObject *proto)
|
|||
{
|
||||
JSContext *cx = f.cx;
|
||||
StackFrame *fp = f.fp();
|
||||
JSObject *callee = &fp->callee();
|
||||
RootedVarObject callee(cx, &fp->callee());
|
||||
JSObject *obj = js_CreateThisForFunctionWithProto(cx, callee, proto);
|
||||
if (!obj)
|
||||
THROW();
|
||||
|
@ -903,7 +903,7 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
|
|||
break;
|
||||
|
||||
case REJOIN_THIS_PROTOTYPE: {
|
||||
JSObject *callee = &fp->callee();
|
||||
RootedVarObject callee(cx, &fp->callee());
|
||||
JSObject *proto = f.regs.sp[0].isObject() ? &f.regs.sp[0].toObject() : NULL;
|
||||
JSObject *obj = js_CreateThisForFunctionWithProto(cx, callee, proto);
|
||||
if (!obj)
|
||||
|
|
|
@ -695,13 +695,12 @@ struct GetPropHelper {
|
|||
// These fields are set in the constructor and describe a property lookup.
|
||||
JSContext *cx;
|
||||
JSObject *obj;
|
||||
PropertyName *name;
|
||||
RootedVarPropertyName name;
|
||||
IC ⁣
|
||||
VMFrame &f;
|
||||
|
||||
// These fields are set by |bind| and |lookup|. After a call to either
|
||||
// function, these are set exactly as they are in JSOP_GETPROP or JSOP_NAME.
|
||||
JSObject *aobj;
|
||||
JSObject *holder;
|
||||
JSProperty *prop;
|
||||
|
||||
|
@ -710,13 +709,13 @@ struct GetPropHelper {
|
|||
const Shape *shape;
|
||||
|
||||
GetPropHelper(JSContext *cx, JSObject *obj, PropertyName *name, IC &ic, VMFrame &f)
|
||||
: cx(cx), obj(obj), name(name), ic(ic), f(f), holder(NULL), prop(NULL), shape(NULL)
|
||||
: cx(cx), obj(obj), name(cx, name), ic(ic), f(f), holder(NULL), prop(NULL), shape(NULL)
|
||||
{ }
|
||||
|
||||
public:
|
||||
LookupStatus bind() {
|
||||
RecompilationMonitor monitor(cx);
|
||||
JSObject *scopeChain = cx->stack.currentScriptedScopeChain();
|
||||
RootedVarObject scopeChain(cx, cx->stack.currentScriptedScopeChain());
|
||||
if (js_CodeSpec[*f.pc()].format & JOF_GNAME)
|
||||
scopeChain = &scopeChain->global();
|
||||
if (!FindProperty(cx, name, scopeChain, &obj, &holder, &prop))
|
||||
|
@ -734,7 +733,9 @@ struct GetPropHelper {
|
|||
}
|
||||
|
||||
LookupStatus lookup() {
|
||||
JSObject *aobj = js_GetProtoIfDenseArray(obj);
|
||||
JSObject *aobj = obj;
|
||||
if (obj->isDenseArray())
|
||||
aobj = obj->getProto();
|
||||
if (!aobj->isNative())
|
||||
return ic.disable(f, "non-native");
|
||||
|
||||
|
@ -2380,8 +2381,7 @@ GetElementIC::update(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *
|
|||
/*
|
||||
* Only treat this as a GETPROP for non-numeric string identifiers. The
|
||||
* GETPROP IC assumes the id has already gone through filtering for string
|
||||
* indexes in the emitter, i.e. js_GetProtoIfDenseArray is only valid to
|
||||
* use when looking up non-integer identifiers.
|
||||
* indexes in the emitter.
|
||||
*/
|
||||
uint32_t dummy;
|
||||
if (v.isString() && JSID_IS_ATOM(id) && !JSID_TO_ATOM(id)->isIndex(&dummy))
|
||||
|
@ -2421,7 +2421,7 @@ ic::GetElement(VMFrame &f, ic::GetElementIC *ic)
|
|||
|
||||
RecompilationMonitor monitor(cx);
|
||||
|
||||
JSObject *obj = ValueToObject(cx, f.regs.sp[-2]);
|
||||
RootedVarObject obj(cx, ValueToObject(cx, f.regs.sp[-2]));
|
||||
if (!obj)
|
||||
THROW();
|
||||
|
||||
|
|
|
@ -216,11 +216,14 @@ stubs::ToId(VMFrame &f)
|
|||
}
|
||||
|
||||
void JS_FASTCALL
|
||||
stubs::ImplicitThis(VMFrame &f, PropertyName *name)
|
||||
stubs::ImplicitThis(VMFrame &f, PropertyName *name_)
|
||||
{
|
||||
RootedVarObject scopeObj(f.cx, f.cx->stack.currentScriptedScopeChain());
|
||||
RootedVarPropertyName name(f.cx, name_);
|
||||
|
||||
JSObject *obj, *obj2;
|
||||
JSProperty *prop;
|
||||
if (!FindPropertyHelper(f.cx, name, false, f.cx->stack.currentScriptedScopeChain(), &obj, &obj2, &prop))
|
||||
if (!FindPropertyHelper(f.cx, name, false, scopeObj, &obj, &obj2, &prop))
|
||||
THROW();
|
||||
|
||||
if (!ComputeImplicitThis(f.cx, obj, &f.regs.sp[0]))
|
||||
|
@ -316,9 +319,9 @@ stubs::Ursh(VMFrame &f)
|
|||
|
||||
template<JSBool strict>
|
||||
void JS_FASTCALL
|
||||
stubs::DefFun(VMFrame &f, JSFunction *fun)
|
||||
stubs::DefFun(VMFrame &f, JSFunction *fun_)
|
||||
{
|
||||
JSObject *obj2;
|
||||
RootedVarFunction fun(f.cx, fun_);
|
||||
|
||||
JSContext *cx = f.cx;
|
||||
StackFrame *fp = f.fp();
|
||||
|
@ -331,6 +334,7 @@ stubs::DefFun(VMFrame &f, JSFunction *fun)
|
|||
*/
|
||||
JSObject *obj = fun;
|
||||
|
||||
RootedVarObject obj2(f.cx);
|
||||
if (fun->isNullClosure()) {
|
||||
/*
|
||||
* Even a null closure needs a parent for principals finding.
|
||||
|
@ -620,7 +624,7 @@ stubs::Add(VMFrame &f)
|
|||
/* The string + string case is easily the hottest; try it first. */
|
||||
bool lIsString = lval.isString();
|
||||
bool rIsString = rval.isString();
|
||||
JSString *lstr, *rstr;
|
||||
RootedVarString lstr(cx), rstr(cx);
|
||||
if (lIsString && rIsString) {
|
||||
lstr = lval.toString();
|
||||
rstr = rval.toString();
|
||||
|
@ -924,7 +928,7 @@ stubs::NewInitObject(VMFrame &f, JSObject *baseobj)
|
|||
JSObject *obj;
|
||||
|
||||
if (baseobj) {
|
||||
obj = CopyInitializerObject(cx, baseobj);
|
||||
obj = CopyInitializerObject(cx, RootedVarObject(cx, baseobj));
|
||||
} else {
|
||||
gc::AllocKind kind = GuessObjectGCKind(0);
|
||||
obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
|
||||
|
@ -999,9 +1003,11 @@ stubs::RegExp(VMFrame &f, JSObject *regex)
|
|||
}
|
||||
|
||||
JSObject * JS_FASTCALL
|
||||
stubs::Lambda(VMFrame &f, JSFunction *fun)
|
||||
stubs::Lambda(VMFrame &f, JSFunction *fun_)
|
||||
{
|
||||
JSObject *parent;
|
||||
RootedVarFunction fun(f.cx, fun_);
|
||||
|
||||
RootedVarObject parent(f.cx);
|
||||
if (fun->isNullClosure()) {
|
||||
parent = &f.fp()->scopeChain();
|
||||
} else {
|
||||
|
@ -1072,7 +1078,7 @@ InitPropOrMethod(VMFrame &f, PropertyName *name, JSOp op)
|
|||
rval = regs.sp[-1];
|
||||
|
||||
/* Load the object being initialized into lval/obj. */
|
||||
JSObject *obj = ®s.sp[-2].toObject();
|
||||
RootedVarObject obj(cx, ®s.sp[-2].toObject());
|
||||
JS_ASSERT(obj->isNative());
|
||||
|
||||
/* Get the immediate property name into id. */
|
||||
|
@ -1113,7 +1119,7 @@ stubs::IterMore(VMFrame &f)
|
|||
|
||||
Value v;
|
||||
JSObject *iterobj = &f.regs.sp[-1].toObject();
|
||||
if (!js_IteratorMore(f.cx, iterobj, &v))
|
||||
if (!js_IteratorMore(f.cx, RootedVarObject(f.cx, iterobj), &v))
|
||||
THROWV(JS_FALSE);
|
||||
|
||||
return v.toBoolean();
|
||||
|
@ -1416,11 +1422,14 @@ stubs::Pos(VMFrame &f)
|
|||
}
|
||||
|
||||
void JS_FASTCALL
|
||||
stubs::DelName(VMFrame &f, PropertyName *name)
|
||||
stubs::DelName(VMFrame &f, PropertyName *name_)
|
||||
{
|
||||
RootedVarObject scopeObj(f.cx, f.cx->stack.currentScriptedScopeChain());
|
||||
RootedVarPropertyName name(f.cx, name_);
|
||||
|
||||
JSObject *obj, *obj2;
|
||||
JSProperty *prop;
|
||||
if (!FindProperty(f.cx, name, f.cx->stack.currentScriptedScopeChain(), &obj, &obj2, &prop))
|
||||
if (!FindProperty(f.cx, name, scopeObj, &obj, &obj2, &prop))
|
||||
THROW();
|
||||
|
||||
/* Strict mode code should never contain JSOP_DELNAME opcodes. */
|
||||
|
@ -1483,7 +1492,7 @@ stubs::DefVarOrConst(VMFrame &f, PropertyName *dn)
|
|||
|
||||
JSObject &obj = f.fp()->varObj();
|
||||
|
||||
if (!DefVarOrConstOperation(f.cx, obj, dn, attrs))
|
||||
if (!DefVarOrConstOperation(f.cx, RootedVarObject(f.cx, &obj), dn, attrs))
|
||||
THROW();
|
||||
}
|
||||
|
||||
|
|
|
@ -2742,7 +2742,7 @@ ShapeOf(JSContext *cx, unsigned argc, jsval *vp)
|
|||
* non-native referent may be simplified to data properties.
|
||||
*/
|
||||
static JSBool
|
||||
CopyProperty(JSContext *cx, JSObject *obj, JSObject *referent, jsid id,
|
||||
CopyProperty(JSContext *cx, JSObject *obj_, JSObject *referent, jsid id,
|
||||
unsigned lookupFlags, JSObject **objp)
|
||||
{
|
||||
JSProperty *prop;
|
||||
|
@ -2750,6 +2750,8 @@ CopyProperty(JSContext *cx, JSObject *obj, JSObject *referent, jsid id,
|
|||
unsigned propFlags = 0;
|
||||
JSObject *obj2;
|
||||
|
||||
RootedVarObject obj(cx, obj_);
|
||||
|
||||
*objp = NULL;
|
||||
if (referent->isNative()) {
|
||||
if (!LookupPropertyWithFlags(cx, referent, id, lookupFlags, &obj2, &prop))
|
||||
|
@ -4301,9 +4303,11 @@ global_enumerate(JSContext *cx, JSObject *obj)
|
|||
}
|
||||
|
||||
static JSBool
|
||||
global_resolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
|
||||
global_resolve(JSContext *cx, JSObject *obj_, jsid id, unsigned flags,
|
||||
JSObject **objp)
|
||||
{
|
||||
RootedVarObject obj(cx, obj_);
|
||||
|
||||
#ifdef LAZY_STANDARD_CLASSES
|
||||
JSBool resolved;
|
||||
|
||||
|
|
|
@ -86,11 +86,11 @@ js_PutArgsObject(StackFrame *fp)
|
|||
}
|
||||
|
||||
ArgumentsObject *
|
||||
ArgumentsObject::create(JSContext *cx, uint32_t argc, JSObject &callee)
|
||||
ArgumentsObject::create(JSContext *cx, uint32_t argc, HandleObject callee)
|
||||
{
|
||||
JS_ASSERT(argc <= StackSpace::ARGS_LENGTH_MAX);
|
||||
|
||||
JSObject *proto = callee.global().getOrCreateObjectPrototype(cx);
|
||||
RootedVarObject proto(cx, callee->global().getOrCreateObjectPrototype(cx));
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
|
@ -100,7 +100,7 @@ ArgumentsObject::create(JSContext *cx, uint32_t argc, JSObject &callee)
|
|||
if (!type)
|
||||
return NULL;
|
||||
|
||||
bool strict = callee.toFunction()->inStrictMode();
|
||||
bool strict = callee->toFunction()->inStrictMode();
|
||||
Class *clasp = strict ? &StrictArgumentsObjectClass : &NormalArgumentsObjectClass;
|
||||
|
||||
RootedVarShape emptyArgumentsShape(cx);
|
||||
|
@ -120,7 +120,7 @@ ArgumentsObject::create(JSContext *cx, uint32_t argc, JSObject &callee)
|
|||
if (!data)
|
||||
return NULL;
|
||||
|
||||
data->callee.init(ObjectValue(callee));
|
||||
data->callee.init(ObjectValue(*callee));
|
||||
for (HeapValue *vp = data->slots; vp != data->slots + argc; vp++)
|
||||
vp->init(UndefinedValue());
|
||||
data->deletedBits = (size_t *)(data->slots + argc);
|
||||
|
@ -149,7 +149,8 @@ ArgumentsObject::create(JSContext *cx, StackFrame *fp)
|
|||
{
|
||||
JS_ASSERT(fp->script()->needsArgsObj());
|
||||
|
||||
ArgumentsObject *argsobj = ArgumentsObject::create(cx, fp->numActualArgs(), fp->callee());
|
||||
ArgumentsObject *argsobj = ArgumentsObject::create(cx, fp->numActualArgs(),
|
||||
RootedVarObject(cx, &fp->callee()));
|
||||
if (!argsobj)
|
||||
return NULL;
|
||||
|
||||
|
@ -170,7 +171,7 @@ ArgumentsObject::create(JSContext *cx, StackFrame *fp)
|
|||
ArgumentsObject *
|
||||
ArgumentsObject::createUnexpected(JSContext *cx, StackFrame *fp)
|
||||
{
|
||||
ArgumentsObject *argsobj = create(cx, fp->numActualArgs(), fp->callee());
|
||||
ArgumentsObject *argsobj = create(cx, fp->numActualArgs(), RootedVarObject(cx, &fp->callee()));
|
||||
if (!argsobj)
|
||||
return NULL;
|
||||
|
||||
|
@ -275,31 +276,31 @@ args_resolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
|
|||
{
|
||||
*objp = NULL;
|
||||
|
||||
NormalArgumentsObject &argsobj = obj->asNormalArguments();
|
||||
RootedVar<NormalArgumentsObject*> argsobj(cx, &obj->asNormalArguments());
|
||||
|
||||
unsigned attrs = JSPROP_SHARED | JSPROP_SHADOWABLE;
|
||||
if (JSID_IS_INT(id)) {
|
||||
uint32_t arg = uint32_t(JSID_TO_INT(id));
|
||||
if (arg >= argsobj.initialLength() || argsobj.isElementDeleted(arg))
|
||||
if (arg >= argsobj->initialLength() || argsobj->isElementDeleted(arg))
|
||||
return true;
|
||||
|
||||
attrs |= JSPROP_ENUMERATE;
|
||||
} else if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
|
||||
if (argsobj.hasOverriddenLength())
|
||||
if (argsobj->hasOverriddenLength())
|
||||
return true;
|
||||
} else {
|
||||
if (!JSID_IS_ATOM(id, cx->runtime->atomState.calleeAtom))
|
||||
return true;
|
||||
|
||||
if (argsobj.callee().isMagic(JS_OVERWRITTEN_CALLEE))
|
||||
if (argsobj->callee().isMagic(JS_OVERWRITTEN_CALLEE))
|
||||
return true;
|
||||
}
|
||||
|
||||
Value undef = UndefinedValue();
|
||||
if (!js_DefineProperty(cx, &argsobj, id, &undef, ArgGetter, ArgSetter, attrs))
|
||||
if (!js_DefineProperty(cx, argsobj, id, &undef, ArgGetter, ArgSetter, attrs))
|
||||
return JS_FALSE;
|
||||
|
||||
*objp = &argsobj;
|
||||
*objp = argsobj;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -404,12 +405,13 @@ StrictArgSetter(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp)
|
|||
if (!obj->isStrictArguments())
|
||||
return true;
|
||||
|
||||
StrictArgumentsObject &argsobj = obj->asStrictArguments();
|
||||
RootedVar<StrictArgumentsObject*> argsobj(cx, &obj->asStrictArguments());
|
||||
RootId idRoot(cx, &id);
|
||||
|
||||
if (JSID_IS_INT(id)) {
|
||||
unsigned arg = unsigned(JSID_TO_INT(id));
|
||||
if (arg < argsobj.initialLength()) {
|
||||
argsobj.setElement(arg, *vp);
|
||||
if (arg < argsobj->initialLength()) {
|
||||
argsobj->setElement(arg, *vp);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
@ -423,8 +425,8 @@ StrictArgSetter(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp)
|
|||
* collect its value.
|
||||
*/
|
||||
AutoValueRooter tvr(cx);
|
||||
return js_DeleteGeneric(cx, &argsobj, id, tvr.addr(), strict) &&
|
||||
js_SetPropertyHelper(cx, &argsobj, id, 0, vp, strict);
|
||||
return js_DeleteGeneric(cx, argsobj, id, tvr.addr(), strict) &&
|
||||
js_SetPropertyHelper(cx, argsobj, id, 0, vp, strict);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
|
|
@ -138,7 +138,7 @@ class ArgumentsObject : public JSObject
|
|||
|
||||
void initInitialLength(uint32_t length);
|
||||
void initData(ArgumentsData *data);
|
||||
static ArgumentsObject *create(JSContext *cx, uint32_t argc, JSObject &callee);
|
||||
static ArgumentsObject *create(JSContext *cx, uint32_t argc, HandleObject callee);
|
||||
|
||||
public:
|
||||
static const uint32_t RESERVED_SLOTS = 3;
|
||||
|
|
|
@ -828,7 +828,7 @@ Debugger::newCompletionValue(JSContext *cx, JSTrapStatus status, Value value, Va
|
|||
}
|
||||
|
||||
/* Common tail for JSTRAP_RETURN and JSTRAP_THROW. */
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass);
|
||||
RootedVarObject obj(cx, NewBuiltinClassInstance(cx, &ObjectClass));
|
||||
if (!obj ||
|
||||
!wrapDebuggeeValue(cx, &value) ||
|
||||
!DefineNativeProperty(cx, obj, key, value, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
|
@ -904,7 +904,7 @@ Debugger::parseResumptionValue(AutoCompartment &ac, bool ok, const Value &rv, Va
|
|||
}
|
||||
|
||||
bool
|
||||
CallMethodIfPresent(JSContext *cx, JSObject *obj, const char *name, int argc, Value *argv,
|
||||
CallMethodIfPresent(JSContext *cx, HandleObject obj, const char *name, int argc, Value *argv,
|
||||
Value *rval)
|
||||
{
|
||||
rval->setUndefined();
|
||||
|
@ -1142,7 +1142,7 @@ Debugger::onTrap(JSContext *cx, Value *vp)
|
|||
if (!dbg->getScriptFrame(cx, fp, &argv[0]))
|
||||
return dbg->handleUncaughtException(ac, vp, false);
|
||||
Value rv;
|
||||
bool ok = CallMethodIfPresent(cx, bp->handler, "hit", 1, argv, &rv);
|
||||
bool ok = CallMethodIfPresent(cx, RootedVarObject(cx, bp->handler), "hit", 1, argv, &rv);
|
||||
JSTrapStatus st = dbg->parseResumptionValue(ac, ok, rv, vp, true);
|
||||
if (st != JSTRAP_CONTINUE)
|
||||
return st;
|
||||
|
@ -3172,7 +3172,7 @@ DebuggerFrame_getArguments(JSContext *cx, unsigned argc, Value *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
JSObject *argsobj;
|
||||
RootedVarObject argsobj(cx);
|
||||
if (fp->hasArgs()) {
|
||||
/* Create an arguments object. */
|
||||
RootedVar<GlobalObject*> global(cx);
|
||||
|
@ -3437,7 +3437,7 @@ DebuggerFrameEval(JSContext *cx, unsigned argc, Value *vp, EvalBindingsMode mode
|
|||
if (!ac.enter())
|
||||
return false;
|
||||
|
||||
Env *env = JS_GetFrameScopeChain(cx, Jsvalify(fp));
|
||||
RootedVar<Env*> env(cx, JS_GetFrameScopeChain(cx, Jsvalify(fp)));
|
||||
if (!env)
|
||||
return false;
|
||||
|
||||
|
@ -3564,7 +3564,7 @@ DebuggerObject_checkThis(JSContext *cx, const CallArgs &args, const char *fnname
|
|||
|
||||
#define THIS_DEBUGOBJECT_REFERENT(cx, argc, vp, fnname, args, obj) \
|
||||
CallArgs args = CallArgsFromVp(argc, vp); \
|
||||
JSObject *obj = DebuggerObject_checkThis(cx, args, fnname); \
|
||||
RootedVarObject obj(cx, DebuggerObject_checkThis(cx, args, fnname)); \
|
||||
if (!obj) \
|
||||
return false; \
|
||||
obj = (JSObject *) obj->getPrivate(); \
|
||||
|
@ -3572,7 +3572,7 @@ DebuggerObject_checkThis(JSContext *cx, const CallArgs &args, const char *fnname
|
|||
|
||||
#define THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, fnname, args, dbg, obj) \
|
||||
CallArgs args = CallArgsFromVp(argc, vp); \
|
||||
JSObject *obj = DebuggerObject_checkThis(cx, args, fnname); \
|
||||
RootedVarObject obj(cx, DebuggerObject_checkThis(cx, args, fnname)); \
|
||||
if (!obj) \
|
||||
return false; \
|
||||
Debugger *dbg = Debugger::fromChildJSObject(obj); \
|
||||
|
@ -3720,15 +3720,15 @@ DebuggerObject_getOwnPropertyDescriptor(JSContext *cx, unsigned argc, Value *vp)
|
|||
{
|
||||
THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "getOwnPropertyDescriptor", args, dbg, obj);
|
||||
|
||||
jsid id;
|
||||
if (!ValueToId(cx, argc >= 1 ? args[0] : UndefinedValue(), &id))
|
||||
RootedVarId id(cx);
|
||||
if (!ValueToId(cx, argc >= 1 ? args[0] : UndefinedValue(), id.address()))
|
||||
return false;
|
||||
|
||||
/* Bug: This can cause the debuggee to run! */
|
||||
AutoPropertyDescriptorRooter desc(cx);
|
||||
{
|
||||
AutoCompartment ac(cx, obj);
|
||||
if (!ac.enter() || !cx->compartment->wrapId(cx, &id))
|
||||
if (!ac.enter() || !cx->compartment->wrapId(cx, id.address()))
|
||||
return false;
|
||||
|
||||
ErrorCopier ec(ac, dbg->toJSObject());
|
||||
|
@ -3854,8 +3854,8 @@ DebuggerObject_defineProperty(JSContext *cx, unsigned argc, Value *vp)
|
|||
THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "defineProperty", args, dbg, obj);
|
||||
REQUIRE_ARGC("Debugger.Object.defineProperty", 2);
|
||||
|
||||
jsid id;
|
||||
if (!ValueToId(cx, args[0], &id))
|
||||
RootedVarId id(cx);
|
||||
if (!ValueToId(cx, args[0], id.address()))
|
||||
return JS_FALSE;
|
||||
|
||||
const Value &descval = args[1];
|
||||
|
@ -3870,7 +3870,7 @@ DebuggerObject_defineProperty(JSContext *cx, unsigned argc, Value *vp)
|
|||
|
||||
{
|
||||
AutoCompartment ac(cx, obj);
|
||||
if (!ac.enter() || !WrapIdAndPropDesc(cx, obj, &id, desc))
|
||||
if (!ac.enter() || !WrapIdAndPropDesc(cx, obj, id.address(), desc))
|
||||
return false;
|
||||
|
||||
ErrorCopier ec(ac, dbg->toJSObject());
|
||||
|
@ -3915,7 +3915,7 @@ DebuggerObject_defineProperties(JSContext *cx, unsigned argc, Value *vp)
|
|||
ErrorCopier ec(ac, dbg->toJSObject());
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
bool dummy;
|
||||
if (!DefineProperty(cx, obj, ids[i], descs[i], true, &dummy))
|
||||
if (!DefineProperty(cx, obj, RootedVarId(cx, ids[i]), descs[i], true, &dummy))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,6 +142,15 @@ js::ObjectImpl::nativeLookup(JSContext *cx, jsid id)
|
|||
return Shape::search(cx, lastProperty(), id, &spp);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
const Shape *
|
||||
js::ObjectImpl::nativeLookupNoAllocation(JSContext *cx, jsid id)
|
||||
{
|
||||
MOZ_ASSERT(isNative());
|
||||
return Shape::searchNoAllocation(cx, lastProperty(), id);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
js::ObjectImpl::markChildren(JSTracer *trc)
|
||||
{
|
||||
|
|
|
@ -747,6 +747,10 @@ class ObjectImpl : public gc::Cell
|
|||
|
||||
const Shape * nativeLookup(JSContext *cx, jsid id);
|
||||
|
||||
#ifdef DEBUG
|
||||
const Shape * nativeLookupNoAllocation(JSContext *cx, jsid id);
|
||||
#endif
|
||||
|
||||
inline Class *getClass() const;
|
||||
inline JSClass *getJSClass() const;
|
||||
inline bool hasClass(const Class *c) const;
|
||||
|
|
|
@ -60,7 +60,7 @@ JS_STATIC_ASSERT(StickyFlag == JSREG_STICKY);
|
|||
/* RegExpObjectBuilder */
|
||||
|
||||
RegExpObjectBuilder::RegExpObjectBuilder(JSContext *cx, RegExpObject *reobj)
|
||||
: cx(cx), reobj_(reobj)
|
||||
: cx(cx), reobj_(cx, reobj)
|
||||
{}
|
||||
|
||||
bool
|
||||
|
@ -93,7 +93,7 @@ RegExpObjectBuilder::getOrCreateClone(RegExpObject *proto)
|
|||
}
|
||||
|
||||
RegExpObject *
|
||||
RegExpObjectBuilder::build(JSAtom *source, RegExpShared &shared)
|
||||
RegExpObjectBuilder::build(HandleAtom source, RegExpShared &shared)
|
||||
{
|
||||
if (!getOrCreate())
|
||||
return NULL;
|
||||
|
@ -106,16 +106,16 @@ RegExpObjectBuilder::build(JSAtom *source, RegExpShared &shared)
|
|||
}
|
||||
|
||||
RegExpObject *
|
||||
RegExpObjectBuilder::build(JSAtom *source, RegExpFlag flags)
|
||||
RegExpObjectBuilder::build(HandleAtom source, RegExpFlag flags)
|
||||
{
|
||||
if (!getOrCreate())
|
||||
return NULL;
|
||||
|
||||
return reobj_->init(cx, source, flags) ? reobj_ : NULL;
|
||||
return reobj_->init(cx, source, flags) ? reobj_.raw() : NULL;
|
||||
}
|
||||
|
||||
RegExpObject *
|
||||
RegExpObjectBuilder::clone(RegExpObject *other, RegExpObject *proto)
|
||||
RegExpObjectBuilder::clone(Handle<RegExpObject *> other, Handle<RegExpObject *> proto)
|
||||
{
|
||||
if (!getOrCreateClone(proto))
|
||||
return NULL;
|
||||
|
@ -130,14 +130,14 @@ RegExpObjectBuilder::clone(RegExpObject *other, RegExpObject *proto)
|
|||
RegExpFlag staticsFlags = res->getFlags();
|
||||
if ((origFlags & staticsFlags) != staticsFlags) {
|
||||
RegExpFlag newFlags = RegExpFlag(origFlags | staticsFlags);
|
||||
return build(other->getSource(), newFlags);
|
||||
return build(RootedVar<JSLinearString*>(cx, other->getSource()), newFlags);
|
||||
}
|
||||
|
||||
RegExpGuard g;
|
||||
if (!other->getShared(cx, &g))
|
||||
return NULL;
|
||||
|
||||
return build(other->getSource(), *g);
|
||||
return build(RootedVarAtom(cx, other->getSource()), *g);
|
||||
}
|
||||
|
||||
/* MatchPairs */
|
||||
|
@ -373,7 +373,7 @@ RegExpObject *
|
|||
RegExpObject::createNoStatics(JSContext *cx, const jschar *chars, size_t length, RegExpFlag flags,
|
||||
TokenStream *tokenStream)
|
||||
{
|
||||
JSAtom *source = js_AtomizeChars(cx, chars, length);
|
||||
RootedVarAtom source(cx, js_AtomizeChars(cx, chars, length));
|
||||
if (!source)
|
||||
return NULL;
|
||||
|
||||
|
@ -381,7 +381,7 @@ RegExpObject::createNoStatics(JSContext *cx, const jschar *chars, size_t length,
|
|||
}
|
||||
|
||||
RegExpObject *
|
||||
RegExpObject::createNoStatics(JSContext *cx, JSAtom *source, RegExpFlag flags,
|
||||
RegExpObject::createNoStatics(JSContext *cx, HandleAtom source, RegExpFlag flags,
|
||||
TokenStream *tokenStream)
|
||||
{
|
||||
if (!RegExpCode::checkSyntax(cx, tokenStream, source))
|
||||
|
@ -415,6 +415,8 @@ RegExpObject::assignInitialShape(JSContext *cx)
|
|||
JS_STATIC_ASSERT(MULTILINE_FLAG_SLOT == IGNORE_CASE_FLAG_SLOT + 1);
|
||||
JS_STATIC_ASSERT(STICKY_FLAG_SLOT == MULTILINE_FLAG_SLOT + 1);
|
||||
|
||||
RootedVarObject self(cx, this);
|
||||
|
||||
/* The lastIndex property alone is writable but non-configurable. */
|
||||
if (!addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.lastIndexAtom),
|
||||
LAST_INDEX_SLOT, JSPROP_PERMANENT))
|
||||
|
@ -423,25 +425,27 @@ RegExpObject::assignInitialShape(JSContext *cx)
|
|||
}
|
||||
|
||||
/* Remaining instance properties are non-writable and non-configurable. */
|
||||
if (!addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.sourceAtom),
|
||||
SOURCE_SLOT, JSPROP_PERMANENT | JSPROP_READONLY) ||
|
||||
!addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.globalAtom),
|
||||
GLOBAL_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY) ||
|
||||
!addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.ignoreCaseAtom),
|
||||
IGNORE_CASE_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY) ||
|
||||
!addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.multilineAtom),
|
||||
MULTILINE_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY))
|
||||
if (!self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.sourceAtom),
|
||||
SOURCE_SLOT, JSPROP_PERMANENT | JSPROP_READONLY) ||
|
||||
!self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.globalAtom),
|
||||
GLOBAL_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY) ||
|
||||
!self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.ignoreCaseAtom),
|
||||
IGNORE_CASE_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY) ||
|
||||
!self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.multilineAtom),
|
||||
MULTILINE_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.stickyAtom),
|
||||
STICKY_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY);
|
||||
return self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.stickyAtom),
|
||||
STICKY_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY);
|
||||
}
|
||||
|
||||
inline bool
|
||||
RegExpObject::init(JSContext *cx, JSAtom *source, RegExpFlag flags)
|
||||
RegExpObject::init(JSContext *cx, HandleAtom source, RegExpFlag flags)
|
||||
{
|
||||
RootedVar<RegExpObject *> self(cx, this);
|
||||
|
||||
if (nativeEmpty()) {
|
||||
if (isDelegate()) {
|
||||
if (!assignInitialShape(cx))
|
||||
|
@ -450,33 +454,37 @@ RegExpObject::init(JSContext *cx, JSAtom *source, RegExpFlag flags)
|
|||
Shape *shape = assignInitialShape(cx);
|
||||
if (!shape)
|
||||
return false;
|
||||
EmptyShape::insertInitialShape(cx, shape, getProto());
|
||||
EmptyShape::insertInitialShape(cx, shape, self->getProto());
|
||||
}
|
||||
JS_ASSERT(!nativeEmpty());
|
||||
JS_ASSERT(!self->nativeEmpty());
|
||||
}
|
||||
|
||||
DebugOnly<JSAtomState *> atomState = &cx->runtime->atomState;
|
||||
JS_ASSERT(nativeLookup(cx, ATOM_TO_JSID(atomState->lastIndexAtom))->slot() == LAST_INDEX_SLOT);
|
||||
JS_ASSERT(nativeLookup(cx, ATOM_TO_JSID(atomState->sourceAtom))->slot() == SOURCE_SLOT);
|
||||
JS_ASSERT(nativeLookup(cx, ATOM_TO_JSID(atomState->globalAtom))->slot() == GLOBAL_FLAG_SLOT);
|
||||
JS_ASSERT(nativeLookup(cx, ATOM_TO_JSID(atomState->ignoreCaseAtom))->slot() ==
|
||||
IGNORE_CASE_FLAG_SLOT);
|
||||
JS_ASSERT(nativeLookup(cx, ATOM_TO_JSID(atomState->multilineAtom))->slot() ==
|
||||
MULTILINE_FLAG_SLOT);
|
||||
JS_ASSERT(nativeLookup(cx, ATOM_TO_JSID(atomState->stickyAtom))->slot() == STICKY_FLAG_SLOT);
|
||||
JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->lastIndexAtom))->slot() ==
|
||||
LAST_INDEX_SLOT);
|
||||
JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->sourceAtom))->slot() ==
|
||||
SOURCE_SLOT);
|
||||
JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->globalAtom))->slot() ==
|
||||
GLOBAL_FLAG_SLOT);
|
||||
JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->ignoreCaseAtom))->slot() ==
|
||||
IGNORE_CASE_FLAG_SLOT);
|
||||
JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->multilineAtom))->slot() ==
|
||||
MULTILINE_FLAG_SLOT);
|
||||
JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->stickyAtom))->slot() ==
|
||||
STICKY_FLAG_SLOT);
|
||||
|
||||
/*
|
||||
* If this is a re-initialization with an existing RegExpShared, 'flags'
|
||||
* may not match getShared()->flags, so forget the RegExpShared.
|
||||
*/
|
||||
JSObject::setPrivate(NULL);
|
||||
self->JSObject::setPrivate(NULL);
|
||||
|
||||
zeroLastIndex();
|
||||
setSource(source);
|
||||
setGlobal(flags & GlobalFlag);
|
||||
setIgnoreCase(flags & IgnoreCaseFlag);
|
||||
setMultiline(flags & MultilineFlag);
|
||||
setSticky(flags & StickyFlag);
|
||||
self->zeroLastIndex();
|
||||
self->setSource(source);
|
||||
self->setGlobal(flags & GlobalFlag);
|
||||
self->setIgnoreCase(flags & IgnoreCaseFlag);
|
||||
self->setMultiline(flags & MultilineFlag);
|
||||
self->setSticky(flags & StickyFlag);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -707,7 +715,8 @@ js::CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *proto)
|
|||
JS_ASSERT(proto->isRegExp());
|
||||
|
||||
RegExpObjectBuilder builder(cx);
|
||||
return builder.clone(&obj->asRegExp(), &proto->asRegExp());
|
||||
return builder.clone(RootedVar<RegExpObject*>(cx, &obj->asRegExp()),
|
||||
RootedVar<RegExpObject*>(cx, &proto->asRegExp()));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -751,7 +760,7 @@ template<XDRMode mode>
|
|||
bool
|
||||
js::XDRScriptRegExpObject(XDRState<mode> *xdr, HeapPtrObject *objp)
|
||||
{
|
||||
JSAtom *source = 0;
|
||||
RootedVarAtom source(xdr->cx());
|
||||
uint32_t flagsword = 0;
|
||||
|
||||
if (mode == XDR_ENCODE) {
|
||||
|
@ -760,7 +769,7 @@ js::XDRScriptRegExpObject(XDRState<mode> *xdr, HeapPtrObject *objp)
|
|||
source = reobj.getSource();
|
||||
flagsword = reobj.getFlags();
|
||||
}
|
||||
if (!XDRAtom(xdr, &source) || !xdr->codeUint32(&flagsword))
|
||||
if (!XDRAtom(xdr, source.address()) || !xdr->codeUint32(&flagsword))
|
||||
return false;
|
||||
if (mode == XDR_DECODE) {
|
||||
RegExpFlag flags = RegExpFlag(flagsword);
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include "jscntxt.h"
|
||||
#include "jsobj.h"
|
||||
|
||||
#include "js/TemplateLib.h"
|
||||
|
@ -87,8 +88,8 @@ enum RegExpRunStatus
|
|||
|
||||
class RegExpObjectBuilder
|
||||
{
|
||||
JSContext *cx;
|
||||
RegExpObject *reobj_;
|
||||
JSContext *cx;
|
||||
RootedVar<RegExpObject*> reobj_;
|
||||
|
||||
bool getOrCreate();
|
||||
bool getOrCreateClone(RegExpObject *proto);
|
||||
|
@ -98,11 +99,11 @@ class RegExpObjectBuilder
|
|||
|
||||
RegExpObject *reobj() { return reobj_; }
|
||||
|
||||
RegExpObject *build(JSAtom *source, RegExpFlag flags);
|
||||
RegExpObject *build(JSAtom *source, RegExpShared &shared);
|
||||
RegExpObject *build(HandleAtom source, RegExpFlag flags);
|
||||
RegExpObject *build(HandleAtom source, RegExpShared &shared);
|
||||
|
||||
/* Perform a VM-internal clone. */
|
||||
RegExpObject *clone(RegExpObject *other, RegExpObject *proto);
|
||||
RegExpObject *clone(Handle<RegExpObject*> other, Handle<RegExpObject*> proto);
|
||||
};
|
||||
|
||||
JSObject *
|
||||
|
@ -366,7 +367,7 @@ class RegExpObject : public JSObject
|
|||
TokenStream *ts);
|
||||
|
||||
static RegExpObject *
|
||||
createNoStatics(JSContext *cx, JSAtom *atom, RegExpFlag flags, TokenStream *ts);
|
||||
createNoStatics(JSContext *cx, HandleAtom atom, RegExpFlag flags, TokenStream *ts);
|
||||
|
||||
/*
|
||||
* Run the regular expression over the input text.
|
||||
|
@ -433,7 +434,7 @@ class RegExpObject : public JSObject
|
|||
*/
|
||||
Shape *assignInitialShape(JSContext *cx);
|
||||
|
||||
inline bool init(JSContext *cx, JSAtom *source, RegExpFlag flags);
|
||||
inline bool init(JSContext *cx, HandleAtom source, RegExpFlag flags);
|
||||
|
||||
/*
|
||||
* Precondition: the syntax for |source| has already been validated.
|
||||
|
|
|
@ -66,11 +66,12 @@ ScopeObject::enclosingScope() const
|
|||
}
|
||||
|
||||
inline bool
|
||||
ScopeObject::setEnclosingScope(JSContext *cx, JSObject &obj)
|
||||
ScopeObject::setEnclosingScope(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
if (!obj.setDelegate(cx))
|
||||
RootedVarObject self(cx, this);
|
||||
if (!obj->setDelegate(cx))
|
||||
return false;
|
||||
setFixedSlot(SCOPE_CHAIN_SLOT, ObjectValue(obj));
|
||||
self->setFixedSlot(SCOPE_CHAIN_SLOT, ObjectValue(*obj));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ js_PutCallObject(StackFrame *fp)
|
|||
* must be null.
|
||||
*/
|
||||
CallObject *
|
||||
CallObject::create(JSContext *cx, JSScript *script, JSObject &enclosing, JSObject *callee)
|
||||
CallObject::create(JSContext *cx, JSScript *script, HandleObject enclosing, HandleObject callee)
|
||||
{
|
||||
RootedVarShape shape(cx);
|
||||
shape = script->bindings.callObjectShape(cx);
|
||||
|
@ -159,7 +159,6 @@ CallObject::create(JSContext *cx, JSScript *script, JSObject &enclosing, JSObjec
|
|||
gc::AllocKind kind = gc::GetGCObjectKind(shape->numFixedSlots() + 1);
|
||||
|
||||
RootedVarTypeObject type(cx);
|
||||
|
||||
type = cx->compartment->getEmptyType(cx);
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
@ -168,7 +167,7 @@ CallObject::create(JSContext *cx, JSScript *script, JSObject &enclosing, JSObjec
|
|||
if (!PreallocateObjectDynamicSlots(cx, shape, &slots))
|
||||
return NULL;
|
||||
|
||||
JSObject *obj = JSObject::create(cx, kind, shape, type, slots);
|
||||
RootedVarObject obj(cx, JSObject::create(cx, kind, shape, type, slots));
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
|
@ -177,7 +176,7 @@ CallObject::create(JSContext *cx, JSScript *script, JSObject &enclosing, JSObjec
|
|||
* whose call objects do not have a consistent global variable and need
|
||||
* to be updated dynamically.
|
||||
*/
|
||||
JSObject &global = enclosing.global();
|
||||
JSObject &global = enclosing->global();
|
||||
if (&global != obj->getParent()) {
|
||||
JS_ASSERT(obj->getParent() == NULL);
|
||||
if (!obj->setParent(cx, &global))
|
||||
|
@ -205,8 +204,10 @@ CallObject::create(JSContext *cx, JSScript *script, JSObject &enclosing, JSObjec
|
|||
* If |bindings| is for a function that has extensible parents, that means
|
||||
* its Call should have its own shape; see BaseShape::extensibleParents.
|
||||
*/
|
||||
if (obj->lastProperty()->extensibleParents() && !obj->generateOwnShape(cx))
|
||||
return NULL;
|
||||
if (obj->lastProperty()->extensibleParents()) {
|
||||
if (!obj->generateOwnShape(cx))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &obj->asCall();
|
||||
}
|
||||
|
@ -217,7 +218,7 @@ CallObject::createForFunction(JSContext *cx, StackFrame *fp)
|
|||
JS_ASSERT(fp->isNonEvalFunctionFrame());
|
||||
JS_ASSERT(!fp->hasCallObj());
|
||||
|
||||
JSObject *scopeChain = &fp->scopeChain();
|
||||
RootedVarObject scopeChain(cx, &fp->scopeChain());
|
||||
JS_ASSERT_IF(scopeChain->isWith() || scopeChain->isBlock() || scopeChain->isCall(),
|
||||
scopeChain->getPrivate() != fp);
|
||||
|
||||
|
@ -237,7 +238,7 @@ CallObject::createForFunction(JSContext *cx, StackFrame *fp)
|
|||
}
|
||||
}
|
||||
|
||||
CallObject *callobj = create(cx, fp->script(), *scopeChain, &fp->callee());
|
||||
CallObject *callobj = create(cx, fp->script(), scopeChain, RootedVarObject(cx, &fp->callee()));
|
||||
if (!callobj)
|
||||
return NULL;
|
||||
|
||||
|
@ -249,7 +250,9 @@ CallObject::createForFunction(JSContext *cx, StackFrame *fp)
|
|||
CallObject *
|
||||
CallObject::createForStrictEval(JSContext *cx, StackFrame *fp)
|
||||
{
|
||||
CallObject *callobj = create(cx, fp->script(), fp->scopeChain(), NULL);
|
||||
CallObject *callobj = create(cx, fp->script(),
|
||||
RootedVarObject(cx, &fp->scopeChain()),
|
||||
RootedVarObject(cx));
|
||||
if (!callobj)
|
||||
return NULL;
|
||||
|
||||
|
@ -428,24 +431,24 @@ DeclEnvObject::create(JSContext *cx, StackFrame *fp)
|
|||
return NULL;
|
||||
|
||||
obj->setPrivate(fp);
|
||||
if (!obj->asScope().setEnclosingScope(cx, fp->scopeChain()))
|
||||
if (!obj->asScope().setEnclosingScope(cx, RootedVarObject(cx, &fp->scopeChain())))
|
||||
return NULL;
|
||||
|
||||
return &obj->asDeclEnv();
|
||||
}
|
||||
|
||||
WithObject *
|
||||
WithObject::create(JSContext *cx, StackFrame *fp, JSObject &proto, JSObject &enclosing,
|
||||
WithObject::create(JSContext *cx, StackFrame *fp, HandleObject proto, HandleObject enclosing,
|
||||
uint32_t depth)
|
||||
{
|
||||
RootedVarTypeObject type(cx);
|
||||
type = proto.getNewType(cx);
|
||||
type = proto->getNewType(cx);
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
RootedVarShape emptyWithShape(cx);
|
||||
emptyWithShape = EmptyShape::getInitialShape(cx, &WithClass, &proto,
|
||||
&enclosing.global(), FINALIZE_KIND);
|
||||
emptyWithShape = EmptyShape::getInitialShape(cx, &WithClass, proto,
|
||||
&enclosing->global(), FINALIZE_KIND);
|
||||
if (!emptyWithShape)
|
||||
return NULL;
|
||||
|
||||
|
@ -459,7 +462,7 @@ WithObject::create(JSContext *cx, StackFrame *fp, JSObject &proto, JSObject &enc
|
|||
obj->setReservedSlot(DEPTH_SLOT, PrivateUint32Value(depth));
|
||||
obj->setPrivate(js_FloatingFrameIfGenerator(cx, fp));
|
||||
|
||||
JSObject *thisp = proto.thisObject(cx);
|
||||
JSObject *thisp = proto->thisObject(cx);
|
||||
if (!thisp)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ class ScopeObject : public JSObject
|
|||
* enclosing scope of a ScopeObject is necessarily non-null.
|
||||
*/
|
||||
inline JSObject &enclosingScope() const;
|
||||
inline bool setEnclosingScope(JSContext *cx, JSObject &obj);
|
||||
inline bool setEnclosingScope(JSContext *cx, HandleObject obj);
|
||||
|
||||
/*
|
||||
* The stack frame for this scope object, if the frame is still active.
|
||||
|
@ -139,7 +139,7 @@ class CallObject : public ScopeObject
|
|||
static const uint32_t CALLEE_SLOT = 1;
|
||||
|
||||
static CallObject *
|
||||
create(JSContext *cx, JSScript *script, JSObject &enclosing, JSObject *callee);
|
||||
create(JSContext *cx, JSScript *script, HandleObject enclosing, HandleObject callee);
|
||||
|
||||
public:
|
||||
static const uint32_t RESERVED_SLOTS = 3;
|
||||
|
@ -219,7 +219,7 @@ class WithObject : public NestedScopeObject
|
|||
static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT4;
|
||||
|
||||
static WithObject *
|
||||
create(JSContext *cx, StackFrame *fp, JSObject &proto, JSObject &enclosing, uint32_t depth);
|
||||
create(JSContext *cx, StackFrame *fp, HandleObject proto, HandleObject enclosing, uint32_t depth);
|
||||
|
||||
/* Return object for the 'this' class hook. */
|
||||
JSObject &withThis() const;
|
||||
|
|
|
@ -117,7 +117,7 @@ JSRope::init(JSString *left, JSString *right, size_t length)
|
|||
}
|
||||
|
||||
JS_ALWAYS_INLINE JSRope *
|
||||
JSRope::new_(JSContext *cx, JSString *left, JSString *right, size_t length)
|
||||
JSRope::new_(JSContext *cx, js::HandleString left, js::HandleString right, size_t length)
|
||||
{
|
||||
if (!validateLength(cx, length))
|
||||
return NULL;
|
||||
|
@ -138,6 +138,7 @@ JSRope::markChildren(JSTracer *trc)
|
|||
JS_ALWAYS_INLINE void
|
||||
JSDependentString::init(JSLinearString *base, const jschar *chars, size_t length)
|
||||
{
|
||||
JS_ASSERT(!js::IsPoisonedPtr(base));
|
||||
d.lengthAndFlags = buildLengthAndFlags(length, DEPENDENT_BIT);
|
||||
d.u1.chars = chars;
|
||||
d.s.u2.base = base;
|
||||
|
@ -155,6 +156,15 @@ JSDependentString::new_(JSContext *cx, JSLinearString *base, const jschar *chars
|
|||
JS_ASSERT(chars >= base->chars() && chars < base->chars() + base->length());
|
||||
JS_ASSERT(length <= base->length() - (chars - base->chars()));
|
||||
|
||||
JS::Root<JSLinearString*> baseRoot(cx, &base);
|
||||
|
||||
/*
|
||||
* The characters may be an internal pointer to a GC thing, so prevent them
|
||||
* from being overwritten. For now this prevents strings used as dependent
|
||||
* bases of other strings from being moved by the GC.
|
||||
*/
|
||||
JS::SkipRoot charsRoot(cx, &chars);
|
||||
|
||||
JSDependentString *str = (JSDependentString *)js_NewGCString(cx);
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
|
|
@ -306,7 +306,7 @@ JSRope::flatten(JSContext *maybecx)
|
|||
}
|
||||
|
||||
JSString * JS_FASTCALL
|
||||
js_ConcatStrings(JSContext *cx, JSString *left, JSString *right)
|
||||
js_ConcatStrings(JSContext *cx, HandleString left, HandleString right)
|
||||
{
|
||||
JS_ASSERT_IF(!left->isAtom(), left->compartment() == cx->compartment);
|
||||
JS_ASSERT_IF(!right->isAtom(), right->compartment() == cx->compartment);
|
||||
|
|
|
@ -432,8 +432,8 @@ class JSRope : public JSString
|
|||
void init(JSString *left, JSString *right, size_t length);
|
||||
|
||||
public:
|
||||
static inline JSRope *new_(JSContext *cx, JSString *left,
|
||||
JSString *right, size_t length);
|
||||
static inline JSRope *new_(JSContext *cx, js::HandleString left,
|
||||
js::HandleString right, size_t length);
|
||||
|
||||
inline JSString *leftChild() const {
|
||||
JS_ASSERT(isRope());
|
||||
|
@ -498,6 +498,7 @@ class JSFlatString : public JSLinearString
|
|||
{
|
||||
friend class JSRope;
|
||||
void morphExtensibleIntoDependent(JSLinearString *base) {
|
||||
JS_ASSERT(!js::IsPoisonedPtr(base));
|
||||
d.lengthAndFlags = buildLengthAndFlags(length(), DEPENDENT_BIT);
|
||||
d.s.u2.base = base;
|
||||
}
|
||||
|
|
|
@ -53,10 +53,12 @@ JSObject::asString()
|
|||
namespace js {
|
||||
|
||||
inline bool
|
||||
StringObject::init(JSContext *cx, JSString *str)
|
||||
StringObject::init(JSContext *cx, HandleString str)
|
||||
{
|
||||
JS_ASSERT(gc::GetGCKindSlots(getAllocKind()) == 2);
|
||||
|
||||
RootedVar<StringObject *> self(cx, this);
|
||||
|
||||
if (nativeEmpty()) {
|
||||
if (isDelegate()) {
|
||||
if (!assignInitialShape(cx))
|
||||
|
@ -65,39 +67,40 @@ StringObject::init(JSContext *cx, JSString *str)
|
|||
Shape *shape = assignInitialShape(cx);
|
||||
if (!shape)
|
||||
return false;
|
||||
EmptyShape::insertInitialShape(cx, shape, getProto());
|
||||
EmptyShape::insertInitialShape(cx, shape, self->getProto());
|
||||
}
|
||||
}
|
||||
|
||||
JS_ASSERT(!nativeEmpty());
|
||||
JS_ASSERT(nativeLookup(cx, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom))->slot() == LENGTH_SLOT);
|
||||
JS_ASSERT(nativeLookupNoAllocation(cx, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom))->slot()
|
||||
== LENGTH_SLOT);
|
||||
|
||||
self->setStringThis(str);
|
||||
|
||||
setStringThis(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline StringObject *
|
||||
StringObject::create(JSContext *cx, JSString *str)
|
||||
StringObject::create(JSContext *cx, HandleString str)
|
||||
{
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, &StringClass);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
StringObject &strobj = obj->asString();
|
||||
if (!strobj.init(cx, str))
|
||||
RootedVar<StringObject*> strobj(cx, &obj->asString());
|
||||
if (!strobj->init(cx, str))
|
||||
return NULL;
|
||||
return &strobj;
|
||||
return strobj;
|
||||
}
|
||||
|
||||
inline StringObject *
|
||||
StringObject::createWithProto(JSContext *cx, JSString *str, JSObject &proto)
|
||||
StringObject::createWithProto(JSContext *cx, HandleString str, JSObject &proto)
|
||||
{
|
||||
JSObject *obj = NewObjectWithClassProto(cx, &StringClass, &proto, NULL);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
StringObject &strobj = obj->asString();
|
||||
if (!strobj.init(cx, str))
|
||||
RootedVar<StringObject*> strobj(cx, &obj->asString());
|
||||
if (!strobj->init(cx, str))
|
||||
return NULL;
|
||||
return &strobj;
|
||||
return strobj;
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
|
|
@ -60,13 +60,13 @@ class StringObject : public JSObject
|
|||
* Creates a new String object boxing the given string. The object's
|
||||
* [[Prototype]] is determined from context.
|
||||
*/
|
||||
static inline StringObject *create(JSContext *cx, JSString *str);
|
||||
static inline StringObject *create(JSContext *cx, HandleString str);
|
||||
|
||||
/*
|
||||
* Identical to create(), but uses |proto| as [[Prototype]]. This method
|
||||
* must not be used to create |String.prototype|.
|
||||
*/
|
||||
static inline StringObject *createWithProto(JSContext *cx, JSString *str, JSObject &proto);
|
||||
static inline StringObject *createWithProto(JSContext *cx, HandleString str, JSObject &proto);
|
||||
|
||||
JSString *unbox() const {
|
||||
return getFixedSlot(PRIMITIVE_VALUE_SLOT).toString();
|
||||
|
@ -81,7 +81,7 @@ class StringObject : public JSObject
|
|||
}
|
||||
|
||||
private:
|
||||
inline bool init(JSContext *cx, JSString *str);
|
||||
inline bool init(JSContext *cx, HandleString str);
|
||||
|
||||
void setStringThis(JSString *str) {
|
||||
JS_ASSERT(getReservedSlot(PRIMITIVE_VALUE_SLOT).isUndefined());
|
||||
|
|
Загрузка…
Ссылка в новой задаче