mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
bug 684529 - remove script object. r=jorendorff
This commit is contained in:
parent
45833dc0a5
commit
328fbe7fcc
@ -1643,7 +1643,7 @@ nsJSContext::ExecuteScript(void *aScriptObject,
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
|
||||
rv = sSecurityManager->GetObjectPrincipal(mContext,
|
||||
JS_GetObjectFromScript(script),
|
||||
JS_GetGlobalFromScript(script),
|
||||
getter_AddRefs(principal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -72,7 +72,7 @@ BytecodeCompiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame
|
||||
bool inDirectivePrologue;
|
||||
|
||||
JS_ASSERT(!(tcflags & ~(TCF_COMPILE_N_GO | TCF_NO_SCRIPT_RVAL | TCF_NEED_MUTABLE_SCRIPT |
|
||||
TCF_COMPILE_FOR_EVAL | TCF_NEED_SCRIPT_OBJECT)));
|
||||
TCF_COMPILE_FOR_EVAL | TCF_NEED_SCRIPT_GLOBAL)));
|
||||
|
||||
/*
|
||||
* The scripted callerFrame can only be given for compile-and-go scripts
|
||||
|
@ -275,7 +275,7 @@ struct StmtInfo {
|
||||
/*
|
||||
* The caller is JS_Compile*Script*.
|
||||
*/
|
||||
#define TCF_NEED_SCRIPT_OBJECT 0x40000000
|
||||
#define TCF_NEED_SCRIPT_GLOBAL 0x40000000
|
||||
|
||||
/*
|
||||
* Flags to check for return; vs. return expr; in a function.
|
||||
|
@ -1278,30 +1278,33 @@ JS_EnterCrossCompartmentCall(JSContext *cx, JSObject *target)
|
||||
return reinterpret_cast<JSCrossCompartmentCall *>(call);
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
// Declared in jscompartment.h
|
||||
JSClass js_dummy_class = {
|
||||
Class dummy_class = {
|
||||
"jdummy",
|
||||
JSCLASS_GLOBAL_FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
JS_ConvertStub, NULL,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
JS_ConvertStub
|
||||
};
|
||||
|
||||
} /*namespace js */
|
||||
|
||||
JS_PUBLIC_API(JSCrossCompartmentCall *)
|
||||
JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
JSObject *scriptObject = target->u.object;
|
||||
if (!scriptObject) {
|
||||
JS_ASSERT(!target->isCachedEval);
|
||||
GlobalObject *global = target->u.globalObject;
|
||||
if (!global) {
|
||||
SwitchToCompartment sc(cx, target->compartment());
|
||||
scriptObject = JS_NewGlobalObject(cx, &js_dummy_class);
|
||||
if (!scriptObject)
|
||||
global = GlobalObject::create(cx, &dummy_class);
|
||||
if (!global)
|
||||
return NULL;
|
||||
}
|
||||
return JS_EnterCrossCompartmentCall(cx, scriptObject);
|
||||
return JS_EnterCrossCompartmentCall(cx, global);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSCrossCompartmentCall *)
|
||||
@ -4582,7 +4585,7 @@ CompileUCScriptForPrincipalsCommon(JSContext *cx, JSObject *obj, JSPrincipals *p
|
||||
assertSameCompartment(cx, obj, principals);
|
||||
AutoLastFrameCheck lfc(cx);
|
||||
|
||||
uint32 tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT | TCF_NEED_SCRIPT_OBJECT;
|
||||
uint32 tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT | TCF_NEED_SCRIPT_GLOBAL;
|
||||
return BytecodeCompiler::compileScript(cx, obj, NULL, principals, tcflags, chars, length,
|
||||
filename, lineno, version);
|
||||
}
|
||||
@ -4759,7 +4762,7 @@ CompileFileHelper(JSContext *cx, JSObject *obj, JSPrincipals *principals,
|
||||
|
||||
JS_ASSERT(i <= len);
|
||||
len = i;
|
||||
uint32 tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT | TCF_NEED_SCRIPT_OBJECT;
|
||||
uint32 tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT | TCF_NEED_SCRIPT_GLOBAL;
|
||||
script = BytecodeCompiler::compileScript(cx, obj, NULL, principals, tcflags, buf, len,
|
||||
filename, 1, cx->findVersion());
|
||||
cx->free_(buf);
|
||||
@ -4820,11 +4823,12 @@ JS_CompileFileHandle(JSContext *cx, JSObject *obj, const char *filename, FILE *f
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_GetObjectFromScript(JSScript *script)
|
||||
JS_GetGlobalFromScript(JSScript *script)
|
||||
{
|
||||
JS_ASSERT(script->u.object);
|
||||
JS_ASSERT(!script->isCachedEval);
|
||||
JS_ASSERT(script->u.globalObject);
|
||||
|
||||
return script->u.object;
|
||||
return script->u.globalObject;
|
||||
}
|
||||
|
||||
static JSFunction *
|
||||
@ -5018,7 +5022,7 @@ EvaluateUCScriptForPrincipalsCommon(JSContext *cx, JSObject *obj,
|
||||
{
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
|
||||
uint32 flags = TCF_COMPILE_N_GO | TCF_NEED_SCRIPT_OBJECT;
|
||||
uint32 flags = TCF_COMPILE_N_GO | TCF_NEED_SCRIPT_GLOBAL;
|
||||
if (!rval)
|
||||
flags |= TCF_NO_SCRIPT_RVAL;
|
||||
|
||||
|
@ -3817,7 +3817,7 @@ JS_CompileFileHandleForPrincipalsVersion(JSContext *cx, JSObject *obj,
|
||||
JSVersion version);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_GetObjectFromScript(JSScript *script);
|
||||
JS_GetGlobalFromScript(JSScript *script);
|
||||
|
||||
extern JS_PUBLIC_API(JSFunction *)
|
||||
JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name,
|
||||
|
@ -208,8 +208,8 @@ class CompartmentChecker
|
||||
void check(JSScript *script) {
|
||||
if (script) {
|
||||
check(script->compartment());
|
||||
if (script->u.object)
|
||||
check(script->u.object);
|
||||
if (!script->isCachedEval && script->u.globalObject)
|
||||
check(script->u.globalObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
|
||||
if (vp->isObject()) {
|
||||
JSObject *obj = &vp->toObject();
|
||||
JS_ASSERT(obj->isCrossCompartmentWrapper());
|
||||
if (global->getJSClass() != &js_dummy_class && obj->getParent() != global) {
|
||||
if (global->getClass() != &dummy_class && obj->getParent() != global) {
|
||||
do {
|
||||
obj->setParent(global);
|
||||
obj = obj->getProto();
|
||||
@ -861,14 +861,11 @@ JSCompartment::getBreakpointSite(jsbytecode *pc)
|
||||
}
|
||||
|
||||
BreakpointSite *
|
||||
JSCompartment::getOrCreateBreakpointSite(JSContext *cx, JSScript *script, jsbytecode *pc, JSObject *scriptObject)
|
||||
JSCompartment::getOrCreateBreakpointSite(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
GlobalObject *scriptGlobal)
|
||||
{
|
||||
JS_ASSERT(script->code <= pc);
|
||||
JS_ASSERT(pc < script->code + script->length);
|
||||
JS_ASSERT_IF(scriptObject, scriptObject->isScript() || scriptObject->isFunction());
|
||||
JS_ASSERT_IF(scriptObject && scriptObject->isFunction(),
|
||||
scriptObject->getFunctionPrivate()->script() == script);
|
||||
JS_ASSERT_IF(scriptObject && scriptObject->isScript(), scriptObject->getScript() == script);
|
||||
|
||||
BreakpointSiteMap::AddPtr p = breakpointSites.lookupForAdd(pc);
|
||||
if (!p) {
|
||||
@ -880,10 +877,10 @@ JSCompartment::getOrCreateBreakpointSite(JSContext *cx, JSScript *script, jsbyte
|
||||
}
|
||||
|
||||
BreakpointSite *site = p->value;
|
||||
if (site->scriptObject)
|
||||
JS_ASSERT_IF(scriptObject, site->scriptObject == scriptObject);
|
||||
if (site->scriptGlobal)
|
||||
JS_ASSERT_IF(scriptGlobal, site->scriptGlobal == scriptGlobal);
|
||||
else
|
||||
site->scriptObject = scriptObject;
|
||||
site->scriptGlobal = scriptGlobal;
|
||||
|
||||
return site;
|
||||
}
|
||||
|
@ -293,10 +293,11 @@ struct TraceMonitor {
|
||||
namespace mjit {
|
||||
class JaegerCompartment;
|
||||
}
|
||||
}
|
||||
|
||||
/* Defined in jsapi.cpp */
|
||||
extern JSClass js_dummy_class;
|
||||
extern Class dummy_class;
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#ifndef JS_EVAL_CACHE_SHIFT
|
||||
# define JS_EVAL_CACHE_SHIFT 6
|
||||
@ -615,7 +616,7 @@ struct JS_FRIEND_API(JSCompartment) {
|
||||
|
||||
js::BreakpointSite *getBreakpointSite(jsbytecode *pc);
|
||||
js::BreakpointSite *getOrCreateBreakpointSite(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
JSObject *scriptObject);
|
||||
js::GlobalObject *scriptGlobal);
|
||||
void clearBreakpointsIn(JSContext *cx, js::Debugger *dbg, JSScript *script, JSObject *handler);
|
||||
void clearTraps(JSContext *cx, JSScript *script);
|
||||
bool markTrapClosuresIteratively(JSTracer *trc);
|
||||
|
@ -1049,9 +1049,6 @@ JS_GetScriptTotalSize(JSContext *cx, JSScript *script)
|
||||
JSPrincipals *principals;
|
||||
|
||||
nbytes = sizeof *script;
|
||||
if (script->u.object)
|
||||
nbytes += JS_GetObjectTotalSize(cx, script->u.object);
|
||||
|
||||
nbytes += script->length * sizeof script->code[0];
|
||||
nbytes += script->natoms * sizeof script->atoms[0];
|
||||
for (size_t i = 0; i < script->natoms; i++)
|
||||
|
@ -1558,6 +1558,7 @@ js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp)
|
||||
uint32 flagsword; /* word for argument count and fun->flags */
|
||||
|
||||
cx = xdr->cx;
|
||||
JSScript *script;
|
||||
if (xdr->mode == JSXDR_ENCODE) {
|
||||
fun = (*objp)->getFunctionPrivate();
|
||||
if (!fun->isInterpreted()) {
|
||||
@ -1570,12 +1571,14 @@ js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp)
|
||||
}
|
||||
firstword = (fun->u.i.skipmin << 2) | !!fun->atom;
|
||||
flagsword = (fun->nargs << 16) | fun->flags;
|
||||
script = fun->script();
|
||||
} else {
|
||||
fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, NULL, NULL);
|
||||
if (!fun)
|
||||
return false;
|
||||
fun->clearParent();
|
||||
fun->clearType();
|
||||
script = NULL;
|
||||
}
|
||||
|
||||
AutoObjectRooter tvr(cx, fun);
|
||||
@ -1587,28 +1590,20 @@ js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp)
|
||||
if (!JS_XDRUint32(xdr, &flagsword))
|
||||
return false;
|
||||
|
||||
if (!js_XDRScript(xdr, &script))
|
||||
return false;
|
||||
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
fun->nargs = flagsword >> 16;
|
||||
JS_ASSERT((flagsword & JSFUN_KINDMASK) >= JSFUN_INTERPRETED);
|
||||
fun->flags = uint16(flagsword);
|
||||
fun->u.i.skipmin = uint16(firstword >> 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't directly store into fun->u.i.script because we want this to happen
|
||||
* at the same time as we set the script's owner.
|
||||
*/
|
||||
JSScript *script = fun->script();
|
||||
if (!js_XDRScript(xdr, &script))
|
||||
return false;
|
||||
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
*objp = fun;
|
||||
fun->setScript(script);
|
||||
if (!fun->script()->typeSetFunction(cx, fun))
|
||||
if (!script->typeSetFunction(cx, fun))
|
||||
return false;
|
||||
JS_ASSERT(fun->nargs == fun->script()->bindings.countArgs());
|
||||
js_CallNewScriptHook(cx, fun->script(), fun);
|
||||
*objp = fun;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1674,10 +1669,8 @@ fun_trace(JSTracer *trc, JSObject *obj)
|
||||
if (fun->atom)
|
||||
MarkString(trc, fun->atom, "atom");
|
||||
|
||||
if (fun->isInterpreted() && fun->script()) {
|
||||
CheckScriptOwner(fun->script(), obj);
|
||||
if (fun->isInterpreted() && fun->script())
|
||||
MarkScript(trc, fun->script(), "script");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2421,19 +2414,18 @@ js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent,
|
||||
JS_ASSERT(script);
|
||||
JS_ASSERT(script->compartment() == fun->compartment());
|
||||
JS_ASSERT(script->compartment() != cx->compartment);
|
||||
JS_OPT_ASSERT(script->ownerObject == fun);
|
||||
|
||||
cfun->u.i.script_ = NULL;
|
||||
JSScript *cscript = js_CloneScript(cx, script);
|
||||
if (!cscript)
|
||||
return NULL;
|
||||
|
||||
cscript->u.globalObject = cfun->getGlobal();
|
||||
cfun->setScript(cscript);
|
||||
if (!cfun->script()->typeSetFunction(cx, cfun))
|
||||
if (!cscript->typeSetFunction(cx, cfun))
|
||||
return NULL;
|
||||
|
||||
js_CallNewScriptHook(cx, cfun->script(), cfun);
|
||||
Debugger::onNewScript(cx, cfun->script(), cfun, NULL);
|
||||
Debugger::onNewScript(cx, cfun->script(), NULL);
|
||||
}
|
||||
}
|
||||
return clone;
|
||||
|
@ -203,10 +203,9 @@ struct JSFunction : public JSObject_Slots2
|
||||
void setScript(JSScript *script) {
|
||||
JS_ASSERT(isInterpreted());
|
||||
u.i.script_ = script;
|
||||
script->setOwnerObject(this);
|
||||
}
|
||||
|
||||
JSScript * maybeScript() const {
|
||||
JSScript *maybeScript() const {
|
||||
return isInterpreted() ? script() : NULL;
|
||||
}
|
||||
|
||||
|
@ -832,8 +832,8 @@ MarkChildren(JSTracer *trc, JSScript *script)
|
||||
MarkValueRange(trc, constarray->length, constarray->vector, "consts");
|
||||
}
|
||||
|
||||
if (!script->isCachedEval && script->u.object)
|
||||
MarkObject(trc, *script->u.object, "object");
|
||||
if (!script->isCachedEval && script->u.globalObject)
|
||||
MarkObject(trc, *script->u.globalObject, "object");
|
||||
|
||||
if (IS_GC_MARKING_TRACER(trc) && script->filename)
|
||||
js_MarkScriptFilename(script->filename);
|
||||
|
@ -1126,7 +1126,6 @@ class EvalScriptGuard
|
||||
void setNewScript(JSScript *script) {
|
||||
/* NewScriptFromCG has already called js_CallNewScriptHook. */
|
||||
JS_ASSERT(!script_ && script);
|
||||
script->setOwnerObject(JS_CACHED_SCRIPT);
|
||||
script_ = script;
|
||||
script_->isActiveEval = true;
|
||||
}
|
||||
@ -6751,25 +6750,21 @@ js_GetClassPrototype(JSContext *cx, JSObject *scopeobj, JSProtoKey protoKey,
|
||||
JS_ASSERT(protoKey < JSProto_LIMIT);
|
||||
|
||||
if (protoKey != JSProto_Null) {
|
||||
if (!scopeobj) {
|
||||
if (cx->hasfp())
|
||||
scopeobj = &cx->fp()->scopeChain();
|
||||
if (!scopeobj) {
|
||||
scopeobj = cx->globalObject;
|
||||
if (!scopeobj) {
|
||||
*protop = NULL;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
scopeobj = scopeobj->getGlobal();
|
||||
if (scopeobj->isGlobal()) {
|
||||
const Value &v = scopeobj->getReservedSlot(JSProto_LIMIT + protoKey);
|
||||
if (v.isObject()) {
|
||||
*protop = &v.toObject();
|
||||
GlobalObject *global;
|
||||
if (scopeobj) {
|
||||
global = scopeobj->getGlobal();
|
||||
} else {
|
||||
global = GetCurrentGlobal(cx);
|
||||
if (!global) {
|
||||
*protop = NULL;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
const Value &v = global->getReservedSlot(JSProto_LIMIT + protoKey);
|
||||
if (v.isObject()) {
|
||||
*protop = &v.toObject();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return FindClassPrototype(cx, scopeobj, protoKey, protop, clasp);
|
||||
|
@ -1184,12 +1184,6 @@ struct JSObject : js::gc::Cell {
|
||||
inline js::NativeIterator *getNativeIterator() const;
|
||||
inline void setNativeIterator(js::NativeIterator *);
|
||||
|
||||
/*
|
||||
* Script-related getters.
|
||||
*/
|
||||
|
||||
inline JSScript *getScript() const;
|
||||
|
||||
/*
|
||||
* XML-related getters and setters.
|
||||
*/
|
||||
@ -1465,7 +1459,6 @@ struct JSObject : js::gc::Cell {
|
||||
inline bool isCall() const { return clasp == &js::CallClass; }
|
||||
inline bool isDeclEnv() const { return clasp == &js::DeclEnvClass; }
|
||||
inline bool isRegExp() const { return clasp == &js::RegExpClass; }
|
||||
inline bool isScript() const { return clasp == &js::ScriptClass; }
|
||||
inline bool isGenerator() const { return clasp == &js::GeneratorClass; }
|
||||
inline bool isIterator() const { return clasp == &js::IteratorClass; }
|
||||
inline bool isStopIteration() const { return clasp == &js::StopIterationClass; }
|
||||
|
@ -1472,6 +1472,13 @@ NewNativeClassInstance(JSContext *cx, Class *clasp, JSObject *proto, JSObject *p
|
||||
return NewNativeClassInstance(cx, clasp, proto, parent, kind);
|
||||
}
|
||||
|
||||
inline GlobalObject *
|
||||
GetCurrentGlobal(JSContext *cx)
|
||||
{
|
||||
JSObject *scopeChain = (cx->hasfp()) ? &cx->fp()->scopeChain() : cx->globalObject;
|
||||
return scopeChain ? scopeChain->getGlobal() : NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
FindClassPrototype(JSContext *cx, JSObject *scope, JSProtoKey protoKey, JSObject **protop,
|
||||
Class *clasp);
|
||||
|
@ -306,14 +306,6 @@ CheckScript(JSScript *script, JSScript *prev)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CheckScriptOwner(JSScript *script, JSObject *owner)
|
||||
{
|
||||
JS_OPT_ASSERT(script->ownerObject == owner);
|
||||
if (owner != JS_NEW_SCRIPT && owner != JS_CACHED_SCRIPT)
|
||||
JS_OPT_ASSERT(script->compartment() == owner->compartment());
|
||||
}
|
||||
|
||||
#endif /* JS_CRASH_DIAGNOSTICS */
|
||||
|
||||
} /* namespace js */
|
||||
@ -756,37 +748,6 @@ JSPCCounters::destroy(JSContext *cx)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
script_trace(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
JSScript *script = (JSScript *) obj->getPrivate();
|
||||
if (script) {
|
||||
CheckScriptOwner(script, obj);
|
||||
MarkScript(trc, script, "script");
|
||||
}
|
||||
}
|
||||
|
||||
JS_FRIEND_DATA(Class) js::ScriptClass = {
|
||||
"Script",
|
||||
JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
|
||||
JS_PropertyStub, /* addProperty */
|
||||
JS_PropertyStub, /* delProperty */
|
||||
JS_PropertyStub, /* getProperty */
|
||||
JS_StrictPropertyStub, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
NULL, /* finalize */
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
script_trace
|
||||
};
|
||||
|
||||
/*
|
||||
* Shared script filename management.
|
||||
*/
|
||||
@ -965,7 +926,6 @@ JSScript::NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natom
|
||||
PodZero(script);
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
script->cookie1[0] = script->cookie2[0] = JS_SCRIPT_COOKIE;
|
||||
script->ownerObject = JS_NEW_SCRIPT;
|
||||
#endif
|
||||
#if JS_SCRIPT_INLINE_DATA_LIMIT
|
||||
if (!data)
|
||||
@ -1241,23 +1201,26 @@ JSScript::NewScriptFromCG(JSContext *cx, CodeGenerator *cg)
|
||||
return NULL;
|
||||
|
||||
fun->setScript(script);
|
||||
script->u.globalObject = fun->getParent() ? fun->getParent()->getGlobal() : NULL;
|
||||
} else {
|
||||
/*
|
||||
* Initialize script->object, if necessary, so that the debugger has a
|
||||
* valid holder object.
|
||||
*/
|
||||
if ((cg->flags & TCF_NEED_SCRIPT_OBJECT) && !js_NewScriptObject(cx, script))
|
||||
return NULL;
|
||||
if (cg->flags & TCF_NEED_SCRIPT_GLOBAL)
|
||||
script->u.globalObject = GetCurrentGlobal(cx);
|
||||
}
|
||||
|
||||
/* Tell the debugger about this compiled script. */
|
||||
js_CallNewScriptHook(cx, script, fun);
|
||||
if (!cg->parent) {
|
||||
JSObject *owner = fun ? fun : script->u.object;
|
||||
GlobalObject *compileAndGoGlobal = NULL;
|
||||
if (script->compileAndGo)
|
||||
compileAndGoGlobal = (owner ? owner : cg->scopeChain())->getGlobal();
|
||||
Debugger::onNewScript(cx, script, owner, compileAndGoGlobal);
|
||||
if (script->compileAndGo) {
|
||||
compileAndGoGlobal = script->u.globalObject;
|
||||
if (!compileAndGoGlobal)
|
||||
compileAndGoGlobal = cg->scopeChain()->getGlobal();
|
||||
}
|
||||
Debugger::onNewScript(cx, script, compileAndGoGlobal);
|
||||
}
|
||||
|
||||
return script;
|
||||
@ -1288,15 +1251,6 @@ JSScript::dataSize(JSUsableSizeFun usf)
|
||||
return usable ? usable : dataSize();
|
||||
}
|
||||
|
||||
void
|
||||
JSScript::setOwnerObject(JSObject *owner)
|
||||
{
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
CheckScriptOwner(this, JS_NEW_SCRIPT);
|
||||
ownerObject = owner;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Nb: srcnotes are variable-length. This function computes the number of
|
||||
* srcnote *slots*, which may be greater than the number of srcnotes.
|
||||
@ -1371,27 +1325,6 @@ JSScript::finalize(JSContext *cx)
|
||||
}
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_NewScriptObject(JSContext *cx, JSScript *script)
|
||||
{
|
||||
JS_ASSERT(!script->u.object);
|
||||
|
||||
JSObject *obj = NewNonFunction<WithProto::Class>(cx, &ScriptClass, NULL, NULL);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
obj->setPrivate(script);
|
||||
script->u.object = obj;
|
||||
script->setOwnerObject(obj);
|
||||
|
||||
/*
|
||||
* Clear the object's type/proto, to avoid entraining stuff. Once we no longer use the parent
|
||||
* for security checks, then we can clear the parent, too.
|
||||
*/
|
||||
obj->clearType();
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
static const uint32 GSN_CACHE_THRESHOLD = 100;
|
||||
|
@ -426,9 +426,6 @@ class JSPCCounters {
|
||||
|
||||
static const uint32 JS_SCRIPT_COOKIE = 0xc00cee;
|
||||
|
||||
static JSObject * const JS_NEW_SCRIPT = (JSObject *)0x12345678;
|
||||
static JSObject * const JS_CACHED_SCRIPT = (JSObject *)0x12341234;
|
||||
|
||||
struct JSScript : public js::gc::Cell {
|
||||
/*
|
||||
* Two successively less primitive ways to make a new JSScript. The first
|
||||
@ -561,19 +558,20 @@ struct JSScript : public js::gc::Cell {
|
||||
|
||||
union {
|
||||
/*
|
||||
* A script object of class ScriptClass, to ensure the script is GC'd.
|
||||
* A global object for the script.
|
||||
* - All scripts returned by JSAPI functions (JS_CompileScript,
|
||||
* JS_CompileFile, etc.) have these objects.
|
||||
* - Function scripts never have script objects; such scripts are owned
|
||||
* by their function objects.
|
||||
* JS_CompileFile, etc.) have a non-null globalObject.
|
||||
* - A function script has a globalObject if the function comes from a
|
||||
* compile-and-go script.
|
||||
* - Temporary scripts created by obj_eval, JS_EvaluateScript, and
|
||||
* similar functions never have these objects; such scripts are
|
||||
* explicitly destroyed by the code that created them.
|
||||
* similar functions never have the globalObject field set; for such
|
||||
* scripts the global should be extracted from the JS frame that
|
||||
* execute scripts.
|
||||
*/
|
||||
JSObject *object;
|
||||
js::GlobalObject *globalObject;
|
||||
|
||||
/* Hash table chaining for JSCompartment::evalCache. */
|
||||
JSScript *evalHashLink;
|
||||
JSScript *evalHashLink;
|
||||
} u;
|
||||
|
||||
uint32 *closedSlots; /* vector of closed slots; args first, then vars. */
|
||||
@ -582,14 +580,10 @@ struct JSScript : public js::gc::Cell {
|
||||
JSPCCounters pcCounters;
|
||||
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
JSObject *ownerObject;
|
||||
|
||||
/* All diagnostic fields must be multiples of Cell::CellSize. */
|
||||
uint32 cookie2[sizeof(JSObject *) == 4 ? 1 : 2];
|
||||
uint32 cookie2[Cell::CellSize / sizeof(uint32)];
|
||||
#endif
|
||||
|
||||
void setOwnerObject(JSObject *owner);
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Unique identifier within the compartment for this script, used for
|
||||
@ -638,6 +632,11 @@ struct JSScript : public js::gc::Cell {
|
||||
|
||||
inline void clearNesting();
|
||||
|
||||
/* Return creation time global or null. */
|
||||
js::GlobalObject *getGlobalObjectOrNull() const {
|
||||
return isCachedEval ? NULL : u.globalObject;
|
||||
}
|
||||
|
||||
private:
|
||||
bool makeTypes(JSContext *cx, JSFunction *fun);
|
||||
bool makeAnalysis(JSContext *cx);
|
||||
@ -685,7 +684,7 @@ struct JSScript : public js::gc::Cell {
|
||||
|
||||
/* Size of the JITScript and all sections. (This method is implemented in MethodJIT.h.) */
|
||||
JS_FRIEND_API(size_t) jitDataSize(JSUsableSizeFun usf);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
jsbytecode *main() {
|
||||
@ -803,7 +802,7 @@ struct JSScript : public js::gc::Cell {
|
||||
* count-style interface.)
|
||||
*/
|
||||
bool setStepModeFlag(JSContext *cx, bool step);
|
||||
|
||||
|
||||
/*
|
||||
* Increment or decrement the single-step count. If the count is non-zero or
|
||||
* the flag (set by setStepModeFlag) is set, then the script is in
|
||||
@ -848,9 +847,6 @@ StackDepth(JSScript *script)
|
||||
JS_END_MACRO
|
||||
|
||||
|
||||
extern JSObject *
|
||||
js_InitScriptClass(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern void
|
||||
js_MarkScriptFilename(const char *filename);
|
||||
|
||||
@ -873,19 +869,11 @@ namespace js {
|
||||
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
|
||||
void
|
||||
CheckScriptOwner(JSScript *script, JSObject *owner);
|
||||
|
||||
void
|
||||
CheckScript(JSScript *script, JSScript *prev);
|
||||
|
||||
#else
|
||||
|
||||
inline void
|
||||
CheckScriptOwner(JSScript *script, JSObject *owner)
|
||||
{
|
||||
}
|
||||
|
||||
inline void
|
||||
CheckScript(JSScript *script, JSScript *prev)
|
||||
{
|
||||
@ -895,9 +883,6 @@ CheckScript(JSScript *script, JSScript *prev)
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern JSObject *
|
||||
js_NewScriptObject(JSContext *cx, JSScript *script);
|
||||
|
||||
/*
|
||||
* To perturb as little code as possible, we introduce a js_GetSrcNote lookup
|
||||
* cache without adding an explicit cx parameter. Thus js_GetSrcNote becomes
|
||||
|
@ -215,11 +215,4 @@ JSScript::clearNesting()
|
||||
}
|
||||
}
|
||||
|
||||
inline JSScript *
|
||||
JSObject::getScript() const
|
||||
{
|
||||
JS_ASSERT(isScript());
|
||||
return static_cast<JSScript *>(getPrivate());
|
||||
}
|
||||
|
||||
#endif /* jsscriptinlines_h___ */
|
||||
|
@ -723,10 +723,9 @@ JS_XDRScript(JSXDRState *xdr, JSScript **scriptp)
|
||||
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
JS_ASSERT(!script->compileAndGo);
|
||||
if (!js_NewScriptObject(xdr->cx, script))
|
||||
return false;
|
||||
script->u.globalObject = GetCurrentGlobal(xdr->cx);
|
||||
js_CallNewScriptHook(xdr->cx, script, NULL);
|
||||
Debugger::onNewScript(xdr->cx, script, script->u.object, NULL);
|
||||
Debugger::onNewScript(xdr->cx, script, NULL);
|
||||
*scriptp = script;
|
||||
}
|
||||
|
||||
|
@ -1562,9 +1562,7 @@ ValueToScript(JSContext *cx, jsval v, JSFunction **funp = NULL)
|
||||
JSObject *obj = JSVAL_TO_OBJECT(v);
|
||||
JSClass *clasp = JS_GET_CLASS(cx, obj);
|
||||
|
||||
if (clasp == Jsvalify(&ScriptClass)) {
|
||||
script = (JSScript *) JS_GetPrivate(cx, obj);
|
||||
} else if (clasp == Jsvalify(&GeneratorClass)) {
|
||||
if (clasp == Jsvalify(&GeneratorClass)) {
|
||||
JSGenerator *gen = (JSGenerator *) JS_GetPrivate(cx, obj);
|
||||
fun = gen->floatingFrame()->fun();
|
||||
script = fun->script();
|
||||
@ -1624,8 +1622,7 @@ GetTrapArgs(JSContext *cx, uintN argc, jsval *argv, JSScript **scriptp,
|
||||
v = argv[0];
|
||||
intarg = 0;
|
||||
if (!JSVAL_IS_PRIMITIVE(v) &&
|
||||
(JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == Jsvalify(&FunctionClass) ||
|
||||
JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == Jsvalify(&ScriptClass))) {
|
||||
JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == Jsvalify(&FunctionClass)) {
|
||||
script = ValueToScript(cx, v);
|
||||
if (!script)
|
||||
return JS_FALSE;
|
||||
|
@ -88,7 +88,6 @@ extern Class DebuggerScript_class;
|
||||
|
||||
enum {
|
||||
JSSLOT_DEBUGSCRIPT_OWNER,
|
||||
JSSLOT_DEBUGSCRIPT_HOLDER, /* PrivateValue, cross-compartment pointer */
|
||||
JSSLOT_DEBUGSCRIPT_COUNT
|
||||
};
|
||||
|
||||
@ -125,7 +124,7 @@ ReportObjectRequired(JSContext *cx)
|
||||
/*** Breakpoints *********************************************************************************/
|
||||
|
||||
BreakpointSite::BreakpointSite(JSScript *script, jsbytecode *pc)
|
||||
: script(script), pc(pc), realOpcode(JSOp(*pc)), scriptObject(NULL), enabledCount(0),
|
||||
: script(script), pc(pc), realOpcode(JSOp(*pc)), scriptGlobal(NULL), enabledCount(0),
|
||||
trapHandler(NULL), trapClosure(UndefinedValue())
|
||||
{
|
||||
JS_ASSERT(realOpcode != JSOP_TRAP);
|
||||
@ -136,11 +135,11 @@ BreakpointSite::BreakpointSite(JSScript *script, jsbytecode *pc)
|
||||
* Precondition: script is live, meaning either it is a non-held script that is
|
||||
* on the stack or a held script that hasn't been GC'd.
|
||||
*/
|
||||
static JSObject *
|
||||
ScriptScope(JSContext *cx, JSScript *script, JSObject *holder)
|
||||
static GlobalObject *
|
||||
ScriptGlobal(JSContext *cx, JSScript *script, GlobalObject *scriptGlobal)
|
||||
{
|
||||
if (holder)
|
||||
return holder;
|
||||
if (scriptGlobal)
|
||||
return scriptGlobal;
|
||||
|
||||
/*
|
||||
* The referent is a non-held script. There is no direct reference from
|
||||
@ -149,9 +148,9 @@ ScriptScope(JSContext *cx, JSScript *script, JSObject *holder)
|
||||
for (AllFramesIter i(cx->stack.space()); ; ++i) {
|
||||
JS_ASSERT(!i.done());
|
||||
if (i.fp()->maybeScript() == script)
|
||||
return &i.fp()->scopeChain();
|
||||
return i.fp()->scopeChain().getGlobal();
|
||||
}
|
||||
JS_NOT_REACHED("ScriptScope: live non-held script not on stack");
|
||||
JS_NOT_REACHED("ScriptGlobal: live non-held script not on stack");
|
||||
}
|
||||
|
||||
bool
|
||||
@ -161,7 +160,7 @@ BreakpointSite::recompile(JSContext *cx, bool forTrap)
|
||||
if (script->hasJITCode()) {
|
||||
Maybe<AutoCompartment> ac;
|
||||
if (!forTrap) {
|
||||
ac.construct(cx, ScriptScope(cx, script, scriptObject));
|
||||
ac.construct(cx, ScriptGlobal(cx, script, scriptGlobal));
|
||||
if (!ac.ref().enter())
|
||||
return false;
|
||||
}
|
||||
@ -733,7 +732,7 @@ Debugger::fireEnterFrame(JSContext *cx)
|
||||
}
|
||||
|
||||
void
|
||||
Debugger::fireNewScript(JSContext *cx, JSScript *script, JSObject *obj)
|
||||
Debugger::fireNewScript(JSContext *cx, JSScript *script)
|
||||
{
|
||||
JSObject *hook = getHook(OnNewScript);
|
||||
JS_ASSERT(hook);
|
||||
@ -743,7 +742,7 @@ Debugger::fireNewScript(JSContext *cx, JSScript *script, JSObject *obj)
|
||||
if (!ac.enter())
|
||||
return;
|
||||
|
||||
JSObject *dsobj = wrapScript(cx, script, obj);
|
||||
JSObject *dsobj = wrapScript(cx, script);
|
||||
if (!dsobj) {
|
||||
handleUncaughtException(ac, NULL, false);
|
||||
return;
|
||||
@ -816,8 +815,7 @@ AddNewScriptRecipients(GlobalObject::DebuggerVector *src, AutoValueVector *dest)
|
||||
}
|
||||
|
||||
void
|
||||
Debugger::slowPathOnNewScript(JSContext *cx, JSScript *script, JSObject *obj,
|
||||
GlobalObject *compileAndGoGlobal)
|
||||
Debugger::slowPathOnNewScript(JSContext *cx, JSScript *script, GlobalObject *compileAndGoGlobal)
|
||||
{
|
||||
JS_ASSERT(script->compileAndGo == !!compileAndGoGlobal);
|
||||
|
||||
@ -849,7 +847,7 @@ Debugger::slowPathOnNewScript(JSContext *cx, JSScript *script, JSObject *obj,
|
||||
Debugger *dbg = Debugger::fromJSObject(&p->toObject());
|
||||
if ((!compileAndGoGlobal || dbg->debuggees.has(compileAndGoGlobal)) &&
|
||||
dbg->enabled && dbg->getHook(OnNewScript)) {
|
||||
dbg->fireNewScript(cx, script, obj);
|
||||
dbg->fireNewScript(cx, script);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1782,15 +1780,7 @@ static inline JSScript *
|
||||
GetScriptReferent(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->getClass() == &DebuggerScript_class);
|
||||
return (JSScript *) obj->getPrivate();
|
||||
}
|
||||
|
||||
static inline JSObject *
|
||||
GetScriptHolder(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->getClass() == &DebuggerScript_class);
|
||||
Value v = obj->getReservedSlot(JSSLOT_DEBUGSCRIPT_HOLDER);
|
||||
return (JSObject *) v.toPrivate();
|
||||
return static_cast<JSScript *>(obj->getPrivate());
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1799,11 +1789,6 @@ DebuggerScript_trace(JSTracer *trc, JSObject *obj)
|
||||
if (!trc->context->runtime->gcCurrentCompartment) {
|
||||
if (JSScript *script = GetScriptReferent(obj))
|
||||
MarkScript(trc, script, "Debugger.Script referent");
|
||||
Value v = obj->getReservedSlot(JSSLOT_DEBUGSCRIPT_HOLDER);
|
||||
if (!v.isUndefined()) {
|
||||
if (JSObject *obj = (JSObject *) v.toPrivate())
|
||||
MarkObject(trc, *obj, "Debugger.Script referent holder");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1821,7 +1806,7 @@ Class DebuggerScript_class = {
|
||||
};
|
||||
|
||||
JSObject *
|
||||
Debugger::newDebuggerScript(JSContext *cx, JSScript *script, JSObject *holder)
|
||||
Debugger::newDebuggerScript(JSContext *cx, JSScript *script)
|
||||
{
|
||||
assertSameCompartment(cx, object);
|
||||
|
||||
@ -1832,21 +1817,18 @@ Debugger::newDebuggerScript(JSContext *cx, JSScript *script, JSObject *holder)
|
||||
return NULL;
|
||||
scriptobj->setPrivate(script);
|
||||
scriptobj->setReservedSlot(JSSLOT_DEBUGSCRIPT_OWNER, ObjectValue(*object));
|
||||
scriptobj->setReservedSlot(JSSLOT_DEBUGSCRIPT_HOLDER, PrivateValue(holder));
|
||||
|
||||
return scriptobj;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
Debugger::wrapScript(JSContext *cx, JSScript *script, JSObject *obj)
|
||||
Debugger::wrapScript(JSContext *cx, JSScript *script)
|
||||
{
|
||||
assertSameCompartment(cx, object);
|
||||
JS_ASSERT(cx->compartment != script->compartment());
|
||||
JS_ASSERT_IF(obj, script->compartment() == obj->compartment());
|
||||
|
||||
CellWeakMap::AddPtr p = scripts.lookupForAdd(script);
|
||||
if (!p) {
|
||||
JSObject *scriptobj = newDebuggerScript(cx, script, obj);
|
||||
JSObject *scriptobj = newDebuggerScript(cx, script);
|
||||
|
||||
/* The allocation may have caused a GC, which can remove table entries. */
|
||||
if (!scriptobj || !scripts.relookupOrAdd(p, script, scriptobj))
|
||||
@ -1857,12 +1839,6 @@ Debugger::wrapScript(JSContext *cx, JSScript *script, JSObject *obj)
|
||||
return p->value;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
Debugger::wrapFunctionScript(JSContext *cx, JSFunction *fun)
|
||||
{
|
||||
return wrapScript(cx, fun->script(), fun);
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
DebuggerScript_check(JSContext *cx, const Value &v, const char *clsname, const char *fnname)
|
||||
{
|
||||
@ -1879,15 +1855,14 @@ DebuggerScript_check(JSContext *cx, const Value &v, const char *clsname, const c
|
||||
|
||||
/*
|
||||
* Check for Debugger.Script.prototype, which is of class DebuggerScript_class
|
||||
* but whose holding object is undefined.
|
||||
* but whose script is null.
|
||||
*/
|
||||
if (thisobj->getReservedSlot(JSSLOT_DEBUGSCRIPT_HOLDER).isUndefined()) {
|
||||
if (!GetScriptReferent(thisobj)) {
|
||||
JS_ASSERT(!GetScriptReferent(thisobj));
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
|
||||
clsname, fnname, "prototype object");
|
||||
return NULL;
|
||||
}
|
||||
JS_ASSERT(GetScriptReferent(thisobj));
|
||||
|
||||
return thisobj;
|
||||
}
|
||||
@ -1954,7 +1929,8 @@ DebuggerScript_getChildScripts(JSContext *cx, uintN argc, Value *vp)
|
||||
for (uint32 i = script->savedCallerFun ? 1 : 0; i < objects->length; i++) {
|
||||
JSObject *obj = objects->vector[i];
|
||||
if (obj->isFunction()) {
|
||||
JSObject *s = dbg->wrapFunctionScript(cx, (JSFunction *) obj);
|
||||
JSFunction *fun = static_cast<JSFunction *>(obj);
|
||||
JSObject *s = dbg->wrapScript(cx, fun->script());
|
||||
if (!s || !js_NewbornArrayPush(cx, result, ObjectValue(*s)))
|
||||
return false;
|
||||
}
|
||||
@ -2257,8 +2233,8 @@ DebuggerScript_setBreakpoint(JSContext *cx, uintN argc, Value *vp)
|
||||
THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "setBreakpoint", args, obj, script);
|
||||
Debugger *dbg = Debugger::fromChildJSObject(obj);
|
||||
|
||||
JSObject *holder = GetScriptHolder(obj);
|
||||
if (!dbg->observesScope(ScriptScope(cx, script, holder))) {
|
||||
GlobalObject *scriptGlobal = script->getGlobalObjectOrNull();
|
||||
if (!dbg->observesGlobal(ScriptGlobal(cx, script, scriptGlobal))) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEBUG_NOT_DEBUGGING);
|
||||
return false;
|
||||
}
|
||||
@ -2273,7 +2249,7 @@ DebuggerScript_setBreakpoint(JSContext *cx, uintN argc, Value *vp)
|
||||
|
||||
JSCompartment *comp = script->compartment();
|
||||
jsbytecode *pc = script->code + offset;
|
||||
BreakpointSite *site = comp->getOrCreateBreakpointSite(cx, script, pc, holder);
|
||||
BreakpointSite *site = comp->getOrCreateBreakpointSite(cx, script, pc, scriptGlobal);
|
||||
if (!site)
|
||||
return false;
|
||||
if (site->inc(cx)) {
|
||||
@ -2628,7 +2604,7 @@ DebuggerFrame_getScript(JSContext *cx, uintN argc, Value *vp)
|
||||
if (fp->isFunctionFrame() && !fp->isEvalFrame()) {
|
||||
JSFunction *callee = fp->callee().getFunctionPrivate();
|
||||
if (callee->isInterpreted()) {
|
||||
scriptObject = debug->wrapFunctionScript(cx, callee);
|
||||
scriptObject = debug->wrapScript(cx, callee->script());
|
||||
if (!scriptObject)
|
||||
return false;
|
||||
}
|
||||
@ -2638,8 +2614,7 @@ DebuggerFrame_getScript(JSContext *cx, uintN argc, Value *vp)
|
||||
* frames.
|
||||
*/
|
||||
JSScript *script = fp->script();
|
||||
scriptObject = debug->wrapScript(cx, script,
|
||||
script->isCachedEval ? NULL : script->u.object);
|
||||
scriptObject = debug->wrapScript(cx, script);
|
||||
if (!scriptObject)
|
||||
return false;
|
||||
}
|
||||
@ -2744,7 +2719,7 @@ EvaluateInScope(JSContext *cx, JSObject *scobj, StackFrame *fp, const jschar *ch
|
||||
*/
|
||||
JSScript *script = BytecodeCompiler::compileScript(cx, scobj, fp,
|
||||
fp->scopeChain().principals(cx),
|
||||
TCF_COMPILE_N_GO | TCF_NEED_SCRIPT_OBJECT,
|
||||
TCF_COMPILE_N_GO | TCF_NEED_SCRIPT_GLOBAL,
|
||||
chars, length, filename, lineno,
|
||||
cx->findVersion(), NULL,
|
||||
UpvarCookie::UPVAR_LEVEL_LIMIT);
|
||||
@ -3056,7 +3031,7 @@ DebuggerObject_getScript(JSContext *cx, uintN argc, Value *vp)
|
||||
if (!fun->isInterpreted())
|
||||
return true;
|
||||
|
||||
JSObject *scriptObject = dbg->wrapFunctionScript(cx, fun);
|
||||
JSObject *scriptObject = dbg->wrapScript(cx, fun->script());
|
||||
if (!scriptObject)
|
||||
return false;
|
||||
|
||||
|
@ -201,7 +201,7 @@ class Debugger {
|
||||
|
||||
static void slowPathOnEnterFrame(JSContext *cx);
|
||||
static void slowPathOnLeaveFrame(JSContext *cx);
|
||||
static void slowPathOnNewScript(JSContext *cx, JSScript *script, JSObject *obj,
|
||||
static void slowPathOnNewScript(JSContext *cx, JSScript *script,
|
||||
GlobalObject *compileAndGoGlobal);
|
||||
static JSTrapStatus dispatchHook(JSContext *cx, js::Value *vp, Hook which);
|
||||
|
||||
@ -210,18 +210,16 @@ class Debugger {
|
||||
void fireEnterFrame(JSContext *cx);
|
||||
|
||||
/*
|
||||
* Allocate and initialize a Debugger.Script instance whose referent is |script| and
|
||||
* whose holder is |obj|. If |obj| is NULL, this creates a Debugger.Script whose holder
|
||||
* is null, for non-held scripts.
|
||||
* Allocate and initialize a Debugger.Script instance whose referent is
|
||||
* |script|.
|
||||
*/
|
||||
JSObject *newDebuggerScript(JSContext *cx, JSScript *script, JSObject *obj);
|
||||
JSObject *newDebuggerScript(JSContext *cx, JSScript *script);
|
||||
|
||||
/*
|
||||
* Receive a "new script" event from the engine. A new script was compiled
|
||||
* or deserialized. For eval scripts obj must be null, otherwise it must be
|
||||
* a script object.
|
||||
* or deserialized.
|
||||
*/
|
||||
void fireNewScript(JSContext *cx, JSScript *script, JSObject *obj);
|
||||
void fireNewScript(JSContext *cx, JSScript *script);
|
||||
|
||||
static inline Debugger *fromLinks(JSCList *links);
|
||||
inline Breakpoint *firstBreakpoint() const;
|
||||
@ -262,7 +260,7 @@ class Debugger {
|
||||
static inline void onLeaveFrame(JSContext *cx);
|
||||
static inline JSTrapStatus onDebuggerStatement(JSContext *cx, js::Value *vp);
|
||||
static inline JSTrapStatus onExceptionUnwind(JSContext *cx, js::Value *vp);
|
||||
static inline void onNewScript(JSContext *cx, JSScript *script, JSObject *obj,
|
||||
static inline void onNewScript(JSContext *cx, JSScript *script,
|
||||
GlobalObject *compileAndGoGlobal);
|
||||
static JSTrapStatus onTrap(JSContext *cx, Value *vp);
|
||||
static JSTrapStatus onSingleStep(JSContext *cx, Value *vp);
|
||||
@ -271,7 +269,7 @@ class Debugger {
|
||||
|
||||
inline bool observesEnterFrame() const;
|
||||
inline bool observesNewScript() const;
|
||||
inline bool observesScope(JSObject *obj) const;
|
||||
inline bool observesGlobal(GlobalObject *global) const;
|
||||
inline bool observesFrame(StackFrame *fp) const;
|
||||
|
||||
/*
|
||||
@ -331,21 +329,12 @@ class Debugger {
|
||||
*/
|
||||
bool newCompletionValue(AutoCompartment &ac, bool ok, Value val, Value *vp);
|
||||
|
||||
/*
|
||||
* Return the Debugger.Script object for |fun|'s script, or create a new
|
||||
* one if needed. The context |cx| must be in the debugger compartment;
|
||||
* |fun| must be a cross-compartment wrapper referring to the JSFunction in
|
||||
* a debuggee compartment.
|
||||
*/
|
||||
JSObject *wrapFunctionScript(JSContext *cx, JSFunction *fun);
|
||||
|
||||
/*
|
||||
* Return the Debugger.Script object for |script|, or create a new one if
|
||||
* needed. The context |cx| must be in the debugger compartment; |script| must
|
||||
* be a script in a debuggee compartment. |obj| is either the script holder or
|
||||
* null for non-held scripts.
|
||||
* needed. The context |cx| must be in the debugger compartment; |script|
|
||||
* must be a script in a debuggee compartment.
|
||||
*/
|
||||
JSObject *wrapScript(JSContext *cx, JSScript *script, JSObject *obj);
|
||||
JSObject *wrapScript(JSContext *cx, JSScript *script);
|
||||
|
||||
private:
|
||||
/* Prohibit copying. */
|
||||
@ -369,7 +358,7 @@ class BreakpointSite {
|
||||
* cached eval scripts and for JSD1 traps. It is always non-null for JSD2
|
||||
* breakpoints in held scripts.
|
||||
*/
|
||||
JSObject *scriptObject;
|
||||
GlobalObject *scriptGlobal;
|
||||
|
||||
JSCList breakpoints; /* cyclic list of all js::Breakpoints at this instruction */
|
||||
size_t enabledCount; /* number of breakpoints in the list that are enabled */
|
||||
@ -383,7 +372,7 @@ class BreakpointSite {
|
||||
Breakpoint *firstBreakpoint() const;
|
||||
bool hasBreakpoint(Breakpoint *bp);
|
||||
bool hasTrap() const { return !!trapHandler; }
|
||||
JSObject *getScriptObject() const { return scriptObject; }
|
||||
GlobalObject *getScriptGlobal() const { return scriptGlobal; }
|
||||
|
||||
bool inc(JSContext *cx);
|
||||
void dec(JSContext *cx);
|
||||
@ -475,15 +464,15 @@ Debugger::observesNewScript() const
|
||||
}
|
||||
|
||||
bool
|
||||
Debugger::observesScope(JSObject *obj) const
|
||||
Debugger::observesGlobal(GlobalObject *global) const
|
||||
{
|
||||
return debuggees.has(obj->getGlobal());
|
||||
return debuggees.has(global);
|
||||
}
|
||||
|
||||
bool
|
||||
Debugger::observesFrame(StackFrame *fp) const
|
||||
{
|
||||
return observesScope(&fp->scopeChain());
|
||||
return observesGlobal(fp->scopeChain().getGlobal());
|
||||
}
|
||||
|
||||
void
|
||||
@ -517,13 +506,12 @@ Debugger::onExceptionUnwind(JSContext *cx, js::Value *vp)
|
||||
}
|
||||
|
||||
void
|
||||
Debugger::onNewScript(JSContext *cx, JSScript *script, JSObject *obj,
|
||||
GlobalObject *compileAndGoGlobal)
|
||||
Debugger::onNewScript(JSContext *cx, JSScript *script, GlobalObject *compileAndGoGlobal)
|
||||
{
|
||||
JS_ASSERT_IF(script->compileAndGo, compileAndGoGlobal);
|
||||
JS_ASSERT_IF(!script->compileAndGo, !compileAndGoGlobal);
|
||||
if (!script->compartment()->getDebuggees().empty())
|
||||
slowPathOnNewScript(cx, script, obj, compileAndGoGlobal);
|
||||
slowPathOnNewScript(cx, script, compileAndGoGlobal);
|
||||
}
|
||||
|
||||
extern JSBool
|
||||
|
@ -373,7 +373,7 @@ js::GlobalObject *
|
||||
JSObject::asGlobal()
|
||||
{
|
||||
JS_ASSERT(isGlobal());
|
||||
return reinterpret_cast<js::GlobalObject *>(this);
|
||||
return static_cast<js::GlobalObject *>(this);
|
||||
}
|
||||
|
||||
#endif /* GlobalObject_h___ */
|
||||
|
@ -779,15 +779,6 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
||||
if (si) {
|
||||
JS_snprintf(name, sizeof(name), "JS Object (%s - %s)",
|
||||
clazz->name, si->GetJSClass()->name);
|
||||
} else if (clazz == &js::ScriptClass) {
|
||||
JSScript* script = (JSScript*) xpc_GetJSPrivate(obj);
|
||||
if (script->filename) {
|
||||
JS_snprintf(name, sizeof(name),
|
||||
"JS Object (Script - %s)",
|
||||
script->filename);
|
||||
} else {
|
||||
JS_snprintf(name, sizeof(name), "JS Object (Script)");
|
||||
}
|
||||
} else if (clazz == &js::FunctionClass) {
|
||||
JSFunction* fun = (JSFunction*) xpc_GetJSPrivate(obj);
|
||||
JSString* str = JS_GetFunctionId(fun);
|
||||
|
Loading…
Reference in New Issue
Block a user