Bug 717749 - Part 1: Add a slow script debug handler service. (r=smaug)

This commit is contained in:
Shu-yu Guo 2014-05-20 18:27:24 -07:00
Родитель c8ef15deb3
Коммит b02d702198
6 изменённых файлов: 93 добавлений и 21 удалений

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

@ -531,6 +531,9 @@
@BINPATH@/components/Push.manifest @BINPATH@/components/Push.manifest
@BINPATH@/components/PushServiceLauncher.js @BINPATH@/components/PushServiceLauncher.js
@BINPATH@/components/SlowScriptDebug.manifest
@BINPATH@/components/SlowScriptDebug.js
#ifndef RELEASE_BUILD #ifndef RELEASE_BUILD
@BINPATH@/components/InterAppComm.manifest @BINPATH@/components/InterAppComm.manifest
@BINPATH@/components/InterAppCommService.js @BINPATH@/components/InterAppCommService.js

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

@ -0,0 +1,21 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
function SlowScriptDebug() { }
SlowScriptDebug.prototype = {
classID: Components.ID("{e740ddb4-18b4-4aac-8ae1-9b0f4320769d}"),
classDescription: "Slow script debug handler",
contractID: "@mozilla.org/dom/slow-script-debug;1",
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISlowScriptDebug]),
get activationHandler() { return this._activationHandler; },
set activationHandler(cb) { return this._activationHandler = cb; },
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SlowScriptDebug]);

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

@ -0,0 +1,2 @@
component {e740ddb4-18b4-4aac-8ae1-9b0f4320769d} SlowScriptDebug.js
contract @mozilla.org/dom/slow-script-debug;1 {e740ddb4-18b4-4aac-8ae1-9b0f4320769d}

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

@ -13,6 +13,7 @@ XPIDL_SOURCES += [
'nsIEntropyCollector.idl', 'nsIEntropyCollector.idl',
'nsIScriptChannel.idl', 'nsIScriptChannel.idl',
'nsISiteSpecificUserAgent.idl', 'nsISiteSpecificUserAgent.idl',
'nsISlowScriptDebug.idl',
] ]
XPIDL_MODULE = 'dom' XPIDL_MODULE = 'dom'
@ -128,6 +129,8 @@ EXTRA_COMPONENTS += [
'ConsoleAPIStorage.js', 'ConsoleAPIStorage.js',
'SiteSpecificUserAgent.js', 'SiteSpecificUserAgent.js',
'SiteSpecificUserAgent.manifest', 'SiteSpecificUserAgent.manifest',
'SlowScriptDebug.js',
'SlowScriptDebug.manifest',
] ]
EXTRA_JS_MODULES += [ EXTRA_JS_MODULES += [

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

@ -35,6 +35,7 @@
#include "nsIScriptTimeoutHandler.h" #include "nsIScriptTimeoutHandler.h"
#include "nsIController.h" #include "nsIController.h"
#include "nsScriptNameSpaceManager.h" #include "nsScriptNameSpaceManager.h"
#include "nsISlowScriptDebug.h"
#include "nsWindowMemoryReporter.h" #include "nsWindowMemoryReporter.h"
#include "WindowNamedPropertiesHandler.h" #include "WindowNamedPropertiesHandler.h"
@ -10769,27 +10770,43 @@ nsGlobalWindow::ShowSlowScriptDialog()
unsigned lineno; unsigned lineno;
bool hasFrame = JS::DescribeScriptedCaller(cx, &filename, &lineno); bool hasFrame = JS::DescribeScriptedCaller(cx, &filename, &lineno);
bool debugPossible = hasFrame && js::CanCallContextDebugHandler(cx); // Prioritize the SlowScriptDebug interface over JSD1.
#ifdef MOZ_JSDEBUGGER nsCOMPtr<nsISlowScriptDebugCallback> debugCallback;
// Get the debugger service if necessary. bool oldDebugPossible = false;
if (debugPossible) {
bool jsds_IsOn = false;
const char jsdServiceCtrID[] = "@mozilla.org/js/jsd/debugger-service;1";
nsCOMPtr<jsdIExecutionHook> jsdHook;
nsCOMPtr<jsdIDebuggerService> jsds = do_GetService(jsdServiceCtrID, &rv);
// Check if there's a user for the debugger service that's 'on' for us if (hasFrame) {
const char *debugCID = "@mozilla.org/dom/slow-script-debug;1";
nsCOMPtr<nsISlowScriptDebug> debugService = do_GetService(debugCID, &rv);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
jsds->GetDebuggerHook(getter_AddRefs(jsdHook)); debugService->GetActivationHandler(getter_AddRefs(debugCallback));
jsds->GetIsOn(&jsds_IsOn);
} }
// If there is a debug handler registered for this runtime AND if (!debugCallback) {
// ((jsd is on AND has a hook) OR (jsd isn't on (something else debugs))) oldDebugPossible = js::CanCallContextDebugHandler(cx);
// then something useful will be done with our request to debug. #ifdef MOZ_JSDEBUGGER
debugPossible = ((jsds_IsOn && (jsdHook != nullptr)) || !jsds_IsOn); // Get the debugger service if necessary.
} if (oldDebugPossible) {
bool jsds_IsOn = false;
const char jsdServiceCtrID[] = "@mozilla.org/js/jsd/debugger-service;1";
nsCOMPtr<jsdIExecutionHook> jsdHook;
nsCOMPtr<jsdIDebuggerService> jsds = do_GetService(jsdServiceCtrID, &rv);
// Check if there's a user for the debugger service that's 'on' for us
if (NS_SUCCEEDED(rv)) {
jsds->GetDebuggerHook(getter_AddRefs(jsdHook));
jsds->GetIsOn(&jsds_IsOn);
}
// If there is a debug handler registered for this runtime AND
// ((jsd is on AND has a hook) OR (jsd isn't on (something else debugs)))
// then something useful will be done with our request to debug.
oldDebugPossible = ((jsds_IsOn && (jsdHook != nullptr)) || !jsds_IsOn);
}
#endif #endif
}
}
bool showDebugButton = debugCallback || oldDebugPossible;
// Get localizable strings // Get localizable strings
nsXPIDLString title, msg, stopButton, waitButton, debugButton, neverShowDlg; nsXPIDLString title, msg, stopButton, waitButton, debugButton, neverShowDlg;
@ -10820,7 +10837,7 @@ nsGlobalWindow::ShowSlowScriptDialog()
} }
if (debugPossible) { if (showDebugButton) {
tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES, tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
"DebugScriptButton", "DebugScriptButton",
debugButton); debugButton);
@ -10846,7 +10863,7 @@ nsGlobalWindow::ShowSlowScriptDialog()
// GetStringFromName can return NS_OK and still give nullptr string // GetStringFromName can return NS_OK and still give nullptr string
if (NS_FAILED(rv) || !title || !msg || !stopButton || !waitButton || if (NS_FAILED(rv) || !title || !msg || !stopButton || !waitButton ||
(!debugButton && debugPossible) || !neverShowDlg) { (!debugButton && showDebugButton) || !neverShowDlg) {
NS_ERROR("Failed to get localized strings."); NS_ERROR("Failed to get localized strings.");
return ContinueSlowScript; return ContinueSlowScript;
} }
@ -10876,7 +10893,7 @@ nsGlobalWindow::ShowSlowScriptDialog()
(nsIPrompt::BUTTON_POS_0 + nsIPrompt::BUTTON_POS_1)); (nsIPrompt::BUTTON_POS_0 + nsIPrompt::BUTTON_POS_1));
// Add a third button if necessary. // Add a third button if necessary.
if (debugPossible) if (showDebugButton)
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.
@ -10893,8 +10910,15 @@ nsGlobalWindow::ShowSlowScriptDialog()
if (NS_SUCCEEDED(rv) && (buttonPressed == 0)) { if (NS_SUCCEEDED(rv) && (buttonPressed == 0)) {
return neverShowDlgChk ? AlwaysContinueSlowScript : ContinueSlowScript; return neverShowDlgChk ? AlwaysContinueSlowScript : ContinueSlowScript;
} }
if ((buttonPressed == 2) && debugPossible) { if (buttonPressed == 2) {
return js_CallContextDebugHandler(cx) ? ContinueSlowScript : KillSlowScript; if (debugCallback) {
rv = debugCallback->HandleSlowScriptDebug(this);
return NS_SUCCEEDED(rv) ? ContinueSlowScript : KillSlowScript;
}
if (oldDebugPossible) {
return js_CallContextDebugHandler(cx) ? ContinueSlowScript : KillSlowScript;
}
} }
JS_ClearPendingException(cx); JS_ClearPendingException(cx);
return KillSlowScript; return KillSlowScript;

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

@ -0,0 +1,19 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIDOMWindow;
[scriptable, function, uuid(f7dbb80c-5d1e-4fd9-b55c-a9ffda4a75b1)]
interface nsISlowScriptDebugCallback : nsISupports
{
void handleSlowScriptDebug(in nsIDOMWindow aWindow);
};
[scriptable, uuid(f75d4164-3aa7-4395-ba44-a5f95b2e8427)]
interface nsISlowScriptDebug : nsISupports
{
attribute nsISlowScriptDebugCallback activationHandler;
};