mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 691192 - JSAutoEnterCompartment::enter shouldn't malloc(). r=luke
This commit is contained in:
parent
930a45b1fb
commit
0aeafafb09
@ -1323,13 +1323,20 @@ JS_LeaveCrossCompartmentCall(JSCrossCompartmentCall *call)
|
||||
bool
|
||||
JSAutoEnterCompartment::enter(JSContext *cx, JSObject *target)
|
||||
{
|
||||
JS_ASSERT(!call);
|
||||
if (cx->compartment == target->compartment()) {
|
||||
call = reinterpret_cast<JSCrossCompartmentCall*>(1);
|
||||
JS_ASSERT(state == STATE_UNENTERED);
|
||||
if (cx->compartment == target->getCompartment()) {
|
||||
state = STATE_SAME_COMPARTMENT;
|
||||
return true;
|
||||
}
|
||||
call = JS_EnterCrossCompartmentCall(cx, target);
|
||||
return call != NULL;
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(bytes) == sizeof(AutoCompartment));
|
||||
CHECK_REQUEST(cx);
|
||||
AutoCompartment *call = new (bytes) AutoCompartment(cx, target);
|
||||
if (call->enter()) {
|
||||
state = STATE_OTHER_COMPARTMENT;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1338,6 +1345,15 @@ JSAutoEnterCompartment::enterAndIgnoreErrors(JSContext *cx, JSObject *target)
|
||||
(void) enter(cx, target);
|
||||
}
|
||||
|
||||
JSAutoEnterCompartment::~JSAutoEnterCompartment()
|
||||
{
|
||||
if (state == STATE_OTHER_COMPARTMENT) {
|
||||
AutoCompartment* ac = reinterpret_cast<AutoCompartment*>(bytes);
|
||||
CHECK_REQUEST(ac->context);
|
||||
ac->~AutoCompartment();
|
||||
}
|
||||
}
|
||||
|
||||
namespace JS {
|
||||
|
||||
bool
|
||||
|
@ -2214,27 +2214,41 @@ JS_END_EXTERN_C
|
||||
|
||||
class JS_PUBLIC_API(JSAutoEnterCompartment)
|
||||
{
|
||||
JSCrossCompartmentCall *call;
|
||||
/*
|
||||
* This is a poor man's Maybe<AutoCompartment>, because we don't have
|
||||
* access to the AutoCompartment definition here. We statically assert in
|
||||
* jsapi.cpp that we have the right size here.
|
||||
*/
|
||||
#ifndef _MSC_VER
|
||||
void* bytes[13];
|
||||
#else
|
||||
void* bytes[sizeof(void*) == 4 ? 16 : 13];
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This object may be in one of three states. If enter() or
|
||||
* enterAndIgnoreErrors() hasn't been called, it's in STATE_UNENTERED.
|
||||
* Otherwise, if we were asked to enter into the current compartment, our
|
||||
* state is STATE_SAME_COMPARTMENT. If we actually created an
|
||||
* AutoCompartment and entered another compartment, our state is
|
||||
* STATE_OTHER_COMPARTMENT.
|
||||
*/
|
||||
enum State {
|
||||
STATE_UNENTERED,
|
||||
STATE_SAME_COMPARTMENT,
|
||||
STATE_OTHER_COMPARTMENT
|
||||
} state;
|
||||
|
||||
public:
|
||||
JSAutoEnterCompartment() : call(NULL) {}
|
||||
JSAutoEnterCompartment() : state(STATE_UNENTERED) {}
|
||||
|
||||
bool enter(JSContext *cx, JSObject *target);
|
||||
|
||||
void enterAndIgnoreErrors(JSContext *cx, JSObject *target);
|
||||
|
||||
bool entered() const { return call != NULL; }
|
||||
bool entered() const { return state != STATE_UNENTERED; }
|
||||
|
||||
~JSAutoEnterCompartment() {
|
||||
if (call && call != reinterpret_cast<JSCrossCompartmentCall*>(1))
|
||||
JS_LeaveCrossCompartmentCall(call);
|
||||
}
|
||||
|
||||
void swap(JSAutoEnterCompartment &other) {
|
||||
JSCrossCompartmentCall *tmp = call;
|
||||
call = other.call;
|
||||
other.call = tmp;
|
||||
}
|
||||
~JSAutoEnterCompartment();
|
||||
};
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
Loading…
Reference in New Issue
Block a user