Bug 1070842 - Move nsJSUtils::CompileFunction (and consequently event handler compilation and XBL compilation) off of nsJSUtils::ReportPendingException. r=bz

This commit is contained in:
Bobby Holley 2014-09-29 15:34:21 +02:00
parent 470def0448
commit ceb4c65b4b
11 changed files with 47 additions and 26 deletions

View File

@ -299,6 +299,9 @@ private:
Maybe<JSErrorReporter> mOldErrorReporter;
void InitInternal(JSObject* aGlobal, JSContext* aCx, bool aIsMainThread);
AutoJSAPI(const AutoJSAPI&) MOZ_DELETE;
AutoJSAPI& operator= (const AutoJSAPI&) MOZ_DELETE;
};
/*

View File

@ -28,6 +28,10 @@
#include "nsContentUtils.h"
#include "nsGlobalWindow.h"
#include "mozilla/dom/ScriptSettings.h"
using namespace mozilla::dom;
bool
nsJSUtils::GetCallingLocation(JSContext* aContext, const char* *aFilename,
uint32_t* aLineno)
@ -120,7 +124,7 @@ nsJSUtils::ReportPendingException(JSContext *aContext)
}
nsresult
nsJSUtils::CompileFunction(JSContext* aCx,
nsJSUtils::CompileFunction(AutoJSAPI& jsapi,
JS::Handle<JSObject*> aTarget,
JS::CompileOptions& aOptions,
const nsACString& aName,
@ -129,10 +133,12 @@ nsJSUtils::CompileFunction(JSContext* aCx,
const nsAString& aBody,
JSObject** aFunctionObject)
{
MOZ_ASSERT(js::GetEnterCompartmentDepth(aCx) > 0);
MOZ_ASSERT_IF(aTarget, js::IsObjectInContextCompartment(aTarget, aCx));
MOZ_ASSERT(jsapi.OwnsErrorReporting());
JSContext* cx = jsapi.cx();
MOZ_ASSERT(js::GetEnterCompartmentDepth(cx) > 0);
MOZ_ASSERT_IF(aTarget, js::IsObjectInContextCompartment(aTarget, cx));
MOZ_ASSERT_IF(aOptions.versionSet, aOptions.version != JSVERSION_UNKNOWN);
mozilla::DebugOnly<nsIScriptContext*> ctx = GetScriptContextFromJSContext(aCx);
mozilla::DebugOnly<nsIScriptContext*> ctx = GetScriptContextFromJSContext(cx);
MOZ_ASSERT_IF(ctx, ctx->IsContextInitialized());
// Do the junk Gecko is supposed to do before calling into JSAPI.
@ -141,14 +147,13 @@ nsJSUtils::CompileFunction(JSContext* aCx,
}
// Compile.
JS::Rooted<JSFunction*> fun(aCx);
if (!JS::CompileFunction(aCx, aTarget, aOptions,
JS::Rooted<JSFunction*> fun(cx);
if (!JS::CompileFunction(cx, aTarget, aOptions,
PromiseFlatCString(aName).get(),
aArgCount, aArgArray,
PromiseFlatString(aBody).get(),
aBody.Length(), &fun))
{
ReportPendingException(aCx);
return NS_ERROR_FAILURE;
}

View File

@ -22,6 +22,12 @@
class nsIScriptContext;
class nsIScriptGlobalObject;
namespace mozilla {
namespace dom {
class AutoJSAPI;
}
}
class nsJSUtils
{
public:
@ -49,7 +55,7 @@ public:
*/
static void ReportPendingException(JSContext *aContext);
static nsresult CompileFunction(JSContext* aCx,
static nsresult CompileFunction(mozilla::dom::AutoJSAPI& jsapi,
JS::Handle<JSObject*> aTarget,
JS::CompileOptions& aOptions,
const nsACString& aName,

View File

@ -776,9 +776,10 @@ EventListenerManager::CompileEventHandlerInternal(Listener* aListener,
// Activate JSAPI, and make sure that exceptions are reported on the right
// Window.
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(global))) {
if (NS_WARN_IF(!jsapi.Init(global))) {
return NS_ERROR_UNEXPECTED;
}
jsapi.TakeOwnershipOfErrorReporting();
JSContext* cx = jsapi.cx();
nsCOMPtr<nsIAtom> typeAtom = aListener->mTypeAtom;
@ -895,7 +896,7 @@ EventListenerManager::CompileEventHandlerInternal(Listener* aListener,
.setDefineOnScope(false);
JS::Rooted<JSObject*> handler(cx);
result = nsJSUtils::CompileFunction(cx, target, options,
result = nsJSUtils::CompileFunction(jsapi, target, options,
nsAtomCString(typeAtom),
argCount, argNames, *body, handler.address());
NS_ENSURE_SUCCESS(result, result);

View File

@ -22,6 +22,7 @@
#include "js/CharacterEncoding.h"
using namespace mozilla;
using namespace mozilla::dom;
using js::GetGlobalForObjectCrossCompartment;
using js::AssertSameCompartment;
@ -239,9 +240,12 @@ nsXBLProtoImpl::CompilePrototypeMembers(nsXBLPrototypeBinding* aBinding)
// We want to pre-compile our implementation's members against a "prototype context". Then when we actually
// bind the prototype to a real xbl instance, we'll clone the pre-compiled JS into the real instance's
// context.
AutoSafeJSContext cx;
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(xpc::CompilationScope())))
return NS_ERROR_FAILURE;
jsapi.TakeOwnershipOfErrorReporting();
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> compilationGlobal(cx, xpc::CompilationScope());
JSAutoCompartment ac(cx, compilationGlobal);
mPrecompiledMemberHolder = JS_NewObjectWithGivenProto(cx, nullptr, JS::NullPtr(), compilationGlobal);
if (!mPrecompiledMemberHolder)
@ -253,7 +257,7 @@ nsXBLProtoImpl::CompilePrototypeMembers(nsXBLPrototypeBinding* aBinding)
for (nsXBLProtoImplMember* curr = mMembers;
curr;
curr = curr->GetNext()) {
nsresult rv = curr->CompileMember(mClassName, rootedHolder);
nsresult rv = curr->CompileMember(jsapi, mClassName, rootedHolder);
if (NS_FAILED(rv)) {
DestroyMembers();
return rv;

View File

@ -80,7 +80,7 @@ public:
virtual nsresult InstallMember(JSContext* aCx,
JS::Handle<JSObject*> aTargetClassObject) = 0;
virtual nsresult CompileMember(const nsCString& aClassStr,
virtual nsresult CompileMember(mozilla::dom::AutoJSAPI& jsapi, const nsCString& aClassStr,
JS::Handle<JSObject*> aClassObject) = 0;
virtual void Trace(const TraceCallbacks& aCallbacks, void *aClosure) = 0;

View File

@ -21,6 +21,7 @@
#include "mozilla/dom/ScriptSettings.h"
using namespace mozilla;
using namespace mozilla::dom;
nsXBLProtoImplMethod::nsXBLProtoImplMethod(const char16_t* aName) :
nsXBLProtoImplMember(aName),
@ -125,7 +126,7 @@ nsXBLProtoImplMethod::InstallMember(JSContext* aCx,
}
nsresult
nsXBLProtoImplMethod::CompileMember(const nsCString& aClassStr,
nsXBLProtoImplMethod::CompileMember(AutoJSAPI& jsapi, const nsCString& aClassStr,
JS::Handle<JSObject*> aClassObject)
{
AssertInCompilationScope();
@ -188,14 +189,14 @@ nsXBLProtoImplMethod::CompileMember(const nsCString& aClassStr,
functionUri.Truncate(hash);
}
AutoJSContext cx;
JSContext *cx = jsapi.cx();
JSAutoCompartment ac(cx, aClassObject);
JS::CompileOptions options(cx);
options.setFileAndLine(functionUri.get(),
uncompiledMethod->mBodyText.GetLineNumber())
.setVersion(JSVERSION_LATEST);
JS::Rooted<JSObject*> methodObject(cx);
nsresult rv = nsJSUtils::CompileFunction(cx, JS::NullPtr(), options, cname,
nsresult rv = nsJSUtils::CompileFunction(jsapi, JS::NullPtr(), options, cname,
paramCount,
const_cast<const char**>(args),
body, methodObject.address());

View File

@ -91,7 +91,7 @@ public:
virtual nsresult InstallMember(JSContext* aCx,
JS::Handle<JSObject*> aTargetClassObject) MOZ_OVERRIDE;
virtual nsresult CompileMember(const nsCString& aClassStr,
virtual nsresult CompileMember(mozilla::dom::AutoJSAPI& jsapi, const nsCString& aClassStr,
JS::Handle<JSObject*> aClassObject) MOZ_OVERRIDE;
virtual void Trace(const TraceCallbacks& aCallbacks, void *aClosure) MOZ_OVERRIDE;

View File

@ -16,6 +16,7 @@
#include "xpcpublic.h"
using namespace mozilla;
using namespace mozilla::dom;
nsXBLProtoImplProperty::nsXBLProtoImplProperty(const char16_t* aName,
const char16_t* aGetter,
@ -157,7 +158,7 @@ nsXBLProtoImplProperty::InstallMember(JSContext *aCx,
}
nsresult
nsXBLProtoImplProperty::CompileMember(const nsCString& aClassStr,
nsXBLProtoImplProperty::CompileMember(AutoJSAPI& jsapi, const nsCString& aClassStr,
JS::Handle<JSObject*> aClassObject)
{
AssertInCompilationScope();
@ -166,6 +167,7 @@ nsXBLProtoImplProperty::CompileMember(const nsCString& aClassStr,
NS_PRECONDITION(aClassObject,
"Must have class object to compile");
MOZ_ASSERT(!mGetter.IsCompiled() && !mSetter.IsCompiled());
JSContext *cx = jsapi.cx();
if (!mName)
return NS_ERROR_FAILURE; // Without a valid name, we can't install the member.
@ -187,14 +189,13 @@ nsXBLProtoImplProperty::CompileMember(const nsCString& aClassStr,
if (getterText && getterText->GetText()) {
nsDependentString getter(getterText->GetText());
if (!getter.IsEmpty()) {
AutoJSContext cx;
JSAutoCompartment ac(cx, aClassObject);
JS::CompileOptions options(cx);
options.setFileAndLine(functionUri.get(), getterText->GetLineNumber())
.setVersion(JSVERSION_LATEST);
nsCString name = NS_LITERAL_CSTRING("get_") + NS_ConvertUTF16toUTF8(mName);
JS::Rooted<JSObject*> getterObject(cx);
rv = nsJSUtils::CompileFunction(cx, JS::NullPtr(), options, name, 0,
rv = nsJSUtils::CompileFunction(jsapi, JS::NullPtr(), options, name, 0,
nullptr, getter, getterObject.address());
delete getterText;
@ -233,14 +234,13 @@ nsXBLProtoImplProperty::CompileMember(const nsCString& aClassStr,
if (setterText && setterText->GetText()) {
nsDependentString setter(setterText->GetText());
if (!setter.IsEmpty()) {
AutoJSContext cx;
JSAutoCompartment ac(cx, aClassObject);
JS::CompileOptions options(cx);
options.setFileAndLine(functionUri.get(), setterText->GetLineNumber())
.setVersion(JSVERSION_LATEST);
nsCString name = NS_LITERAL_CSTRING("set_") + NS_ConvertUTF16toUTF8(mName);
JS::Rooted<JSObject*> setterObject(cx);
rv = nsJSUtils::CompileFunction(cx, JS::NullPtr(), options, name, 1,
rv = nsJSUtils::CompileFunction(jsapi, JS::NullPtr(), options, name, 1,
gPropertyArgs, setter,
setterObject.address());

View File

@ -35,7 +35,7 @@ public:
virtual nsresult InstallMember(JSContext* aCx,
JS::Handle<JSObject*> aTargetClassObject) MOZ_OVERRIDE;
virtual nsresult CompileMember(const nsCString& aClassStr,
virtual nsresult CompileMember(mozilla::dom::AutoJSAPI& jsapi, const nsCString& aClassStr,
JS::Handle<JSObject*> aClassObject) MOZ_OVERRIDE;
virtual void Trace(const TraceCallbacks& aCallback, void *aClosure) MOZ_OVERRIDE;

View File

@ -272,9 +272,10 @@ nsXBLPrototypeHandler::ExecuteHandler(EventTarget* aTarget,
// Initiatize an AutoJSAPI with aTarget's bound global to make sure any errors
// are reported to the correct place.
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(boundGlobal))) {
if (NS_WARN_IF(!jsapi.Init(boundGlobal))) {
return NS_OK;
}
jsapi.TakeOwnershipOfErrorReporting();
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> handler(cx);
@ -378,7 +379,7 @@ nsXBLPrototypeHandler::EnsureEventHandler(AutoJSAPI& jsapi, nsIAtom* aName,
.setVersion(JSVERSION_LATEST);
JS::Rooted<JSObject*> handlerFun(cx);
nsresult rv = nsJSUtils::CompileFunction(cx, JS::NullPtr(), options,
nsresult rv = nsJSUtils::CompileFunction(jsapi, JS::NullPtr(), options,
nsAtomCString(aName), argCount,
argNames, handlerText,
handlerFun.address());