Bug 1474522 - Change PrepareScriptEnvironmentAndInvoke to always take a global object instead of an arbitrary scope. r=bholley

js-ctypse now passes the context's current global instead of the closure function it's calling.
This commit is contained in:
Jan de Mooij 2018-07-11 11:44:52 +02:00
Родитель 70d45075c2
Коммит c542e6498e
9 изменённых файлов: 35 добавлений и 29 удалений

Просмотреть файл

@ -1167,7 +1167,7 @@ RejectMaybeWrappedPromise(JSContext *cx, HandleObject promiseObj, HandleValue re
// floor.
RootedObject realReason(cx, UncheckedUnwrap(&reason.toObject()));
RootedValue realReasonVal(cx, ObjectValue(*realReason));
RootedObject realGlobal(cx, &realReason->nonCCWGlobal());
Rooted<GlobalObject*> realGlobal(cx, &realReason->nonCCWGlobal());
ReportErrorToGlobal(cx, realGlobal, realReasonVal);
// Async stacks are only properly adopted if there's at least one

Просмотреть файл

@ -7511,9 +7511,13 @@ CClosure::ClosureStub(ffi_cif* cif, void* result, void** args, void* userData)
// Retrieve the essentials from our closure object.
ArgClosure argClosure(cif, result, args, static_cast<ClosureInfo*>(userData));
JSContext* cx = argClosure.cinfo->cx;
RootedObject fun(cx, argClosure.cinfo->jsfnObj);
js::PrepareScriptEnvironmentAndInvoke(cx, fun, argClosure);
js::AssertSameCompartment(cx, argClosure.cinfo->jsfnObj);
RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
MOZ_ASSERT(global);
js::PrepareScriptEnvironmentAndInvoke(cx, global, argClosure);
}
bool CClosure::ArgClosure::operator()(JSContext* cx)

Просмотреть файл

@ -1405,14 +1405,16 @@ js::detail::IdMatchesAtom(jsid id, JSString* atom)
}
JS_FRIEND_API(void)
js::PrepareScriptEnvironmentAndInvoke(JSContext* cx, HandleObject scope, ScriptEnvironmentPreparer::Closure& closure)
js::PrepareScriptEnvironmentAndInvoke(JSContext* cx, HandleObject global,
ScriptEnvironmentPreparer::Closure& closure)
{
MOZ_ASSERT(!cx->isExceptionPending());
MOZ_ASSERT(global->is<GlobalObject>());
MOZ_RELEASE_ASSERT(cx->runtime()->scriptEnvironmentPreparer,
"Embedding needs to set a scriptEnvironmentPreparer callback");
cx->runtime()->scriptEnvironmentPreparer->invoke(scope, closure);
cx->runtime()->scriptEnvironmentPreparer->invoke(global, closure);
}
JS_FRIEND_API(void)

Просмотреть файл

@ -2734,20 +2734,15 @@ IdToValue(jsid id)
}
/**
* If the embedder has registered a ScriptEnvironmentPreparer,
* PrepareScriptEnvironmentAndInvoke will call the preparer's 'invoke' method
* PrepareScriptEnvironmentAndInvoke asserts the embedder has registered a
* ScriptEnvironmentPreparer and then it calls the preparer's 'invoke' method
* with the given |closure|, with the assumption that the preparer will set up
* any state necessary to run script in |scope|, invoke |closure| with a valid
* any state necessary to run script in |global|, invoke |closure| with a valid
* JSContext*, report any exceptions thrown from the closure, and return.
*
* If no preparer is registered, PrepareScriptEnvironmentAndInvoke will assert
* that |rt| has exactly one JSContext associated with it, enter the compartment
* of |scope| on that context, and invoke |closure|.
*
* In both cases, PrepareScriptEnvironmentAndInvoke will report any exceptions
* that are thrown by the closure. Consumers who want to propagate back
* whether the closure succeeded should do so via members of the closure
* itself.
* PrepareScriptEnvironmentAndInvoke will report any exceptions that are thrown
* by the closure. Consumers who want to propagate back whether the closure
* succeeded should do so via members of the closure itself.
*/
struct ScriptEnvironmentPreparer {
@ -2755,11 +2750,11 @@ struct ScriptEnvironmentPreparer {
virtual bool operator()(JSContext* cx) = 0;
};
virtual void invoke(JS::HandleObject scope, Closure& closure) = 0;
virtual void invoke(JS::HandleObject global, Closure& closure) = 0;
};
extern JS_FRIEND_API(void)
PrepareScriptEnvironmentAndInvoke(JSContext* cx, JS::HandleObject scope,
PrepareScriptEnvironmentAndInvoke(JSContext* cx, JS::HandleObject global,
ScriptEnvironmentPreparer::Closure& closure);
JS_FRIEND_API(void)

Просмотреть файл

@ -479,7 +479,7 @@ struct MOZ_STACK_CLASS EnvironmentPreparer : public js::ScriptEnvironmentPrepare
{
js::SetScriptEnvironmentPreparer(cx, this);
}
void invoke(JS::HandleObject scope, Closure& closure) override;
void invoke(JS::HandleObject global, Closure& closure) override;
};
// Shell state set once at startup.
@ -796,12 +796,14 @@ SkipUTF8BOM(FILE* file)
}
void
EnvironmentPreparer::invoke(HandleObject scope, Closure& closure)
EnvironmentPreparer::invoke(HandleObject global, Closure& closure)
{
MOZ_ASSERT(JS_IsGlobalObject(global));
JSContext* cx = TlsContext.get();
MOZ_ASSERT(!JS_IsExceptionPending(cx));
AutoRealm ar(cx, scope);
AutoRealm ar(cx, global);
AutoReportException are(cx);
if (!closure(cx))
return;

Просмотреть файл

@ -147,7 +147,7 @@ class MOZ_STACK_CLASS ReportExceptionClosure
} // anonymous namespace
void
js::ReportErrorToGlobal(JSContext* cx, HandleObject global, HandleValue error)
js::ReportErrorToGlobal(JSContext* cx, Handle<GlobalObject*> global, HandleValue error)
{
MOZ_ASSERT(!cx->isExceptionPending());
#ifdef DEBUG

Просмотреть файл

@ -92,13 +92,15 @@ extern MOZ_MUST_USE bool
ReportCompileWarning(JSContext* cx, ErrorMetadata&& metadata, UniquePtr<JSErrorNotes> notes,
unsigned flags, unsigned errorNumber, va_list args);
class GlobalObject;
/**
* Report the given error Value to the given global. The JSContext is not
* assumed to be in any particular compartment, but the global and error are
* assumed to be in any particular realm, but the global and error are
* expected to be same-compartment.
*/
extern void
ReportErrorToGlobal(JSContext* cx, JS::HandleObject global, JS::HandleValue error);
ReportErrorToGlobal(JSContext* cx, JS::Handle<js::GlobalObject*> global, JS::HandleValue error);
} // namespace js

Просмотреть файл

@ -1549,15 +1549,16 @@ CycleCollectedJSRuntime::PrepareWaitingZonesForGC()
}
void
CycleCollectedJSRuntime::EnvironmentPreparer::invoke(JS::HandleObject scope,
CycleCollectedJSRuntime::EnvironmentPreparer::invoke(JS::HandleObject global,
js::ScriptEnvironmentPreparer::Closure& closure)
{
nsIGlobalObject* global = xpc::NativeGlobal(scope);
MOZ_ASSERT(JS_IsGlobalObject(global));
nsIGlobalObject* nativeGlobal = xpc::NativeGlobal(global);
// Not much we can do if we simply don't have a usable global here...
NS_ENSURE_TRUE_VOID(global && global->GetGlobalJSObject());
NS_ENSURE_TRUE_VOID(nativeGlobal && nativeGlobal->GetGlobalJSObject());
AutoEntryScript aes(global, "JS-engine-initiated execution");
AutoEntryScript aes(nativeGlobal, "JS-engine-initiated execution");
MOZ_ASSERT(!JS_IsExceptionPending(aes.cx()));

Просмотреть файл

@ -368,7 +368,7 @@ private:
nsTHashtable<nsPtrHashKey<JS::Zone>> mZonesWaitingForGC;
struct EnvironmentPreparer : public js::ScriptEnvironmentPreparer {
void invoke(JS::HandleObject scope, Closure& closure) override;
void invoke(JS::HandleObject global, Closure& closure) override;
};
EnvironmentPreparer mEnvironmentPreparer;