diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index d005723de3b..0c117cfe352 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -1323,20 +1323,13 @@ JS_LeaveCrossCompartmentCall(JSCrossCompartmentCall *call) bool JSAutoEnterCompartment::enter(JSContext *cx, JSObject *target) { - JS_ASSERT(state == STATE_UNENTERED); - if (cx->compartment == target->getCompartment()) { - state = STATE_SAME_COMPARTMENT; + JS_ASSERT(!call); + if (cx->compartment == target->compartment()) { + call = reinterpret_cast(1); return true; } - - 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; + call = JS_EnterCrossCompartmentCall(cx, target); + return call != NULL; } void @@ -1345,15 +1338,6 @@ JSAutoEnterCompartment::enterAndIgnoreErrors(JSContext *cx, JSObject *target) (void) enter(cx, target); } -JSAutoEnterCompartment::~JSAutoEnterCompartment() -{ - if (state == STATE_OTHER_COMPARTMENT) { - AutoCompartment* ac = reinterpret_cast(bytes); - CHECK_REQUEST(ac->context); - ac->~AutoCompartment(); - } -} - namespace JS { bool diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 28ca2a3b4fd..63530844d52 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -2214,41 +2214,27 @@ JS_END_EXTERN_C class JS_PUBLIC_API(JSAutoEnterCompartment) { - /* - * This is a poor man's Maybe, 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; + JSCrossCompartmentCall *call; public: - JSAutoEnterCompartment() : state(STATE_UNENTERED) {} + JSAutoEnterCompartment() : call(NULL) {} bool enter(JSContext *cx, JSObject *target); void enterAndIgnoreErrors(JSContext *cx, JSObject *target); - bool entered() const { return state != STATE_UNENTERED; } + bool entered() const { return call != NULL; } - ~JSAutoEnterCompartment(); + ~JSAutoEnterCompartment() { + if (call && call != reinterpret_cast(1)) + JS_LeaveCrossCompartmentCall(call); + } + + void swap(JSAutoEnterCompartment &other) { + JSCrossCompartmentCall *tmp = call; + call = other.call; + other.call = tmp; + } }; JS_BEGIN_EXTERN_C