Bug 593147 - TM: global Object created in _newJSDContext needs a compartment. r=gal.

This commit is contained in:
Jason Orendorff 2010-09-14 16:24:59 -07:00
parent 9901eaf870
commit a43bea11f5
6 changed files with 62 additions and 28 deletions

View File

@ -340,7 +340,9 @@ extern void JSD_ASSERT_VALID_OBJECT(JSDObject* jsdobj);
extern JSDContext*
jsd_DebuggerOnForUser(JSRuntime* jsrt,
JSD_UserCallbacks* callbacks,
void* user);
void* user,
JSObject* scopeobj);
extern JSDContext*
jsd_DebuggerOn(void);

View File

@ -86,9 +86,11 @@ _validateUserCallbacks(JSD_UserCallbacks* callbacks)
static JSDContext*
_newJSDContext(JSRuntime* jsrt,
JSD_UserCallbacks* callbacks,
void* user)
void* user,
JSObject* scopeobj)
{
JSDContext* jsdc = NULL;
JSCompartment *compartment;
if( ! jsrt )
return NULL;
@ -137,7 +139,11 @@ _newJSDContext(JSRuntime* jsrt,
JS_BeginRequest(jsdc->dumbContext);
if( scopeobj )
compartment = js_SwitchToObjectCompartment(jsdc->dumbContext, scopeobj);
jsdc->glob = JS_NewGlobalObject(jsdc->dumbContext, &global_class);
if( scopeobj )
js_SwitchToCompartment(jsdc->dumbContext, compartment);
if( ! jsdc->glob )
goto label_newJSDContext_failure;
@ -194,12 +200,13 @@ _destroyJSDContext(JSDContext* jsdc)
JSDContext*
jsd_DebuggerOnForUser(JSRuntime* jsrt,
JSD_UserCallbacks* callbacks,
void* user)
void* user,
JSObject* scopeobj)
{
JSDContext* jsdc;
JSContext* iter = NULL;
jsdc = _newJSDContext(jsrt, callbacks, user);
jsdc = _newJSDContext(jsrt, callbacks, user, scopeobj);
if( ! jsdc )
return NULL;
@ -226,7 +233,7 @@ jsd_DebuggerOn(void)
{
JS_ASSERT(_jsrt);
JS_ASSERT(_validateUserCallbacks(&_callbacks));
return jsd_DebuggerOnForUser(_jsrt, &_callbacks, _user);
return jsd_DebuggerOnForUser(_jsrt, &_callbacks, _user, NULL);
}
void

View File

@ -49,7 +49,7 @@ JSD_DebuggerOnForUser(JSRuntime* jsrt,
JSD_UserCallbacks* callbacks,
void* user)
{
return jsd_DebuggerOnForUser(jsrt, callbacks, user);
return jsd_DebuggerOnForUser(jsrt, callbacks, user, NULL);
}
JSD_PUBLIC_API(JSDContext*)

View File

@ -142,6 +142,16 @@ JSD_DebuggerOnForUser(JSRuntime* jsrt,
JSD_UserCallbacks* callbacks,
void* user);
/*
* Startup JSD in an application that uses compartments. Debugger
* objects will be allocated in the same compartment as scopeobj.
*/
extern JSD_PUBLIC_API(JSDContext*)
JSD_DebuggerOnForUserWithCompartment(JSRuntime* jsrt,
JSD_UserCallbacks* callbacks,
void* user,
JSObject* scopeobj);
/*
* Shutdown JSD for this JSDContext
*/

View File

@ -1185,22 +1185,20 @@ JSAutoCrossCompartmentCall::enter(JSContext *cx, JSObject *target)
return call != NULL;
}
JSAutoEnterCompartment::JSAutoEnterCompartment(JSContext *cx,
JSCompartment *newCompartment)
: cx(cx), compartment(cx->compartment)
{
cx->compartment = newCompartment;
}
JSAutoEnterCompartment::JSAutoEnterCompartment(JSContext *cx, JSObject *target)
: cx(cx), compartment(cx->compartment)
{
cx->compartment = target->getCompartment(cx);
}
JSAutoEnterCompartment::~JSAutoEnterCompartment()
JS_FRIEND_API(JSCompartment *)
js_SwitchToCompartment(JSContext *cx, JSCompartment *compartment)
{
JSCompartment *c = cx->compartment;
cx->compartment = compartment;
return c;
}
JS_FRIEND_API(JSCompartment *)
js_SwitchToObjectCompartment(JSContext *cx, JSObject *obj)
{
JSCompartment *c = cx->compartment;
cx->compartment = obj->getCompartment(cx);
return c;
}
JS_PUBLIC_API(void *)
@ -1245,7 +1243,8 @@ JS_SetGlobalObject(JSContext *cx, JSObject *obj)
CHECK_REQUEST(cx);
cx->globalObject = obj;
cx->compartment = obj ? obj->getCompartment(cx) : cx->runtime->defaultCompartment;
if (!cx->maybefp())
cx->compartment = obj ? obj->getCompartment(cx) : cx->runtime->defaultCompartment;
}
class AutoResolvingEntry {
@ -1334,10 +1333,14 @@ JS_InitStandardClasses(JSContext *cx, JSObject *obj)
{
CHECK_REQUEST(cx);
if (cx->globalObject)
assertSameCompartment(cx, obj);
else
/*
* JS_SetGlobalObject might or might not change cx's compartment, so call
* it before assertSameCompartment. (The API contract is that *after* this,
* cx and obj must be in the same compartment.)
*/
if (!cx->globalObject)
JS_SetGlobalObject(cx, obj);
assertSameCompartment(cx, obj);
/* Define a top-level property 'undefined' with the undefined value. */
JSAtom *atom = cx->runtime->atomState.typeAtoms[JSTYPE_VOID];

View File

@ -957,6 +957,12 @@ JS_RewrapObject(JSContext *cx, JSObject **objp);
extern JS_PUBLIC_API(JSBool)
JS_RewrapValue(JSContext *cx, jsval *p);
extern JS_FRIEND_API(JSCompartment *)
js_SwitchToCompartment(JSContext *cx, JSCompartment *compartment);
extern JS_FRIEND_API(JSCompartment *)
js_SwitchToObjectCompartment(JSContext *cx, JSObject *obj);
#ifdef __cplusplus
JS_END_EXTERN_C
@ -982,14 +988,20 @@ class JS_PUBLIC_API(JSAutoCrossCompartmentCall)
}
};
class JS_FRIEND_API(JSAutoEnterCompartment)
class JSAutoEnterCompartment
{
JSContext *cx;
JSCompartment *compartment;
public:
JSAutoEnterCompartment(JSContext *cx, JSCompartment *newCompartment);
JSAutoEnterCompartment(JSContext *cx, JSObject *target);
~JSAutoEnterCompartment();
JSAutoEnterCompartment(JSContext *cx, JSCompartment *newCompartment) : cx(cx) {
compartment = js_SwitchToCompartment(cx, newCompartment);
}
JSAutoEnterCompartment(JSContext *cx, JSObject *target) : cx(cx) {
compartment = js_SwitchToObjectCompartment(cx, target);
}
~JSAutoEnterCompartment() {
js_SwitchToCompartment(cx, compartment);
}
};
JS_BEGIN_EXTERN_C