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); 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_PUBLIC_API(JSCrossCompartmentCall *)
JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target) 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); CHECK_REQUEST(cx);
JS_ASSERT(target);
JSObject *scriptObject = target->u.object; JSObject *scriptObject = target->u.object;
if (!scriptObject) { if (!scriptObject) {
SwitchToCompartment sc(cx, target->compartment); SwitchToCompartment sc(cx, target->compartment);
scriptObject = JS_NewGlobalObject(cx, &dummy_class); scriptObject = JS_NewGlobalObject(cx, &js_dummy_class);
if (!scriptObject) if (!scriptObject)
return NULL; return NULL;
} }
return JS_EnterCrossCompartmentCall(cx, scriptObject); 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_PUBLIC_API(void)
JS_LeaveCrossCompartmentCall(JSCrossCompartmentCall *call) JS_LeaveCrossCompartmentCall(JSCrossCompartmentCall *call)
{ {
@ -1268,6 +1277,19 @@ AutoEnterScriptCompartment::enter(JSContext *cx, JSScript *target)
return call != NULL; 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 */ } /* namespace JS */
JS_PUBLIC_API(void *) JS_PUBLIC_API(void *)

View File

@ -288,7 +288,7 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
if (vp->isObject()) { if (vp->isObject()) {
JSObject *obj = &vp->toObject(); JSObject *obj = &vp->toObject();
JS_ASSERT(IsCrossCompartmentWrapper(obj)); JS_ASSERT(IsCrossCompartmentWrapper(obj));
if (obj->getParent() != global) { if (global->getJSClass() != &js_dummy_class && obj->getParent() != global) {
do { do {
obj->setParent(global); obj->setParent(global);
obj = obj->getProto(); 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. */ /* Number of potentially reusable scriptsToGC to search for the eval cache. */
#ifndef JS_EVAL_CACHE_SHIFT #ifndef JS_EVAL_CACHE_SHIFT
# define JS_EVAL_CACHE_SHIFT 6 # define JS_EVAL_CACHE_SHIFT 6

View File

@ -52,6 +52,9 @@ JS_BEGIN_EXTERN_C
extern JS_PUBLIC_API(JSCrossCompartmentCall *) extern JS_PUBLIC_API(JSCrossCompartmentCall *)
JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target); JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target);
extern JS_PUBLIC_API(JSCrossCompartmentCall *)
JS_EnterCrossCompartmentCallStackFrame(JSContext *cx, JSStackFrame *target);
#ifdef __cplusplus #ifdef __cplusplus
JS_END_EXTERN_C JS_END_EXTERN_C
@ -59,6 +62,7 @@ namespace JS {
class JS_PUBLIC_API(AutoEnterScriptCompartment) class JS_PUBLIC_API(AutoEnterScriptCompartment)
{ {
protected:
JSCrossCompartmentCall *call; JSCrossCompartmentCall *call;
public: 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 */ } /* namespace JS */
JS_BEGIN_EXTERN_C JS_BEGIN_EXTERN_C

View File

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