Merge mozilla-central to mozilla-inbound

This commit is contained in:
arthur.iakab 2019-04-27 01:07:28 +03:00
Родитель 74f2c2db2e 67bd1aa6e8
Коммит 4bb9a04eff
138 изменённых файлов: 2314 добавлений и 2177 удалений

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

@ -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&&gtkWidget) 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&&gtkWidget) == 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&&gtkWidget) == 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&#x324;&#x326;&#x308;&#x302;</text>
stroke-width="10px" stroke-linejoin="round">g&#x324;&#x326;&#x308;&#x302;</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;
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше