зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound
This commit is contained in:
Коммит
4bb9a04eff
|
@ -132,7 +132,7 @@ support-files =
|
|||
[browser_switch_remoteness.js]
|
||||
run-if = e10s
|
||||
[browser_upgrade_backup.js]
|
||||
skip-if = debug || ((os == 'linux') && asan) || (verify && debug && (os == 'mac')) # Bug 1435394 disabled on Linux, OSX and Windows
|
||||
skip-if = debug || asan || (verify && debug && os == 'mac') # Bug 1435394 disabled on Linux, OSX and Windows
|
||||
[browser_windowRestore_perwindowpb.js]
|
||||
[browser_248970_b_perwindowpb.js]
|
||||
# Disabled because of leaks.
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
# Sets:
|
||||
# MOZ_AUTOMATION flags
|
||||
# SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE - shouldn't be used?
|
||||
# TOOLTOOL_DIR
|
||||
# MAKECAB - shouldn't be used?
|
||||
. "$topsrcdir/build/mozconfig.win-common"
|
||||
|
||||
# MinGW does not have (or need) makecab
|
||||
unset MAKECAB
|
||||
|
||||
# Sets:
|
||||
# build/mozconfig.common
|
||||
# AUTOCLOBBER=1
|
||||
# --enable-crashreporter
|
||||
# --enable-release
|
||||
# LLVM_CONFIG
|
||||
# MOZ_REQUIRE_SIGNING
|
||||
# --enable-js-shell
|
||||
# build/mozconfig.automation
|
||||
# MOZ_AUTOMATION_ flags
|
||||
# build/mozconfig.rust
|
||||
# TOOLTOOL_DIR
|
||||
# RUSTC
|
||||
# CARGO
|
||||
. "$topsrcdir/browser/config/mozconfigs/common"
|
||||
|
||||
# MinGW Stuff
|
||||
ac_add_options --target=i686-w64-mingw32
|
||||
ac_add_options --with-toolchain-prefix=i686-w64-mingw32-
|
||||
|
||||
# GCC compiling for Windows exposes a lot of warnings. We are tracking them in Bug 1394433
|
||||
ac_add_options --disable-warnings-as-errors
|
||||
|
||||
# Temporary config settings until we get these working on mingw
|
||||
ac_add_options --disable-accessibility # https://sourceforge.net/p/mingw-w64/bugs/648/
|
||||
|
||||
# Long story
|
||||
ac_add_options --disable-stylo # Bug 1390583
|
||||
|
||||
# These aren't supported on mingw at this time
|
||||
ac_add_options --disable-webrtc # Bug 1393901
|
||||
ac_add_options --disable-maintenance-service
|
||||
|
||||
# Find our toolchain
|
||||
CC="$TOOLTOOL_DIR/mingw32/bin/i686-w64-mingw32-gcc"
|
||||
CXX="$TOOLTOOL_DIR/mingw32/bin/i686-w64-mingw32-g++"
|
||||
|
||||
# We want to make sure we use binutils and other binaries in the tooltool
|
||||
# package.
|
||||
mk_add_options "export PATH=$TOOLTOOL_DIR/mingw32/bin:$TOOLTOOL_DIR/wine/bin:$TOOLTOOL_DIR/upx/bin:$TOOLTOOL_DIR/fxc2/bin:$PATH"
|
||||
|
||||
LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$TOOLTOOL_DIR/mingw32/lib64
|
||||
mk_add_options "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
|
||||
|
||||
# Do not include the visual studio related mozconfigs of course
|
||||
|
||||
ac_add_options --with-branding=browser/branding/nightly
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
. "$topsrcdir/build/mozconfig.cache"
|
|
@ -1,4 +0,0 @@
|
|||
. "$topsrcdir/browser/config/mozconfigs/win32/mingw32"
|
||||
|
||||
ac_add_options --enable-debug
|
||||
ac_add_options --disable-optimize
|
|
@ -34,6 +34,9 @@ ac_add_options --with-toolchain-prefix=i686-w64-mingw32-
|
|||
ac_add_options --disable-warnings-as-errors
|
||||
MOZ_COPY_PDBS=1
|
||||
|
||||
# This replicates Tor's configuration
|
||||
ac_add_options --enable-proxy-bypass-protection
|
||||
|
||||
# These aren't supported on mingw at this time
|
||||
ac_add_options --disable-maintenance-service
|
||||
ac_add_options --disable-webrtc # Bug 1393901
|
||||
|
|
|
@ -3,4 +3,3 @@ MOZ_AUTOMATION_L10N_CHECK=0
|
|||
. "$topsrcdir/browser/config/mozconfigs/win32/mingwclang"
|
||||
|
||||
ac_add_options --enable-debug
|
||||
ac_add_options --disable-optimize
|
|
@ -34,6 +34,9 @@ ac_add_options --with-toolchain-prefix=x86_64-w64-mingw32-
|
|||
ac_add_options --disable-warnings-as-errors
|
||||
MOZ_COPY_PDBS=1
|
||||
|
||||
# This replicates Tor's configuration
|
||||
ac_add_options --enable-proxy-bypass-protection
|
||||
|
||||
# These aren't supported on mingw at this time
|
||||
ac_add_options --disable-maintenance-service
|
||||
ac_add_options --disable-webrtc # Bug 1393901
|
||||
|
|
|
@ -3,4 +3,3 @@ MOZ_AUTOMATION_L10N_CHECK=0
|
|||
. "$topsrcdir/browser/config/mozconfigs/win64/mingwclang"
|
||||
|
||||
ac_add_options --enable-debug
|
||||
ac_add_options --disable-optimize
|
|
@ -202,6 +202,17 @@ button > hbox > label {
|
|||
display: none;
|
||||
}
|
||||
|
||||
/* All panes */
|
||||
|
||||
.info-icon,
|
||||
.androidIcon,
|
||||
.iOSIcon,
|
||||
#updateSettingCrossUserWarning,
|
||||
.extension-controlled > description {
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
/* General Pane */
|
||||
|
||||
#isDefaultLabel {
|
||||
|
@ -212,7 +223,7 @@ button > hbox > label {
|
|||
.extension-controlled {
|
||||
margin-top: 18px !important;
|
||||
margin-bottom: 18px !important;
|
||||
background: var(--grey-20);
|
||||
background: var(--in-content-warning-container);
|
||||
border-radius: 5px;
|
||||
padding-inline-end: 10px;
|
||||
}
|
||||
|
@ -441,6 +452,11 @@ button > hbox > label {
|
|||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#sanitizeEverythingWarningBox {
|
||||
background-color: var(--in-content-box-background);
|
||||
border: 1px solid var(--in-content-box-border-color);
|
||||
}
|
||||
|
||||
#blockCookies,
|
||||
#keepRow {
|
||||
margin-top: 1.5em;
|
||||
|
@ -668,8 +684,6 @@ button > hbox > label {
|
|||
width: 20px;
|
||||
height: 20px;
|
||||
vertical-align: text-bottom;
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
#updateDeck > hbox > label {
|
||||
|
@ -728,7 +742,7 @@ image.update-throbber {
|
|||
}
|
||||
|
||||
#policies-container {
|
||||
background-color: #ededf0;
|
||||
background-color: var(--in-content-warning-container);
|
||||
padding: 0px 8px;
|
||||
margin-inline-end: 16px;
|
||||
border-radius: 2px;
|
||||
|
@ -736,8 +750,6 @@ image.update-throbber {
|
|||
|
||||
.info-icon {
|
||||
list-style-image: url("chrome://browser/skin/identity-icon.svg");
|
||||
fill: currentColor;
|
||||
-moz-context-properties: fill;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-top: calc((32px - 16px) / 2);
|
||||
|
@ -928,7 +940,7 @@ menulist[indicator=true] > menupopup menuitem[indicator=true]:not([image]) > .me
|
|||
padding-inline-start: 30px;
|
||||
margin-block-start: 20px;
|
||||
line-height: 20px;
|
||||
background-image: url("chrome://global/skin/icons/info.svg");
|
||||
background-image: url("chrome://browser/skin/identity-icon.svg");
|
||||
background-position-x: left 2px;
|
||||
background-position-y: top 2px;
|
||||
background-size: 16px 16px;
|
||||
|
|
|
@ -54,7 +54,10 @@
|
|||
.permission-icon,
|
||||
.content-blocking-category .checkbox-label-box,
|
||||
.extra-information-label > image,
|
||||
.arrowhead {
|
||||
.arrowhead,
|
||||
.content-blocking-info-image,
|
||||
.reload-tabs-button,
|
||||
.content-blocking-warning-image {
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
@ -181,8 +184,6 @@
|
|||
}
|
||||
|
||||
.reload-tabs-button {
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
max-height: 30px;
|
||||
min-height: 30px;
|
||||
padding: 0 20px;
|
||||
|
@ -279,8 +280,6 @@
|
|||
|
||||
.content-blocking-warning-image {
|
||||
list-style-image: url("chrome://global/skin/icons/warning.svg");
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
margin-inline-end: 8px;
|
||||
margin-inline-start: 4px;
|
||||
}
|
||||
|
|
|
@ -187,9 +187,12 @@ function requestExtensions() {
|
|||
await clientWrapper.listAddons({ iconDataURL: isIconDataURLRequired });
|
||||
let extensions = addons.filter(a => a.debuggable);
|
||||
|
||||
// Filter out system addons unless the dedicated preference is set to true.
|
||||
if (!getState().ui.showSystemAddons) {
|
||||
extensions = extensions.filter(e => !e.isSystem);
|
||||
// Filter out hidden & system addons unless the dedicated preference is set to true.
|
||||
if (!getState().ui.showHiddenAddons) {
|
||||
// System addons should normally also have the hidden flag. However on DevTools
|
||||
// side, `hidden` is not available on FF67 servers or older. Check both flags for
|
||||
// backward compatibility.
|
||||
extensions = extensions.filter(e => !e.isSystem && !e.hidden);
|
||||
}
|
||||
|
||||
if (runtime.type !== RUNTIMES.THIS_FIREFOX) {
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
|
||||
/* padding will give space for card shadow to appear and
|
||||
margin will correct the alignment */
|
||||
margin-inline: calc(var(--card-shadow-blur-radius) * -1);
|
||||
margin-inline-start: calc(var(--card-shadow-blur-radius) * -1);
|
||||
padding-inline: var(--card-shadow-blur-radius);
|
||||
}
|
||||
|
||||
|
|
|
@ -105,8 +105,8 @@ const PREFERENCES = {
|
|||
LOCAL_TAB_DEBUGGING_ENABLED: "devtools.aboutdebugging.local-tab-debugging",
|
||||
// Preference that drives the display of the "Processes" debug target category.
|
||||
PROCESS_DEBUGGING_ENABLED: "devtools.aboutdebugging.process-debugging",
|
||||
// Preference that drives the display of system addons in about:debugging.
|
||||
SHOW_SYSTEM_ADDONS: "devtools.aboutdebugging.showSystemAddons",
|
||||
// Preference that drives the display of hidden & system addons in about:debugging.
|
||||
SHOW_HIDDEN_ADDONS: "devtools.aboutdebugging.showHiddenAddons",
|
||||
};
|
||||
|
||||
const RUNTIME_PREFERENCE = {
|
||||
|
|
|
@ -49,9 +49,9 @@ function configureStore() {
|
|||
function getUiState() {
|
||||
const collapsibilities = getDebugTargetCollapsibilities();
|
||||
const locations = getNetworkLocations();
|
||||
const showSystemAddons = Services.prefs.getBoolPref(PREFERENCES.SHOW_SYSTEM_ADDONS,
|
||||
const showHiddenAddons = Services.prefs.getBoolPref(PREFERENCES.SHOW_HIDDEN_ADDONS,
|
||||
false);
|
||||
return new UiState(locations, collapsibilities, showSystemAddons);
|
||||
return new UiState(locations, collapsibilities, showHiddenAddons);
|
||||
}
|
||||
|
||||
exports.configureStore = configureStore;
|
||||
|
|
|
@ -19,7 +19,7 @@ const {
|
|||
} = require("../constants");
|
||||
|
||||
function UiState(locations = [], debugTargetCollapsibilities = {},
|
||||
showSystemAddons = false) {
|
||||
showHiddenAddons = false) {
|
||||
return {
|
||||
adbAddonStatus: null,
|
||||
debugTargetCollapsibilities,
|
||||
|
@ -28,7 +28,7 @@ function UiState(locations = [], debugTargetCollapsibilities = {},
|
|||
networkLocations: locations,
|
||||
selectedPage: null,
|
||||
showProfilerDialog: false,
|
||||
showSystemAddons,
|
||||
showHiddenAddons,
|
||||
temporaryInstallError: null,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
tags = devtools
|
||||
subsuite = devtools
|
||||
prefs =
|
||||
# showSystemAddons has different values depending on the build flags,
|
||||
# ensure consistent test behavior by always setting this to false.
|
||||
devtools.aboutdebugging.showSystemAddons=false
|
||||
# showHiddenAddons has different values depending on the build flags, ensure consistent
|
||||
# test behavior by always setting it to false.
|
||||
devtools.aboutdebugging.showHiddenAddons=false
|
||||
support-files =
|
||||
head.js
|
||||
helper-adb.js
|
||||
|
@ -104,7 +104,7 @@ skip-if = debug || asan # Frequent intermittent failures, Bug 1522800
|
|||
[browser_aboutdebugging_sidebar_usb_status.js]
|
||||
[browser_aboutdebugging_sidebar_usb_unavailable_runtime.js]
|
||||
[browser_aboutdebugging_sidebar_usb_unplugged_device.js]
|
||||
[browser_aboutdebugging_system_addons.js]
|
||||
[browser_aboutdebugging_hidden_addons.js]
|
||||
[browser_aboutdebugging_tab_favicons.js]
|
||||
[browser_aboutdebugging_telemetry_basic.js]
|
||||
[browser_aboutdebugging_telemetry_inspect.js]
|
||||
|
|
|
@ -3,49 +3,45 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
// Test that system addons are only displayed when the showSystemAddons preference is
|
||||
// true.
|
||||
// Test that system and hidden addons are only displayed when the showSystemAddons
|
||||
// preferences is true.
|
||||
|
||||
const SYSTEM_ADDON =
|
||||
createAddonData({ id: "system", name: "System Addon", isSystem: true });
|
||||
const INSTALLED_ADDON =
|
||||
createAddonData({ id: "installed", name: "Installed Addon", isSystem: false });
|
||||
|
||||
add_task(async function testShowSystemAddonsFalse() {
|
||||
const thisFirefoxClient = setupThisFirefoxMock();
|
||||
thisFirefoxClient.listAddons = () => ([SYSTEM_ADDON, INSTALLED_ADDON]);
|
||||
|
||||
info("Hide system addons in aboutdebugging via preference");
|
||||
await pushPref("devtools.aboutdebugging.showSystemAddons", false);
|
||||
|
||||
const { document, tab, window } = await openAboutDebugging();
|
||||
await selectThisFirefoxPage(document, window.AboutDebugging.store);
|
||||
|
||||
const hasSystemAddon = !!findDebugTargetByText("System Addon", document);
|
||||
const hasInstalledAddon = !!findDebugTargetByText("Installed Addon", document);
|
||||
ok(!hasSystemAddon, "System addon is hidden when system addon pref is false");
|
||||
ok(hasInstalledAddon, "Installed addon is displayed when system addon pref is false");
|
||||
|
||||
await removeTab(tab);
|
||||
});
|
||||
createAddonData({ id: "system", name: "System Addon", isSystem: true, hidden: true });
|
||||
const HIDDEN_ADDON =
|
||||
createAddonData({ id: "hidden", name: "Hidden Addon", isSystem: false, hidden: true });
|
||||
const NORMAL_ADDON =
|
||||
createAddonData({ id: "normal", name: "Normal Addon", isSystem: false, hidden: false });
|
||||
|
||||
add_task(async function testShowSystemAddonsTrue() {
|
||||
const thisFirefoxClient = setupThisFirefoxMock();
|
||||
thisFirefoxClient.listAddons = () => ([SYSTEM_ADDON, INSTALLED_ADDON]);
|
||||
info("Test with showHiddenAddons set to true");
|
||||
await testAddonsDisplay(true);
|
||||
|
||||
info("Show system addons in aboutdebugging via preference");
|
||||
await pushPref("devtools.aboutdebugging.showSystemAddons", true);
|
||||
info("Test with showHiddenAddons set to false");
|
||||
await testAddonsDisplay(false);
|
||||
});
|
||||
|
||||
async function testAddonsDisplay(showHidden) {
|
||||
const thisFirefoxClient = setupThisFirefoxMock();
|
||||
thisFirefoxClient.listAddons = () => ([SYSTEM_ADDON, HIDDEN_ADDON, NORMAL_ADDON]);
|
||||
|
||||
info("Set showHiddenAddons to " + showHidden);
|
||||
await pushPref("devtools.aboutdebugging.showHiddenAddons", showHidden);
|
||||
|
||||
const { document, tab, window } = await openAboutDebugging();
|
||||
await selectThisFirefoxPage(document, window.AboutDebugging.store);
|
||||
|
||||
const hasSystemAddon = !!findDebugTargetByText("System Addon", document);
|
||||
const hasInstalledAddon = !!findDebugTargetByText("Installed Addon", document);
|
||||
ok(hasSystemAddon, "System addon is displayed when system addon pref is true");
|
||||
ok(hasInstalledAddon, "Installed addon is displayed when system addon pref is true");
|
||||
const hasHiddenAddon = !!findDebugTargetByText("Hidden Addon", document);
|
||||
const hasInstalledAddon = !!findDebugTargetByText("Normal Addon", document);
|
||||
is(hasSystemAddon, showHidden,
|
||||
"System addon display is correct when showHiddenAddons is " + showHidden);
|
||||
is(hasHiddenAddon, showHidden,
|
||||
"Hidden addon display is correct when showHiddenAddons is " + showHidden);
|
||||
ok(hasInstalledAddon, "Installed addon is always displayed");
|
||||
|
||||
await removeTab(tab);
|
||||
});
|
||||
}
|
||||
|
||||
// Create a basic mock for this-firefox client, and setup a runtime-client-factory mock
|
||||
// to return our mock client when needed.
|
||||
|
@ -71,9 +67,10 @@ function setupThisFirefoxMock() {
|
|||
|
||||
// Create basic addon data as the DebuggerClient would return it (debuggable and non
|
||||
// temporary).
|
||||
function createAddonData({ id, name, isSystem }) {
|
||||
function createAddonData({ id, name, isSystem, hidden }) {
|
||||
return {
|
||||
actor: `actorid-${id}`,
|
||||
hidden,
|
||||
iconURL: `moz-extension://${id}/icon-url.png`,
|
||||
id,
|
||||
manifestURL: `moz-extension://${id}/manifest-url.json`,
|
|
@ -25,7 +25,7 @@ const Strings = Services.strings.createBundle(
|
|||
const ExtensionIcon = "chrome://mozapps/skin/extensions/extensionGeneric.svg";
|
||||
const CHROME_ENABLED_PREF = "devtools.chrome.enabled";
|
||||
const REMOTE_ENABLED_PREF = "devtools.debugger.remote-enabled";
|
||||
const SYSTEM_ENABLED_PREF = "devtools.aboutdebugging.showSystemAddons";
|
||||
const SYSTEM_ENABLED_PREF = "devtools.aboutdebugging.showHiddenAddons";
|
||||
const WEB_EXT_URL = "https://developer.mozilla.org/Add-ons" +
|
||||
"/WebExtensions/Getting_started_with_web-ext";
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
const { Preferences } = ChromeUtils.import("resource://gre/modules/Preferences.jsm");
|
||||
|
||||
const UUID_REGEX = /^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/;
|
||||
const SHOW_SYSTEM_ADDONS_PREF = "devtools.aboutdebugging.showSystemAddons";
|
||||
const SHOW_SYSTEM_ADDONS_PREF = "devtools.aboutdebugging.showHiddenAddons";
|
||||
|
||||
function testFilePath(container, expectedFilePath) {
|
||||
// Verify that the path to the install location is shown next to its label.
|
||||
|
|
|
@ -97,7 +97,12 @@ export function updateSearchResults(
|
|||
};
|
||||
}
|
||||
|
||||
export function searchContents(cx: Context, query: string, editor: Object) {
|
||||
export function searchContents(
|
||||
cx: Context,
|
||||
query: string,
|
||||
editor: Object,
|
||||
focusFirstResult?: boolean = true
|
||||
) {
|
||||
return async ({ getState, dispatch }: ThunkArgs) => {
|
||||
const modifiers = getFileSearchModifiers(getState());
|
||||
const selectedSourceWithContent = getSelectedSourceWithContent(getState());
|
||||
|
@ -131,7 +136,7 @@ export function searchContents(cx: Context, query: string, editor: Object) {
|
|||
|
||||
const matches = await getMatches(query, text, _modifiers);
|
||||
|
||||
const res = find(ctx, query, true, _modifiers);
|
||||
const res = find(ctx, query, true, _modifiers, focusFirstResult);
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ export function updateActiveFileSearch(cx: Context) {
|
|||
const fileSearchQuery = getFileSearchQuery(getState());
|
||||
if (isFileSearchOpen && fileSearchQuery) {
|
||||
const editor = getEditor();
|
||||
dispatch(searchContents(cx, fileSearchQuery, editor));
|
||||
dispatch(searchContents(cx, fileSearchQuery, editor, false));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { isTesting } from "devtools-environment";
|
||||
import type { ThunkArgs } from "../../types";
|
||||
import { prefs } from "../../../utils/prefs";
|
||||
|
||||
const blacklist = [
|
||||
"ADD_BREAKPOINT_POSITIONS",
|
||||
|
@ -95,7 +96,7 @@ export function log({ dispatch, getState }: ThunkArgs) {
|
|||
return (next: any) => (action: any) => {
|
||||
const asyncMsg = !action.status ? "" : `[${action.status}]`;
|
||||
|
||||
if (isTesting()) {
|
||||
if (isTesting() && prefs.logActions) {
|
||||
// $FlowIgnore
|
||||
dump(
|
||||
`[ACTION] ${action.type} ${asyncMsg} - ${serializeAction(action)}\n`
|
||||
|
|
|
@ -181,8 +181,8 @@ async function sourceContents({
|
|||
thread
|
||||
}: SourceActor): Promise<{| source: any, contentType: ?string |}> {
|
||||
const sourceThreadClient = lookupThreadClient(thread);
|
||||
const sourceClient = sourceThreadClient.source({ actor });
|
||||
const { source, contentType } = await sourceClient.source();
|
||||
const sourceFront = sourceThreadClient.source({ actor });
|
||||
const { source, contentType } = await sourceFront.source();
|
||||
return { source, contentType };
|
||||
}
|
||||
|
||||
|
@ -365,11 +365,11 @@ async function blackBox(
|
|||
isBlackBoxed: boolean,
|
||||
range?: Range
|
||||
): Promise<*> {
|
||||
const sourceClient = threadClient.source({ actor: sourceActor.actor });
|
||||
const sourceFront = threadClient.source({ actor: sourceActor.actor });
|
||||
if (isBlackBoxed) {
|
||||
await sourceClient.unblackBox(range);
|
||||
await sourceFront.unblackBox(range);
|
||||
} else {
|
||||
await sourceClient.blackBox(range);
|
||||
await sourceFront.blackBox(range);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -464,8 +464,8 @@ async function getBreakpointPositions(
|
|||
|
||||
for (const { thread, actor } of actors) {
|
||||
const sourceThreadClient = lookupThreadClient(thread);
|
||||
const sourceClient = sourceThreadClient.source({ actor });
|
||||
const { positions } = await sourceClient.getBreakpointPositionsCompressed(
|
||||
const sourceFront = sourceThreadClient.source({ actor });
|
||||
const positions = await sourceFront.getBreakpointPositionsCompressed(
|
||||
range
|
||||
);
|
||||
|
||||
|
|
|
@ -132,8 +132,15 @@ export function getMatchIndex(
|
|||
* @memberof utils/source-search
|
||||
* @static
|
||||
*/
|
||||
function doSearch(ctx, rev, query, keepSelection, modifiers: SearchModifiers) {
|
||||
const { cm } = ctx;
|
||||
function doSearch(
|
||||
ctx,
|
||||
rev,
|
||||
query,
|
||||
keepSelection,
|
||||
modifiers: SearchModifiers,
|
||||
focusFirstResult?: boolean = true
|
||||
) {
|
||||
const { cm, ed } = ctx;
|
||||
if (!cm) {
|
||||
return;
|
||||
}
|
||||
|
@ -153,6 +160,13 @@ function doSearch(ctx, rev, query, keepSelection, modifiers: SearchModifiers) {
|
|||
updateCursor(cm, state, keepSelection);
|
||||
const searchLocation = searchNext(ctx, rev, query, isNewQuery, modifiers);
|
||||
|
||||
// We don't want to jump the editor
|
||||
// when we're selecting text
|
||||
if (!cm.state.selectingText && searchLocation && focusFirstResult) {
|
||||
ed.alignLine(searchLocation.from.line, "center");
|
||||
cm.setSelection(searchLocation.from, searchLocation.to);
|
||||
}
|
||||
|
||||
return searchLocation ? searchLocation.from : defaultIndex;
|
||||
});
|
||||
}
|
||||
|
@ -197,7 +211,7 @@ function getCursorPos(newQuery, rev, state) {
|
|||
* @static
|
||||
*/
|
||||
function searchNext(ctx, rev, query, newQuery, modifiers) {
|
||||
const { cm, ed } = ctx;
|
||||
const { cm } = ctx;
|
||||
let nextMatch;
|
||||
cm.operation(function() {
|
||||
const state = getSearchState(cm, query);
|
||||
|
@ -220,13 +234,6 @@ function searchNext(ctx, rev, query, newQuery, modifiers) {
|
|||
}
|
||||
}
|
||||
|
||||
// We don't want to jump the editor
|
||||
// when we're selecting text
|
||||
if (!cm.state.selectingText) {
|
||||
ed.alignLine(cursor.from().line, "center");
|
||||
cm.setSelection(cursor.from(), cursor.to());
|
||||
}
|
||||
|
||||
nextMatch = { from: cursor.from(), to: cursor.to() };
|
||||
});
|
||||
|
||||
|
@ -296,10 +303,18 @@ export function find(
|
|||
ctx: any,
|
||||
query: string,
|
||||
keepSelection: boolean,
|
||||
modifiers: SearchModifiers
|
||||
modifiers: SearchModifiers,
|
||||
focusFirstResult?: boolean
|
||||
) {
|
||||
clearSearch(ctx.cm, query);
|
||||
return doSearch(ctx, false, query, keepSelection, modifiers);
|
||||
return doSearch(
|
||||
ctx,
|
||||
false,
|
||||
query,
|
||||
keepSelection,
|
||||
modifiers,
|
||||
focusFirstResult
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -68,6 +68,7 @@ if (isDevelopment()) {
|
|||
pref("devtools.debugger.features.windowless-workers", true);
|
||||
pref("devtools.debugger.features.event-listeners-breakpoints", true);
|
||||
pref("devtools.debugger.features.log-points", true);
|
||||
pref("devtools.debugger.log-actions", true);
|
||||
}
|
||||
|
||||
export const prefs = new PrefsHelper("devtools", {
|
||||
|
@ -102,7 +103,8 @@ export const prefs = new PrefsHelper("devtools", {
|
|||
debuggerPrefsSchemaVersion: ["Char", "debugger.prefs-schema-version"],
|
||||
projectDirectoryRoot: ["Char", "debugger.project-directory-root", ""],
|
||||
skipPausing: ["Bool", "debugger.skip-pausing"],
|
||||
mapScopes: ["Bool", "debugger.map-scopes-enabled"]
|
||||
mapScopes: ["Bool", "debugger.map-scopes-enabled"],
|
||||
logActions: ["Bool", "debugger.log-actions"]
|
||||
});
|
||||
|
||||
export const features = new PrefsHelper("devtools.debugger.features", {
|
||||
|
|
|
@ -755,6 +755,8 @@ skip-if = true
|
|||
[browser_dbg-scopes-mutations.js]
|
||||
[browser_dbg-search-file.js]
|
||||
skip-if = os == "win" # Bug 1393121
|
||||
[browser_dbg-search-file-paused.js]
|
||||
skip-if = os == "win" # Bug 1393121
|
||||
[browser_dbg-quick-open.js]
|
||||
skip-if = os == "win"
|
||||
[browser_dbg-search-project.js]
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* 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/>. */
|
||||
|
||||
// Tests the search bar correctly responds to queries, enter, shift enter
|
||||
|
||||
function waitForSearchState(dbg) {
|
||||
return waitForState(dbg, () => getCM(dbg).state.search);
|
||||
}
|
||||
|
||||
function getFocusedEl(dbg) {
|
||||
const doc = dbg.win.document;
|
||||
return doc.activeElement;
|
||||
}
|
||||
|
||||
function pressMouseDown(dbg, node) {
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, node, dbg.win);
|
||||
}
|
||||
|
||||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-scripts.html", "simple1.js", "simple2.js");
|
||||
const {
|
||||
selectors: { getBreakpoints, getBreakpoint, getActiveSearch },
|
||||
getState
|
||||
} = dbg;
|
||||
|
||||
info("Add a breakpoint, wait for pause");
|
||||
const source = findSource(dbg, "simple2.js");
|
||||
await selectSource(dbg, source.url);
|
||||
await addBreakpoint(dbg, source, 5);
|
||||
invokeInTab("main");
|
||||
await waitForPaused(dbg);
|
||||
|
||||
info("Starting a search for 'bar'");
|
||||
const cm = getCM(dbg);
|
||||
pressKey(dbg, "fileSearch");
|
||||
is(dbg.selectors.getActiveSearch(), "file");
|
||||
const el = getFocusedEl(dbg);
|
||||
type(dbg, "bar");
|
||||
await waitForSearchState(dbg);
|
||||
|
||||
info("Ensuring 'bar' matches are highlighted");
|
||||
pressKey(dbg, "Enter");
|
||||
is(cm.state.search.posFrom.line, 1);
|
||||
pressKey(dbg, "Enter");
|
||||
is(cm.state.search.posFrom.line, 4);
|
||||
|
||||
info("Switching files via frame click");
|
||||
const frames = findAllElements(dbg, "frames");
|
||||
pressMouseDown(dbg, frames[1])
|
||||
|
||||
// Ensure that the debug line is in view, and not the first "bar" instance,
|
||||
// which the user would have to scroll down for
|
||||
const { top } = cm.getScrollInfo();
|
||||
is(top, 0, "First search term is not in view");
|
||||
|
||||
// Change the search term and go back to the first source in stack
|
||||
info("Switching to paused file via frame click");
|
||||
pressKey(dbg, "fileSearch");
|
||||
el.value = "";
|
||||
type(dbg, "func");
|
||||
await waitForSearchState(dbg);
|
||||
pressMouseDown(dbg, frames[0]);
|
||||
await waitFor(() => cm.state.search.query === "func");
|
||||
|
||||
// Ensure there is a match for the new term
|
||||
pressKey(dbg, "Enter");
|
||||
is(cm.state.search.posFrom.line, 0);
|
||||
pressKey(dbg, "Enter");
|
||||
is(cm.state.search.posFrom.line, 1);
|
||||
});
|
|
@ -524,7 +524,7 @@ function isSelectedFrameSelected(dbg, state) {
|
|||
/**
|
||||
* Clear all the debugger related preferences.
|
||||
*/
|
||||
function clearDebuggerPreferences() {
|
||||
async function clearDebuggerPreferences() {
|
||||
asyncStorage.clear();
|
||||
Services.prefs.clearUserPref("devtools.recordreplay.enabled");
|
||||
Services.prefs.clearUserPref("devtools.debugger.pause-on-exceptions");
|
||||
|
@ -536,6 +536,7 @@ function clearDebuggerPreferences() {
|
|||
Services.prefs.clearUserPref("devtools.debugger.scopes-visible");
|
||||
Services.prefs.clearUserPref("devtools.debugger.skip-pausing");
|
||||
Services.prefs.clearUserPref("devtools.debugger.map-scopes-enabled");
|
||||
await pushPref("devtools.debugger.log-actions", true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -547,7 +548,7 @@ function clearDebuggerPreferences() {
|
|||
* @static
|
||||
*/
|
||||
async function initDebugger(url, ...sources) {
|
||||
clearDebuggerPreferences();
|
||||
await clearDebuggerPreferences();
|
||||
const toolbox = await openNewTabAndToolbox(EXAMPLE_URL + url, "jsdebugger");
|
||||
const dbg = createDebuggerContext(toolbox);
|
||||
dbg.client.waitForWorkers(false);
|
||||
|
@ -557,7 +558,7 @@ async function initDebugger(url, ...sources) {
|
|||
}
|
||||
|
||||
async function initPane(url, pane) {
|
||||
clearDebuggerPreferences();
|
||||
await clearDebuggerPreferences();
|
||||
return openNewTabAndToolbox(EXAMPLE_URL + url, pane);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ const osString = Services.appinfo.OS;
|
|||
loader.lazyGetter(this, "OptionsPanel", () => require("devtools/client/framework/toolbox-options").OptionsPanel);
|
||||
loader.lazyGetter(this, "InspectorPanel", () => require("devtools/client/inspector/panel").InspectorPanel);
|
||||
loader.lazyGetter(this, "WebConsolePanel", () => require("devtools/client/webconsole/panel").WebConsolePanel);
|
||||
loader.lazyGetter(this, "NewDebuggerPanel", () => require("devtools/client/debugger/panel").DebuggerPanel);
|
||||
loader.lazyGetter(this, "DebuggerPanel", () => require("devtools/client/debugger/panel").DebuggerPanel);
|
||||
loader.lazyGetter(this, "StyleEditorPanel", () => require("devtools/client/styleeditor/panel").StyleEditorPanel);
|
||||
loader.lazyGetter(this, "MemoryPanel", () => require("devtools/client/memory/panel").MemoryPanel);
|
||||
loader.lazyGetter(this, "PerformancePanel", () => require("devtools/client/performance/panel").PerformancePanel);
|
||||
|
@ -144,7 +144,7 @@ Tools.jsdebugger = {
|
|||
return true;
|
||||
},
|
||||
build: function(iframeWindow, toolbox) {
|
||||
return new NewDebuggerPanel(iframeWindow, toolbox);
|
||||
return new DebuggerPanel(iframeWindow, toolbox);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ pref("devtools.debugger.project-directory-root", "");
|
|||
pref("devtools.debugger.skip-pausing", false);
|
||||
pref("devtools.debugger.logging", false);
|
||||
pref("devtools.debugger.map-scopes-enabled", false);
|
||||
pref("devtools.debugger.log-actions", false);
|
||||
|
||||
pref("devtools.debugger.features.wasm", true);
|
||||
pref("devtools.debugger.features.shortcuts", true);
|
||||
|
|
|
@ -369,11 +369,11 @@ pref("devtools.aboutdebugging.collapsibilities.sharedWorker", false);
|
|||
pref("devtools.aboutdebugging.collapsibilities.tab", false);
|
||||
pref("devtools.aboutdebugging.collapsibilities.temporaryExtension", false);
|
||||
|
||||
// about:debugging: only show system add-ons in local builds by default.
|
||||
// about:debugging: only show system and hidden extensions in local builds by default.
|
||||
#ifdef MOZILLA_OFFICIAL
|
||||
pref("devtools.aboutdebugging.showSystemAddons", false);
|
||||
pref("devtools.aboutdebugging.showHiddenAddons", false);
|
||||
#else
|
||||
pref("devtools.aboutdebugging.showSystemAddons", true);
|
||||
pref("devtools.aboutdebugging.showHiddenAddons", true);
|
||||
#endif
|
||||
|
||||
// Map top-level await expressions in the console
|
||||
|
|
|
@ -80,21 +80,18 @@ class RemoteClientManager {
|
|||
}
|
||||
|
||||
const key = decodeURIComponent(remoteId);
|
||||
const type = this._getType(key);
|
||||
return Object.values(CONNECTION_TYPES).includes(type)
|
||||
? type
|
||||
: CONNECTION_TYPES.UNKNOWN;
|
||||
for (const type of Object.values(CONNECTION_TYPES)) {
|
||||
if (key.endsWith(type)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return CONNECTION_TYPES.UNKNOWN;
|
||||
}
|
||||
|
||||
_getKey(id, type) {
|
||||
return id + "-" + type;
|
||||
}
|
||||
|
||||
_getType(key) {
|
||||
const chunks = key.split("-");
|
||||
return chunks[chunks.length - 1];
|
||||
}
|
||||
|
||||
_removeClientByKey(key) {
|
||||
const client = this._clients.get(key);
|
||||
if (client) {
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { remoteClientManager } =
|
||||
require("devtools/client/shared/remote-debugging/remote-client-manager");
|
||||
const { CONNECTION_TYPES } =
|
||||
require("devtools/client/shared/remote-debugging/constants");
|
||||
|
||||
add_task(async function testRemoteClientManager() {
|
||||
for (const type of Object.values(CONNECTION_TYPES)) {
|
||||
const fakeClient = createFakeClient();
|
||||
const clientId = "clientId";
|
||||
const remoteId = remoteClientManager.getRemoteId(clientId, type);
|
||||
|
||||
const connectionType = remoteClientManager.getConnectionTypeByRemoteId(remoteId);
|
||||
equal(connectionType, type,
|
||||
`[${type}]: Correct connection type was returned by getConnectionTypeByRemoteId`);
|
||||
|
||||
equal(remoteClientManager.hasClient(clientId, type), false,
|
||||
`[${type}]: hasClient returns false if no client was set`);
|
||||
equal(remoteClientManager.getClient(clientId, type), null,
|
||||
`[${type}]: getClient returns null if no client was set`);
|
||||
equal(remoteClientManager.getClientByRemoteId(remoteId), null,
|
||||
`[${type}]: getClientByRemoteId returns null if no client was set`);
|
||||
|
||||
remoteClientManager.setClient(clientId, type, fakeClient);
|
||||
equal(remoteClientManager.hasClient(clientId, type), true,
|
||||
`[${type}]: hasClient returns true`);
|
||||
equal(remoteClientManager.getClient(clientId, type), fakeClient,
|
||||
`[${type}]: getClient returns the correct client`);
|
||||
equal(remoteClientManager.getClientByRemoteId(remoteId), fakeClient,
|
||||
`[${type}]: getClientByRemoteId returns the correct client`);
|
||||
|
||||
remoteClientManager.removeClient(clientId, type);
|
||||
equal(remoteClientManager.hasClient(clientId, type), false,
|
||||
`[${type}]: hasClient returns false after removing the client`);
|
||||
equal(remoteClientManager.getClient(clientId, type), null,
|
||||
`[${type}]: getClient returns null after removing the client`);
|
||||
equal(remoteClientManager.getClientByRemoteId(remoteId), null,
|
||||
`[${type}]: getClientByRemoteId returns null after removing the client`);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(async function testRemoteClientManagerWithUnknownType() {
|
||||
const remoteId = remoteClientManager.getRemoteId("someClientId", "NotARealType");
|
||||
const connectionType = remoteClientManager.getConnectionTypeByRemoteId(remoteId);
|
||||
equal(connectionType, CONNECTION_TYPES.UNKNOWN,
|
||||
`Connection type UNKNOWN was returned by getConnectionTypeByRemoteId`);
|
||||
});
|
||||
|
||||
function createFakeClient() {
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
|
||||
const client = {};
|
||||
EventEmitter.decorate(client);
|
||||
|
||||
// Define aliases expected by the remote-client-manager.
|
||||
client.addOneTimeListener = (evt, listener) => {
|
||||
return client.once(evt, listener);
|
||||
};
|
||||
client.addListener = (evt, listener) => {
|
||||
return client.on(evt, listener);
|
||||
};
|
||||
client.removeListener = (evt, listener) => {
|
||||
return client.off(evt, listener);
|
||||
};
|
||||
|
||||
return client;
|
||||
}
|
|
@ -4,4 +4,5 @@ head = xpcshell-head.js
|
|||
firefox-appdir = browser
|
||||
skip-if = toolkit == 'android'
|
||||
|
||||
[test_remote_client_manager.js]
|
||||
[test_version_checker.js]
|
||||
|
|
|
@ -70,19 +70,20 @@ const WebExtensionActor = protocol.ActorClassWithSpec(webExtensionSpec, {
|
|||
const policy = ExtensionParent.WebExtensionPolicy.getByID(this.addonId);
|
||||
return {
|
||||
actor: this.actorID,
|
||||
id: this.addonId,
|
||||
name: this.addon.name,
|
||||
url: this.addon.sourceURI ? this.addon.sourceURI.spec : undefined,
|
||||
debuggable: this.addon.isDebuggable,
|
||||
hidden: this.addon.hidden,
|
||||
// iconDataURL is available after calling loadIconDataURL
|
||||
iconDataURL: this._iconDataURL,
|
||||
iconURL: this.addon.iconURL,
|
||||
id: this.addonId,
|
||||
isAPIExtension: this.addon.isAPIExtension,
|
||||
isSystem: this.addon.isSystem,
|
||||
debuggable: this.addon.isDebuggable,
|
||||
isWebExtension: this.addon.isWebExtension,
|
||||
manifestURL: policy && policy.getURL("manifest.json"),
|
||||
name: this.addon.name,
|
||||
temporarilyInstalled: this.addon.temporarilyInstalled,
|
||||
type: this.addon.type,
|
||||
isWebExtension: this.addon.isWebExtension,
|
||||
isAPIExtension: this.addon.isAPIExtension,
|
||||
manifestURL: policy && policy.getURL("manifest.json"),
|
||||
url: this.addon.sourceURI ? this.addon.sourceURI.spec : undefined,
|
||||
warnings: ExtensionParent.DebugUtils.getExtensionManifestWarnings(this.addonId),
|
||||
};
|
||||
},
|
||||
|
@ -97,11 +98,11 @@ const WebExtensionActor = protocol.ActorClassWithSpec(webExtensionSpec, {
|
|||
// Merge into the child actor form, some addon metadata
|
||||
// (e.g. the addon name shown in the addon debugger window title).
|
||||
return Object.assign(form, {
|
||||
id: this.addon.id,
|
||||
name: this.addon.name,
|
||||
iconURL: this.addon.iconURL,
|
||||
id: this.addon.id,
|
||||
// Set the isOOP attribute on the connected child actor form.
|
||||
isOOP: proxy.isOOP,
|
||||
name: this.addon.name,
|
||||
});
|
||||
});
|
||||
this._destroyProxy = () => proxy.destroy();
|
||||
|
|
|
@ -324,7 +324,11 @@ const SourceActor = ActorClassWithSpec(sourceSpec, {
|
|||
},
|
||||
|
||||
/**
|
||||
* Handler for the "source" packet.
|
||||
* Handler for the "onSource" packet.
|
||||
* @return Object
|
||||
* The return of this function contains a field `contentType`, and
|
||||
* a field `source`. `source` can either be an arrayBufferActor grip,
|
||||
* or a LongStringActor grip.
|
||||
*/
|
||||
onSource: function() {
|
||||
return Promise.resolve(this._init)
|
||||
|
|
|
@ -741,38 +741,38 @@ function getFrames(threadClient, first, count) {
|
|||
/**
|
||||
* Black box the specified source.
|
||||
*
|
||||
* @param SourceClient sourceClient
|
||||
* @param SourceFront sourceFront
|
||||
* @returns Promise
|
||||
*/
|
||||
async function blackBox(sourceClient, range = null) {
|
||||
dumpn("Black boxing source: " + sourceClient.actor);
|
||||
const { error, pausedInSource } = await sourceClient.blackBox(range);
|
||||
Assert.ok(!error, "Should not get an error: " + error);
|
||||
return {error, pausedInSource};
|
||||
async function blackBox(sourceFront, range = null) {
|
||||
dumpn("Black boxing source: " + sourceFront.actor);
|
||||
const pausedInSource = await sourceFront.blackBox(range);
|
||||
ok(true, "blackBox didn't throw");
|
||||
return pausedInSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop black boxing the specified source.
|
||||
*
|
||||
* @param SourceClient sourceClient
|
||||
* @param SourceFront sourceFront
|
||||
* @returns Promise
|
||||
*/
|
||||
async function unBlackBox(sourceClient, range = null) {
|
||||
dumpn("Un-black boxing source: " + sourceClient.actor);
|
||||
const {error} = await sourceClient.unblackBox(range);
|
||||
Assert.ok(!error, "Should not get an error: " + error);
|
||||
async function unBlackBox(sourceFront, range = null) {
|
||||
dumpn("Un-black boxing source: " + sourceFront.actor);
|
||||
await sourceFront.unblackBox(range);
|
||||
ok(true, "unblackBox didn't throw");
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a "source" RDP request with the given SourceClient to get the source
|
||||
* Perform a "source" RDP request with the given SourceFront to get the source
|
||||
* content and content type.
|
||||
*
|
||||
* @param SourceClient sourceClient
|
||||
* @param SourceFront sourceFront
|
||||
* @returns Promise
|
||||
*/
|
||||
function getSourceContent(sourceClient) {
|
||||
dumpn("Getting source content for " + sourceClient.actor);
|
||||
return sourceClient.source();
|
||||
function getSourceContent(sourceFront) {
|
||||
dumpn("Getting source content for " + sourceFront.actor);
|
||||
return sourceFront.source();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -780,7 +780,7 @@ function getSourceContent(sourceClient) {
|
|||
*
|
||||
* @param ThreadClient threadClient
|
||||
* @param string url
|
||||
* @returns Promise<SourceClient>
|
||||
* @returns Promise<SourceFront>
|
||||
*/
|
||||
async function getSource(threadClient, url) {
|
||||
const source = await getSourceForm(threadClient, url);
|
||||
|
@ -872,8 +872,8 @@ async function setupTestFromUrl(url) {
|
|||
loadSubScript(sourceUrl, global);
|
||||
const { source } = await promise;
|
||||
|
||||
const sourceClient = threadClient.source(source);
|
||||
return { global, debuggerClient, threadClient, sourceClient };
|
||||
const sourceFront = threadClient.source(source);
|
||||
return { global, debuggerClient, threadClient, sourceFront };
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -70,24 +70,24 @@ function test_black_box() {
|
|||
function test_black_box_breakpoint() {
|
||||
gThreadClient.getSources(async function({error, sources}) {
|
||||
Assert.ok(!error, "Should not get an error: " + error);
|
||||
const sourceClient = gThreadClient.source(
|
||||
const sourceFront = gThreadClient.source(
|
||||
sources.filter(s => s.url == BLACK_BOXED_URL)[0]
|
||||
);
|
||||
|
||||
await blackBox(sourceClient);
|
||||
await blackBox(sourceFront);
|
||||
|
||||
gClient.addOneTimeListener("paused", function(event, packet) {
|
||||
Assert.equal(
|
||||
packet.why.type, "debuggerStatement",
|
||||
"We should pass over the breakpoint since the source is black boxed.");
|
||||
gThreadClient.resume(test_unblack_box_breakpoint.bind(null, sourceClient));
|
||||
gThreadClient.resume(test_unblack_box_breakpoint.bind(null, sourceFront));
|
||||
});
|
||||
gDebuggee.runTest();
|
||||
});
|
||||
}
|
||||
|
||||
async function test_unblack_box_breakpoint(sourceClient) {
|
||||
await unBlackBox(sourceClient);
|
||||
async function test_unblack_box_breakpoint(sourceFront) {
|
||||
await unBlackBox(sourceFront);
|
||||
gClient.addOneTimeListener("paused", function(event, packet) {
|
||||
Assert.equal(packet.why.type, "breakpoint",
|
||||
"We should hit the breakpoint again");
|
||||
|
|
|
@ -69,9 +69,9 @@ function test_black_box() {
|
|||
function test_black_box_dbg_statement() {
|
||||
gThreadClient.getSources(async function({error, sources}) {
|
||||
Assert.ok(!error, "Should not get an error: " + error);
|
||||
const sourceClient = await getSource(gThreadClient, BLACK_BOXED_URL);
|
||||
const sourceFront = await getSource(gThreadClient, BLACK_BOXED_URL);
|
||||
|
||||
await blackBox(sourceClient);
|
||||
await blackBox(sourceFront);
|
||||
|
||||
gThreadClient.addOneTimeListener("paused", async function(event, packet) {
|
||||
Assert.equal(packet.why.type, "breakpoint",
|
||||
|
@ -81,14 +81,14 @@ function test_black_box_dbg_statement() {
|
|||
gThreadClient.removeBreakpoint({ sourceUrl: source.url, line: 4 }, {});
|
||||
|
||||
await gThreadClient.resume();
|
||||
await test_unblack_box_dbg_statement(sourceClient);
|
||||
await test_unblack_box_dbg_statement(sourceFront);
|
||||
});
|
||||
gDebuggee.runTest();
|
||||
});
|
||||
}
|
||||
|
||||
async function test_unblack_box_dbg_statement(sourceClient) {
|
||||
await unBlackBox(sourceClient);
|
||||
async function test_unblack_box_dbg_statement(sourceFront) {
|
||||
await unBlackBox(sourceFront);
|
||||
|
||||
gClient.addOneTimeListener("paused", function(event, packet) {
|
||||
Assert.equal(packet.why.type, "debuggerStatement",
|
||||
|
|
|
@ -67,11 +67,11 @@ function test_black_box() {
|
|||
function test_black_box_paused() {
|
||||
gThreadClient.getSources(async function({error, sources}) {
|
||||
Assert.ok(!error, "Should not get an error: " + error);
|
||||
const sourceClient = gThreadClient.source(
|
||||
const sourceFront = gThreadClient.source(
|
||||
sources.filter(s => s.url == BLACK_BOXED_URL)[0]
|
||||
);
|
||||
|
||||
const {pausedInSource} = await blackBox(sourceClient);
|
||||
const pausedInSource = await blackBox(sourceFront);
|
||||
Assert.ok(pausedInSource,
|
||||
"We should be notified that we are currently paused in this source");
|
||||
finishClient(gClient);
|
||||
|
|
|
@ -71,8 +71,8 @@ function test_black_box() {
|
|||
function test_black_box_exception() {
|
||||
gThreadClient.getSources(async function({error, sources}) {
|
||||
Assert.ok(!error, "Should not get an error: " + error);
|
||||
const sourceClient = await getSource(gThreadClient, BLACK_BOXED_URL);
|
||||
await blackBox(sourceClient);
|
||||
const sourceFront = await getSource(gThreadClient, BLACK_BOXED_URL);
|
||||
await blackBox(sourceFront);
|
||||
gThreadClient.pauseOnExceptions(true, false);
|
||||
|
||||
gClient.addOneTimeListener("paused", async function(event, packet) {
|
||||
|
|
|
@ -29,21 +29,21 @@ function run_test() {
|
|||
await invokeAndPause(dbg, `chaining()`);
|
||||
|
||||
const { sources } = await getSources(threadClient);
|
||||
const sourceClient = threadClient.source(sources[0]);
|
||||
const sourceFront = threadClient.source(sources[0]);
|
||||
|
||||
await setBreakpoint(threadClient, { sourceUrl: sourceClient.url, line: 7 });
|
||||
await setBreakpoint(threadClient, { sourceUrl: sourceClient.url, line: 11 });
|
||||
await setBreakpoint(threadClient, { sourceUrl: sourceFront.url, line: 7 });
|
||||
await setBreakpoint(threadClient, { sourceUrl: sourceFront.url, line: 11 });
|
||||
|
||||
// 1. lets blackbox function a, and assert that we pause in b
|
||||
const range = {start: { line: 6, column: 0 }, end: { line: 8, colum: 1 }};
|
||||
blackBox(sourceClient, range);
|
||||
blackBox(sourceFront, range);
|
||||
resume(threadClient);
|
||||
const paused = await waitForPause(threadClient);
|
||||
equal(paused.frame.where.line, 11, "paused inside of b");
|
||||
await resume(threadClient);
|
||||
|
||||
// 2. lets unblackbox function a, and assert that we pause in a
|
||||
unBlackBox(sourceClient, range);
|
||||
unBlackBox(sourceFront, range);
|
||||
await invokeAndPause(dbg, `chaining()`);
|
||||
resume(threadClient);
|
||||
const paused2 = await waitForPause(threadClient);
|
||||
|
|
|
@ -22,7 +22,7 @@ add_task(threadClientTest(({ threadClient, debuggee }) => {
|
|||
threadClient.addOneTimeListener("paused", function(event, packet) {
|
||||
// Check the return value.
|
||||
Assert.equal(packet.type, "paused");
|
||||
Assert.equal(packet.frame.where.actor, source.actor);
|
||||
Assert.equal(packet.frame.where.actor, source.actorID);
|
||||
Assert.equal(packet.frame.where.line, location.line);
|
||||
Assert.equal(packet.why.type, "breakpoint");
|
||||
// Check that the breakpoint worked.
|
||||
|
|
|
@ -6,9 +6,9 @@ add_task(threadClientTest(async ({ threadClient, debuggee, client }) => {
|
|||
const promise = waitForNewSource(threadClient, SOURCE_URL);
|
||||
loadSubScript(SOURCE_URL, debuggee);
|
||||
const { source } = await promise;
|
||||
const sourceClient = threadClient.source(source);
|
||||
const sourceFront = threadClient.source(source);
|
||||
|
||||
const location = { sourceUrl: sourceClient.url, line: 4 };
|
||||
const location = { sourceUrl: sourceFront.url, line: 4 };
|
||||
setBreakpoint(threadClient, location);
|
||||
|
||||
let packet = await executeOnNextTickAndWaitForPause(function() {
|
||||
|
@ -25,7 +25,7 @@ add_task(threadClientTest(async ({ threadClient, debuggee, client }) => {
|
|||
let variables = frame.environment.bindings.variables;
|
||||
Assert.equal(variables.i.value.type, "undefined");
|
||||
|
||||
const location2 = { sourceUrl: sourceClient.url, line: 7 };
|
||||
const location2 = { sourceUrl: sourceFront.url, line: 7 };
|
||||
setBreakpoint(threadClient, location2);
|
||||
|
||||
packet = await executeOnNextTickAndWaitForPause(
|
||||
|
|
|
@ -6,9 +6,9 @@ add_task(threadClientTest(async ({ threadClient, debuggee, client }) => {
|
|||
const promise = waitForNewSource(threadClient, SOURCE_URL);
|
||||
loadSubScript(SOURCE_URL, debuggee);
|
||||
const { source } = await promise;
|
||||
const sourceClient = threadClient.source(source);
|
||||
const sourceFront = threadClient.source(source);
|
||||
|
||||
const location = { sourceUrl: sourceClient.url, line: 4 };
|
||||
const location = { sourceUrl: sourceFront.url, line: 4 };
|
||||
setBreakpoint(threadClient, location);
|
||||
|
||||
const packet = await executeOnNextTickAndWaitForPause(function() {
|
||||
|
|
|
@ -8,10 +8,10 @@ add_task(threadClientTest(async ({ threadClient, debuggee, client, targetFront }
|
|||
Cu.forceGC(); Cu.forceGC(); Cu.forceGC();
|
||||
|
||||
const { source } = await promise;
|
||||
const sourceClient = threadClient.source(source);
|
||||
const sourceFront = threadClient.source(source);
|
||||
|
||||
const location = { line: 7 };
|
||||
let [packet, breakpointClient] = await setBreakpoint(sourceClient, location);
|
||||
let [packet, breakpointClient] = await setBreakpoint(sourceFront, location);
|
||||
Assert.ok(packet.isPending);
|
||||
Assert.equal(false, "actualLocation" in packet);
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@ add_task(threadClientTest(async ({ threadClient, debuggee, client }) => {
|
|||
const promise = waitForNewSource(threadClient, SOURCE_URL);
|
||||
loadSubScript(SOURCE_URL, debuggee);
|
||||
const { source } = await promise;
|
||||
const sourceClient = threadClient.source(source);
|
||||
const sourceFront = threadClient.source(source);
|
||||
|
||||
const location = { line: 5 };
|
||||
let [packet, breakpointClient] = await setBreakpoint(sourceClient, location);
|
||||
let [packet, breakpointClient] = await setBreakpoint(sourceFront, location);
|
||||
Assert.ok(!packet.isPending);
|
||||
Assert.ok("actualLocation" in packet);
|
||||
const actualLocation = packet.actualLocation;
|
||||
|
|
|
@ -6,9 +6,9 @@ add_task(threadClientTest(async ({ threadClient, debuggee, client }) => {
|
|||
const promise = waitForNewSource(threadClient, SOURCE_URL);
|
||||
loadSubScript(SOURCE_URL, debuggee);
|
||||
const { source } = await promise;
|
||||
const sourceClient = threadClient.source(source);
|
||||
const sourceFront = threadClient.source(source);
|
||||
|
||||
const location = { sourceUrl: sourceClient.url, line: 5 };
|
||||
const location = { sourceUrl: sourceFront.url, line: 5 };
|
||||
setBreakpoint(threadClient, location);
|
||||
|
||||
const packet = await executeOnNextTickAndWaitForPause(function() {
|
||||
|
|
|
@ -9,7 +9,7 @@ var gDebuggee;
|
|||
var gClient;
|
||||
var gThreadClient;
|
||||
|
||||
// This test ensures that we can create SourceActors and SourceClients properly,
|
||||
// This test ensures that we can create SourceActors and SourceFronts properly,
|
||||
// and that they can communicate over the protocol to fetch the source text for
|
||||
// a given script.
|
||||
|
||||
|
@ -53,8 +53,8 @@ function test_source() {
|
|||
|
||||
Assert.ok(!!source);
|
||||
|
||||
const sourceClient = gThreadClient.source(source);
|
||||
sourceClient.source().then(function(response) {
|
||||
const sourceFront = gThreadClient.source(source);
|
||||
sourceFront.source().then(function(response) {
|
||||
Assert.ok(!!response);
|
||||
Assert.ok(!!response.contentType);
|
||||
Assert.ok(response.contentType.includes("javascript"));
|
||||
|
|
|
@ -9,7 +9,7 @@ var gDebuggee;
|
|||
var gClient;
|
||||
var gThreadClient;
|
||||
|
||||
// This test ensures that we can create SourceActors and SourceClients properly,
|
||||
// This test ensures that we can create SourceActors and SourceFronts properly,
|
||||
// and that they can communicate over the protocol to fetch the source text for
|
||||
// a given script.
|
||||
|
||||
|
@ -58,12 +58,11 @@ function test_source() {
|
|||
|
||||
Assert.ok(!!source);
|
||||
|
||||
const sourceClient = gThreadClient.source(source);
|
||||
response = await sourceClient.getBreakpointPositions();
|
||||
const sourceFront = gThreadClient.source(source);
|
||||
response = await sourceFront.getBreakpointPositions();
|
||||
Assert.ok(!!response);
|
||||
Assert.ok(!!response.positions);
|
||||
Assert.deepEqual(
|
||||
response.positions,
|
||||
response,
|
||||
[{
|
||||
line: 2,
|
||||
column: 2,
|
||||
|
@ -85,11 +84,10 @@ function test_source() {
|
|||
}]
|
||||
);
|
||||
|
||||
response = await sourceClient.getBreakpointPositionsCompressed();
|
||||
response = await sourceFront.getBreakpointPositionsCompressed();
|
||||
Assert.ok(!!response);
|
||||
Assert.ok(!!response.positions);
|
||||
Assert.deepEqual(
|
||||
response.positions,
|
||||
response,
|
||||
{
|
||||
2: [2],
|
||||
3: [14, 17, 24],
|
||||
|
|
|
@ -65,8 +65,8 @@ function test_source() {
|
|||
|
||||
Assert.ok(!!source);
|
||||
|
||||
const sourceClient = gThreadClient.source(source);
|
||||
sourceClient.source().then(function(response) {
|
||||
const sourceFront = gThreadClient.source(source);
|
||||
sourceFront.source().then(function(response) {
|
||||
Assert.ok(!!response);
|
||||
Assert.ok(!!response.contentType);
|
||||
Assert.ok(response.contentType.includes("wasm"));
|
||||
|
|
|
@ -14,7 +14,6 @@ DevToolsModules(
|
|||
'long-string-client.js',
|
||||
'object-client.js',
|
||||
'property-iterator-client.js',
|
||||
'source-client.js',
|
||||
'symbol-iterator-client.js',
|
||||
'thread-client.js',
|
||||
)
|
||||
|
|
|
@ -1,144 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const {arg, DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
|
||||
/**
|
||||
* A SourceClient provides a way to access the source text of a script.
|
||||
*
|
||||
* @param client ThreadClient
|
||||
* The thread client parent.
|
||||
* @param form Object
|
||||
* The form sent across the remote debugging protocol.
|
||||
*/
|
||||
function SourceClient(client, form) {
|
||||
this._form = form;
|
||||
this._activeThread = client;
|
||||
this._client = client.client;
|
||||
}
|
||||
|
||||
SourceClient.prototype = {
|
||||
get _transport() {
|
||||
return this._client._transport;
|
||||
},
|
||||
get actor() {
|
||||
return this._form.actor;
|
||||
},
|
||||
get request() {
|
||||
return this._client.request;
|
||||
},
|
||||
get url() {
|
||||
return this._form.url;
|
||||
},
|
||||
|
||||
/**
|
||||
* Black box this SourceClient's source.
|
||||
*/
|
||||
blackBox: DebuggerClient.requester(
|
||||
{
|
||||
type: "blackbox",
|
||||
range: arg(0),
|
||||
},
|
||||
{
|
||||
telemetry: "BLACKBOX",
|
||||
},
|
||||
),
|
||||
|
||||
/**
|
||||
* Un-black box this SourceClient's source.
|
||||
*/
|
||||
unblackBox: DebuggerClient.requester(
|
||||
{
|
||||
type: "unblackbox",
|
||||
range: arg(0),
|
||||
},
|
||||
{
|
||||
telemetry: "UNBLACKBOX",
|
||||
},
|
||||
),
|
||||
|
||||
getBreakpointPositions: function(query) {
|
||||
const packet = {
|
||||
to: this._form.actor,
|
||||
type: "getBreakpointPositions",
|
||||
query,
|
||||
};
|
||||
return this._client.request(packet);
|
||||
},
|
||||
|
||||
getBreakpointPositionsCompressed: function(query) {
|
||||
const packet = {
|
||||
to: this._form.actor,
|
||||
type: "getBreakpointPositionsCompressed",
|
||||
query,
|
||||
};
|
||||
return this._client.request(packet);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a long string grip for this SourceClient's source.
|
||||
*/
|
||||
source: function() {
|
||||
const packet = {
|
||||
to: this._form.actor,
|
||||
type: "source",
|
||||
};
|
||||
return this._client.request(packet).then(response => {
|
||||
return this._onSourceResponse(response);
|
||||
});
|
||||
},
|
||||
|
||||
_onSourceResponse: function(response) {
|
||||
if (typeof response.source === "string") {
|
||||
return response;
|
||||
}
|
||||
|
||||
const { contentType, source } = response;
|
||||
if (source.type === "arrayBuffer") {
|
||||
const arrayBuffer = this._activeThread.threadArrayBuffer(source);
|
||||
return arrayBuffer.slice(0, arrayBuffer.length).then(function(resp) {
|
||||
if (resp.error) {
|
||||
return resp;
|
||||
}
|
||||
// Keeping str as a string, ArrayBuffer/Uint8Array will not survive
|
||||
// setIn/mergeIn operations.
|
||||
const str = atob(resp.encoded);
|
||||
const newResponse = {
|
||||
source: {
|
||||
binary: str,
|
||||
toString: () => "[wasm]",
|
||||
},
|
||||
contentType,
|
||||
};
|
||||
return newResponse;
|
||||
});
|
||||
}
|
||||
|
||||
const longString = this._activeThread.threadLongString(source);
|
||||
return longString.substring(0, longString.length).then(function(resp) {
|
||||
if (resp.error) {
|
||||
return resp;
|
||||
}
|
||||
|
||||
const newResponse = {
|
||||
source: resp.substring,
|
||||
contentType: contentType,
|
||||
};
|
||||
return newResponse;
|
||||
});
|
||||
},
|
||||
|
||||
setPausePoints: function(pausePoints) {
|
||||
const packet = {
|
||||
to: this._form.actor,
|
||||
type: "setPausePoints",
|
||||
pausePoints,
|
||||
};
|
||||
return this._client.request(packet);
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = SourceClient;
|
|
@ -12,7 +12,7 @@ const {ThreadStateTypes} = require("devtools/shared/client/constants");
|
|||
loader.lazyRequireGetter(this, "ArrayBufferClient", "devtools/shared/client/array-buffer-client");
|
||||
loader.lazyRequireGetter(this, "LongStringClient", "devtools/shared/client/long-string-client");
|
||||
loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/object-client");
|
||||
loader.lazyRequireGetter(this, "SourceClient", "devtools/shared/client/source-client");
|
||||
loader.lazyRequireGetter(this, "SourceFront", "devtools/shared/fronts/source", true);
|
||||
|
||||
/**
|
||||
* Creates a thread client for the remote debugging protocol server. This client
|
||||
|
@ -537,14 +537,14 @@ ThreadClient.prototype = {
|
|||
}),
|
||||
|
||||
/**
|
||||
* Return an instance of SourceClient for the given source actor form.
|
||||
* Return an instance of SourceFront for the given source actor form.
|
||||
*/
|
||||
source: function(form) {
|
||||
if (form.actor in this._threadGrips) {
|
||||
return this._threadGrips[form.actor];
|
||||
}
|
||||
|
||||
this._threadGrips[form.actor] = new SourceClient(this, form);
|
||||
this._threadGrips[form.actor] = new SourceFront(this.client, form, this);
|
||||
return this._threadGrips[form.actor];
|
||||
},
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ DevToolsModules(
|
|||
'reflow.js',
|
||||
'root.js',
|
||||
'screenshot.js',
|
||||
'source.js',
|
||||
'storage.js',
|
||||
'string.js',
|
||||
'styles.js',
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/* 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";
|
||||
|
||||
const { sourceSpec } = require("devtools/shared/specs/source");
|
||||
const { FrontClassWithSpec, registerFront } = require("devtools/shared/protocol");
|
||||
|
||||
/**
|
||||
* A SourceFront provides a way to access the source text of a script.
|
||||
*
|
||||
* @param client DebuggerClient
|
||||
* The Debugger Client instance.
|
||||
* @param form Object
|
||||
* The form sent across the remote debugging protocol.
|
||||
* @param activeThread ThreadClient
|
||||
* The thread client parent. Used until the SourceFront marshalls LongStringFront
|
||||
* and ArrayBuffer.
|
||||
*/
|
||||
class SourceFront extends FrontClassWithSpec(sourceSpec) {
|
||||
constructor(client, form, activeThread) {
|
||||
super(client);
|
||||
this._url = form.url;
|
||||
this._activeThread = activeThread;
|
||||
// this is here for the time being, until the source front is managed
|
||||
// via protocol.js marshalling
|
||||
this.actorID = form.actor;
|
||||
this.manage(this);
|
||||
}
|
||||
|
||||
get actor() {
|
||||
return this.actorID;
|
||||
}
|
||||
|
||||
get url() {
|
||||
return this._url;
|
||||
}
|
||||
|
||||
// Alias for source.blackbox to avoid changing protocol.js packets
|
||||
blackBox(range) {
|
||||
return this.blackbox(range);
|
||||
}
|
||||
|
||||
// Alias for source.unblackbox to avoid changing protocol.js packets
|
||||
unblackBox() {
|
||||
return this.unblackbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a long string grip for this SourceFront's source.
|
||||
*/
|
||||
async source() {
|
||||
const response = await this.onSource();
|
||||
return this._onSourceResponse(response);
|
||||
}
|
||||
|
||||
_onSourceResponse(response) {
|
||||
if (typeof response.source === "string") {
|
||||
return response;
|
||||
}
|
||||
|
||||
const { contentType, source } = response;
|
||||
if (source.type === "arrayBuffer") {
|
||||
const arrayBuffer = this._activeThread.threadArrayBuffer(source);
|
||||
return arrayBuffer.slice(0, arrayBuffer.length).then(function(resp) {
|
||||
if (resp.error) {
|
||||
return resp;
|
||||
}
|
||||
// Keeping str as a string, ArrayBuffer/Uint8Array will not survive
|
||||
// setIn/mergeIn operations.
|
||||
const str = atob(resp.encoded);
|
||||
const newResponse = {
|
||||
source: {
|
||||
binary: str,
|
||||
toString: () => "[wasm]",
|
||||
},
|
||||
contentType,
|
||||
};
|
||||
return newResponse;
|
||||
});
|
||||
}
|
||||
|
||||
const longString = this._activeThread.threadLongString(source);
|
||||
return longString.substring(0, longString.length).then(function(resp) {
|
||||
if (resp.error) {
|
||||
return resp;
|
||||
}
|
||||
|
||||
const newResponse = {
|
||||
source: resp.substring,
|
||||
contentType: contentType,
|
||||
};
|
||||
return newResponse;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
exports.SourceFront = SourceFront;
|
||||
registerFront(SourceFront);
|
|
@ -175,7 +175,7 @@ const Types = exports.__TypesForTests = [
|
|||
{
|
||||
types: ["source"],
|
||||
spec: "devtools/shared/specs/source",
|
||||
front: null,
|
||||
front: "devtools/shared/fronts/source",
|
||||
},
|
||||
{
|
||||
types: ["cookies", "localStorage", "sessionStorage", "Cache", "indexedDB", "storage"],
|
||||
|
|
|
@ -39,6 +39,8 @@ const sourceSpec = generateActorSpec({
|
|||
},
|
||||
},
|
||||
onSource: {
|
||||
// we are sending the type "source" to be compatible
|
||||
// with FF67 and older
|
||||
request: { type: "source" },
|
||||
response: RetVal("json"),
|
||||
},
|
||||
|
|
|
@ -11,6 +11,7 @@ support-files =
|
|||
|
||||
[test_child_navigation_by_location.html]
|
||||
[test_marquee_event_handlers.html]
|
||||
skip-if = toolkit == 'android' && !is_fennec # Bug 1455996
|
||||
[test_other_auxiliary_navigation_by_location.html]
|
||||
skip-if = toolkit == 'android' && !is_fennec # Bug 1525959
|
||||
tags = openwindow
|
||||
|
|
|
@ -3360,6 +3360,11 @@ class nsContentUtils {
|
|||
static bool HighPriorityEventPendingForTopLevelDocumentBeforeContentfulPaint(
|
||||
Document* aDocument);
|
||||
|
||||
/**
|
||||
* Gets the global cookie lifetime policy.
|
||||
*/
|
||||
static uint32_t GetCookieLifetimePolicy() { return sCookiesLifetimePolicy; }
|
||||
|
||||
private:
|
||||
static bool InitializeEventTable();
|
||||
|
||||
|
|
|
@ -1628,7 +1628,7 @@ class RTCPeerConnection {
|
|||
if (maxPacketLifeTime !== undefined && maxRetransmits !== undefined) {
|
||||
throw new this._win.DOMException(
|
||||
"Both maxPacketLifeTime and maxRetransmits cannot be provided",
|
||||
"InvalidParameterError");
|
||||
"TypeError");
|
||||
}
|
||||
if (id == 65535) {
|
||||
throw new this._win.DOMException(
|
||||
|
|
|
@ -24,7 +24,8 @@ class MediaTransportParent : public dom::PMediaTransportParent {
|
|||
mozilla::ipc::IPCResult RecvCreateIceCtx(
|
||||
const string& name, nsTArray<RTCIceServer>&& iceServers,
|
||||
const RTCIceTransportPolicy& icePolicy);
|
||||
mozilla::ipc::IPCResult RecvSetProxyServer(const PBrowserOrId& browserOrId,
|
||||
mozilla::ipc::IPCResult RecvSetProxyServer(const dom::TabId& tabId,
|
||||
const net::LoadInfoArgs& args,
|
||||
const nsCString& alpn);
|
||||
mozilla::ipc::IPCResult RecvEnsureProvisionalTransport(
|
||||
const string& transportId, const string& localUfrag,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
include protocol PSocketProcessBridge;
|
||||
|
||||
#ifdef MOZ_WEBRTC
|
||||
include PBrowserOrId;
|
||||
include NeckoChannelParams;
|
||||
|
||||
// ParamTraits stuff for generated code and other classes we don't want to change
|
||||
include "mozilla/net/NrIceStunAddrMessageUtils.h";
|
||||
|
@ -19,6 +19,7 @@ using struct mozilla::dom::MovableRTCStatsReportInternal from "mozilla/media/web
|
|||
using WebrtcGlobalLog from "mozilla/media/webrtc/WebrtcGlobal.h";
|
||||
using mozilla::dom::RTCIceServer from "mozilla/dom/RTCConfigurationBinding.h";
|
||||
using mozilla::dom::RTCIceTransportPolicy from "mozilla/dom/RTCConfigurationBinding.h";
|
||||
using TabId from "mozilla/dom/ipc/IdType.h";
|
||||
|
||||
// ParamTraits stuff for our own classes
|
||||
using MediaPacket from "mtransport/mediapacket.h";
|
||||
|
@ -44,7 +45,8 @@ parent:
|
|||
RTCIceServer[] iceServers,
|
||||
RTCIceTransportPolicy icePolicy);
|
||||
|
||||
async SetProxyServer(PBrowserOrId browserOrId,
|
||||
async SetProxyServer(TabId id,
|
||||
LoadInfoArgs args, // Does this have the id?
|
||||
nsCString alpn);
|
||||
|
||||
async EnsureProvisionalTransport(string transportId,
|
||||
|
|
|
@ -6,16 +6,14 @@
|
|||
|
||||
#include "nsCookiePermission.h"
|
||||
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
#include "nsICookie2.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsICookieManager.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
|
@ -27,20 +25,13 @@
|
|||
#include "nsNetCID.h"
|
||||
#include "prtime.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
/****************************************************************
|
||||
************************ nsCookiePermission ********************
|
||||
****************************************************************/
|
||||
|
||||
// values for mCookiesLifetimePolicy
|
||||
// 0 == accept normally
|
||||
// 1 == ask before accepting, no more supported, treated like ACCEPT_NORMALLY
|
||||
// (Bug 606655). 2 == downgrade to session 3 == limit lifetime to N days
|
||||
static const uint32_t ACCEPT_NORMALLY = 0;
|
||||
static const uint32_t ACCEPT_SESSION = 2;
|
||||
|
||||
static const bool kDefaultPolicy = true;
|
||||
static const char kCookiesLifetimePolicy[] = "network.cookie.lifetimePolicy";
|
||||
|
||||
static const nsLiteralCString kPermissionType(NS_LITERAL_CSTRING("cookie"));
|
||||
|
||||
|
@ -48,7 +39,7 @@ namespace {
|
|||
mozilla::StaticRefPtr<nsCookiePermission> gSingleton;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsCookiePermission, nsICookiePermission, nsIObserver)
|
||||
NS_IMPL_ISUPPORTS(nsCookiePermission, nsICookiePermission)
|
||||
|
||||
// static
|
||||
already_AddRefed<nsICookiePermission> nsCookiePermission::GetOrCreate() {
|
||||
|
@ -68,34 +59,10 @@ bool nsCookiePermission::Init() {
|
|||
nsresult rv;
|
||||
mPermMgr = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return false;
|
||||
mThirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return false;
|
||||
|
||||
// failure to access the pref service is non-fatal...
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (prefBranch) {
|
||||
prefBranch->AddObserver(kCookiesLifetimePolicy, this, false);
|
||||
PrefChanged(prefBranch, nullptr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void nsCookiePermission::PrefChanged(nsIPrefBranch *aPrefBranch,
|
||||
const char *aPref) {
|
||||
int32_t val;
|
||||
|
||||
#define PREF_CHANGED(_P) (!aPref || !strcmp(aPref, _P))
|
||||
|
||||
if (PREF_CHANGED(kCookiesLifetimePolicy) &&
|
||||
NS_SUCCEEDED(aPrefBranch->GetIntPref(kCookiesLifetimePolicy, &val))) {
|
||||
if (val != static_cast<int32_t>(ACCEPT_SESSION)) {
|
||||
val = ACCEPT_NORMALLY;
|
||||
}
|
||||
mCookiesLifetimePolicy = val;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCookiePermission::SetAccess(nsIURI *aURI, nsCookieAccess aAccess) {
|
||||
// Lazily initialize ourselves
|
||||
|
@ -128,23 +95,6 @@ nsCookiePermission::CanAccess(nsIPrincipal *aPrincipal,
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCookiePermission::CanAccessURI(nsIURI *aURI, nsCookieAccess *aResult) {
|
||||
// Lazily initialize ourselves
|
||||
if (!EnsureInitialized()) return NS_ERROR_UNEXPECTED;
|
||||
|
||||
// finally, check with permission manager...
|
||||
nsresult rv =
|
||||
mPermMgr->TestPermission(aURI, kPermissionType, (uint32_t *)aResult);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (*aResult == nsICookiePermission::ACCESS_SESSION) {
|
||||
*aResult = nsICookiePermission::ACCESS_ALLOW;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCookiePermission::CanSetCookie(nsIURI *aURI, nsIChannel *aChannel,
|
||||
nsICookie2 *aCookie, bool *aIsSession,
|
||||
|
@ -176,7 +126,8 @@ nsCookiePermission::CanSetCookie(nsIURI *aURI, nsIChannel *aChannel,
|
|||
|
||||
// now we need to figure out what type of accept policy we're dealing with
|
||||
// if we accept cookies normally, just bail and return
|
||||
if (mCookiesLifetimePolicy == ACCEPT_NORMALLY) {
|
||||
if (nsContentUtils::GetCookieLifetimePolicy() ==
|
||||
nsICookieService::ACCEPT_NORMALLY) {
|
||||
*aResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -188,7 +139,8 @@ nsCookiePermission::CanSetCookie(nsIURI *aURI, nsIChannel *aChannel,
|
|||
// We are accepting the cookie, but,
|
||||
// if it's not a session cookie, we may have to limit its lifetime.
|
||||
if (!*aIsSession && delta > 0) {
|
||||
if (mCookiesLifetimePolicy == ACCEPT_SESSION) {
|
||||
if (nsContentUtils::GetCookieLifetimePolicy() ==
|
||||
nsICookieService::ACCEPT_SESSION) {
|
||||
// limit lifetime to session
|
||||
*aIsSession = true;
|
||||
}
|
||||
|
@ -197,15 +149,3 @@ nsCookiePermission::CanSetCookie(nsIURI *aURI, nsIChannel *aChannel,
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCookiePermission::Observe(nsISupports *aSubject, const char *aTopic,
|
||||
const char16_t *aData) {
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(aSubject);
|
||||
NS_ASSERTION(!nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic),
|
||||
"unexpected topic - we only deal with pref changes!");
|
||||
|
||||
if (prefBranch)
|
||||
PrefChanged(prefBranch, NS_LossyConvertUTF16toASCII(aData).get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -7,40 +7,25 @@
|
|||
|
||||
#include "nsICookiePermission.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
|
||||
class nsIPrefBranch;
|
||||
|
||||
class nsCookiePermission final : public nsICookiePermission,
|
||||
public nsIObserver {
|
||||
class nsCookiePermission final : public nsICookiePermission {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICOOKIEPERMISSION
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
// Singleton accessor
|
||||
static already_AddRefed<nsICookiePermission> GetOrCreate();
|
||||
static void Shutdown();
|
||||
|
||||
bool Init();
|
||||
void PrefChanged(nsIPrefBranch *, const char *);
|
||||
|
||||
private:
|
||||
nsCookiePermission()
|
||||
: mCookiesLifetimePolicy(0) // ACCEPT_NORMALLY
|
||||
{}
|
||||
virtual ~nsCookiePermission() {}
|
||||
~nsCookiePermission() = default;
|
||||
|
||||
bool EnsureInitialized() {
|
||||
return (mPermMgr != nullptr && mThirdPartyUtil != nullptr) || Init();
|
||||
};
|
||||
bool EnsureInitialized() { return (mPermMgr != nullptr) || Init(); };
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> mPermMgr;
|
||||
nsCOMPtr<mozIThirdPartyUtil> mThirdPartyUtil;
|
||||
|
||||
uint8_t mCookiesLifetimePolicy; // pref for how long cookies are stored
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -380,6 +380,32 @@ static bool AsyncTransformShouldBeUnapplied(
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a fixed-position layer, check if it's fixed with respect to the
|
||||
* zoomed APZC.
|
||||
*/
|
||||
static bool IsFixedToZoomContainer(Layer* aFixedLayer) {
|
||||
ScrollableLayerGuid::ViewID targetId =
|
||||
aFixedLayer->GetFixedPositionScrollContainerId();
|
||||
MOZ_ASSERT(targetId != ScrollableLayerGuid::NULL_SCROLL_ID);
|
||||
LayerMetricsWrapper result(aFixedLayer, LayerMetricsWrapper::StartAt::BOTTOM);
|
||||
while (result) {
|
||||
if (Maybe<ScrollableLayerGuid::ViewID> zoomedScrollId =
|
||||
result.IsAsyncZoomContainer()) {
|
||||
return *zoomedScrollId == targetId;
|
||||
}
|
||||
// Don't ascend into another layer tree. Scroll IDs are not unique
|
||||
// across layer trees, and in any case position:fixed doesn't reach
|
||||
// across documents.
|
||||
if (result.AsRefLayer() != nullptr) {
|
||||
break;
|
||||
}
|
||||
|
||||
result = result.GetParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// If |aLayer| is fixed or sticky, returns the scroll id of the scroll frame
|
||||
// that it's fixed or sticky to. Otherwise, returns Nothing().
|
||||
static Maybe<ScrollableLayerGuid::ViewID> IsFixedOrSticky(Layer* aLayer) {
|
||||
|
@ -1084,7 +1110,7 @@ bool AsyncCompositionManager::ApplyAsyncContentTransformToTree(
|
|||
metrics);
|
||||
}
|
||||
}
|
||||
fixedLayerMargins = mFixedLayerMargins;
|
||||
fixedLayerMargins = GetFixedLayerMargins();
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
@ -1197,6 +1223,27 @@ bool AsyncCompositionManager::ApplyAsyncContentTransformToTree(
|
|||
// scroll metadata for zoomedScrollId appears in the layer tree.
|
||||
}
|
||||
}
|
||||
|
||||
// Layers fixed to the RCD-RSF no longer need
|
||||
// AdjustFixedOrStickyLayer() to scroll them by the eVisual transform,
|
||||
// as that's now applied to the async zoom container itself. However,
|
||||
// we still need to adjust them by the fixed layer margins to
|
||||
// account for dynamic toolbar transitions. This is also handled by
|
||||
// AdjustFixedOrStickyLayer(), so we now call it with empty transforms
|
||||
// to get it to perform just the fixed margins adjustment.
|
||||
if (zoomedMetrics && layer->GetIsFixedPosition() &&
|
||||
!layer->GetParent()->GetIsFixedPosition() &&
|
||||
IsFixedToZoomContainer(layer)) {
|
||||
LayerToParentLayerMatrix4x4 emptyTransform;
|
||||
ScreenMargin marginsForFixedLayer;
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
marginsForFixedLayer = GetFixedLayerMargins();
|
||||
#endif
|
||||
AdjustFixedOrStickyLayer(zoomContainer, layer,
|
||||
sampler->GetGuid(*zoomedMetrics).mScrollId,
|
||||
emptyTransform, emptyTransform,
|
||||
marginsForFixedLayer, clipPartsCache);
|
||||
}
|
||||
}
|
||||
|
||||
bool clipChanged = (hasAsyncTransform || clipDeferredFromChildren ||
|
||||
|
@ -1407,9 +1454,9 @@ bool AsyncCompositionManager::TransformShadowTree(
|
|||
if (ApplyAsyncContentTransformToTree(root, &foundRoot)) {
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
MOZ_ASSERT(foundRoot);
|
||||
if (foundRoot && mFixedLayerMargins != ScreenMargin()) {
|
||||
if (foundRoot && GetFixedLayerMargins() != ScreenMargin()) {
|
||||
MoveScrollbarForLayerMargin(root, mRootScrollableId,
|
||||
mFixedLayerMargins);
|
||||
GetFixedLayerMargins());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1441,6 +1488,14 @@ void AsyncCompositionManager::SetFixedLayerMargins(ScreenIntCoord aTop,
|
|||
mFixedLayerMargins.top = aTop;
|
||||
mFixedLayerMargins.bottom = aBottom;
|
||||
}
|
||||
ScreenMargin AsyncCompositionManager::GetFixedLayerMargins() const {
|
||||
ScreenMargin result = mFixedLayerMargins;
|
||||
if (gfxPrefs::APZFixedMarginOverrideEnabled()) {
|
||||
result.top = gfxPrefs::APZFixedMarginOverrideTop();
|
||||
result.bottom = gfxPrefs::APZFixedMarginOverrideBottom();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif // defined(MOZ_WIDGET_ANDROID)
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -237,6 +237,7 @@ class AsyncCompositionManager final {
|
|||
#ifdef MOZ_WIDGET_ANDROID
|
||||
public:
|
||||
void SetFixedLayerMargins(ScreenIntCoord aTop, ScreenIntCoord aBottom);
|
||||
ScreenMargin GetFixedLayerMargins() const;
|
||||
|
||||
private:
|
||||
// This calculates whether frame metrics should be sent to Java.
|
||||
|
|
|
@ -317,6 +317,9 @@ class gfxPrefs final {
|
|||
DECL_GFX_PREF(Live, "apz.drag.initial.enabled", APZDragInitiationEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "apz.drag.touch.enabled", APZTouchDragEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "apz.enlarge_displayport_when_clipped", APZEnlargeDisplayPortWhenClipped, bool, false);
|
||||
DECL_GFX_PREF(Live, "apz.fixed-margin-override.enabled", APZFixedMarginOverrideEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "apz.fixed-margin-override.bottom", APZFixedMarginOverrideBottom, int32_t, 0);
|
||||
DECL_GFX_PREF(Live, "apz.fixed-margin-override.top", APZFixedMarginOverrideTop, int32_t, 0);
|
||||
DECL_GFX_PREF(Live, "apz.fling_accel_base_mult", APZFlingAccelBaseMultiplier, float, 1.0f);
|
||||
DECL_GFX_PREF(Live, "apz.fling_accel_interval_ms", APZFlingAccelInterval, int32_t, 500);
|
||||
DECL_GFX_PREF(Live, "apz.fling_accel_supplemental_mult", APZFlingAccelSupplementalMultiplier, float, 1.0f);
|
||||
|
|
|
@ -47,6 +47,9 @@
|
|||
END_CATEGORY \
|
||||
BEGIN_CATEGORY(JS, "JavaScript", "yellow") \
|
||||
SUBCATEGORY(JS, JS, "Other") \
|
||||
SUBCATEGORY(JS, JS_Parsing, "JS Parsing") \
|
||||
SUBCATEGORY(JS, JS_IonCompilation, "Ion JIT Compilation") \
|
||||
SUBCATEGORY(JS, JS_BaselineCompilation, "Baseline JIT Compilation") \
|
||||
END_CATEGORY \
|
||||
BEGIN_CATEGORY(GCCC, "GC / CC", "orange") \
|
||||
SUBCATEGORY(GCCC, GCCC, "Other") \
|
||||
|
|
|
@ -528,7 +528,8 @@ JSScript* frontend::ScriptCompiler<Unit>::compileScript(
|
|||
for (;;) {
|
||||
ParseNode* pn;
|
||||
{
|
||||
AutoGeckoProfilerEntry pseudoFrame(cx, "script parsing");
|
||||
AutoGeckoProfilerEntry pseudoFrame(cx, "script parsing",
|
||||
JS::ProfilingCategoryPair::JS_Parsing);
|
||||
if (sc->isEvalContext()) {
|
||||
pn = parser->evalBody(sc->asEvalContext());
|
||||
} else {
|
||||
|
@ -537,7 +538,8 @@ JSScript* frontend::ScriptCompiler<Unit>::compileScript(
|
|||
}
|
||||
|
||||
// Successfully parsed. Emit the script.
|
||||
AutoGeckoProfilerEntry pseudoFrame(cx, "script emit");
|
||||
AutoGeckoProfilerEntry pseudoFrame(cx, "script emit",
|
||||
JS::ProfilingCategoryPair::JS_Parsing);
|
||||
if (pn) {
|
||||
if (sc->isEvalContext() && sc->hasDebuggerStatement() &&
|
||||
!cx->helperThread()) {
|
||||
|
|
|
@ -372,7 +372,11 @@ class InterpreterFrameInfo : public FrameInfo {
|
|||
|
||||
void popn(uint32_t n) { masm.addToStackPtr(Imm32(n * sizeof(Value))); }
|
||||
|
||||
void popn(Register reg) { masm.addToStackPtr(reg); }
|
||||
void popn(Register reg) {
|
||||
// sp := sp + reg * sizeof(Value)
|
||||
Register spReg = AsRegister(masm.getStackPointer());
|
||||
masm.computeEffectiveAddress(BaseValueIndex(spReg, reg), spReg);
|
||||
}
|
||||
|
||||
void popValue(ValueOperand dest) { masm.popValue(dest); }
|
||||
|
||||
|
|
|
@ -739,13 +739,21 @@ static void TryAttachStub(const char* name, JSContext* cx, BaselineFrame* frame,
|
|||
bool attached = false;
|
||||
IRGenerator gen(cx, script, pc, stub->state().mode(),
|
||||
std::forward<Args>(args)...);
|
||||
if (gen.tryAttachStub()) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(
|
||||
cx, gen.writerRef(), gen.cacheKind(), kind, script, stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " %s %s CacheIR stub",
|
||||
attached ? "Attached" : "Failed to attach", name);
|
||||
}
|
||||
switch (gen.tryAttachStub()) {
|
||||
case AttachDecision::Attach: {
|
||||
ICStub* newStub =
|
||||
AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
|
||||
kind, script, stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached %s CacheIR stub", name);
|
||||
}
|
||||
} break;
|
||||
case AttachDecision::NoAction:
|
||||
break;
|
||||
case AttachDecision::TemporarilyUnoptimizable:
|
||||
case AttachDecision::Deferred:
|
||||
MOZ_ASSERT_UNREACHABLE("Not expected in generic TryAttachStub");
|
||||
break;
|
||||
}
|
||||
if (!attached) {
|
||||
stub->state().trackNotAttached();
|
||||
|
@ -2033,6 +2041,49 @@ static void StripPreliminaryObjectStubs(JSContext* cx, ICFallbackStub* stub) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool TryAttachGetPropStub(const char* name, JSContext* cx,
|
||||
BaselineFrame* frame, ICFallbackStub* stub,
|
||||
CacheKind kind, HandleValue val,
|
||||
HandleValue idVal, HandleValue receiver) {
|
||||
bool attached = false;
|
||||
|
||||
if (stub->state().maybeTransition()) {
|
||||
stub->discardStubs(cx);
|
||||
}
|
||||
|
||||
if (stub->state().canAttachStub()) {
|
||||
RootedScript script(cx, frame->script());
|
||||
jsbytecode* pc = stub->icEntry()->pc(script);
|
||||
|
||||
GetPropIRGenerator gen(cx, script, pc, stub->state().mode(), kind, val,
|
||||
idVal, receiver, GetPropertyResultFlags::All);
|
||||
switch (gen.tryAttachStub()) {
|
||||
case AttachDecision::Attach: {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(
|
||||
cx, gen.writerRef(), gen.cacheKind(),
|
||||
BaselineCacheIRStubKind::Monitored, script, stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached %s CacheIR stub", name);
|
||||
if (gen.shouldNotePreliminaryObjectStub()) {
|
||||
newStub->toCacheIR_Monitored()->notePreliminaryObject();
|
||||
} else if (gen.shouldUnlinkPreliminaryObjectStubs()) {
|
||||
StripPreliminaryObjectStubs(cx, stub);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case AttachDecision::NoAction:
|
||||
break;
|
||||
case AttachDecision::TemporarilyUnoptimizable:
|
||||
attached = true;
|
||||
break;
|
||||
case AttachDecision::Deferred:
|
||||
MOZ_ASSERT_UNREACHABLE("No deferred GetProp stubs");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return attached;
|
||||
}
|
||||
|
||||
//
|
||||
// GetElem_Fallback
|
||||
//
|
||||
|
@ -2066,34 +2117,8 @@ bool DoGetElemFallback(JSContext* cx, BaselineFrame* frame,
|
|||
}
|
||||
}
|
||||
|
||||
bool attached = false;
|
||||
bool isTemporarilyUnoptimizable = false;
|
||||
|
||||
if (stub->state().maybeTransition()) {
|
||||
stub->discardStubs(cx);
|
||||
}
|
||||
|
||||
if (stub->state().canAttachStub()) {
|
||||
GetPropIRGenerator gen(cx, script, pc, CacheKind::GetElem,
|
||||
stub->state().mode(), &isTemporarilyUnoptimizable,
|
||||
lhs, rhs, lhs, GetPropertyResultFlags::All);
|
||||
if (gen.tryAttachStub()) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(
|
||||
cx, gen.writerRef(), gen.cacheKind(),
|
||||
BaselineCacheIRStubKind::Monitored, script, stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached GetElem CacheIR stub");
|
||||
if (gen.shouldNotePreliminaryObjectStub()) {
|
||||
newStub->toCacheIR_Monitored()->notePreliminaryObject();
|
||||
} else if (gen.shouldUnlinkPreliminaryObjectStubs()) {
|
||||
StripPreliminaryObjectStubs(cx, stub);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!attached && !isTemporarilyUnoptimizable) {
|
||||
stub->state().trackNotAttached();
|
||||
}
|
||||
}
|
||||
bool attached = TryAttachGetPropStub("GetElem", cx, frame, stub,
|
||||
CacheKind::GetElem, lhs, rhs, lhs);
|
||||
|
||||
if (!isOptimizedArgs) {
|
||||
if (!GetElementOperation(cx, op, lhsCopy, rhs, res)) {
|
||||
|
@ -2144,34 +2169,9 @@ bool DoGetElemSuperFallback(JSContext* cx, BaselineFrame* frame,
|
|||
|
||||
MOZ_ASSERT(op == JSOP_GETELEM_SUPER);
|
||||
|
||||
bool attached = false;
|
||||
bool isTemporarilyUnoptimizable = false;
|
||||
|
||||
if (stub->state().maybeTransition()) {
|
||||
stub->discardStubs(cx);
|
||||
}
|
||||
|
||||
if (stub->state().canAttachStub()) {
|
||||
GetPropIRGenerator gen(cx, script, pc, CacheKind::GetElemSuper,
|
||||
stub->state().mode(), &isTemporarilyUnoptimizable,
|
||||
lhs, rhs, receiver, GetPropertyResultFlags::All);
|
||||
if (gen.tryAttachStub()) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(
|
||||
cx, gen.writerRef(), gen.cacheKind(),
|
||||
BaselineCacheIRStubKind::Monitored, script, stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached GetElemSuper CacheIR stub");
|
||||
if (gen.shouldNotePreliminaryObjectStub()) {
|
||||
newStub->toCacheIR_Monitored()->notePreliminaryObject();
|
||||
} else if (gen.shouldUnlinkPreliminaryObjectStubs()) {
|
||||
StripPreliminaryObjectStubs(cx, stub);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!attached && !isTemporarilyUnoptimizable) {
|
||||
stub->state().trackNotAttached();
|
||||
}
|
||||
}
|
||||
bool attached =
|
||||
TryAttachGetPropStub("GetElemSuper", cx, frame, stub,
|
||||
CacheKind::GetElemSuper, lhs, rhs, receiver);
|
||||
|
||||
// |lhs| is [[HomeObject]].[[Prototype]] which must be Object
|
||||
RootedObject lhsObj(cx, &lhs.toObject());
|
||||
|
@ -2301,6 +2301,8 @@ static void SetUpdateStubData(ICCacheIR_Updated* stub,
|
|||
bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame,
|
||||
ICSetElem_Fallback* stub, Value* stack, HandleValue objv,
|
||||
HandleValue index, HandleValue rhs) {
|
||||
using DeferType = SetPropIRGenerator::DeferType;
|
||||
|
||||
stub->incrementEnteredCount();
|
||||
|
||||
RootedScript script(cx, frame->script());
|
||||
|
@ -2324,8 +2326,7 @@ bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool isTemporarilyUnoptimizable = false;
|
||||
bool canAddSlot = false;
|
||||
DeferType deferType = DeferType::None;
|
||||
bool attached = false;
|
||||
|
||||
if (stub->state().maybeTransition()) {
|
||||
|
@ -2334,27 +2335,37 @@ bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame,
|
|||
|
||||
if (stub->state().canAttachStub()) {
|
||||
SetPropIRGenerator gen(cx, script, pc, CacheKind::SetElem,
|
||||
stub->state().mode(), &isTemporarilyUnoptimizable,
|
||||
&canAddSlot, objv, index, rhs);
|
||||
if (gen.tryAttachStub()) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(
|
||||
cx, gen.writerRef(), gen.cacheKind(),
|
||||
BaselineCacheIRStubKind::Updated, frame->script(), stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached SetElem CacheIR stub");
|
||||
stub->state().mode(), objv, index, rhs);
|
||||
switch (gen.tryAttachStub()) {
|
||||
case AttachDecision::Attach: {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(
|
||||
cx, gen.writerRef(), gen.cacheKind(),
|
||||
BaselineCacheIRStubKind::Updated, frame->script(), stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached SetElem CacheIR stub");
|
||||
|
||||
SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo());
|
||||
SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo());
|
||||
|
||||
if (gen.shouldNotePreliminaryObjectStub()) {
|
||||
newStub->toCacheIR_Updated()->notePreliminaryObject();
|
||||
} else if (gen.shouldUnlinkPreliminaryObjectStubs()) {
|
||||
StripPreliminaryObjectStubs(cx, stub);
|
||||
if (gen.shouldNotePreliminaryObjectStub()) {
|
||||
newStub->toCacheIR_Updated()->notePreliminaryObject();
|
||||
} else if (gen.shouldUnlinkPreliminaryObjectStubs()) {
|
||||
StripPreliminaryObjectStubs(cx, stub);
|
||||
}
|
||||
|
||||
if (gen.attachedTypedArrayOOBStub()) {
|
||||
stub->noteHasTypedArrayOOB();
|
||||
}
|
||||
}
|
||||
|
||||
if (gen.attachedTypedArrayOOBStub()) {
|
||||
stub->noteHasTypedArrayOOB();
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case AttachDecision::NoAction:
|
||||
break;
|
||||
case AttachDecision::TemporarilyUnoptimizable:
|
||||
attached = true;
|
||||
break;
|
||||
case AttachDecision::Deferred:
|
||||
deferType = gen.deferType();
|
||||
MOZ_ASSERT(deferType != DeferType::None);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2402,34 +2413,44 @@ bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame,
|
|||
stub->discardStubs(cx);
|
||||
}
|
||||
|
||||
if (stub->state().canAttachStub()) {
|
||||
bool canAttachStub = stub->state().canAttachStub();
|
||||
|
||||
if (deferType != DeferType::None && canAttachStub) {
|
||||
SetPropIRGenerator gen(cx, script, pc, CacheKind::SetElem,
|
||||
stub->state().mode(), &isTemporarilyUnoptimizable,
|
||||
&canAddSlot, objv, index, rhs);
|
||||
if (canAddSlot && gen.tryAttachAddSlotStub(oldGroup, oldShape)) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(
|
||||
cx, gen.writerRef(), gen.cacheKind(),
|
||||
BaselineCacheIRStubKind::Updated, frame->script(), stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached SetElem CacheIR stub");
|
||||
stub->state().mode(), objv, index, rhs);
|
||||
|
||||
SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo());
|
||||
MOZ_ASSERT(deferType == DeferType::AddSlot);
|
||||
AttachDecision decision = gen.tryAttachAddSlotStub(oldGroup, oldShape);
|
||||
|
||||
if (gen.shouldNotePreliminaryObjectStub()) {
|
||||
newStub->toCacheIR_Updated()->notePreliminaryObject();
|
||||
} else if (gen.shouldUnlinkPreliminaryObjectStubs()) {
|
||||
StripPreliminaryObjectStubs(cx, stub);
|
||||
switch (decision) {
|
||||
case AttachDecision::Attach: {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(
|
||||
cx, gen.writerRef(), gen.cacheKind(),
|
||||
BaselineCacheIRStubKind::Updated, frame->script(), stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached SetElem CacheIR stub");
|
||||
|
||||
SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo());
|
||||
|
||||
if (gen.shouldNotePreliminaryObjectStub()) {
|
||||
newStub->toCacheIR_Updated()->notePreliminaryObject();
|
||||
} else if (gen.shouldUnlinkPreliminaryObjectStubs()) {
|
||||
StripPreliminaryObjectStubs(cx, stub);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
gen.trackAttached(IRGenerator::NotAttached);
|
||||
}
|
||||
if (!attached && !isTemporarilyUnoptimizable) {
|
||||
stub->state().trackNotAttached();
|
||||
} break;
|
||||
case AttachDecision::NoAction:
|
||||
gen.trackAttached(IRGenerator::NotAttached);
|
||||
break;
|
||||
case AttachDecision::TemporarilyUnoptimizable:
|
||||
case AttachDecision::Deferred:
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid attach result");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!attached && canAttachStub) {
|
||||
stub->state().trackNotAttached();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2834,40 +2855,10 @@ bool DoGetPropFallback(JSContext* cx, BaselineFrame* frame,
|
|||
op == JSOP_GETBOUNDNAME);
|
||||
|
||||
RootedPropertyName name(cx, script->getName(pc));
|
||||
RootedValue idVal(cx, StringValue(name));
|
||||
|
||||
// There are some reasons we can fail to attach a stub that are temporary.
|
||||
// We want to avoid calling noteUnoptimizableAccess() if the reason we
|
||||
// failed to attach a stub is one of those temporary reasons, since we might
|
||||
// end up attaching a stub for the exact same access later.
|
||||
bool isTemporarilyUnoptimizable = false;
|
||||
|
||||
if (stub->state().maybeTransition()) {
|
||||
stub->discardStubs(cx);
|
||||
}
|
||||
|
||||
bool attached = false;
|
||||
if (stub->state().canAttachStub()) {
|
||||
RootedValue idVal(cx, StringValue(name));
|
||||
GetPropIRGenerator gen(cx, script, pc, CacheKind::GetProp,
|
||||
stub->state().mode(), &isTemporarilyUnoptimizable,
|
||||
val, idVal, val, GetPropertyResultFlags::All);
|
||||
if (gen.tryAttachStub()) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(
|
||||
cx, gen.writerRef(), gen.cacheKind(),
|
||||
BaselineCacheIRStubKind::Monitored, script, stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached GetProp CacheIR stub");
|
||||
if (gen.shouldNotePreliminaryObjectStub()) {
|
||||
newStub->toCacheIR_Monitored()->notePreliminaryObject();
|
||||
} else if (gen.shouldUnlinkPreliminaryObjectStubs()) {
|
||||
StripPreliminaryObjectStubs(cx, stub);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!attached && !isTemporarilyUnoptimizable) {
|
||||
stub->state().trackNotAttached();
|
||||
}
|
||||
}
|
||||
TryAttachGetPropStub("GetProp", cx, frame, stub, CacheKind::GetProp, val,
|
||||
idVal, val);
|
||||
|
||||
if (!ComputeGetPropResult(cx, frame, op, name, val, res)) {
|
||||
return false;
|
||||
|
@ -2895,40 +2886,10 @@ bool DoGetPropSuperFallback(JSContext* cx, BaselineFrame* frame,
|
|||
MOZ_ASSERT(JSOp(*pc) == JSOP_GETPROP_SUPER);
|
||||
|
||||
RootedPropertyName name(cx, script->getName(pc));
|
||||
RootedValue idVal(cx, StringValue(name));
|
||||
|
||||
// There are some reasons we can fail to attach a stub that are temporary.
|
||||
// We want to avoid calling noteUnoptimizableAccess() if the reason we
|
||||
// failed to attach a stub is one of those temporary reasons, since we might
|
||||
// end up attaching a stub for the exact same access later.
|
||||
bool isTemporarilyUnoptimizable = false;
|
||||
|
||||
if (stub->state().maybeTransition()) {
|
||||
stub->discardStubs(cx);
|
||||
}
|
||||
|
||||
bool attached = false;
|
||||
if (stub->state().canAttachStub()) {
|
||||
RootedValue idVal(cx, StringValue(name));
|
||||
GetPropIRGenerator gen(cx, script, pc, CacheKind::GetPropSuper,
|
||||
stub->state().mode(), &isTemporarilyUnoptimizable,
|
||||
val, idVal, receiver, GetPropertyResultFlags::All);
|
||||
if (gen.tryAttachStub()) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(
|
||||
cx, gen.writerRef(), gen.cacheKind(),
|
||||
BaselineCacheIRStubKind::Monitored, script, stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached GetPropSuper CacheIR stub");
|
||||
if (gen.shouldNotePreliminaryObjectStub()) {
|
||||
newStub->toCacheIR_Monitored()->notePreliminaryObject();
|
||||
} else if (gen.shouldUnlinkPreliminaryObjectStubs()) {
|
||||
StripPreliminaryObjectStubs(cx, stub);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!attached && !isTemporarilyUnoptimizable) {
|
||||
stub->state().trackNotAttached();
|
||||
}
|
||||
}
|
||||
TryAttachGetPropStub("GetPropSuper", cx, frame, stub, CacheKind::GetPropSuper,
|
||||
val, idVal, receiver);
|
||||
|
||||
// |val| is [[HomeObject]].[[Prototype]] which must be Object
|
||||
RootedObject valObj(cx, &val.toObject());
|
||||
|
@ -3024,6 +2985,8 @@ bool FallbackICCodeCompiler::emit_GetPropSuper() {
|
|||
bool DoSetPropFallback(JSContext* cx, BaselineFrame* frame,
|
||||
ICSetProp_Fallback* stub, Value* stack, HandleValue lhs,
|
||||
HandleValue rhs) {
|
||||
using DeferType = SetPropIRGenerator::DeferType;
|
||||
|
||||
stub->incrementEnteredCount();
|
||||
|
||||
RootedScript script(cx, frame->script());
|
||||
|
@ -3050,13 +3013,7 @@ bool DoSetPropFallback(JSContext* cx, BaselineFrame* frame,
|
|||
return false;
|
||||
}
|
||||
|
||||
// There are some reasons we can fail to attach a stub that are temporary.
|
||||
// We want to avoid calling noteUnoptimizableAccess() if the reason we
|
||||
// failed to attach a stub is one of those temporary reasons, since we might
|
||||
// end up attaching a stub for the exact same access later.
|
||||
bool isTemporarilyUnoptimizable = false;
|
||||
bool canAddSlot = false;
|
||||
|
||||
DeferType deferType = DeferType::None;
|
||||
bool attached = false;
|
||||
if (stub->state().maybeTransition()) {
|
||||
stub->discardStubs(cx);
|
||||
|
@ -3065,23 +3022,33 @@ bool DoSetPropFallback(JSContext* cx, BaselineFrame* frame,
|
|||
if (stub->state().canAttachStub()) {
|
||||
RootedValue idVal(cx, StringValue(name));
|
||||
SetPropIRGenerator gen(cx, script, pc, CacheKind::SetProp,
|
||||
stub->state().mode(), &isTemporarilyUnoptimizable,
|
||||
&canAddSlot, lhs, idVal, rhs);
|
||||
if (gen.tryAttachStub()) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(
|
||||
cx, gen.writerRef(), gen.cacheKind(),
|
||||
BaselineCacheIRStubKind::Updated, frame->script(), stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached SetProp CacheIR stub");
|
||||
stub->state().mode(), lhs, idVal, rhs);
|
||||
switch (gen.tryAttachStub()) {
|
||||
case AttachDecision::Attach: {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(
|
||||
cx, gen.writerRef(), gen.cacheKind(),
|
||||
BaselineCacheIRStubKind::Updated, frame->script(), stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached SetProp CacheIR stub");
|
||||
|
||||
SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo());
|
||||
SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo());
|
||||
|
||||
if (gen.shouldNotePreliminaryObjectStub()) {
|
||||
newStub->toCacheIR_Updated()->notePreliminaryObject();
|
||||
} else if (gen.shouldUnlinkPreliminaryObjectStubs()) {
|
||||
StripPreliminaryObjectStubs(cx, stub);
|
||||
if (gen.shouldNotePreliminaryObjectStub()) {
|
||||
newStub->toCacheIR_Updated()->notePreliminaryObject();
|
||||
} else if (gen.shouldUnlinkPreliminaryObjectStubs()) {
|
||||
StripPreliminaryObjectStubs(cx, stub);
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case AttachDecision::NoAction:
|
||||
break;
|
||||
case AttachDecision::TemporarilyUnoptimizable:
|
||||
attached = true;
|
||||
break;
|
||||
case AttachDecision::Deferred:
|
||||
deferType = gen.deferType();
|
||||
MOZ_ASSERT(deferType != DeferType::None);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3130,33 +3097,45 @@ bool DoSetPropFallback(JSContext* cx, BaselineFrame* frame,
|
|||
stub->discardStubs(cx);
|
||||
}
|
||||
|
||||
if (stub->state().canAttachStub()) {
|
||||
bool canAttachStub = stub->state().canAttachStub();
|
||||
|
||||
if (deferType != DeferType::None && canAttachStub) {
|
||||
RootedValue idVal(cx, StringValue(name));
|
||||
SetPropIRGenerator gen(cx, script, pc, CacheKind::SetProp,
|
||||
stub->state().mode(), &isTemporarilyUnoptimizable,
|
||||
&canAddSlot, lhs, idVal, rhs);
|
||||
if (canAddSlot && gen.tryAttachAddSlotStub(oldGroup, oldShape)) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(
|
||||
cx, gen.writerRef(), gen.cacheKind(),
|
||||
BaselineCacheIRStubKind::Updated, frame->script(), stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached SetProp CacheIR stub");
|
||||
stub->state().mode(), lhs, idVal, rhs);
|
||||
|
||||
SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo());
|
||||
MOZ_ASSERT(deferType == DeferType::AddSlot);
|
||||
AttachDecision decision = gen.tryAttachAddSlotStub(oldGroup, oldShape);
|
||||
|
||||
if (gen.shouldNotePreliminaryObjectStub()) {
|
||||
newStub->toCacheIR_Updated()->notePreliminaryObject();
|
||||
} else if (gen.shouldUnlinkPreliminaryObjectStubs()) {
|
||||
StripPreliminaryObjectStubs(cx, stub);
|
||||
switch (decision) {
|
||||
case AttachDecision::Attach: {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(
|
||||
cx, gen.writerRef(), gen.cacheKind(),
|
||||
BaselineCacheIRStubKind::Updated, frame->script(), stub, &attached);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached SetElem CacheIR stub");
|
||||
|
||||
SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo());
|
||||
|
||||
if (gen.shouldNotePreliminaryObjectStub()) {
|
||||
newStub->toCacheIR_Updated()->notePreliminaryObject();
|
||||
} else if (gen.shouldUnlinkPreliminaryObjectStubs()) {
|
||||
StripPreliminaryObjectStubs(cx, stub);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gen.trackAttached(IRGenerator::NotAttached);
|
||||
}
|
||||
if (!attached && !isTemporarilyUnoptimizable) {
|
||||
stub->state().trackNotAttached();
|
||||
} break;
|
||||
case AttachDecision::NoAction:
|
||||
gen.trackAttached(IRGenerator::NotAttached);
|
||||
break;
|
||||
case AttachDecision::TemporarilyUnoptimizable:
|
||||
case AttachDecision::Deferred:
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid attach result");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!attached && canAttachStub) {
|
||||
stub->state().trackNotAttached();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3952,10 +3931,8 @@ bool DoCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub,
|
|||
}
|
||||
}
|
||||
|
||||
if (!handled) {
|
||||
if (canAttachStub) {
|
||||
stub->state().trackNotAttached();
|
||||
}
|
||||
if (!handled && canAttachStub) {
|
||||
stub->state().trackNotAttached();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -5701,7 +5678,7 @@ bool DoUnaryArithFallback(JSContext* cx, BaselineFrame* frame,
|
|||
stub->setSawDoubleResult();
|
||||
}
|
||||
|
||||
TryAttachStub<UnaryArithIRGenerator>("UniaryArith", cx, frame, stub,
|
||||
TryAttachStub<UnaryArithIRGenerator>("UniryArith", cx, frame, stub,
|
||||
BaselineCacheIRStubKind::Regular, op,
|
||||
val, res);
|
||||
return true;
|
||||
|
|
|
@ -205,7 +205,9 @@ MethodStatus jit::BaselineCompile(JSContext* cx, JSScript* script,
|
|||
MOZ_ASSERT(!script->hasBaselineScript());
|
||||
MOZ_ASSERT(script->canBaselineCompile());
|
||||
MOZ_ASSERT(IsBaselineEnabled(cx));
|
||||
AutoGeckoProfilerEntry pseudoFrame(cx, "Baseline script compilation");
|
||||
AutoGeckoProfilerEntry pseudoFrame(
|
||||
cx, "Baseline script compilation",
|
||||
JS::ProfilingCategoryPair::JS_BaselineCompilation);
|
||||
|
||||
script->ensureNonLazyCanonicalFunction();
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -511,12 +511,37 @@ class CallFlags {
|
|||
};
|
||||
|
||||
enum class AttachDecision {
|
||||
// We cannot attach a stub.
|
||||
NoAction,
|
||||
|
||||
// We can attach a stub.
|
||||
Attach,
|
||||
|
||||
// We cannot currently attach a stub, but we expect to be able to do so in the
|
||||
// future. In this case, we do not call trackNotAttached().
|
||||
TemporarilyUnoptimizable,
|
||||
|
||||
// We want to attach a stub, but the result of the operation is
|
||||
// needed to generate that stub. For example, AddSlot needs to know
|
||||
// the resulting shape. Note: the attached stub will inspect the
|
||||
// inputs to the operation, so most input checks should be done
|
||||
// before the actual operation, with only minimal checks remaining
|
||||
// for the deferred portion. This prevents arbitrary scripted code
|
||||
// run by the operation from interfering with the conditions being
|
||||
// checked.
|
||||
Deferred
|
||||
};
|
||||
|
||||
// If the input expression evaluates to an AttachDecision other than NoAction,
|
||||
// return that AttachDecision. If it is NoAction, do nothing.
|
||||
#define TRY_ATTACH(expr) \
|
||||
do { \
|
||||
AttachDecision result = expr; \
|
||||
if (result != AttachDecision::NoAction) { \
|
||||
return result; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Set of arguments supported by GetIndexOfArgument.
|
||||
// Support for Arg2 and up can be added easily, but is currently unneeded.
|
||||
enum class ArgumentKind : uint8_t { Callee, This, NewTarget, Arg0, Arg1 };
|
||||
|
@ -1941,59 +1966,71 @@ class MOZ_RAII GetPropIRGenerator : public IRGenerator {
|
|||
HandleValue val_;
|
||||
HandleValue idVal_;
|
||||
HandleValue receiver_;
|
||||
bool* isTemporarilyUnoptimizable_;
|
||||
GetPropertyResultFlags resultFlags_;
|
||||
|
||||
enum class PreliminaryObjectAction { None, Unlink, NotePreliminary };
|
||||
PreliminaryObjectAction preliminaryObjectAction_;
|
||||
|
||||
bool tryAttachNative(HandleObject obj, ObjOperandId objId, HandleId id);
|
||||
bool tryAttachUnboxed(HandleObject obj, ObjOperandId objId, HandleId id);
|
||||
bool tryAttachUnboxedExpando(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
bool tryAttachTypedObject(HandleObject obj, ObjOperandId objId, HandleId id);
|
||||
bool tryAttachObjectLength(HandleObject obj, ObjOperandId objId, HandleId id);
|
||||
bool tryAttachModuleNamespace(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
bool tryAttachWindowProxy(HandleObject obj, ObjOperandId objId, HandleId id);
|
||||
bool tryAttachCrossCompartmentWrapper(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
bool tryAttachXrayCrossCompartmentWrapper(HandleObject obj,
|
||||
ObjOperandId objId, HandleId id);
|
||||
bool tryAttachFunction(HandleObject obj, ObjOperandId objId, HandleId id);
|
||||
|
||||
bool tryAttachGenericProxy(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
bool handleDOMProxies);
|
||||
bool tryAttachDOMProxyExpando(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
bool tryAttachDOMProxyShadowed(HandleObject obj, ObjOperandId objId,
|
||||
AttachDecision tryAttachNative(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
bool tryAttachDOMProxyUnshadowed(HandleObject obj, ObjOperandId objId,
|
||||
AttachDecision tryAttachUnboxed(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
AttachDecision tryAttachUnboxedExpando(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
AttachDecision tryAttachTypedObject(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
AttachDecision tryAttachObjectLength(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
AttachDecision tryAttachModuleNamespace(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
AttachDecision tryAttachWindowProxy(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
AttachDecision tryAttachCrossCompartmentWrapper(HandleObject obj,
|
||||
ObjOperandId objId,
|
||||
HandleId id);
|
||||
AttachDecision tryAttachXrayCrossCompartmentWrapper(HandleObject obj,
|
||||
ObjOperandId objId,
|
||||
HandleId id);
|
||||
AttachDecision tryAttachFunction(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
bool tryAttachProxy(HandleObject obj, ObjOperandId objId, HandleId id);
|
||||
|
||||
bool tryAttachPrimitive(ValOperandId valId, HandleId id);
|
||||
bool tryAttachStringChar(ValOperandId valId, ValOperandId indexId);
|
||||
bool tryAttachStringLength(ValOperandId valId, HandleId id);
|
||||
bool tryAttachMagicArgumentsName(ValOperandId valId, HandleId id);
|
||||
AttachDecision tryAttachGenericProxy(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, bool handleDOMProxies);
|
||||
AttachDecision tryAttachDOMProxyExpando(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
AttachDecision tryAttachDOMProxyShadowed(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
AttachDecision tryAttachDOMProxyUnshadowed(HandleObject obj,
|
||||
ObjOperandId objId, HandleId id);
|
||||
AttachDecision tryAttachProxy(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id);
|
||||
|
||||
bool tryAttachMagicArgument(ValOperandId valId, ValOperandId indexId);
|
||||
bool tryAttachArgumentsObjectArg(HandleObject obj, ObjOperandId objId,
|
||||
Int32OperandId indexId);
|
||||
AttachDecision tryAttachPrimitive(ValOperandId valId, HandleId id);
|
||||
AttachDecision tryAttachStringChar(ValOperandId valId, ValOperandId indexId);
|
||||
AttachDecision tryAttachStringLength(ValOperandId valId, HandleId id);
|
||||
AttachDecision tryAttachMagicArgumentsName(ValOperandId valId, HandleId id);
|
||||
|
||||
bool tryAttachDenseElement(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index, Int32OperandId indexId);
|
||||
bool tryAttachDenseElementHole(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index, Int32OperandId indexId);
|
||||
bool tryAttachSparseElement(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index, Int32OperandId indexId);
|
||||
bool tryAttachTypedElement(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index, Int32OperandId indexId);
|
||||
AttachDecision tryAttachMagicArgument(ValOperandId valId,
|
||||
ValOperandId indexId);
|
||||
AttachDecision tryAttachArgumentsObjectArg(HandleObject obj,
|
||||
ObjOperandId objId,
|
||||
Int32OperandId indexId);
|
||||
|
||||
bool tryAttachGenericElement(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index, Int32OperandId indexId);
|
||||
AttachDecision tryAttachDenseElement(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index, Int32OperandId indexId);
|
||||
AttachDecision tryAttachDenseElementHole(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index,
|
||||
Int32OperandId indexId);
|
||||
AttachDecision tryAttachSparseElement(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index, Int32OperandId indexId);
|
||||
AttachDecision tryAttachTypedElement(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index, Int32OperandId indexId);
|
||||
|
||||
bool tryAttachProxyElement(HandleObject obj, ObjOperandId objId);
|
||||
AttachDecision tryAttachGenericElement(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index,
|
||||
Int32OperandId indexId);
|
||||
|
||||
AttachDecision tryAttachProxyElement(HandleObject obj, ObjOperandId objId);
|
||||
|
||||
void attachMegamorphicNativeSlot(ObjOperandId objId, jsid id,
|
||||
bool handleMissing);
|
||||
|
@ -2030,13 +2067,12 @@ class MOZ_RAII GetPropIRGenerator : public IRGenerator {
|
|||
|
||||
public:
|
||||
GetPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
|
||||
CacheKind cacheKind, ICState::Mode mode,
|
||||
bool* isTemporarilyUnoptimizable, HandleValue val,
|
||||
ICState::Mode mode, CacheKind cacheKind, HandleValue val,
|
||||
HandleValue idVal, HandleValue receiver,
|
||||
GetPropertyResultFlags resultFlags);
|
||||
|
||||
bool tryAttachStub();
|
||||
bool tryAttachIdempotentStub();
|
||||
AttachDecision tryAttachStub();
|
||||
AttachDecision tryAttachIdempotentStub();
|
||||
|
||||
bool shouldUnlinkPreliminaryObjectStubs() const {
|
||||
return preliminaryObjectAction_ == PreliminaryObjectAction::Unlink;
|
||||
|
@ -2051,9 +2087,9 @@ class MOZ_RAII GetNameIRGenerator : public IRGenerator {
|
|||
HandleObject env_;
|
||||
HandlePropertyName name_;
|
||||
|
||||
bool tryAttachGlobalNameValue(ObjOperandId objId, HandleId id);
|
||||
bool tryAttachGlobalNameGetter(ObjOperandId objId, HandleId id);
|
||||
bool tryAttachEnvironmentName(ObjOperandId objId, HandleId id);
|
||||
AttachDecision tryAttachGlobalNameValue(ObjOperandId objId, HandleId id);
|
||||
AttachDecision tryAttachGlobalNameGetter(ObjOperandId objId, HandleId id);
|
||||
AttachDecision tryAttachEnvironmentName(ObjOperandId objId, HandleId id);
|
||||
|
||||
void trackAttached(const char* name);
|
||||
|
||||
|
@ -2062,7 +2098,7 @@ class MOZ_RAII GetNameIRGenerator : public IRGenerator {
|
|||
ICState::Mode mode, HandleObject env,
|
||||
HandlePropertyName name);
|
||||
|
||||
bool tryAttachStub();
|
||||
AttachDecision tryAttachStub();
|
||||
};
|
||||
|
||||
// BindNameIRGenerator generates CacheIR for a BindName IC.
|
||||
|
@ -2070,8 +2106,8 @@ class MOZ_RAII BindNameIRGenerator : public IRGenerator {
|
|||
HandleObject env_;
|
||||
HandlePropertyName name_;
|
||||
|
||||
bool tryAttachGlobalName(ObjOperandId objId, HandleId id);
|
||||
bool tryAttachEnvironmentName(ObjOperandId objId, HandleId id);
|
||||
AttachDecision tryAttachGlobalName(ObjOperandId objId, HandleId id);
|
||||
AttachDecision tryAttachEnvironmentName(ObjOperandId objId, HandleId id);
|
||||
|
||||
void trackAttached(const char* name);
|
||||
|
||||
|
@ -2080,7 +2116,7 @@ class MOZ_RAII BindNameIRGenerator : public IRGenerator {
|
|||
ICState::Mode mode, HandleObject env,
|
||||
HandlePropertyName name);
|
||||
|
||||
bool tryAttachStub();
|
||||
AttachDecision tryAttachStub();
|
||||
};
|
||||
|
||||
// Information used by SetProp/SetElem stubs to check/update property types.
|
||||
|
@ -2122,8 +2158,6 @@ class MOZ_RAII SetPropIRGenerator : public IRGenerator {
|
|||
HandleValue lhsVal_;
|
||||
HandleValue idVal_;
|
||||
HandleValue rhsVal_;
|
||||
bool* isTemporarilyUnoptimizable_;
|
||||
bool* canAddSlot_;
|
||||
PropertyTypeCheckInfo typeCheckInfo_;
|
||||
|
||||
enum class PreliminaryObjectAction { None, Unlink, NotePreliminary };
|
||||
|
@ -2132,6 +2166,12 @@ class MOZ_RAII SetPropIRGenerator : public IRGenerator {
|
|||
|
||||
bool maybeHasExtraIndexedProps_;
|
||||
|
||||
public:
|
||||
enum class DeferType { None, AddSlot };
|
||||
|
||||
private:
|
||||
DeferType deferType_ = DeferType::None;
|
||||
|
||||
ValOperandId setElemKeyValueId() const {
|
||||
MOZ_ASSERT(cacheKind_ == CacheKind::SetElem);
|
||||
return ValOperandId(1);
|
||||
|
@ -2148,63 +2188,74 @@ class MOZ_RAII SetPropIRGenerator : public IRGenerator {
|
|||
// matches |id|.
|
||||
void maybeEmitIdGuard(jsid id);
|
||||
|
||||
bool tryAttachNativeSetSlot(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId);
|
||||
bool tryAttachUnboxedExpandoSetSlot(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, ValOperandId rhsId);
|
||||
bool tryAttachUnboxedProperty(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, ValOperandId rhsId);
|
||||
bool tryAttachTypedObjectProperty(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, ValOperandId rhsId);
|
||||
bool tryAttachSetter(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId);
|
||||
bool tryAttachSetArrayLength(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, ValOperandId rhsId);
|
||||
bool tryAttachWindowProxy(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId);
|
||||
|
||||
bool tryAttachSetDenseElement(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index, Int32OperandId indexId,
|
||||
ValOperandId rhsId);
|
||||
bool tryAttachSetTypedElement(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index, Int32OperandId indexId,
|
||||
ValOperandId rhsId);
|
||||
|
||||
bool tryAttachSetDenseElementHole(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index, Int32OperandId indexId,
|
||||
ValOperandId rhsId);
|
||||
|
||||
bool tryAttachAddOrUpdateSparseElement(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index, Int32OperandId indexId,
|
||||
ValOperandId rhsId);
|
||||
|
||||
bool tryAttachGenericProxy(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId, bool handleDOMProxies);
|
||||
bool tryAttachDOMProxyShadowed(HandleObject obj, ObjOperandId objId,
|
||||
AttachDecision tryAttachNativeSetSlot(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, ValOperandId rhsId);
|
||||
AttachDecision tryAttachUnboxedExpandoSetSlot(HandleObject obj,
|
||||
ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId);
|
||||
AttachDecision tryAttachUnboxedProperty(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, ValOperandId rhsId);
|
||||
AttachDecision tryAttachTypedObjectProperty(HandleObject obj,
|
||||
ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId);
|
||||
AttachDecision tryAttachSetter(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, ValOperandId rhsId);
|
||||
bool tryAttachDOMProxyUnshadowed(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, ValOperandId rhsId);
|
||||
bool tryAttachDOMProxyExpando(HandleObject obj, ObjOperandId objId,
|
||||
AttachDecision tryAttachSetArrayLength(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, ValOperandId rhsId);
|
||||
AttachDecision tryAttachWindowProxy(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, ValOperandId rhsId);
|
||||
|
||||
AttachDecision tryAttachSetDenseElement(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index,
|
||||
Int32OperandId indexId,
|
||||
ValOperandId rhsId);
|
||||
AttachDecision tryAttachSetTypedElement(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index,
|
||||
Int32OperandId indexId,
|
||||
ValOperandId rhsId);
|
||||
|
||||
AttachDecision tryAttachSetDenseElementHole(HandleObject obj,
|
||||
ObjOperandId objId,
|
||||
uint32_t index,
|
||||
Int32OperandId indexId,
|
||||
ValOperandId rhsId);
|
||||
|
||||
AttachDecision tryAttachAddOrUpdateSparseElement(HandleObject obj,
|
||||
ObjOperandId objId,
|
||||
uint32_t index,
|
||||
Int32OperandId indexId,
|
||||
ValOperandId rhsId);
|
||||
|
||||
AttachDecision tryAttachGenericProxy(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, ValOperandId rhsId,
|
||||
bool handleDOMProxies);
|
||||
AttachDecision tryAttachDOMProxyShadowed(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, ValOperandId rhsId);
|
||||
AttachDecision tryAttachDOMProxyUnshadowed(HandleObject obj,
|
||||
ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId);
|
||||
AttachDecision tryAttachDOMProxyExpando(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, ValOperandId rhsId);
|
||||
AttachDecision tryAttachProxy(HandleObject obj, ObjOperandId objId,
|
||||
HandleId id, ValOperandId rhsId);
|
||||
bool tryAttachProxy(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId);
|
||||
bool tryAttachProxyElement(HandleObject obj, ObjOperandId objId,
|
||||
ValOperandId rhsId);
|
||||
bool tryAttachMegamorphicSetElement(HandleObject obj, ObjOperandId objId,
|
||||
ValOperandId rhsId);
|
||||
AttachDecision tryAttachProxyElement(HandleObject obj, ObjOperandId objId,
|
||||
ValOperandId rhsId);
|
||||
AttachDecision tryAttachMegamorphicSetElement(HandleObject obj,
|
||||
ObjOperandId objId,
|
||||
ValOperandId rhsId);
|
||||
|
||||
bool canAttachAddSlotStub(HandleObject obj, HandleId id);
|
||||
|
||||
public:
|
||||
SetPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
|
||||
CacheKind cacheKind, ICState::Mode mode,
|
||||
bool* isTemporarilyUnoptimizable, bool* canAddSlot,
|
||||
HandleValue lhsVal, HandleValue idVal, HandleValue rhsVal,
|
||||
bool needsTypeBarrier = true,
|
||||
bool maybeHasExtraIndexedProps = true);
|
||||
|
||||
bool tryAttachStub();
|
||||
bool tryAttachAddSlotStub(HandleObjectGroup oldGroup, HandleShape oldShape);
|
||||
AttachDecision tryAttachStub();
|
||||
AttachDecision tryAttachAddSlotStub(HandleObjectGroup oldGroup,
|
||||
HandleShape oldShape);
|
||||
void trackAttached(const char* name);
|
||||
|
||||
bool shouldUnlinkPreliminaryObjectStubs() const {
|
||||
|
@ -2217,6 +2268,8 @@ class MOZ_RAII SetPropIRGenerator : public IRGenerator {
|
|||
const PropertyTypeCheckInfo* typeCheckInfo() const { return &typeCheckInfo_; }
|
||||
|
||||
bool attachedTypedArrayOOBStub() const { return attachedTypedArrayOOBStub_; }
|
||||
|
||||
DeferType deferType() const { return deferType_; }
|
||||
};
|
||||
|
||||
// HasPropIRGenerator generates CacheIR for a HasProp IC. Used for
|
||||
|
@ -2225,32 +2278,32 @@ class MOZ_RAII HasPropIRGenerator : public IRGenerator {
|
|||
HandleValue val_;
|
||||
HandleValue idVal_;
|
||||
|
||||
bool tryAttachDense(HandleObject obj, ObjOperandId objId, uint32_t index,
|
||||
Int32OperandId indexId);
|
||||
bool tryAttachDenseHole(HandleObject obj, ObjOperandId objId, uint32_t index,
|
||||
Int32OperandId indexId);
|
||||
bool tryAttachTypedArray(HandleObject obj, ObjOperandId objId,
|
||||
Int32OperandId indexId);
|
||||
bool tryAttachSparse(HandleObject obj, ObjOperandId objId,
|
||||
Int32OperandId indexId);
|
||||
bool tryAttachNamedProp(HandleObject obj, ObjOperandId objId, HandleId key,
|
||||
ValOperandId keyId);
|
||||
bool tryAttachMegamorphic(ObjOperandId objId, ValOperandId keyId);
|
||||
bool tryAttachNative(JSObject* obj, ObjOperandId objId, jsid key,
|
||||
ValOperandId keyId, PropertyResult prop,
|
||||
JSObject* holder);
|
||||
bool tryAttachUnboxed(JSObject* obj, ObjOperandId objId, jsid key,
|
||||
ValOperandId keyId);
|
||||
bool tryAttachUnboxedExpando(JSObject* obj, ObjOperandId objId, jsid key,
|
||||
ValOperandId keyId);
|
||||
bool tryAttachTypedObject(JSObject* obj, ObjOperandId objId, jsid key,
|
||||
ValOperandId keyId);
|
||||
bool tryAttachSlotDoesNotExist(JSObject* obj, ObjOperandId objId, jsid key,
|
||||
ValOperandId keyId);
|
||||
bool tryAttachDoesNotExist(HandleObject obj, ObjOperandId objId, HandleId key,
|
||||
ValOperandId keyId);
|
||||
bool tryAttachProxyElement(HandleObject obj, ObjOperandId objId,
|
||||
ValOperandId keyId);
|
||||
AttachDecision tryAttachDense(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index, Int32OperandId indexId);
|
||||
AttachDecision tryAttachDenseHole(HandleObject obj, ObjOperandId objId,
|
||||
uint32_t index, Int32OperandId indexId);
|
||||
AttachDecision tryAttachTypedArray(HandleObject obj, ObjOperandId objId,
|
||||
Int32OperandId indexId);
|
||||
AttachDecision tryAttachSparse(HandleObject obj, ObjOperandId objId,
|
||||
Int32OperandId indexId);
|
||||
AttachDecision tryAttachNamedProp(HandleObject obj, ObjOperandId objId,
|
||||
HandleId key, ValOperandId keyId);
|
||||
AttachDecision tryAttachMegamorphic(ObjOperandId objId, ValOperandId keyId);
|
||||
AttachDecision tryAttachNative(JSObject* obj, ObjOperandId objId, jsid key,
|
||||
ValOperandId keyId, PropertyResult prop,
|
||||
JSObject* holder);
|
||||
AttachDecision tryAttachUnboxed(JSObject* obj, ObjOperandId objId, jsid key,
|
||||
ValOperandId keyId);
|
||||
AttachDecision tryAttachUnboxedExpando(JSObject* obj, ObjOperandId objId,
|
||||
jsid key, ValOperandId keyId);
|
||||
AttachDecision tryAttachTypedObject(JSObject* obj, ObjOperandId objId,
|
||||
jsid key, ValOperandId keyId);
|
||||
AttachDecision tryAttachSlotDoesNotExist(JSObject* obj, ObjOperandId objId,
|
||||
jsid key, ValOperandId keyId);
|
||||
AttachDecision tryAttachDoesNotExist(HandleObject obj, ObjOperandId objId,
|
||||
HandleId key, ValOperandId keyId);
|
||||
AttachDecision tryAttachProxyElement(HandleObject obj, ObjOperandId objId,
|
||||
ValOperandId keyId);
|
||||
|
||||
void trackAttached(const char* name);
|
||||
|
||||
|
@ -2260,7 +2313,7 @@ class MOZ_RAII HasPropIRGenerator : public IRGenerator {
|
|||
ICState::Mode mode, CacheKind cacheKind, HandleValue idVal,
|
||||
HandleValue val);
|
||||
|
||||
bool tryAttachStub();
|
||||
AttachDecision tryAttachStub();
|
||||
};
|
||||
|
||||
class MOZ_RAII InstanceOfIRGenerator : public IRGenerator {
|
||||
|
@ -2273,33 +2326,33 @@ class MOZ_RAII InstanceOfIRGenerator : public IRGenerator {
|
|||
InstanceOfIRGenerator(JSContext*, HandleScript, jsbytecode*, ICState::Mode,
|
||||
HandleValue, HandleObject);
|
||||
|
||||
bool tryAttachStub();
|
||||
AttachDecision tryAttachStub();
|
||||
};
|
||||
|
||||
class MOZ_RAII TypeOfIRGenerator : public IRGenerator {
|
||||
HandleValue val_;
|
||||
|
||||
bool tryAttachPrimitive(ValOperandId valId);
|
||||
bool tryAttachObject(ValOperandId valId);
|
||||
AttachDecision tryAttachPrimitive(ValOperandId valId);
|
||||
AttachDecision tryAttachObject(ValOperandId valId);
|
||||
void trackAttached(const char* name);
|
||||
|
||||
public:
|
||||
TypeOfIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
|
||||
ICState::Mode mode, HandleValue value);
|
||||
|
||||
bool tryAttachStub();
|
||||
AttachDecision tryAttachStub();
|
||||
};
|
||||
|
||||
class MOZ_RAII GetIteratorIRGenerator : public IRGenerator {
|
||||
HandleValue val_;
|
||||
|
||||
bool tryAttachNativeIterator(ObjOperandId objId, HandleObject obj);
|
||||
AttachDecision tryAttachNativeIterator(ObjOperandId objId, HandleObject obj);
|
||||
|
||||
public:
|
||||
GetIteratorIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
|
||||
ICState::Mode mode, HandleValue value);
|
||||
|
||||
bool tryAttachStub();
|
||||
AttachDecision tryAttachStub();
|
||||
|
||||
void trackAttached(const char* name);
|
||||
};
|
||||
|
@ -2362,17 +2415,21 @@ class MOZ_RAII CompareIRGenerator : public IRGenerator {
|
|||
HandleValue lhsVal_;
|
||||
HandleValue rhsVal_;
|
||||
|
||||
bool tryAttachString(ValOperandId lhsId, ValOperandId rhsId);
|
||||
bool tryAttachObject(ValOperandId lhsId, ValOperandId rhsId);
|
||||
bool tryAttachSymbol(ValOperandId lhsId, ValOperandId rhsId);
|
||||
bool tryAttachStrictDifferentTypes(ValOperandId lhsId, ValOperandId rhsId);
|
||||
bool tryAttachInt32(ValOperandId lhsId, ValOperandId rhsId);
|
||||
bool tryAttachNumber(ValOperandId lhsId, ValOperandId rhsId);
|
||||
bool tryAttachNumberUndefined(ValOperandId lhsId, ValOperandId rhsId);
|
||||
bool tryAttachPrimitiveUndefined(ValOperandId lhsId, ValOperandId rhsId);
|
||||
bool tryAttachObjectUndefined(ValOperandId lhsId, ValOperandId rhsId);
|
||||
bool tryAttachNullUndefined(ValOperandId lhsId, ValOperandId rhsId);
|
||||
bool tryAttachStringNumber(ValOperandId lhsId, ValOperandId rhsId);
|
||||
AttachDecision tryAttachString(ValOperandId lhsId, ValOperandId rhsId);
|
||||
AttachDecision tryAttachObject(ValOperandId lhsId, ValOperandId rhsId);
|
||||
AttachDecision tryAttachSymbol(ValOperandId lhsId, ValOperandId rhsId);
|
||||
AttachDecision tryAttachStrictDifferentTypes(ValOperandId lhsId,
|
||||
ValOperandId rhsId);
|
||||
AttachDecision tryAttachInt32(ValOperandId lhsId, ValOperandId rhsId);
|
||||
AttachDecision tryAttachNumber(ValOperandId lhsId, ValOperandId rhsId);
|
||||
AttachDecision tryAttachNumberUndefined(ValOperandId lhsId,
|
||||
ValOperandId rhsId);
|
||||
AttachDecision tryAttachPrimitiveUndefined(ValOperandId lhsId,
|
||||
ValOperandId rhsId);
|
||||
AttachDecision tryAttachObjectUndefined(ValOperandId lhsId,
|
||||
ValOperandId rhsId);
|
||||
AttachDecision tryAttachNullUndefined(ValOperandId lhsId, ValOperandId rhsId);
|
||||
AttachDecision tryAttachStringNumber(ValOperandId lhsId, ValOperandId rhsId);
|
||||
|
||||
void trackAttached(const char* name);
|
||||
|
||||
|
@ -2381,18 +2438,18 @@ class MOZ_RAII CompareIRGenerator : public IRGenerator {
|
|||
ICState::Mode mode, JSOp op, HandleValue lhsVal,
|
||||
HandleValue rhsVal);
|
||||
|
||||
bool tryAttachStub();
|
||||
AttachDecision tryAttachStub();
|
||||
};
|
||||
|
||||
class MOZ_RAII ToBoolIRGenerator : public IRGenerator {
|
||||
HandleValue val_;
|
||||
|
||||
bool tryAttachInt32();
|
||||
bool tryAttachDouble();
|
||||
bool tryAttachString();
|
||||
bool tryAttachSymbol();
|
||||
bool tryAttachNullOrUndefined();
|
||||
bool tryAttachObject();
|
||||
AttachDecision tryAttachInt32();
|
||||
AttachDecision tryAttachDouble();
|
||||
AttachDecision tryAttachString();
|
||||
AttachDecision tryAttachSymbol();
|
||||
AttachDecision tryAttachNullOrUndefined();
|
||||
AttachDecision tryAttachObject();
|
||||
|
||||
void trackAttached(const char* name);
|
||||
|
||||
|
@ -2400,7 +2457,7 @@ class MOZ_RAII ToBoolIRGenerator : public IRGenerator {
|
|||
ToBoolIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
|
||||
ICState::Mode mode, HandleValue val);
|
||||
|
||||
bool tryAttachStub();
|
||||
AttachDecision tryAttachStub();
|
||||
};
|
||||
|
||||
class MOZ_RAII GetIntrinsicIRGenerator : public IRGenerator {
|
||||
|
@ -2412,7 +2469,7 @@ class MOZ_RAII GetIntrinsicIRGenerator : public IRGenerator {
|
|||
GetIntrinsicIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
|
||||
ICState::Mode, HandleValue val);
|
||||
|
||||
bool tryAttachStub();
|
||||
AttachDecision tryAttachStub();
|
||||
};
|
||||
|
||||
class MOZ_RAII UnaryArithIRGenerator : public IRGenerator {
|
||||
|
@ -2420,8 +2477,8 @@ class MOZ_RAII UnaryArithIRGenerator : public IRGenerator {
|
|||
HandleValue val_;
|
||||
HandleValue res_;
|
||||
|
||||
bool tryAttachInt32();
|
||||
bool tryAttachNumber();
|
||||
AttachDecision tryAttachInt32();
|
||||
AttachDecision tryAttachNumber();
|
||||
|
||||
void trackAttached(const char* name);
|
||||
|
||||
|
@ -2430,7 +2487,7 @@ class MOZ_RAII UnaryArithIRGenerator : public IRGenerator {
|
|||
ICState::Mode mode, JSOp op, HandleValue val,
|
||||
HandleValue res);
|
||||
|
||||
bool tryAttachStub();
|
||||
AttachDecision tryAttachStub();
|
||||
};
|
||||
|
||||
class MOZ_RAII BinaryArithIRGenerator : public IRGenerator {
|
||||
|
@ -2441,20 +2498,20 @@ class MOZ_RAII BinaryArithIRGenerator : public IRGenerator {
|
|||
|
||||
void trackAttached(const char* name);
|
||||
|
||||
bool tryAttachInt32();
|
||||
bool tryAttachDouble();
|
||||
bool tryAttachBitwise();
|
||||
bool tryAttachStringConcat();
|
||||
bool tryAttachStringObjectConcat();
|
||||
bool tryAttachStringNumberConcat();
|
||||
bool tryAttachStringBooleanConcat();
|
||||
AttachDecision tryAttachInt32();
|
||||
AttachDecision tryAttachDouble();
|
||||
AttachDecision tryAttachBitwise();
|
||||
AttachDecision tryAttachStringConcat();
|
||||
AttachDecision tryAttachStringObjectConcat();
|
||||
AttachDecision tryAttachStringNumberConcat();
|
||||
AttachDecision tryAttachStringBooleanConcat();
|
||||
|
||||
public:
|
||||
BinaryArithIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
|
||||
ICState::Mode, JSOp op, HandleValue lhs,
|
||||
HandleValue rhs, HandleValue res);
|
||||
|
||||
bool tryAttachStub();
|
||||
AttachDecision tryAttachStub();
|
||||
};
|
||||
|
||||
class MOZ_RAII NewObjectIRGenerator : public IRGenerator {
|
||||
|
@ -2469,7 +2526,7 @@ class MOZ_RAII NewObjectIRGenerator : public IRGenerator {
|
|||
NewObjectIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
|
||||
ICState::Mode, JSOp op, HandleObject templateObj);
|
||||
|
||||
bool tryAttachStub();
|
||||
AttachDecision tryAttachStub();
|
||||
};
|
||||
|
||||
static inline uint32_t SimpleTypeDescrKey(SimpleTypeDescr* descr) {
|
||||
|
|
|
@ -1458,15 +1458,18 @@ void CodeGenerator::visitObjectGroupDispatch(LObjectGroupDispatch* lir) {
|
|||
LBlock* target = skipTrivialBlocks(mir->getCaseBlock(i))->lir();
|
||||
|
||||
DebugOnly<bool> found = false;
|
||||
// Find the function in the prop table.
|
||||
for (size_t j = 0; j < propTable->numEntries(); j++) {
|
||||
if (propTable->getFunction(j) != func) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Emit the previous prop's jump.
|
||||
if (lastBranch.isInitialized()) {
|
||||
lastBranch.emit(masm);
|
||||
}
|
||||
|
||||
// Setup jump for next iteration.
|
||||
ObjectGroup* group = propTable->getObjectGroup(j);
|
||||
lastBranch = MacroAssembler::BranchGCPtr(
|
||||
Assembler::Equal, temp, ImmGCPtr(group), target->label());
|
||||
|
@ -1476,18 +1479,22 @@ void CodeGenerator::visitObjectGroupDispatch(LObjectGroupDispatch* lir) {
|
|||
MOZ_ASSERT(found);
|
||||
}
|
||||
|
||||
// At this point the final case branch hasn't been emitted.
|
||||
|
||||
// Jump to fallback block if we have an unknown ObjectGroup. If there's no
|
||||
// fallback block, we should have handled all cases.
|
||||
|
||||
if (!mir->hasFallback()) {
|
||||
MOZ_ASSERT(lastBranch.isInitialized());
|
||||
|
||||
Label ok;
|
||||
// Change the target of the branch to OK.
|
||||
lastBranch.relink(&ok);
|
||||
lastBranch.emit(masm);
|
||||
masm.assumeUnreachable("Unexpected ObjectGroup");
|
||||
masm.bind(&ok);
|
||||
|
||||
// If we don't naturally fall through to the target,
|
||||
// then jump to the target.
|
||||
if (!isNextBlock(lastBlock)) {
|
||||
masm.jump(lastBlock->label());
|
||||
}
|
||||
|
@ -1495,6 +1502,7 @@ void CodeGenerator::visitObjectGroupDispatch(LObjectGroupDispatch* lir) {
|
|||
}
|
||||
|
||||
LBlock* fallback = skipTrivialBlocks(mir->getFallback())->lir();
|
||||
// This should only happen if we have zero cases. We're done then.
|
||||
if (!lastBranch.isInitialized()) {
|
||||
if (!isNextBlock(fallback)) {
|
||||
masm.jump(fallback->label());
|
||||
|
@ -1502,6 +1510,8 @@ void CodeGenerator::visitObjectGroupDispatch(LObjectGroupDispatch* lir) {
|
|||
return;
|
||||
}
|
||||
|
||||
// If we don't match the last object group and we have a fallback,
|
||||
// we should jump to it.
|
||||
lastBranch.invertCondition();
|
||||
lastBranch.relink(fallback->label());
|
||||
lastBranch.emit(masm);
|
||||
|
|
|
@ -2216,7 +2216,9 @@ static MethodStatus Compile(JSContext* cx, HandleScript script,
|
|||
MOZ_ASSERT(jit::IsIonEnabled(cx));
|
||||
MOZ_ASSERT(jit::IsBaselineEnabled(cx));
|
||||
MOZ_ASSERT_IF(osrPc != nullptr, LoopEntryCanIonOsr(osrPc));
|
||||
AutoGeckoProfilerEntry pseudoFrame(cx, "Ion script compilation");
|
||||
AutoGeckoProfilerEntry pseudoFrame(
|
||||
cx, "Ion script compilation",
|
||||
JS::ProfilingCategoryPair::JS_IonCompilation);
|
||||
|
||||
if (!script->hasBaselineScript()) {
|
||||
return Method_Skipped;
|
||||
|
|
|
@ -115,6 +115,40 @@ void IonIC::trace(JSTracer* trc) {
|
|||
MOZ_ASSERT(nextCodeRaw == fallbackLabel_.raw());
|
||||
}
|
||||
|
||||
// This helper handles ICState updates/transitions while attaching CacheIR
|
||||
// stubs.
|
||||
template <typename IRGenerator, typename IC, typename... Args>
|
||||
static void TryAttachIonStub(JSContext* cx, IC* ic, IonScript* ionScript,
|
||||
Args&&... args) {
|
||||
if (ic->state().maybeTransition()) {
|
||||
ic->discardStubs(cx->zone());
|
||||
}
|
||||
|
||||
if (ic->state().canAttachStub()) {
|
||||
RootedScript script(cx, ic->script());
|
||||
bool attached = false;
|
||||
IRGenerator gen(cx, script, ic->pc(), ic->state().mode(),
|
||||
std::forward<Args>(args)...);
|
||||
switch (gen.tryAttachStub()) {
|
||||
case AttachDecision::Attach:
|
||||
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript,
|
||||
&attached);
|
||||
break;
|
||||
case AttachDecision::NoAction:
|
||||
break;
|
||||
case AttachDecision::TemporarilyUnoptimizable:
|
||||
attached = true;
|
||||
break;
|
||||
case AttachDecision::Deferred:
|
||||
MOZ_ASSERT_UNREACHABLE("Not expected in generic TryAttachIonStub");
|
||||
break;
|
||||
}
|
||||
if (!attached) {
|
||||
ic->state().trackNotAttached();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool IonGetPropertyIC::update(JSContext* cx, HandleScript outerScript,
|
||||
IonGetPropertyIC* ic, HandleValue val,
|
||||
|
@ -134,22 +168,25 @@ bool IonGetPropertyIC::update(JSContext* cx, HandleScript outerScript,
|
|||
|
||||
bool attached = false;
|
||||
if (ic->state().canAttachStub()) {
|
||||
// IonBuilder calls PropertyReadNeedsTypeBarrier to determine if it
|
||||
// needs a type barrier. Unfortunately, PropertyReadNeedsTypeBarrier
|
||||
// does not account for getters, so we should only attach a getter
|
||||
// stub if we inserted a type barrier.
|
||||
jsbytecode* pc = ic->idempotent() ? nullptr : ic->pc();
|
||||
bool isTemporarilyUnoptimizable = false;
|
||||
GetPropIRGenerator gen(cx, outerScript, pc, ic->kind(), ic->state().mode(),
|
||||
&isTemporarilyUnoptimizable, val, idVal, val,
|
||||
ic->resultFlags());
|
||||
if (ic->idempotent() ? gen.tryAttachIdempotentStub()
|
||||
: gen.tryAttachStub()) {
|
||||
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript,
|
||||
&attached);
|
||||
GetPropIRGenerator gen(cx, outerScript, pc, ic->state().mode(), ic->kind(),
|
||||
val, idVal, val, ic->resultFlags());
|
||||
switch (ic->idempotent() ? gen.tryAttachIdempotentStub()
|
||||
: gen.tryAttachStub()) {
|
||||
case AttachDecision::Attach:
|
||||
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript,
|
||||
&attached);
|
||||
break;
|
||||
case AttachDecision::NoAction:
|
||||
break;
|
||||
case AttachDecision::TemporarilyUnoptimizable:
|
||||
attached = true;
|
||||
break;
|
||||
case AttachDecision::Deferred:
|
||||
MOZ_ASSERT_UNREACHABLE("No deferred GetProp stubs");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!attached && !isTemporarilyUnoptimizable) {
|
||||
if (!attached) {
|
||||
ic->state().trackNotAttached();
|
||||
}
|
||||
}
|
||||
|
@ -211,22 +248,10 @@ bool IonGetPropSuperIC::update(JSContext* cx, HandleScript outerScript,
|
|||
ic->discardStubs(cx->zone());
|
||||
}
|
||||
|
||||
bool attached = false;
|
||||
if (ic->state().canAttachStub()) {
|
||||
RootedValue val(cx, ObjectValue(*obj));
|
||||
bool isTemporarilyUnoptimizable = false;
|
||||
GetPropIRGenerator gen(cx, outerScript, ic->pc(), ic->kind(),
|
||||
ic->state().mode(), &isTemporarilyUnoptimizable, val,
|
||||
idVal, receiver, GetPropertyResultFlags::All);
|
||||
if (gen.tryAttachStub()) {
|
||||
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript,
|
||||
&attached);
|
||||
}
|
||||
|
||||
if (!attached && !isTemporarilyUnoptimizable) {
|
||||
ic->state().trackNotAttached();
|
||||
}
|
||||
}
|
||||
RootedValue val(cx, ObjectValue(*obj));
|
||||
TryAttachIonStub<GetPropIRGenerator, IonGetPropSuperIC>(
|
||||
cx, ic, ionScript, ic->kind(), val, idVal, receiver,
|
||||
GetPropertyResultFlags::All);
|
||||
|
||||
RootedId id(cx);
|
||||
if (!ValueToId<CanGC>(cx, idVal, &id)) {
|
||||
|
@ -246,13 +271,14 @@ bool IonGetPropSuperIC::update(JSContext* cx, HandleScript outerScript,
|
|||
bool IonSetPropertyIC::update(JSContext* cx, HandleScript outerScript,
|
||||
IonSetPropertyIC* ic, HandleObject obj,
|
||||
HandleValue idVal, HandleValue rhs) {
|
||||
using DeferType = SetPropIRGenerator::DeferType;
|
||||
|
||||
RootedShape oldShape(cx);
|
||||
RootedObjectGroup oldGroup(cx);
|
||||
IonScript* ionScript = outerScript->ionScript();
|
||||
|
||||
bool attached = false;
|
||||
bool isTemporarilyUnoptimizable = false;
|
||||
bool canAddSlot = false;
|
||||
DeferType deferType = DeferType::None;
|
||||
|
||||
if (ic->state().maybeTransition()) {
|
||||
ic->discardStubs(cx->zone());
|
||||
|
@ -268,13 +294,23 @@ bool IonSetPropertyIC::update(JSContext* cx, HandleScript outerScript,
|
|||
RootedValue objv(cx, ObjectValue(*obj));
|
||||
RootedScript script(cx, ic->script());
|
||||
jsbytecode* pc = ic->pc();
|
||||
SetPropIRGenerator gen(cx, script, pc, ic->kind(), ic->state().mode(),
|
||||
&isTemporarilyUnoptimizable, &canAddSlot, objv,
|
||||
SetPropIRGenerator gen(cx, script, pc, ic->kind(), ic->state().mode(), objv,
|
||||
idVal, rhs, ic->needsTypeBarrier(),
|
||||
ic->guardHoles());
|
||||
if (gen.tryAttachStub()) {
|
||||
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript,
|
||||
&attached, gen.typeCheckInfo());
|
||||
switch (gen.tryAttachStub()) {
|
||||
case AttachDecision::Attach:
|
||||
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript,
|
||||
&attached, gen.typeCheckInfo());
|
||||
break;
|
||||
case AttachDecision::NoAction:
|
||||
break;
|
||||
case AttachDecision::TemporarilyUnoptimizable:
|
||||
attached = true;
|
||||
break;
|
||||
case AttachDecision::Deferred:
|
||||
deferType = gen.deferType();
|
||||
MOZ_ASSERT(deferType != DeferType::None);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,53 +365,38 @@ bool IonSetPropertyIC::update(JSContext* cx, HandleScript outerScript,
|
|||
ic->discardStubs(cx->zone());
|
||||
}
|
||||
|
||||
if (ic->state().canAttachStub()) {
|
||||
bool canAttachStub = ic->state().canAttachStub();
|
||||
if (deferType != DeferType::None && canAttachStub) {
|
||||
RootedValue objv(cx, ObjectValue(*obj));
|
||||
RootedScript script(cx, ic->script());
|
||||
jsbytecode* pc = ic->pc();
|
||||
SetPropIRGenerator gen(cx, script, pc, ic->kind(), ic->state().mode(),
|
||||
&isTemporarilyUnoptimizable, &canAddSlot, objv,
|
||||
SetPropIRGenerator gen(cx, script, pc, ic->kind(), ic->state().mode(), objv,
|
||||
idVal, rhs, ic->needsTypeBarrier(),
|
||||
ic->guardHoles());
|
||||
if (canAddSlot && gen.tryAttachAddSlotStub(oldGroup, oldShape)) {
|
||||
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript,
|
||||
&attached, gen.typeCheckInfo());
|
||||
} else {
|
||||
gen.trackAttached(nullptr);
|
||||
}
|
||||
MOZ_ASSERT(deferType == DeferType::AddSlot);
|
||||
AttachDecision decision = gen.tryAttachAddSlotStub(oldGroup, oldShape);
|
||||
|
||||
if (!attached && !isTemporarilyUnoptimizable) {
|
||||
ic->state().trackNotAttached();
|
||||
switch (decision) {
|
||||
case AttachDecision::Attach:
|
||||
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript,
|
||||
&attached, gen.typeCheckInfo());
|
||||
break;
|
||||
case AttachDecision::NoAction:
|
||||
gen.trackAttached(IRGenerator::NotAttached);
|
||||
break;
|
||||
case AttachDecision::TemporarilyUnoptimizable:
|
||||
case AttachDecision::Deferred:
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid attach result");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!attached && canAttachStub) {
|
||||
ic->state().trackNotAttached();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// This helper handles ICState updates/transitions while attaching CacheIR
|
||||
// stubs.
|
||||
template <typename IRGenerator, typename IC, typename... Args>
|
||||
static void TryAttachIonStub(JSContext* cx, IC* ic, IonScript* ionScript,
|
||||
Args&&... args) {
|
||||
if (ic->state().maybeTransition()) {
|
||||
ic->discardStubs(cx->zone());
|
||||
}
|
||||
|
||||
if (ic->state().canAttachStub()) {
|
||||
RootedScript script(cx, ic->script());
|
||||
bool attached = false;
|
||||
IRGenerator gen(cx, script, ic->pc(), ic->state().mode(),
|
||||
std::forward<Args>(args)...);
|
||||
if (gen.tryAttachStub()) {
|
||||
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript,
|
||||
&attached);
|
||||
}
|
||||
if (!attached) {
|
||||
ic->state().trackNotAttached();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool IonGetNameIC::update(JSContext* cx, HandleScript outerScript,
|
||||
IonGetNameIC* ic, HandleObject envChain,
|
||||
|
|
|
@ -6673,9 +6673,10 @@ static void DrawTextRun(const gfxTextRun* aTextRun,
|
|||
}
|
||||
}
|
||||
}
|
||||
StrokeOptions strokeOpts;
|
||||
// Use ROUND joins as they are less likely to produce ugly artifacts
|
||||
// when stroking glyphs with sharp angles (see bug 1546985).
|
||||
StrokeOptions strokeOpts(aParams.textStrokeWidth, JoinStyle::ROUND);
|
||||
params.textStrokeColor = aParams.textStrokeColor;
|
||||
strokeOpts.mLineWidth = aParams.textStrokeWidth;
|
||||
params.strokeOpts = &strokeOpts;
|
||||
aTextRun->Draw(aRange, aTextBaselinePt, params);
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<style>
|
||||
html {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
#scrolled {
|
||||
height: 2000px;
|
||||
width: 100%;
|
||||
}
|
||||
#fixed {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
background: red;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div id="scrolled"></div>
|
||||
<div id="fixed"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!--
|
||||
Tests that setting a fixed bottom margin in AsyncCompositionManager results
|
||||
in the margin being applied to an element fixed to the bottom.
|
||||
|
||||
The fixed margin is specified as a test-pref in reftest.list.
|
||||
|
||||
The purpose of the fixed margin is to compensate for the transform that the
|
||||
dynamic toolbar applies to the entire content area. We don't have a way of
|
||||
simulating that transform in a reftest, so the fixed margin in isolation will
|
||||
cause the fixed element to be offset from the bottom of the screen, and in
|
||||
the ref page we use a regular CSS "margin-bottom" to match the rendering.
|
||||
-->
|
||||
<html>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<style>
|
||||
html {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
#scrolled {
|
||||
height: 2000px;
|
||||
width: 100%;
|
||||
}
|
||||
#fixed {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
background: red;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div id="scrolled"></div>
|
||||
<div id="fixed"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -93,3 +93,7 @@ skip-if(!Android) pref(apz.allow_zooming,true) == position-fixed-async-zoom-3.ht
|
|||
skip-if(!Android) pref(apz.allow_zooming,true) == position-fixed-async-zoom-4.html position-fixed-async-zoom-4-ref.html
|
||||
skip-if(!Android) pref(apz.allow_zooming,true) == position-sticky-async-zoom-1.html position-sticky-async-zoom-1-ref.html
|
||||
skip-if(!Android) pref(apz.allow_zooming,true) == position-sticky-async-zoom-2.html position-sticky-async-zoom-2-ref.html
|
||||
|
||||
# for this test, apz.allow_zooming is needed to ensure we take the containerless scrolling codepath that creates
|
||||
# an async zoom container (since we are testing a regression in that codepath)
|
||||
skip-if(!Android) pref(apz.allow_zooming,true) test-pref(apz.fixed-margin-override.enabled,true) test-pref(apz.fixed-margin-override.bottom,50) == dynamic-toolbar-fixed-bottom-1.html dynamic-toolbar-fixed-bottom-1-ref.html
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
# fuzzy is needed here for platform dependent backends
|
||||
default-preferences pref(layout.css.prefixes.webkit,true)
|
||||
|
||||
fuzzy-if(gtkWidget,0-255,0-20) fuzzy-if(winWidget,0-20,0-10) fails-if(skiaContent&&(gtkWidget||winWidget)) fuzzy-if(cocoaWidget&&webrender,48-48,44-44) == webkit-text-stroke-property-001.html webkit-text-stroke-property-001-ref.html
|
||||
fuzzy-if(gtkWidget,0-255,0-20) fuzzy-if(winWidget,0-20,0-10) fails-if(skiaContent&&!webrender&>kWidget) fuzzy-if(webrender,3-4,4-24) == webkit-text-stroke-property-002.html webkit-text-stroke-property-002-ref.html
|
||||
fuzzy-if(gtkWidget,0-255,0-20) fuzzy-if(winWidget,0-20,0-10) fuzzy-if(webrender,32-48,26-26) fails-if(skiaContent&>kWidget) == webkit-text-stroke-property-003.html webkit-text-stroke-property-003-ref.html
|
||||
fuzzy-if(gtkWidget,0-255,0-20) fuzzy-if(winWidget,0-20,0-10) fuzzy-if(webrender,48-64,21-33) fails-if(skiaContent&>kWidget) == webkit-text-stroke-property-004.html webkit-text-stroke-property-004-ref.html
|
||||
fuzzy-if(gtkWidget,0-255,0-20) fuzzy-if(winWidget,0-20,0-10) fails-if(skiaContent&&(gtkWidget||winWidget)) fuzzy-if(cocoaWidget&&webrender,48-48,44-44) == webkit-text-stroke-property-005.html webkit-text-stroke-property-005-ref.html
|
||||
fuzzy-if(gtkWidget,0-255,0-392) fuzzy-if(winWidget&&!d2d,0-48,0-372) fuzzy-if(winWidget&&d2d,0-71,0-10) == webkit-text-stroke-property-006.html webkit-text-stroke-property-006-ref.html
|
||||
# These fail on Linux without webrender due to lack of antialiasing of the HTML text stroke
|
||||
fuzzy(0-64,0-44) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-001.html webkit-text-stroke-property-001-ref.html
|
||||
fuzzy(0-4,0-24) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-002.html webkit-text-stroke-property-002-ref.html
|
||||
fuzzy(0-48,0-26) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-003.html webkit-text-stroke-property-003-ref.html
|
||||
fuzzy(0-64,0-33) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-004.html webkit-text-stroke-property-004-ref.html
|
||||
fuzzy(0-64,0-44) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-005.html webkit-text-stroke-property-005-ref.html
|
||||
fuzzy(0-71,0-10) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-006.html webkit-text-stroke-property-006-ref.html
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
<div style="width: 500px; height: 200px;">
|
||||
<!-- set overflow to visible so that stroking near boundary won't be hidden -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="width: 100%; height: 100%; overflow: visible;">
|
||||
<text x="0" y="100" font-size="64px" fill="transparent" stroke="green" stroke-width="2px">TEXT stroke</text>
|
||||
<text x="0" y="100" font-size="64px" fill="transparent" stroke="green"
|
||||
stroke-width="2px" stroke-linejoin="round">TEXT stroke</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
<div style="width: 500px; height: 200px;">
|
||||
<!-- set overflow to visible so that stroking near boundary won't be hidden -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="width: 100%; height: 100%; overflow: visible;">
|
||||
<text x="0" y="100" font-size="64px" fill="transparent" stroke="black" stroke-width="1px">TEXT stroke</text>
|
||||
<text x="0" y="100" font-size="64px" fill="transparent" stroke="black"
|
||||
stroke-width="1px" stroke-linejoin="round">TEXT stroke</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
<div style="width: 500px; height: 200px;">
|
||||
<!-- set overflow to visible so that stroking near boundary won't be hidden -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="width: 100%; height: 100%; overflow: visible;">
|
||||
<text x="0" y="100" font-size="64px" fill="transparent" stroke="black" stroke-width="3px">TEXT stroke</text>
|
||||
<text x="0" y="100" font-size="64px" fill="transparent" stroke="black"
|
||||
stroke-width="3px" stroke-linejoin="round">TEXT stroke</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
<div style="width: 500px; height: 200px;">
|
||||
<!-- set overflow to visible so that stroking near boundary won't be hidden -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="width: 100%; height: 100%; overflow: visible;">
|
||||
<text x="0" y="100" font-size="64px" fill="transparent" stroke="black" stroke-width="5px">TEXT stroke</text>
|
||||
<text x="0" y="100" font-size="64px" fill="transparent" stroke="black"
|
||||
stroke-width="5px" stroke-linejoin="round">TEXT stroke</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
<div style="width: 500px; height: 200px;">
|
||||
<!-- set overflow to visible so that stroking near boundary won't be hidden -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="width: 100%; height: 100%; overflow: visible;">
|
||||
<text x="0" y="100" font-size="64px" fill="transparent" stroke="green" stroke-width="2px">TEXT stroke</text>
|
||||
<text x="0" y="100" font-size="64px" fill="transparent" stroke="green"
|
||||
stroke-width="2px" stroke-linejoin="round">TEXT stroke</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -12,7 +12,7 @@ body { font-family: test; }
|
|||
<div style="width: 500px; height: 400px;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="width: 100%; height: 100%;">
|
||||
<text x="50" y="200" font-size="64px" stroke="green"
|
||||
stroke-width="10px">g̤̦̈̂</text>
|
||||
stroke-width="10px" stroke-linejoin="round">g̤̦̈̂</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "WebrtcProxyChannelWrapper.h"
|
||||
|
||||
#include "mozilla/net/WebrtcProxyChannelChild.h"
|
||||
#include "ipc/WebrtcProxyChannel.h"
|
||||
#include "mozilla/LoadInfo.h"
|
||||
|
||||
#include "nsIEventTarget.h"
|
||||
#include "nsNetCID.h"
|
||||
|
@ -54,9 +56,9 @@ void WebrtcProxyChannelWrapper::AsyncOpen(
|
|||
|
||||
MOZ_ASSERT(!mWebrtcProxyChannel, "wrapper already open");
|
||||
mWebrtcProxyChannel = new WebrtcProxyChannelChild(this);
|
||||
mWebrtcProxyChannel->AsyncOpen(aHost, aPort, aConfig->GetBrowser(),
|
||||
nsContentUtils::GetSystemPrincipal(),
|
||||
aConfig->GetAlpn());
|
||||
mWebrtcProxyChannel->AsyncOpen(aHost, aPort, aConfig->GetLoadInfoArgs(),
|
||||
aConfig->GetAlpn(),
|
||||
dom::TabId(aConfig->GetTabId()));
|
||||
}
|
||||
|
||||
void WebrtcProxyChannelWrapper::SendWrite(nsTArray<uint8_t>&& aReadData) {
|
||||
|
|
|
@ -9,6 +9,7 @@ include protocol PNecko;
|
|||
include protocol PSocketProcess;
|
||||
|
||||
include NeckoChannelParams;
|
||||
using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
@ -20,7 +21,7 @@ async protocol PWebrtcProxyChannel
|
|||
parent:
|
||||
async AsyncOpen(nsCString aHost,
|
||||
int32_t aPort,
|
||||
LoadInfoArgs? aLoadInfoArgs,
|
||||
LoadInfoArgs aLoadInfoArgs,
|
||||
nsCString aAlpn);
|
||||
async Write(uint8_t[] aWriteData);
|
||||
async Close();
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include "nsIURIMutator.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/dom/ContentProcessManager.h"
|
||||
#include "mozilla/dom/BrowserParent.h"
|
||||
|
||||
#include "WebrtcProxyChannelCallback.h"
|
||||
#include "WebrtcProxyLog.h"
|
||||
|
@ -43,13 +45,12 @@ NS_IMPL_ISUPPORTS(WebrtcProxyChannel, nsIAuthPromptProvider,
|
|||
nsIInterfaceRequestor, nsIOutputStreamCallback,
|
||||
nsIRequestObserver, nsIStreamListener)
|
||||
|
||||
WebrtcProxyChannel::WebrtcProxyChannel(nsIAuthPromptProvider* aAuthProvider,
|
||||
WebrtcProxyChannelCallback* aCallbacks)
|
||||
WebrtcProxyChannel::WebrtcProxyChannel(WebrtcProxyChannelCallback* aCallbacks)
|
||||
: mProxyCallbacks(aCallbacks),
|
||||
mClosed(false),
|
||||
mOpened(false),
|
||||
mWriteOffset(0),
|
||||
mAuthProvider(aAuthProvider),
|
||||
mAuthProvider(nullptr),
|
||||
mTransport(nullptr),
|
||||
mSocketIn(nullptr),
|
||||
mSocketOut(nullptr) {
|
||||
|
@ -67,6 +68,12 @@ WebrtcProxyChannel::~WebrtcProxyChannel() {
|
|||
mAuthProvider.forget());
|
||||
}
|
||||
|
||||
void WebrtcProxyChannel::SetTabId(dom::TabId aTabId) {
|
||||
dom::ContentProcessManager* cpm = dom::ContentProcessManager::GetSingleton();
|
||||
dom::ContentParentId cpId = cpm->GetTabProcessId(aTabId);
|
||||
mAuthProvider = cpm->GetBrowserParentByProcessAndTabId(cpId, aTabId);
|
||||
}
|
||||
|
||||
nsresult WebrtcProxyChannel::Write(nsTArray<uint8_t>&& aWriteData) {
|
||||
LOG(("WebrtcProxyChannel::Write %p\n", this));
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
|
@ -128,7 +135,7 @@ void WebrtcProxyChannel::CloseWithReason(nsresult aReason) {
|
|||
}
|
||||
|
||||
nsresult WebrtcProxyChannel::Open(const nsCString& aHost, const int& aPort,
|
||||
nsILoadInfo* aLoadInfo,
|
||||
const net::LoadInfoArgs& aArgs,
|
||||
const nsCString& aAlpn) {
|
||||
LOG(("WebrtcProxyChannel::AsyncOpen %p\n", this));
|
||||
|
||||
|
@ -163,6 +170,15 @@ nsresult WebrtcProxyChannel::Open(const nsCString& aHost, const int& aPort,
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo;
|
||||
Maybe<net::LoadInfoArgs> loadInfoArgs = Some(aArgs);
|
||||
rv = LoadInfoArgsToLoadInfo(loadInfoArgs, getter_AddRefs(loadInfo));
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("WebrtcProxyChannel %p: could not init load info\n", this));
|
||||
CloseWithReason(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// -need to always tunnel since we're using a proxy
|
||||
// -there shouldn't be an opportunity to send cookies, but explicitly disallow
|
||||
// them anyway.
|
||||
|
@ -172,8 +188,8 @@ nsresult WebrtcProxyChannel::Open(const nsCString& aHost, const int& aPort,
|
|||
rv = ioService->NewChannelFromURIWithProxyFlags(
|
||||
uri, nullptr,
|
||||
// Proxy flags are overridden by SetConnectOnly()
|
||||
0, aLoadInfo->LoadingNode(), aLoadInfo->LoadingPrincipal(),
|
||||
aLoadInfo->TriggeringPrincipal(),
|
||||
0, loadInfo->LoadingNode(), loadInfo->LoadingPrincipal(),
|
||||
loadInfo->TriggeringPrincipal(),
|
||||
nsILoadInfo::SEC_DONT_FOLLOW_REDIRECTS | nsILoadInfo::SEC_COOKIES_OMIT |
|
||||
// We need this flag to allow loads from any origin since this channel
|
||||
// is being used to CONNECT to an HTTP proxy.
|
||||
|
|
|
@ -18,12 +18,13 @@
|
|||
#include "nsIStreamListener.h"
|
||||
#include "nsStringFwd.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/dom/ipc/IdType.h" // TabId
|
||||
|
||||
class nsILoadInfo;
|
||||
class nsISocketTransport;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
class LoadInfoArgs;
|
||||
|
||||
class WebrtcProxyChannelCallback;
|
||||
class WebrtcProxyData;
|
||||
|
@ -44,11 +45,11 @@ class WebrtcProxyChannel : public nsIHttpUpgradeListener,
|
|||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_FORWARD_SAFE_NSIAUTHPROMPTPROVIDER(mAuthProvider)
|
||||
|
||||
WebrtcProxyChannel(nsIAuthPromptProvider* aAuthProvider,
|
||||
WebrtcProxyChannelCallback* aProxyCallbacks);
|
||||
explicit WebrtcProxyChannel(WebrtcProxyChannelCallback* aCallbacks);
|
||||
|
||||
void SetTabId(dom::TabId aTabId);
|
||||
nsresult Open(const nsCString& aHost, const int& aPort,
|
||||
nsILoadInfo* aLoadInfo, const nsCString& aAlpn);
|
||||
const net::LoadInfoArgs& aArgs, const nsCString& aAlpn);
|
||||
nsresult Write(nsTArray<uint8_t>&& aBytes);
|
||||
nsresult Close();
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#include "WebrtcProxyChannelChild.h"
|
||||
|
||||
#include "mozilla/dom/PBrowserOrId.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/net/SocketProcessChild.h"
|
||||
|
||||
#include "LoadInfo.h"
|
||||
|
||||
|
@ -16,8 +16,6 @@
|
|||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
using mozilla::dom::PBrowserOrId;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
|
@ -67,9 +65,9 @@ WebrtcProxyChannelChild::~WebrtcProxyChannelChild() {
|
|||
|
||||
void WebrtcProxyChannelChild::AsyncOpen(const nsCString& aHost,
|
||||
const int& aPort,
|
||||
const PBrowserOrId& aBrowser,
|
||||
nsIPrincipal* aLoadingPrincipal,
|
||||
const nsCString& aAlpn) {
|
||||
const net::LoadInfoArgs& aArgs,
|
||||
const nsCString& aAlpn,
|
||||
const dom::TabId& aTabId) {
|
||||
LOG(("WebrtcProxyChannelChild::AsyncOpen %p %s:%d\n", this, aHost.get(),
|
||||
aPort));
|
||||
|
||||
|
@ -77,16 +75,19 @@ void WebrtcProxyChannelChild::AsyncOpen(const nsCString& aHost,
|
|||
|
||||
AddIPDLReference();
|
||||
|
||||
gNeckoChild->SetEventTargetForActor(this, GetMainThreadEventTarget());
|
||||
gNeckoChild->SendPWebrtcProxyChannelConstructor(this, aBrowser);
|
||||
if (IsNeckoChild()) {
|
||||
// We're on a content process
|
||||
gNeckoChild->SetEventTargetForActor(this, GetMainThreadEventTarget());
|
||||
gNeckoChild->SendPWebrtcProxyChannelConstructor(this, aTabId);
|
||||
} else if (IsSocketProcessChild()) {
|
||||
// We're on a socket process
|
||||
SocketProcessChild::GetSingleton()->SetEventTargetForActor(
|
||||
this, GetMainThreadEventTarget());
|
||||
SocketProcessChild::GetSingleton()->SendPWebrtcProxyChannelConstructor(
|
||||
this, aTabId);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo =
|
||||
new LoadInfo(aLoadingPrincipal, nullptr, nullptr, 0, 0);
|
||||
|
||||
Maybe<LoadInfoArgs> loadInfoArgs;
|
||||
MOZ_ALWAYS_SUCCEEDS(LoadInfoToLoadInfoArgs(loadInfo, &loadInfoArgs));
|
||||
|
||||
SendAsyncOpen(aHost, aPort, loadInfoArgs, aAlpn);
|
||||
SendAsyncOpen(aHost, aPort, aArgs, aAlpn);
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -8,13 +8,10 @@
|
|||
#define mozilla_net_WebrtcProxyChannelChild_h
|
||||
|
||||
#include "mozilla/net/PWebrtcProxyChannelChild.h"
|
||||
#include "mozilla/dom/ipc/IdType.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
class PBrowserOrId;
|
||||
} // namespace dom
|
||||
|
||||
namespace net {
|
||||
|
||||
class WebrtcProxyChannelCallback;
|
||||
|
@ -32,8 +29,8 @@ class WebrtcProxyChannelChild : public PWebrtcProxyChannelChild {
|
|||
explicit WebrtcProxyChannelChild(WebrtcProxyChannelCallback* aProxyCallbacks);
|
||||
|
||||
void AsyncOpen(const nsCString& aHost, const int& aPort,
|
||||
const dom::PBrowserOrId& aBrowser,
|
||||
nsIPrincipal* aLoadingPrincipal, const nsCString& aAlpn);
|
||||
const net::LoadInfoArgs& aArgs, const nsCString& aAlpn,
|
||||
const dom::TabId& aTabId);
|
||||
|
||||
void AddIPDLReference() { AddRef(); }
|
||||
void ReleaseIPDLReference() { Release(); }
|
||||
|
|
|
@ -18,24 +18,13 @@ namespace mozilla {
|
|||
namespace net {
|
||||
|
||||
mozilla::ipc::IPCResult WebrtcProxyChannelParent::RecvAsyncOpen(
|
||||
const nsCString& aHost, const int& aPort,
|
||||
const Maybe<LoadInfoArgs>& aLoadInfoArgs, const nsCString& aAlpn) {
|
||||
const nsCString& aHost, const int& aPort, const LoadInfoArgs& aLoadInfoArgs,
|
||||
const nsCString& aAlpn) {
|
||||
LOG(("WebrtcProxyChannelParent::RecvAsyncOpen %p to %s:%d\n", this,
|
||||
aHost.get(), aPort));
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo;
|
||||
|
||||
rv = LoadInfoArgsToLoadInfo(aLoadInfoArgs, getter_AddRefs(loadInfo));
|
||||
if (NS_FAILED(rv)) {
|
||||
IProtocol* mgr = Manager();
|
||||
OnClose(rv);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mChannel, "webrtc proxy channel should be non-null");
|
||||
mChannel->Open(aHost, aPort, loadInfo, aAlpn);
|
||||
mChannel->Open(aHost, aPort, aLoadInfoArgs, aAlpn);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -72,13 +61,13 @@ void WebrtcProxyChannelParent::ActorDestroy(ActorDestroyReason aWhy) {
|
|||
CleanupChannel();
|
||||
}
|
||||
|
||||
WebrtcProxyChannelParent::WebrtcProxyChannelParent(
|
||||
nsIAuthPromptProvider* aAuthProvider) {
|
||||
WebrtcProxyChannelParent::WebrtcProxyChannelParent(dom::TabId aTabId) {
|
||||
MOZ_COUNT_CTOR(WebrtcProxyChannelParent);
|
||||
|
||||
LOG(("WebrtcProxyChannelParent::WebrtcProxyChannelParent %p\n", this));
|
||||
|
||||
mChannel = new WebrtcProxyChannel(aAuthProvider, this);
|
||||
mChannel = new WebrtcProxyChannel(this);
|
||||
mChannel->SetTabId(aTabId);
|
||||
}
|
||||
|
||||
WebrtcProxyChannelParent::~WebrtcProxyChannelParent() {
|
||||
|
|
|
@ -23,10 +23,10 @@ class WebrtcProxyChannelParent : public PWebrtcProxyChannelParent,
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebrtcProxyChannelParent, override)
|
||||
|
||||
mozilla::ipc::IPCResult RecvAsyncOpen(
|
||||
const nsCString& aHost, const int& aPort,
|
||||
const Maybe<LoadInfoArgs>& aLoadInfoArgs,
|
||||
const nsCString& aAlpn) override;
|
||||
mozilla::ipc::IPCResult RecvAsyncOpen(const nsCString& aHost,
|
||||
const int& aPort,
|
||||
const LoadInfoArgs& aLoadInfoArgs,
|
||||
const nsCString& aAlpn) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvWrite(nsTArray<uint8_t>&& aWriteData) override;
|
||||
|
||||
|
@ -34,7 +34,7 @@ class WebrtcProxyChannelParent : public PWebrtcProxyChannelParent,
|
|||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
explicit WebrtcProxyChannelParent(nsIAuthPromptProvider* aAuthProvider);
|
||||
explicit WebrtcProxyChannelParent(dom::TabId aTabId);
|
||||
|
||||
// WebrtcProxyChannelCallback
|
||||
void OnClose(nsresult aReason) override;
|
||||
|
|
|
@ -6,31 +6,36 @@
|
|||
|
||||
#include "nr_socket_proxy_config.h"
|
||||
|
||||
#include "mozilla/dom/PBrowserOrId.h"
|
||||
#include "mozilla/dom/ipc/IdType.h"
|
||||
#include "mozilla/net/NeckoChannelParams.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class NrSocketProxyConfig::Private {
|
||||
public:
|
||||
dom::PBrowserOrId mBrowser;
|
||||
uint64_t mTabId;
|
||||
nsCString mAlpn;
|
||||
net::LoadInfoArgs mLoadInfoArgs;
|
||||
};
|
||||
|
||||
NrSocketProxyConfig::NrSocketProxyConfig(const dom::PBrowserOrId& aBrowser,
|
||||
const nsCString& aAlpn)
|
||||
: mPrivate(new Private({aBrowser, aAlpn})) {}
|
||||
NrSocketProxyConfig::NrSocketProxyConfig(uint64_t aTabId,
|
||||
const nsCString& aAlpn,
|
||||
const net::LoadInfoArgs& aArgs)
|
||||
: mPrivate(new Private({aTabId, aAlpn, aArgs})) {}
|
||||
|
||||
NrSocketProxyConfig::NrSocketProxyConfig(NrSocketProxyConfig&& aOrig)
|
||||
: mPrivate(std::move(aOrig.mPrivate)) {}
|
||||
|
||||
NrSocketProxyConfig::~NrSocketProxyConfig() {}
|
||||
|
||||
const dom::PBrowserOrId& NrSocketProxyConfig::GetBrowser() const {
|
||||
return mPrivate->mBrowser;
|
||||
}
|
||||
uint64_t NrSocketProxyConfig::GetTabId() const { return mPrivate->mTabId; }
|
||||
|
||||
const nsCString& NrSocketProxyConfig::GetAlpn() const {
|
||||
return mPrivate->mAlpn;
|
||||
}
|
||||
|
||||
const net::LoadInfoArgs& NrSocketProxyConfig::GetLoadInfoArgs() const {
|
||||
return mPrivate->mLoadInfoArgs;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -13,14 +13,14 @@
|
|||
class nsIPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class PBrowserOrId;
|
||||
namespace net {
|
||||
class LoadInfoArgs;
|
||||
}
|
||||
|
||||
class NrSocketProxyConfig {
|
||||
public:
|
||||
NrSocketProxyConfig(const dom::PBrowserOrId& aBrowser,
|
||||
const nsCString& aAlpn);
|
||||
NrSocketProxyConfig(uint64_t aTabId, const nsCString& aAlpn,
|
||||
const net::LoadInfoArgs& aArgs);
|
||||
// We need to actually write the default impl ourselves, because the compiler
|
||||
// needs to know how to destroy mPrivate in case an exception is thrown, even
|
||||
// though we disable exceptions in our build.
|
||||
|
@ -28,11 +28,12 @@ class NrSocketProxyConfig {
|
|||
|
||||
~NrSocketProxyConfig();
|
||||
|
||||
const dom::PBrowserOrId& GetBrowser() const;
|
||||
uint64_t GetTabId() const;
|
||||
const nsCString& GetAlpn() const;
|
||||
const net::LoadInfoArgs& GetLoadInfoArgs() const;
|
||||
|
||||
private:
|
||||
// PBrowserOrId includes stuff that conflicts with nICEr includes.
|
||||
// LoadInfoArgs includes stuff that conflicts with nICEr includes.
|
||||
// Make it possible to include this header file without tripping over this
|
||||
// problem.
|
||||
class Private;
|
||||
|
|
|
@ -2098,8 +2098,14 @@ int NrSocketBase::CreateSocket(
|
|||
}
|
||||
|
||||
// create IPC bridge for content process
|
||||
if (XRE_IsParentProcess() || XRE_IsSocketProcess()) {
|
||||
if (XRE_IsParentProcess()) {
|
||||
*sock = new NrSocket();
|
||||
} else if (XRE_IsSocketProcess()) {
|
||||
if (addr->protocol == IPPROTO_TCP && config) {
|
||||
*sock = new NrSocketProxy(config);
|
||||
} else {
|
||||
*sock = new NrSocket();
|
||||
}
|
||||
} else {
|
||||
switch (addr->protocol) {
|
||||
case IPPROTO_UDP:
|
||||
|
|
|
@ -2969,7 +2969,7 @@ void AddNonPairableCandidates(
|
|||
test_utils_));
|
||||
break;
|
||||
default:
|
||||
UNIMPLEMENTED;
|
||||
NR_UNIMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче