Bug 669228 - Don't use the dummy global as a real global. r=jorendorff

This commit is contained in:
Blake Kaplan 2011-07-27 12:33:33 -07:00
parent bcbd536c82
commit b7631383dc
5 changed files with 50 additions and 15 deletions

View File

@ -1201,32 +1201,41 @@ JS_EnterCrossCompartmentCall(JSContext *cx, JSObject *target)
return reinterpret_cast<JSCrossCompartmentCall *>(call);
}
// Declared in jscompartment.h
JSClass js_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_PUBLIC_API(JSCrossCompartmentCall *)
JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target)
{
static JSClass 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
};
CHECK_REQUEST(cx);
JS_ASSERT(target);
JSObject *scriptObject = target->u.object;
if (!scriptObject) {
SwitchToCompartment sc(cx, target->compartment);
scriptObject = JS_NewGlobalObject(cx, &dummy_class);
scriptObject = JS_NewGlobalObject(cx, &js_dummy_class);
if (!scriptObject)
return NULL;
}
return JS_EnterCrossCompartmentCall(cx, scriptObject);
}
JS_PUBLIC_API(JSCrossCompartmentCall *)
JS_EnterCrossCompartmentCallStackFrame(JSContext *cx, JSStackFrame *target)
{
CHECK_REQUEST(cx);
StackFrame *frame = Valueify(target);
return JS_EnterCrossCompartmentCall(cx, frame->scopeChain().getGlobal());
}
JS_PUBLIC_API(void)
JS_LeaveCrossCompartmentCall(JSCrossCompartmentCall *call)
{
@ -1268,6 +1277,19 @@ AutoEnterScriptCompartment::enter(JSContext *cx, JSScript *target)
return call != NULL;
}
bool
AutoEnterFrameCompartment::enter(JSContext *cx, JSStackFrame *target)
{
JS_ASSERT(!call);
js::StackFrame *fp = Valueify(target);
if (cx->compartment == fp->scopeChain().compartment()) {
call = reinterpret_cast<JSCrossCompartmentCall*>(1);
return true;
}
call = JS_EnterCrossCompartmentCallStackFrame(cx, target);
return call != NULL;
}
} /* namespace JS */
JS_PUBLIC_API(void *)

View File

@ -288,7 +288,7 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
if (vp->isObject()) {
JSObject *obj = &vp->toObject();
JS_ASSERT(IsCrossCompartmentWrapper(obj));
if (obj->getParent() != global) {
if (global->getJSClass() != &js_dummy_class && obj->getParent() != global) {
do {
obj->setParent(global);
obj = obj->getProto();

View File

@ -293,6 +293,9 @@ class JaegerCompartment;
}
}
/* Defined in jsapi.cpp */
extern JSClass js_dummy_class;
/* Number of potentially reusable scriptsToGC to search for the eval cache. */
#ifndef JS_EVAL_CACHE_SHIFT
# define JS_EVAL_CACHE_SHIFT 6

View File

@ -52,6 +52,9 @@ JS_BEGIN_EXTERN_C
extern JS_PUBLIC_API(JSCrossCompartmentCall *)
JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target);
extern JS_PUBLIC_API(JSCrossCompartmentCall *)
JS_EnterCrossCompartmentCallStackFrame(JSContext *cx, JSStackFrame *target);
#ifdef __cplusplus
JS_END_EXTERN_C
@ -59,6 +62,7 @@ namespace JS {
class JS_PUBLIC_API(AutoEnterScriptCompartment)
{
protected:
JSCrossCompartmentCall *call;
public:
@ -74,6 +78,12 @@ class JS_PUBLIC_API(AutoEnterScriptCompartment)
}
};
class JS_PUBLIC_API(AutoEnterFrameCompartment) : public AutoEnterScriptCompartment
{
public:
bool enter(JSContext *cx, JSStackFrame *target);
};
} /* namespace JS */
JS_BEGIN_EXTERN_C

View File

@ -148,8 +148,8 @@ XPCJSStackFrame::CreateStack(JSContext* cx, JSStackFrame* fp,
jsbytecode* pc = JS_GetFramePC(cx, fp);
if(script && pc)
{
JS::AutoEnterScriptCompartment ac;
if(ac.enter(cx, script))
JS::AutoEnterFrameCompartment ac;
if(ac.enter(cx, fp))
{
const char* filename = JS_GetScriptFilename(cx, script);
if(filename)