зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1279086 - Allow multiple interrupt callbacks (r=dvander)
This commit is contained in:
Родитель
1d37a92675
Коммит
a51047b439
|
@ -11154,14 +11154,14 @@ nsGlobalWindow::ShowSlowScriptDialog()
|
||||||
buttonFlags += nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_2;
|
buttonFlags += nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_2;
|
||||||
|
|
||||||
// Null out the operation callback while we're re-entering JS here.
|
// Null out the operation callback while we're re-entering JS here.
|
||||||
JSInterruptCallback old = JS_SetInterruptCallback(cx, nullptr);
|
bool old = JS_DisableInterruptCallback(cx);
|
||||||
|
|
||||||
// Open the dialog.
|
// Open the dialog.
|
||||||
rv = prompt->ConfirmEx(title, msg, buttonFlags, waitButton, stopButton,
|
rv = prompt->ConfirmEx(title, msg, buttonFlags, waitButton, stopButton,
|
||||||
debugButton, neverShowDlg, &neverShowDlgChk,
|
debugButton, neverShowDlg, &neverShowDlgChk,
|
||||||
&buttonPressed);
|
&buttonPressed);
|
||||||
|
|
||||||
JS_SetInterruptCallback(cx, old);
|
JS_ResetInterruptCallback(cx, old);
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv) && (buttonPressed == 0)) {
|
if (NS_SUCCEEDED(rv) && (buttonPressed == 0)) {
|
||||||
return neverShowDlgChk ? AlwaysContinueSlowScript : ContinueSlowScript;
|
return neverShowDlgChk ? AlwaysContinueSlowScript : ContinueSlowScript;
|
||||||
|
|
|
@ -994,7 +994,7 @@ InitJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSContext* aWorkerCx)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_SetInterruptCallback(aWorkerCx, InterruptCallback);
|
JS_AddInterruptCallback(aWorkerCx, InterruptCallback);
|
||||||
|
|
||||||
js::SetCTypesActivityCallback(aWorkerCx, CTypesActivityCallback);
|
js::SetCTypesActivityCallback(aWorkerCx, CTypesActivityCallback);
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ RequestInterruptCallback(JSContext* cx, unsigned argc, jsval* vp)
|
||||||
|
|
||||||
BEGIN_TEST(testSlowScript)
|
BEGIN_TEST(testSlowScript)
|
||||||
{
|
{
|
||||||
JS_SetInterruptCallback(cx, InterruptCallback);
|
JS_AddInterruptCallback(cx, InterruptCallback);
|
||||||
JS_DefineFunction(cx, global, "requestInterruptCallback", RequestInterruptCallback, 0, 0);
|
JS_DefineFunction(cx, global, "requestInterruptCallback", RequestInterruptCallback, 0, 0);
|
||||||
|
|
||||||
test("while (true)"
|
test("while (true)"
|
||||||
|
|
|
@ -4617,18 +4617,24 @@ JS_CheckForInterrupt(JSContext* cx)
|
||||||
return js::CheckForInterrupt(cx);
|
return js::CheckForInterrupt(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(JSInterruptCallback)
|
JS_PUBLIC_API(bool)
|
||||||
JS_SetInterruptCallback(JSContext* cx, JSInterruptCallback callback)
|
JS_AddInterruptCallback(JSContext* cx, JSInterruptCallback callback)
|
||||||
{
|
{
|
||||||
JSInterruptCallback old = cx->interruptCallback;
|
return cx->interruptCallbacks.append(callback);
|
||||||
cx->interruptCallback = callback;
|
|
||||||
return old;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(JSInterruptCallback)
|
JS_PUBLIC_API(bool)
|
||||||
JS_GetInterruptCallback(JSContext* cx)
|
JS_DisableInterruptCallback(JSContext* cx)
|
||||||
{
|
{
|
||||||
return cx->interruptCallback;
|
bool result = cx->interruptCallbackDisabled;
|
||||||
|
cx->interruptCallbackDisabled = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS_PUBLIC_API(void)
|
||||||
|
JS_ResetInterruptCallback(JSContext* cx, bool enable)
|
||||||
|
{
|
||||||
|
cx->interruptCallbackDisabled = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
|
@ -4305,11 +4305,14 @@ JS_CheckForInterrupt(JSContext* cx);
|
||||||
* if it re-enters the JS engine. The embedding must ensure that the callback
|
* if it re-enters the JS engine. The embedding must ensure that the callback
|
||||||
* is disconnected before attempting such re-entry.
|
* is disconnected before attempting such re-entry.
|
||||||
*/
|
*/
|
||||||
extern JS_PUBLIC_API(JSInterruptCallback)
|
extern JS_PUBLIC_API(bool)
|
||||||
JS_SetInterruptCallback(JSContext* cx, JSInterruptCallback callback);
|
JS_AddInterruptCallback(JSContext* cx, JSInterruptCallback callback);
|
||||||
|
|
||||||
extern JS_PUBLIC_API(JSInterruptCallback)
|
extern JS_PUBLIC_API(bool)
|
||||||
JS_GetInterruptCallback(JSContext* cx);
|
JS_DisableInterruptCallback(JSContext* cx);
|
||||||
|
|
||||||
|
extern JS_PUBLIC_API(void)
|
||||||
|
JS_ResetInterruptCallback(JSContext* cx, bool enable);
|
||||||
|
|
||||||
extern JS_PUBLIC_API(void)
|
extern JS_PUBLIC_API(void)
|
||||||
JS_RequestInterruptCallback(JSContext* cx);
|
JS_RequestInterruptCallback(JSContext* cx);
|
||||||
|
|
|
@ -7623,7 +7623,7 @@ main(int argc, char** argv, char** envp)
|
||||||
JS_SetSecurityCallbacks(cx, &ShellPrincipals::securityCallbacks);
|
JS_SetSecurityCallbacks(cx, &ShellPrincipals::securityCallbacks);
|
||||||
JS_InitDestroyPrincipalsCallback(cx, ShellPrincipals::destroy);
|
JS_InitDestroyPrincipalsCallback(cx, ShellPrincipals::destroy);
|
||||||
|
|
||||||
JS_SetInterruptCallback(cx, ShellInterruptCallback);
|
JS_AddInterruptCallback(cx, ShellInterruptCallback);
|
||||||
JS::SetBuildIdOp(cx, ShellBuildId);
|
JS::SetBuildIdOp(cx, ShellBuildId);
|
||||||
JS::SetAsmJSCacheOps(cx, &asmJSCacheOps);
|
JS::SetAsmJSCacheOps(cx, &asmJSCacheOps);
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
|
||||||
telemetryCallback(nullptr),
|
telemetryCallback(nullptr),
|
||||||
handlingSegFault(false),
|
handlingSegFault(false),
|
||||||
handlingJitInterrupt_(false),
|
handlingJitInterrupt_(false),
|
||||||
interruptCallback(nullptr),
|
interruptCallbackDisabled(false),
|
||||||
getIncumbentGlobalCallback(nullptr),
|
getIncumbentGlobalCallback(nullptr),
|
||||||
enqueuePromiseJobCallback(nullptr),
|
enqueuePromiseJobCallback(nullptr),
|
||||||
enqueuePromiseJobCallbackData(nullptr),
|
enqueuePromiseJobCallbackData(nullptr),
|
||||||
|
@ -530,11 +530,16 @@ InvokeInterruptCallback(JSContext* cx)
|
||||||
// Important: Additional callbacks can occur inside the callback handler
|
// Important: Additional callbacks can occur inside the callback handler
|
||||||
// if it re-enters the JS engine. The embedding must ensure that the
|
// if it re-enters the JS engine. The embedding must ensure that the
|
||||||
// callback is disconnected before attempting such re-entry.
|
// callback is disconnected before attempting such re-entry.
|
||||||
JSInterruptCallback cb = cx->runtime()->interruptCallback;
|
if (cx->runtime()->interruptCallbackDisabled)
|
||||||
if (!cb)
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (cb(cx)) {
|
bool stop = false;
|
||||||
|
for (JSInterruptCallback cb : cx->runtime()->interruptCallbacks) {
|
||||||
|
if (!cb(cx))
|
||||||
|
stop = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stop) {
|
||||||
// Debugger treats invoking the interrupt callback as a "step", so
|
// Debugger treats invoking the interrupt callback as a "step", so
|
||||||
// invoke the onStep handler.
|
// invoke the onStep handler.
|
||||||
if (cx->compartment()->isDebuggee()) {
|
if (cx->compartment()->isDebuggee()) {
|
||||||
|
|
|
@ -638,7 +638,9 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||||
return handlingJitInterrupt_;
|
return handlingJitInterrupt_;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSInterruptCallback interruptCallback;
|
using InterruptCallbackVector = js::Vector<JSInterruptCallback, 2, js::SystemAllocPolicy>;
|
||||||
|
InterruptCallbackVector interruptCallbacks;
|
||||||
|
bool interruptCallbackDisabled;
|
||||||
|
|
||||||
JSGetIncumbentGlobalCallback getIncumbentGlobalCallback;
|
JSGetIncumbentGlobalCallback getIncumbentGlobalCallback;
|
||||||
JSEnqueuePromiseJobCallback enqueuePromiseJobCallback;
|
JSEnqueuePromiseJobCallback enqueuePromiseJobCallback;
|
||||||
|
|
|
@ -3476,7 +3476,7 @@ XPCJSContext::Initialize()
|
||||||
#endif
|
#endif
|
||||||
JS_SetAccumulateTelemetryCallback(cx, AccumulateTelemetryCallback);
|
JS_SetAccumulateTelemetryCallback(cx, AccumulateTelemetryCallback);
|
||||||
js::SetActivityCallback(cx, ActivityCallback, this);
|
js::SetActivityCallback(cx, ActivityCallback, this);
|
||||||
JS_SetInterruptCallback(cx, InterruptCallback);
|
JS_AddInterruptCallback(cx, InterruptCallback);
|
||||||
js::SetWindowProxyClass(cx, &OuterWindowProxyClass);
|
js::SetWindowProxyClass(cx, &OuterWindowProxyClass);
|
||||||
|
|
||||||
// The JS engine needs to keep the source code around in order to implement
|
// The JS engine needs to keep the source code around in order to implement
|
||||||
|
|
|
@ -1421,7 +1421,7 @@ XRE_XPCShellMain(int argc, char** argv, char** envp,
|
||||||
sScriptedInterruptCallback = new PersistentRootedValue;
|
sScriptedInterruptCallback = new PersistentRootedValue;
|
||||||
sScriptedInterruptCallback->init(cx, UndefinedValue());
|
sScriptedInterruptCallback->init(cx, UndefinedValue());
|
||||||
|
|
||||||
JS_SetInterruptCallback(cx, XPCShellInterruptCallback);
|
JS_AddInterruptCallback(cx, XPCShellInterruptCallback);
|
||||||
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче