зеркало из https://github.com/mozilla/pjs.git
Bug 691192 - JSAutoEnterCompartment::enter shouldn't malloc(). r=luke
--HG-- extra : rebase_source : da6559e93617f17aca01fb9dd3ca7f08361696cd
This commit is contained in:
Родитель
ed1f755498
Коммит
8b5a0064fc
|
@ -1323,13 +1323,20 @@ JS_LeaveCrossCompartmentCall(JSCrossCompartmentCall *call)
|
|||
bool
|
||||
JSAutoEnterCompartment::enter(JSContext *cx, JSObject *target)
|
||||
{
|
||||
JS_ASSERT(!call);
|
||||
JS_ASSERT(state == STATE_UNENTERED);
|
||||
if (cx->compartment == target->compartment()) {
|
||||
call = reinterpret_cast<JSCrossCompartmentCall*>(1);
|
||||
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.
|
||||
*/
|
||||
#if !defined(_MSC_VER) && !defined(__arm__)
|
||||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче