Merge mozilla-central to autoland. a=merge CLOSED TREE

This commit is contained in:
Bogdan Tara 2018-07-07 01:08:19 +03:00
Родитель 1cf4ac0f2e f06fbe92ac
Коммит e7030b9e50
1139 изменённых файлов: 19105 добавлений и 8707 удалений

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

@ -94,44 +94,66 @@
accesskey="&detailsProgressiveDisclosure.accesskey;"
control="detailsExpander"/>
</hbox>
<listbox id="itemList" rows="7" collapsed="true" persist="collapsed">
<listitem label="&itemHistoryAndDownloads.label;"
type="checkbox"
accesskey="&itemHistoryAndDownloads.accesskey;"
preference="privacy.cpd.history"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<listitem label="&itemFormSearchHistory.label;"
type="checkbox"
accesskey="&itemFormSearchHistory.accesskey;"
preference="privacy.cpd.formdata"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<listitem label="&itemCookies.label;"
type="checkbox"
accesskey="&itemCookies.accesskey;"
preference="privacy.cpd.cookies"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<listitem label="&itemCache.label;"
type="checkbox"
accesskey="&itemCache.accesskey;"
preference="privacy.cpd.cache"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<listitem label="&itemActiveLogins.label;"
type="checkbox"
accesskey="&itemActiveLogins.accesskey;"
preference="privacy.cpd.sessions"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<listitem label="&itemOfflineApps.label;"
type="checkbox"
accesskey="&itemOfflineApps.accesskey;"
preference="privacy.cpd.offlineApps"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<listitem label="&itemSitePreferences.label;"
type="checkbox"
accesskey="&itemSitePreferences.accesskey;"
preference="privacy.cpd.siteSettings"
noduration="true"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
</listbox>
<vbox id="itemList" collapsed="true" persist="collapsed">
<groupbox orient="horizontal">
<caption><label>&historySection.label;</label></caption>
<grid flex="1">
<columns>
<column style="width: &sanitizePrefs2.column.width;"/>
<column flex="1"/>
</columns>
<rows>
<row>
<checkbox label="&itemHistoryAndDownloads.label;"
accesskey="&itemHistoryAndDownloads.accesskey;"
preference="privacy.cpd.history"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<checkbox label="&itemCookies.label;"
accesskey="&itemCookies.accesskey;"
preference="privacy.cpd.cookies"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
</row>
<row>
<checkbox label="&itemActiveLogins.label;"
accesskey="&itemActiveLogins.accesskey;"
preference="privacy.cpd.sessions"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<checkbox label="&itemCache.label;"
accesskey="&itemCache.accesskey;"
preference="privacy.cpd.cache"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
</row>
<row>
<checkbox label="&itemFormSearchHistory.label;"
accesskey="&itemFormSearchHistory.accesskey;"
preference="privacy.cpd.formdata"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
</row>
</rows>
</grid>
</groupbox>
<groupbox orient="horizontal">
<caption><label>&dataSection.label;</label></caption>
<grid flex="1">
<columns>
<column style="width: &sanitizePrefs2.column.width;"/>
<column flex="1"/>
</columns>
<rows>
<row>
<checkbox label="&itemSitePreferences.label;"
accesskey="&itemSitePreferences.accesskey;"
preference="privacy.cpd.siteSettings"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<checkbox label="&itemOfflineApps.label;"
accesskey="&itemOfflineApps.accesskey;"
preference="privacy.cpd.offlineApps"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
</row>
</rows>
</grid>
</groupbox>
</vbox>
</vbox>
</dialog>

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

@ -194,7 +194,7 @@ var gSanitizePromptDialog = {
* Check if all of the history items have been selected like the default status.
*/
hasNonSelectedItems() {
let checkboxes = document.querySelectorAll("#itemList > [preference]");
let checkboxes = document.querySelectorAll("checkbox[preference]");
for (let i = 0; i < checkboxes.length; ++i) {
let pref = Preferences.get(checkboxes[i].getAttribute("preference"));
if (!pref.value)

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

@ -31,9 +31,9 @@ skip-if = (verify && !debug && (os == 'win'))
[browser_tabswitch.js]
[browser_toolbariconcolor_restyles.js]
[browser_urlbar_keyed_search.js]
skip-if = (os == 'linux') || (os == 'win' && debug) || (verify && (os == 'win')) # Disabled on Linux and Windows debug due to perma failures. Bug 1392320.
skip-if = (os == 'linux') || (os == 'win' && debug) || (os == 'win' && bits == 32) # Disabled on Linux and Windows debug due to perma failures. Bug 1392320. Disabled on Win32 because of intermittent OOM failures (bug 1448241).
[browser_urlbar_search.js]
skip-if = (debug || ccov) && (os == 'linux' || os == 'win') || (verify && (os == 'win')) # Disabled on Linux and Windows debug and ccov due to intermittent timeouts. Bug 1414126, bug 1426611.
skip-if = (debug || ccov) && (os == 'linux' || os == 'win') || (os == 'win' && bits == 32) # Disabled on Linux and Windows debug and ccov due to intermittent timeouts. Bug 1414126, bug 1426611. Disabled on Win32 because of intermittent OOM failures (bug 1448241).
[browser_window_resize.js]
[browser_windowclose.js]
[browser_windowopen.js]

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

@ -362,12 +362,12 @@ add_task(async function test_cannot_clear_history() {
wh.onload = function() {
// Check that the relevant checkboxes are enabled
var cb = this.win.document.querySelectorAll(
"#itemList > [preference='privacy.cpd.formdata']");
"checkbox[preference='privacy.cpd.formdata']");
ok(cb.length == 1 && !cb[0].disabled, "There is formdata, checkbox to " +
"clear formdata should be enabled.");
cb = this.win.document.querySelectorAll(
"#itemList > [preference='privacy.cpd.history']");
"checkbox[preference='privacy.cpd.history']");
ok(cb.length == 1 && !cb[0].disabled, "There is history, checkbox to " +
"clear history should be enabled.");
@ -398,7 +398,7 @@ add_task(async function test_no_formdata_history_to_clear() {
"formdata checkbox checked");
var cb = this.win.document.querySelectorAll(
"#itemList > [preference='privacy.cpd.history']");
"checkbox[preference='privacy.cpd.history']");
ok(cb.length == 1 && !cb[0].disabled && cb[0].checked,
"There is no history, but history checkbox should always be enabled " +
"and will be checked from previous preference.");
@ -422,7 +422,7 @@ add_task(async function test_form_entries() {
"dialog where you could not clear formdata.");
var cb = this.win.document.querySelectorAll(
"#itemList > [preference='privacy.cpd.formdata']");
"checkbox[preference='privacy.cpd.formdata']");
info("There exists formEntries so the checkbox should be in sync with the pref.");
is(cb.length, 1, "There is only one checkbox for form data");
@ -708,7 +708,7 @@ WindowHelper.prototype = {
checkPrefCheckbox(aPrefName, aCheckState) {
var pref = "privacy.cpd." + aPrefName;
var cb = this.win.document.querySelectorAll(
"#itemList > [preference='" + pref + "']");
"checkbox[preference='" + pref + "']");
is(cb.length, 1, "found checkbox for " + pref + " preference");
if (cb[0].checked != aCheckState)
cb[0].click();
@ -718,7 +718,7 @@ WindowHelper.prototype = {
* Makes sure all the checkboxes are checked.
*/
_checkAllCheckboxesCustom(check) {
var cb = this.win.document.querySelectorAll("#itemList > [preference]");
var cb = this.win.document.querySelectorAll("checkbox[preference]");
ok(cb.length > 1, "found checkboxes for preferences");
for (var i = 0; i < cb.length; ++i) {
var pref = this.win.Preferences.get(cb[i].getAttribute("preference"));

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

@ -4,17 +4,17 @@
/*** Downloads Panel ***/
richlistitem[type="download"] {
#downloadsListBox > richlistitem {
-moz-binding: url('chrome://browser/content/downloads/download.xml#download');
}
richlistitem[type="download"]:not([selected]) button {
#downloadsListBox > richlistitem:not([selected]) button {
/* Only focus buttons in the selected item. */
-moz-user-focus: none;
}
richlistitem[type="download"].download-state[state="1"]:not([exists]) > .downloadButtonArea,
richlistitem[type="download"].download-state[state="1"]:not([exists]) > toolbarseparator {
#downloadsListBox > richlistitem.download-state[state="1"]:not([exists]) > .downloadButtonArea,
#downloadsListBox > richlistitem.download-state[state="1"]:not([exists]) > toolbarseparator {
display: none;
}
@ -49,15 +49,15 @@ richlistitem[type="download"].download-state[state="1"]:not([exists]) > toolbars
*
* We might be able to do away with this workaround once bug 653881 is fixed.
*/
richlistitem.download {
#downloadsRichListBox > richlistitem {
-moz-binding: none;
}
richlistitem.download[active] {
#downloadsRichListBox > richlistitem[active] {
-moz-binding: url("chrome://browser/content/downloads/download.xml#download");
}
richlistitem.download button {
#downloadsRichListBox > richlistitem button {
/* These buttons should never get focus, as that would "disable"
the downloads view controller (it's only used when the richlistbox
is focused). */

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

@ -15,9 +15,6 @@
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="translationbar" extends="chrome://global/content/bindings/notification.xml#notification">
<resources>
<stylesheet src="chrome://global/skin/notification.css"/>
</resources>
<content>
<xul:hbox anonid="details" align="center" flex="1">
<xul:image class="translate-infobar-element messageImage"

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

@ -10,11 +10,6 @@
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="autocomplete-profile-listitem-base" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<resources>
<stylesheet src="chrome://formautofill-shared/skin/autocomplete-item.css"/>
<stylesheet src="chrome://formautofill/skin/autocomplete-item.css"/>
</resources>
<implementation implements="nsIDOMXULSelectControlItemElement">
<constructor>
</constructor>

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

@ -4,7 +4,7 @@
%filter substitution
%define item richlistitem.download
%define item #downloadsRichListBox > richlistitem
%define itemFocused @item@[selected]
/*** View and outer controls ***/
@ -17,7 +17,7 @@
/*** List items ***/
#downloadsRichListBox > richlistitem.download {
@item@ {
height: var(--downloads-item-height);
}

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

@ -6,7 +6,7 @@
%define keyfocus #downloadsPanel[keyfocus]
%define notKeyfocus #downloadsPanel:not([keyfocus])
%define item richlistitem[type="download"]
%define item #downloadsListBox > richlistitem
%define itemFinished @item@[state="1"]
%define itemNotFinished @item@:not([state="1"])
%define itemFocused #downloadsListBox:focus > @item@[selected]
@ -112,17 +112,17 @@
/*** List items and similar elements in the summary ***/
#downloadsSummary,
richlistitem[type="download"] {
@item@ {
height: var(--downloads-item-height);
}
richlistitem[type="download"] {
@item@ {
border-bottom: 1px solid var(--panel-separator-color);
background: transparent;
color: inherit;
}
richlistitem[type="download"]:last-child {
@item@:last-child {
border-bottom: none;
}

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

@ -1031,7 +1031,7 @@ endif # HOST_RUST_PROGRAMS
$(SOBJS):
$(REPORT_BUILD)
$(AS) -o $@ $(SFLAGS) $($(notdir $<)_FLAGS) -c $<
$(AS) $(ASOUTOPTION)$@ $(SFLAGS) $($(notdir $<)_FLAGS) -c $<
$(CPPOBJS):
$(REPORT_BUILD_VERBOSE)

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

@ -1,9 +1,9 @@
This is the debugger.html project output.
See https://github.com/devtools-html/debugger.html
Version 68
Version 69
Comparison: https://github.com/devtools-html/debugger.html/compare/release-67...release-68
Comparison: https://github.com/devtools-html/debugger.html/compare/release-68...release-69
Packages:
- babel-plugin-transform-es2015-modules-commonjs @6.26.2

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

@ -1777,6 +1777,16 @@ menuseparator {
fill: var(--theme-textbox-box-shadow);
}
.source-icon.vue {
background: url("chrome://devtools/skin/images/debugger/vuejs.svg") 1px 1px no-repeat;
background-size: 15px;
}
.source-icon.angular {
background: url("chrome://devtools/skin/images/debugger/angular.svg") 1px 1px no-repeat;
background-size: 13px 13px;
}
.source-icon.blackBox {
mask: url("chrome://devtools/skin/images/debugger/blackBox.svg") no-repeat;
mask-size: 100%;

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

@ -1181,6 +1181,7 @@ exports.isAwaitExpression = isAwaitExpression;
exports.isYieldExpression = isYieldExpression;
exports.isObjectShorthand = isObjectShorthand;
exports.getObjectExpressionValue = getObjectExpressionValue;
exports.getCode = getCode;
exports.getVariableNames = getVariableNames;
exports.getComments = getComments;
exports.getSpecifiers = getSpecifiers;
@ -1241,6 +1242,10 @@ function getObjectExpressionValue(node) {
return shouldWrap ? `(${code})` : code;
}
function getCode(node) {
return (0, _generator2.default)(node).code;
}
function getVariableNames(path) {
if (t.isObjectProperty(path.node) && !isFunction(path.node.value)) {
if (path.node.key.type === "StringLiteral") {
@ -1533,10 +1538,14 @@ function extractSymbol(path, symbols) {
}
if (t.isClassDeclaration(path)) {
const { loc, superClass } = path.node;
symbols.classes.push({
name: path.node.id.name,
parent: path.node.superClass,
location: path.node.loc
parent: superClass ? {
name: t.isMemberExpression(superClass) ? (0, _helpers.getCode)(superClass) : superClass.name,
location: superClass.loc
} : null,
location: loc
});
}

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

@ -17,7 +17,9 @@ var parser = _interopRequireWildcard(_parser);
var _source = require("../../utils/source");
var _devtoolsModules = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-modules"];
var _telemetry = require("devtools/client/shared/telemetry");
var _telemetry2 = _interopRequireDefault(_telemetry);
var _defer = require("../../utils/defer");
@ -33,7 +35,7 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj;
const requests = new Map(); // Measures the time it takes for a source to load
const loadSourceHistogram = "DEVTOOLS_DEBUGGER_LOAD_SOURCE_MS";
const telemetry = new _devtoolsModules.Telemetry();
const telemetry = new _telemetry2.default();
async function loadSource(source, {
sourceMaps,

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

@ -412,16 +412,6 @@ const getSelectedSource = exports.getSelectedSource = (0, _reselect.createSelect
return;
}
const source = sources[selectedLocation.sourceId]; // TODO: remove this when the immutable refactor lands in m-c
if (_devtoolsEnvironment.isTesting) {
const testSource = _objectSpread({}, source, {
get: field => source[field]
});
return testSource;
}
return source;
return sources[selectedLocation.sourceId];
});
exports.default = update;

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

@ -46,7 +46,10 @@ function inComponent(state) {
}
const inReactFile = sourceMetaData.framework == "React";
const isComponent = closestClass.parent && ["Component", "PureComponent"].includes(closestClass.parent.name);
const {
parent
} = closestClass;
const isComponent = parent && parent.name.includes("Component");
if (inReactFile && isComponent) {
return closestClass.name;

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

@ -37,6 +37,7 @@ DevToolsModules(
'source.js',
'tabs.js',
'task.js',
'telemetry.js',
'text.js',
'timings.js',
'ui.js',

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

@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.recordEvent = recordEvent;
var _telemetry = require("devtools/client/shared/telemetry");
var _telemetry2 = _interopRequireDefault(_telemetry);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
const telemetry = new _telemetry2.default();
/**
* @memberof utils/telemetry
* @static
*/
function recordEvent(eventName, fields = {}) {
let sessionId = -1;
if (typeof window === "object" && window.parent.frameElement) {
sessionId = window.parent.frameElement.getAttribute("session_id");
}
/* eslint-disable camelcase */
telemetry.recordEvent("devtools.main", eventName, "debugger", null, _objectSpread({
session_id: sessionId
}, fields));
/* eslint-enable camelcase */
}

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

@ -85,10 +85,17 @@ function extractSymbol(path, symbols) {
}
if (t.isClassDeclaration(path)) {
const {
loc,
superClass
} = path.node;
symbols.classes.push({
name: path.node.id.name,
parent: path.node.superClass,
location: path.node.loc
parent: superClass ? {
name: t.isMemberExpression(superClass) ? (0, _helpers.getCode)(superClass) : superClass.name,
location: superClass.loc
} : null,
location: loc
});
}

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

@ -8,6 +8,7 @@ exports.isAwaitExpression = isAwaitExpression;
exports.isYieldExpression = isYieldExpression;
exports.isObjectShorthand = isObjectShorthand;
exports.getObjectExpressionValue = getObjectExpressionValue;
exports.getCode = getCode;
exports.getVariableNames = getVariableNames;
exports.getComments = getComments;
exports.getSpecifiers = getSpecifiers;
@ -77,6 +78,10 @@ function getObjectExpressionValue(node) {
return shouldWrap ? `(${code})` : code;
}
function getCode(node) {
return (0, _generator2.default)(node).code;
}
function getVariableNames(path) {
if (t.isObjectProperty(path.node) && !isFunction(path.node.value)) {
if (path.node.key.type === "StringLiteral") {

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

@ -56,5 +56,5 @@ add_task(async function() {
is(dbg.selectors.getActiveSearch(dbg.getState()), null);
const selectedSource = dbg.selectors.getSelectedSource(dbg.getState());
ok(selectedSource.get("url").includes("switching-01"));
ok(selectedSource.url.includes("switching-01"));
});

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

@ -49,7 +49,7 @@ add_task(async function() {
const focusedNode = findElementWithSelector(dbg, ".sources-list .focused");
const fourthNode = findElement(dbg, "sourceNode", 4);
const selectedSource = getSelectedSource(getState()).get("url");
const selectedSource = getSelectedSource(getState()).url;
ok(fourthNode.classList.contains("focused"), "4th node is focused");
ok(selectedSource.includes("nested-source.js"), "nested-source is selected");

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

@ -259,6 +259,7 @@ devtools.jar:
skin/images/read-only.svg (themes/images/read-only.svg)
# Debugger
skin/images/debugger/angular.svg (themes/images/debugger/angular.svg)
skin/images/debugger/arrow.svg (themes/images/debugger/arrow.svg)
skin/images/debugger/back.svg (themes/images/debugger/back.svg)
skin/images/debugger/blackBox.svg (themes/images/debugger/blackBox.svg)
@ -281,6 +282,7 @@ devtools.jar:
skin/images/debugger/stepOver.svg (themes/images/debugger/stepOver.svg)
skin/images/debugger/tab.svg (themes/images/debugger/tab.svg)
skin/images/debugger/typescript.svg (themes/images/debugger/typescript.svg)
skin/images/debugger/vuejs.svg (themes/images/debugger/vuejs.svg)
# Netmonitor
content/netmonitor/src/assets/styles/httpi.css (netmonitor/src/assets/styles/httpi.css)

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

@ -65,7 +65,7 @@ async function checkClickOnNode(toolbox, frameLinkNode) {
const dbg = await toolbox.getPanelWhenReady("jsdebugger");
await waitUntil(() => dbg._selectors.getSelectedSource(dbg._getState()));
is(
dbg._selectors.getSelectedSource(dbg._getState()).get("url"),
dbg._selectors.getSelectedSource(dbg._getState()).url,
url,
"expected source url"
);

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

@ -0,0 +1,10 @@
<!-- 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/. -->
<svg width="256px" height="272px" viewBox="0 0 256 272" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<g>
<path d="M0.0996108949,45.522179 L125.908171,0.697276265 L255.103502,44.7252918 L234.185214,211.175097 L125.908171,271.140856 L19.3245136,211.971984 L0.0996108949,45.522179 Z" fill="#E23237"></path>
<path d="M255.103502,44.7252918 L125.908171,0.697276265 L125.908171,271.140856 L234.185214,211.274708 L255.103502,44.7252918 L255.103502,44.7252918 Z" fill="#B52E31"></path>
<path d="M126.107393,32.27393 L126.107393,32.27393 L47.7136187,206.692607 L76.9992218,206.194553 L92.7377432,166.848249 L126.207004,166.848249 L126.306615,166.848249 L163.063035,166.848249 L180.29572,206.692607 L208.286381,207.190661 L126.107393,32.27393 L126.107393,32.27393 Z M126.306615,88.155642 L152.803113,143.5393 L127.402335,143.5393 L126.107393,143.5393 L102.997665,143.5393 L126.306615,88.155642 L126.306615,88.155642 Z" fill="#FFFFFF"></path>
</g>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

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

@ -0,0 +1,31 @@
<!-- 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/. -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 400 400"
height="400"
width="400"
xml:space="preserve"
id="svg2"
version="1.1"><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs6" /><g
transform="matrix(1.3333333,0,0,-1.3333333,0,400)"
id="g10"><g
transform="translate(178.0626,235.0086)"
id="g12"><path
id="path14"
style="fill:#41b883;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 -22.669,-39.264 -45.338,0 h -75.491 L -22.669,-170.017 75.491,0 Z" /></g><g
transform="translate(178.0626,235.0086)"
id="g16"><path
id="path18"
style="fill:#34495e;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 -22.669,-39.264 -45.338,0 H -81.565 L -22.669,-102.01 36.227,0 Z" /></g></g></svg>

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

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

@ -63,7 +63,7 @@ async function checkClickOnNode(hud, toolbox, frameLinkNode) {
const url = frameLinkNode.getAttribute("data-url");
const dbg = toolbox.getPanel("jsdebugger");
is(
dbg._selectors.getSelectedSource(dbg._getState()).get("url"),
dbg._selectors.getSelectedSource(dbg._getState()).url,
url,
`Debugger is opened at expected source url (${url})`
);

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

@ -332,7 +332,7 @@ async function checkClickOnNode(hud, toolbox, frameLinkNode) {
const dbg = toolbox.getPanel("jsdebugger");
is(
dbg._selectors.getSelectedSource(dbg._getState()).get("url"),
dbg._selectors.getSelectedSource(dbg._getState()).url,
url,
"expected source url"
);

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

@ -472,11 +472,5 @@ AllChildrenIterator::GetPreviousChild()
return nullptr;
}
nsIContent*
StyleChildrenIterator::GetNextChild()
{
return AllChildrenIterator::GetNextChild();
}
} // namespace dom
} // namespace mozilla

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

@ -8,6 +8,8 @@
#define ChildIterator_h
#include "nsIContent.h"
#include "nsIContentInlines.h"
#include <stdint.h>
/**
* Iterates over the children on a node. If a child is an insertion point,
@ -18,8 +20,6 @@
* binding's <xbl:content> element.
*/
#include <stdint.h>
#include "nsAutoPtr.h"
class nsIContent;
@ -201,20 +201,34 @@ private:
class AllChildrenIterator : private FlattenedChildIterator
{
public:
AllChildrenIterator(const nsIContent* aNode, uint32_t aFlags,
bool aStartAtBeginning = true) :
FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) { }
AllChildrenIterator(const nsIContent* aNode,
uint32_t aFlags,
bool aStartAtBeginning = true)
: FlattenedChildIterator(aNode, aFlags, aStartAtBeginning)
, mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0)
, mFlags(aFlags)
, mPhase(aStartAtBeginning ? eAtBegin : eAtEnd)
{
}
AllChildrenIterator(AllChildrenIterator&& aOther)
: FlattenedChildIterator(std::move(aOther)),
mAnonKids(std::move(aOther.mAnonKids)), mAnonKidsIdx(aOther.mAnonKidsIdx),
mFlags(aOther.mFlags), mPhase(aOther.mPhase)
: FlattenedChildIterator(std::move(aOther))
, mAnonKids(std::move(aOther.mAnonKids))
, mAnonKidsIdx(aOther.mAnonKidsIdx)
, mFlags(aOther.mFlags)
, mPhase(aOther.mPhase)
#ifdef DEBUG
, mMutationGuard(aOther.mMutationGuard)
, mMutationGuard(aOther.mMutationGuard)
#endif
{}
{
}
AllChildrenIterator& operator=(AllChildrenIterator&& aOther)
{
this->~AllChildrenIterator();
new (this) AllChildrenIterator(std::move(aOther));
return *this;
}
#ifdef DEBUG
~AllChildrenIterator() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); }
@ -285,16 +299,39 @@ private:
class MOZ_NEEDS_MEMMOVABLE_MEMBERS StyleChildrenIterator : private AllChildrenIterator
{
public:
explicit StyleChildrenIterator(const nsIContent* aContent)
static nsIContent* GetParent(const nsIContent& aContent)
{
nsINode* node = aContent.GetFlattenedTreeParentNodeForStyle();
return node && node->IsContent() ? node->AsContent() : nullptr;
}
explicit StyleChildrenIterator(const nsIContent* aContent, bool aStartAtBeginning = true)
: AllChildrenIterator(aContent,
nsIContent::eAllChildren |
nsIContent::eSkipDocumentLevelNativeAnonymousContent)
nsIContent::eSkipDocumentLevelNativeAnonymousContent,
aStartAtBeginning)
{
MOZ_COUNT_CTOR(StyleChildrenIterator);
}
StyleChildrenIterator(StyleChildrenIterator&& aOther)
: AllChildrenIterator(std::move(aOther))
{
MOZ_COUNT_CTOR(StyleChildrenIterator);
}
StyleChildrenIterator& operator=(StyleChildrenIterator&& aOther)
{
AllChildrenIterator::operator=(std::move(aOther));
return *this;
}
~StyleChildrenIterator() { MOZ_COUNT_DTOR(StyleChildrenIterator); }
nsIContent* GetNextChild();
using AllChildrenIterator::GetNextChild;
using AllChildrenIterator::GetPreviousChild;
using AllChildrenIterator::Seek;
};
} // namespace dom

171
dom/base/TreeIterator.h Normal file
Просмотреть файл

@ -0,0 +1,171 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef TreeIterator_h
#define TreeIterator_h
#include "mozilla/Attributes.h"
#include "nsIContent.h"
/**
* A generic pre-order tree iterator on top of ChildIterator.
*
* See ChildIterator.h for the kind of iterators you can use as the template
* argument for this class.
*/
namespace mozilla {
namespace dom {
template<typename ChildIterator>
class MOZ_STACK_CLASS TreeIterator
{
enum class Direction
{
Forward,
Backwards,
};
template<Direction aDirection>
nsIContent* GetNextChild(ChildIterator& aIter)
{
return aDirection == Direction::Forward
? aIter.GetNextChild()
: aIter.GetPreviousChild();
}
template<Direction> inline void Advance();
template<Direction> inline void AdvanceSkippingChildren();
public:
explicit TreeIterator(nsIContent& aRoot)
: mRoot(aRoot)
, mCurrent(&aRoot)
{
}
nsIContent* GetCurrent() const
{
return mCurrent;
}
// Note that this keeps the iterator state consistent in case of failure.
inline bool Seek(nsIContent&);
inline nsIContent* GetNext();
inline nsIContent* GetNextSkippingChildren();
inline nsIContent* GetPrev();
inline nsIContent* GetPrevSkippingChildren();
private:
using IteratorArray = AutoTArray<ChildIterator, 30>;
nsIContent& mRoot;
nsIContent* mCurrent;
IteratorArray mParentIterators;
};
template<typename ChildIterator>
template<typename TreeIterator<ChildIterator>::Direction aDirection>
inline void
TreeIterator<ChildIterator>::AdvanceSkippingChildren()
{
while (true) {
if (MOZ_UNLIKELY(mParentIterators.IsEmpty())) {
mCurrent = nullptr;
return;
}
if (nsIContent* nextSibling =
GetNextChild<aDirection>(mParentIterators.LastElement())) {
mCurrent = nextSibling;
return;
}
mParentIterators.RemoveLastElement();
}
}
template<typename ChildIterator>
inline bool
TreeIterator<ChildIterator>::Seek(nsIContent& aContent)
{
IteratorArray parentIterators;
nsIContent* current = &aContent;
while (current != &mRoot) {
nsIContent* parent = ChildIterator::GetParent(*current);
if (!parent) {
return false;
}
ChildIterator children(parent);
if (!children.Seek(current)) {
return false;
}
parentIterators.AppendElement(std::move(children));
current = parent;
}
parentIterators.Reverse();
mParentIterators.Clear();
mParentIterators.SwapElements(parentIterators);
mCurrent = &aContent;
return true;
}
template<typename ChildIterator>
template<typename TreeIterator<ChildIterator>::Direction aDirection>
inline void
TreeIterator<ChildIterator>::Advance()
{
MOZ_ASSERT(mCurrent);
const bool startAtBeginning = aDirection == Direction::Forward;
ChildIterator children(mCurrent, startAtBeginning);
if (nsIContent* first = GetNextChild<aDirection>(children)) {
mCurrent = first;
mParentIterators.AppendElement(std::move(children));
return;
}
AdvanceSkippingChildren<aDirection>();
}
template<typename ChildIterator>
inline nsIContent*
TreeIterator<ChildIterator>::GetNext()
{
Advance<Direction::Forward>();
return GetCurrent();
}
template<typename ChildIterator>
inline nsIContent*
TreeIterator<ChildIterator>::GetPrev()
{
Advance<Direction::Backwards>();
return GetCurrent();
}
template<typename ChildIterator>
inline nsIContent*
TreeIterator<ChildIterator>::GetNextSkippingChildren()
{
AdvanceSkippingChildren<Direction::Forward>();
return GetCurrent();
}
template<typename ChildIterator>
inline nsIContent*
TreeIterator<ChildIterator>::GetPrevSkippingChildren()
{
AdvanceSkippingChildren<Direction::Backwards>();
return GetCurrent();
}
} // namespace dom
} // namespace mozilla
#endif

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

@ -104,8 +104,7 @@ WindowNamedPropertiesHandler::getOwnPropDescriptor(JSContext* aCx,
}
// Grab the DOM window.
JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, aProxy));
nsGlobalWindowInner* win = xpc::WindowOrNull(global);
nsGlobalWindowInner* win = xpc::WindowGlobalOrNull(aProxy);
if (win->Length() > 0) {
nsCOMPtr<nsPIDOMWindowOuter> childWin = win->GetChildWindow(str);
if (childWin && ShouldExposeChildWindow(str, childWin)) {
@ -175,7 +174,7 @@ WindowNamedPropertiesHandler::ownPropNames(JSContext* aCx,
}
// Grab the DOM window.
nsGlobalWindowInner* win = xpc::WindowOrNull(JS_GetGlobalForObject(aCx, aProxy));
nsGlobalWindowInner* win = xpc::WindowGlobalOrNull(aProxy);
nsTArray<nsString> names;
// The names live on the outer window, which might be null
nsGlobalWindowOuter* outer = win->GetOuterWindowInternal();

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

@ -223,6 +223,7 @@ EXPORTS.mozilla.dom += [
'Timeout.h',
'TimeoutHandler.h',
'TimeoutManager.h',
'TreeIterator.h',
'TreeWalker.h',
'WebKitCSSMatrix.h',
'WindowOrientationObserver.h',

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

@ -628,6 +628,19 @@ nsAttrAndChildArray::DoSetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet)
return MakeMappedUnique(mapped);
}
nsresult
nsAttrAndChildArray::DoUpdateMappedAttrRuleMapper(nsMappedAttributeElement& aElement)
{
MOZ_ASSERT(mImpl && mImpl->mMappedAttrs, "Should have mapped attrs here!");
// First two args don't matter if the assert holds.
RefPtr<nsMappedAttributes> mapped =
GetModifiableMapped(nullptr, nullptr, false);
mapped->SetRuleMapper(aElement.GetAttributeMappingFunction());
return MakeMappedUnique(mapped);
}
void
nsAttrAndChildArray::Compact()

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

@ -126,6 +126,17 @@ public:
return DoSetMappedAttrStyleSheet(aSheet);
}
// Update the rule mapping function on our mapped attributes, if we have any.
// We take a nsMappedAttributeElement, not a nsMapRuleToAttributesFunc,
// because the latter is defined in a header we can't include here.
nsresult UpdateMappedAttrRuleMapper(nsMappedAttributeElement& aElement)
{
if (!mImpl || !mImpl->mMappedAttrs) {
return NS_OK;
}
return DoUpdateMappedAttrRuleMapper(aElement);
}
void Compact();
bool CanFitMoreAttrs() const
@ -224,6 +235,11 @@ private:
*/
nsresult DoSetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet);
/**
* Guts of UpdateMappedAttrRuleMapper for the case when we have mapped attrs.
*/
nsresult DoUpdateMappedAttrRuleMapper(nsMappedAttributeElement& aElement);
struct InternalAttr
{
nsAttrName mName;

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

@ -2600,12 +2600,7 @@ nsIDocument::IsSynthesized() {
bool
nsDocument::IsShadowDOMEnabled(JSContext* aCx, JSObject* aObject)
{
JS::Rooted<JSObject*> obj(aCx, aObject);
JSAutoRealm ar(aCx, obj);
JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, obj));
nsCOMPtr<nsPIDOMWindowInner> window =
do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(global));
nsCOMPtr<nsPIDOMWindowInner> window = xpc::WindowGlobalOrNull(aObject);
nsIDocument* doc = window ? window->GetExtantDoc() : nullptr;
if (!doc) {

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

@ -792,8 +792,9 @@ nsChromeOuterWindowProxy::singleton;
static JSObject*
NewOuterWindowProxy(JSContext *cx, JS::Handle<JSObject*> global, bool isChrome)
{
MOZ_ASSERT(JS_IsGlobalObject(global));
JSAutoRealm ar(cx, global);
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(global) == global);
js::WrapperOptions options;
options.setClass(&OuterWindowProxyClass);
@ -1858,7 +1859,7 @@ nsGlobalWindowOuter::SetNewDocument(nsIDocument* aDocument,
SetWrapper(outerObject);
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(outerObject) == newInnerGlobal);
MOZ_ASSERT(JS::GetNonCCWObjectGlobal(outerObject) == newInnerGlobal);
// Inform the nsJSContext, which is the canonical holder of the outer.
mContext->SetWindowProxy(outerObject);

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

@ -160,7 +160,7 @@ nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
CycleCollectedJSContext::Get()->MicroTaskLevel());
MOZ_ASSERT(mRetValue.isUndefined());
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aGlobal) == aGlobal);
MOZ_ASSERT(JS_IsGlobalObject(aGlobal));
if (MOZ_UNLIKELY(!xpc::Scriptability::Get(aGlobal).Allowed())) {
mSkip = true;
mRv = NS_OK;
@ -472,8 +472,7 @@ nsJSUtils::CompileModule(JSContext* aCx,
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
MOZ_ASSERT(aSrcBuf.get());
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aEvaluationGlobal) ==
aEvaluationGlobal);
MOZ_ASSERT(JS_IsGlobalObject(aEvaluationGlobal));
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx) == aEvaluationGlobal);
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(CycleCollectedJSContext::Get() &&

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

@ -56,6 +56,11 @@ public:
return mSheet;
}
void SetRuleMapper(nsMapRuleToAttributesFunc aRuleMapper)
{
mRuleMapper = aRuleMapper;
}
const nsAttrName* NameAt(uint32_t aPos) const
{
NS_ASSERTION(aPos < mAttrCount, "out-of-bounds");

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

@ -298,7 +298,6 @@ nsRange::nsRange(nsINode* aNode)
, mNextStartRef(nullptr)
, mNextEndRef(nullptr)
, mIsPositioned(false)
, mMaySpanAnonymousSubtrees(false)
, mIsGenerated(false)
, mCalledByJS(false)
{
@ -1147,7 +1146,7 @@ nsRange::IsValidOffset(nsINode* aNode, uint32_t aOffset)
/* static */
nsINode*
nsRange::ComputeRootNode(nsINode* aNode, bool aMaySpanAnonymousSubtrees)
nsRange::ComputeRootNode(nsINode* aNode)
{
if (!aNode) {
return nullptr;
@ -1159,36 +1158,30 @@ nsRange::ComputeRootNode(nsINode* aNode, bool aMaySpanAnonymousSubtrees)
}
nsIContent* content = aNode->AsContent();
if (!aMaySpanAnonymousSubtrees) {
// If the node is in a shadow tree then the ShadowRoot is the root.
ShadowRoot* containingShadow = content->GetContainingShadow();
if (containingShadow) {
return containingShadow;
}
// If the node has a binding parent, that should be the root.
// XXXbz maybe only for native anonymous content?
nsINode* root = content->GetBindingParent();
if (root) {
return root;
}
// If the node is in a shadow tree then the ShadowRoot is the root.
if (ShadowRoot* containingShadow = content->GetContainingShadow()) {
return containingShadow;
}
// If the node has a binding parent, that should be the root.
// XXXbz maybe only for native anonymous content?
if (nsINode* root = content->GetBindingParent()) {
return root;
}
}
// Elements etc. must be in document or in document fragment,
// text nodes in document, in document fragment or in attribute.
nsINode* root = aNode->GetUncomposedDoc();
if (root) {
if (nsINode* root = aNode->GetUncomposedDoc()) {
return root;
}
root = aNode->SubtreeRoot();
NS_ASSERTION(!root->IsDocument(),
NS_ASSERTION(!aNode->SubtreeRoot()->IsDocument(),
"GetUncomposedDoc should have returned a doc");
// We allow this because of backward compatibility.
return root;
return aNode->SubtreeRoot();
}
/* static */
@ -1380,7 +1373,7 @@ nsRange::SelectNodesInContainer(nsINode* aContainer,
MOZ_ASSERT(aStartContent && aContainer->ComputeIndexOf(aStartContent) != -1);
MOZ_ASSERT(aEndContent && aContainer->ComputeIndexOf(aEndContent) != -1);
nsINode* newRoot = ComputeRootNode(aContainer, mMaySpanAnonymousSubtrees);
nsINode* newRoot = ComputeRootNode(aContainer);
MOZ_ASSERT(newRoot);
if (!newRoot) {
return;
@ -2583,8 +2576,6 @@ nsRange::CloneRange() const
{
RefPtr<nsRange> range = new nsRange(mOwner);
range->SetMaySpanAnonymousSubtrees(mMaySpanAnonymousSubtrees);
range->DoSetRange(mStart.AsRaw(), mEnd.AsRaw(), mRoot);
return range.forget();

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

@ -120,11 +120,6 @@ public:
return mIsPositioned;
}
void SetMaySpanAnonymousSubtrees(bool aMaySpanAnonymousSubtrees)
{
mMaySpanAnonymousSubtrees = aMaySpanAnonymousSubtrees;
}
/**
* Return true iff this range is part of a Selection object
* and isn't detached.
@ -389,10 +384,7 @@ public:
* fragment. If this returns nullptr, that means aNode can be neither the
* start container nor end container of any range.
*/
static nsINode* ComputeRootNode(nsINode* aNode)
{
return ComputeRootNode(aNode, false);
}
static nsINode* ComputeRootNode(nsINode* aNode);
/**
* Return true if aStartContainer/aStartOffset and aEndContainer/aEndOffset
@ -461,7 +453,7 @@ protected:
void UnregisterCommonAncestor(nsINode* aNode, bool aIsUnlinking);
nsINode* IsValidBoundary(nsINode* aNode) const
{
return ComputeRootNode(aNode, mMaySpanAnonymousSubtrees);
return ComputeRootNode(aNode);
}
/**
@ -476,9 +468,6 @@ protected:
}
static bool IsValidOffset(nsINode* aNode, uint32_t aOffset);
static nsINode* ComputeRootNode(nsINode* aNode,
bool aMaySpanAnonymousSubtrees);
// CharacterDataChanged set aNotInsertedYet to true to disable an assertion
// and suppress re-registering a range common ancestor node since
// the new text node of a splitText hasn't been inserted yet.
@ -566,7 +555,6 @@ protected:
RangeBoundary mEnd;
bool mIsPositioned : 1;
bool mMaySpanAnonymousSubtrees : 1;
bool mIsGenerated : 1;
bool mCalledByJS : 1;
};

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

@ -25,7 +25,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558726
/** Test for Bug 558726 **/
function runTest() {
is(document.getElementById('test_558726_1').innerHTML, '<select name="selecttest"><option value="0">item 1</option></select>x<input name="test" value="test" type="button">','test_558726_1.innerHTML')
is(document.getElementById('test_558726_1').innerHTML, '<select name="selecttest"><option value="0">item 1</option></select>x<input type="button" name="test" value="test">','test_558726_1.innerHTML')
is(document.getElementById('test_558726_2').innerHTML, 'y<input><i style="-moz-user-select: none;">z</i>','test_558726_2.innerHTML')
SimpleTest.finish();
}

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

@ -2,13 +2,19 @@
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
const t = async_test("Test window.find / nsFind");
function testFindable(isFindable, textToFind, docText, description) {
function testFindable(isFindable, textToFind, buildDoc, description) {
try{
const iframe = document.querySelector("iframe")
iframe.contentDocument.documentElement.innerHTML = docText;
iframe.contentDocument.documentElement.innerHTML =
(typeof buildDoc == "string") ? buildDoc : "";
if (typeof buildDoc == "function")
buildDoc(iframe.contentDocument);
iframe.contentWindow.getSelection().removeAllRanges();
assert_equals(
isFindable,
@ -35,7 +41,7 @@ const BLOCK_LIKE_DISPLAY_VALUES = [
"flex",
];
window.runTests = t.step_func_done(function() {
let runTests = t.step_func_done(function() {
testFindable(true, "me and me", `
me <div style="display: contents">and</div> me
`, "display: contents");
@ -77,6 +83,43 @@ window.runTests = t.step_func_done(function() {
</div>
</div>
`);
testFindable(true, "Shadow text", function(document) {
let div = document.createElement("div");
div.attachShadow({ mode: "open" }).innerHTML = `
Wohoo, this is Shadow text, yay!
`;
document.documentElement.appendChild(div);
}, "In Shadow DOM");
testFindable(true, "Shadow text", function(document) {
let div = document.createElement("div");
div.appendChild(document.createTextNode(
"Wohoo, this is Shadow text, yay!"
));
div.attachShadow({ mode: "open" }).innerHTML = `<slot></slot>`;
document.documentElement.appendChild(div);
}, "Slotted content in Shadow DOM");
// TODO(emilio): Even though this works (as in, find(..) returns true), the
// selection here doesn't end up selecting the shadow content.
//
// This should work in an ideal world.
testFindable(true, "Shadow text", function(document) {
let div = document.createElement("div");
div.appendChild(document.createTextNode("text, yay!"));
div.attachShadow({ mode: "open" }).innerHTML = `This is Shadow <slot></slot>`;
document.documentElement.appendChild(div);
}, "Mixed shadow and non-shadow text");
});
SpecialPowers.pushPrefEnv(
{"set":[['dom.webcomponents.shadowdom.enabled', true]]},
t.step_func(function() {
let iframe = document.createElement("iframe");
iframe.onload = runTests;
iframe.srcdoc = "<!doctype html><html></html>";
document.body.appendChild(iframe);
}));
</script>
<iframe onload="runTests()" srcdoc="<!doctype html><html></html>"></iframe>
</body>

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

@ -1175,21 +1175,8 @@ XPCOMObjectToJsval(JSContext* cx, JS::Handle<JSObject*> scope,
xpcObjectHelper& helper, const nsIID* iid,
bool allowNativeWrapper, JS::MutableHandle<JS::Value> rval)
{
if (!NativeInterface2JSObjectAndThrowIfFailed(cx, scope, rval, helper, iid,
allowNativeWrapper)) {
return false;
}
#ifdef DEBUG
JSObject* jsobj = rval.toObjectOrNull();
if (jsobj &&
js::GetGlobalForObjectCrossCompartment(jsobj) == jsobj) {
NS_ASSERTION(js::GetObjectClass(jsobj)->flags & JSCLASS_IS_GLOBAL,
"Why did we recreate this wrapper?");
}
#endif
return true;
return NativeInterface2JSObjectAndThrowIfFailed(cx, scope, rval, helper, iid,
allowNativeWrapper);
}
bool
@ -2298,9 +2285,8 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg, ErrorResult& aErr
const DOMJSClass* domClass = GetDOMClass(aObj);
// DOM things are always parented to globals.
JS::Rooted<JSObject*> oldParent(aCx,
js::GetGlobalForObjectCrossCompartment(aObj));
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(oldParent) == oldParent);
JS::Rooted<JSObject*> oldParent(aCx, JS::GetNonCCWObjectGlobal(aObj));
MOZ_ASSERT(JS_IsGlobalObject(oldParent));
JS::Rooted<JSObject*> newParent(aCx,
domClass->mGetAssociatedGlobal(aCx, aObj));
@ -2430,7 +2416,7 @@ GlobalObject::GlobalObject(JSContext* aCx, JSObject* aObject)
}
}
mGlobalJSObject = js::GetGlobalForObjectCrossCompartment(obj);
mGlobalJSObject = JS::GetNonCCWObjectGlobal(obj);
}
nsISupports*
@ -3696,7 +3682,7 @@ GetDesiredProto(JSContext* aCx, const JS::CallArgs& aCallArgs,
if (protoID != prototypes::id::_ID_Count) {
ProtoAndIfaceCache& protoAndIfaceCache =
*GetProtoAndIfaceCache(js::GetGlobalForObjectCrossCompartment(newTarget));
*GetProtoAndIfaceCache(JS::GetNonCCWObjectGlobal(newTarget));
aDesiredProto.set(protoAndIfaceCache.EntrySlotMustExist(protoID));
if (newTarget != originalNewTarget) {
return JS_WrapObject(aCx, aDesiredProto);

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

@ -196,7 +196,7 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
globalObject = win;
} else {
// No DOM Window. Store the global.
JSObject* global = js::GetGlobalForObjectCrossCompartment(realCallback);
JSObject* global = JS::GetNonCCWObjectGlobal(realCallback);
globalObject = xpc::NativeGlobal(global);
MOZ_ASSERT(globalObject);
}

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

@ -2234,10 +2234,6 @@ def MakeClearCachedValueNativeName(member):
return "ClearCached%sValue" % MakeNativeName(member.identifier.name)
def MakeJSImplClearCachedValueNativeName(member):
return "_" + MakeClearCachedValueNativeName(member)
def IDLToCIdentifier(name):
return name.replace("-", "_")
@ -2434,17 +2430,6 @@ class MethodDefiner(PropertyDefiner):
"flags": "0",
"condition": MemberCondition()
})
elif not unforgeable:
for m in clearableCachedAttrs(descriptor):
attrName = MakeNativeName(m.identifier.name)
self.chrome.append({
"name": "_clearCached%sValue" % attrName,
"nativeName": MakeJSImplClearCachedValueNativeName(m),
"methodInfo": False,
"length": "0",
"flags": "0",
"condition": MemberCondition()
})
self.unforgeable = unforgeable
@ -5409,7 +5394,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("${sourceDescription}"));
return nullptr;
}
globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
globalObj = JS::GetNonCCWObjectGlobal(unwrappedVal);
""",
sourceDescription=sourceDescription)
elif isCallbackReturnValue == "Callback":
@ -8490,43 +8475,24 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
CGThing which is already properly indented.
getThisObj should be code for getting a JSObject* for the binding
object. If this is None, we will auto-generate code based on
descriptor to do the right thing. "" can be passed in if the
binding object is already stored in 'obj'.
object. "" can be passed in if the binding object is already stored in
'obj'.
callArgs should be code for getting a JS::CallArgs into a variable
called 'args'. This can be "" if there is already such a variable
around.
"""
def __init__(self, descriptor, name, args, unwrapFailureCode=None,
getThisObj=None,
def __init__(self, descriptor, name, args, getThisObj,
callArgs="JS::CallArgs args = JS::CallArgsFromVp(argc, vp);\n"):
CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
if unwrapFailureCode is None:
self.unwrapFailureCode = 'return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "%s");\n' % descriptor.interface.identifier.name
else:
self.unwrapFailureCode = unwrapFailureCode
self.unwrapFailureCode = 'return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "%s");\n' % descriptor.interface.identifier.name
if getThisObj == "":
self.getThisObj = None
else:
if getThisObj is None:
if descriptor.interface.isOnGlobalProtoChain():
ensureCondition = "!args.thisv().isNullOrUndefined() && !args.thisv().isObject()"
getThisObj = "args.thisv().isObject() ? &args.thisv().toObject() : js::GetGlobalForObjectCrossCompartment(&args.callee())"
else:
ensureCondition = "!args.thisv().isObject()"
getThisObj = "&args.thisv().toObject()"
unwrapFailureCode = self.unwrapFailureCode % {'securityError': 'false'}
ensureThisObj = CGIfWrapper(CGGeneric(unwrapFailureCode),
ensureCondition)
else:
ensureThisObj = None
self.getThisObj = CGList(
[ensureThisObj,
CGGeneric("JS::Rooted<JSObject*> obj(cx, %s);\n" %
getThisObj)])
self.getThisObj = CGGeneric("JS::Rooted<JSObject*> obj(cx, %s);\n" %
getThisObj)
self.callArgs = callArgs
def definition_body(self):
@ -12418,11 +12384,6 @@ class CGDescriptor(CGThing):
if descriptor.concrete and descriptor.wrapperCache and not descriptor.proxy:
cgThings.append(CGClassObjectMovedHook(descriptor))
# Generate the _ClearCachedFooValue methods before the property arrays that use them.
if descriptor.interface.isJSImplemented():
for m in clearableCachedAttrs(descriptor):
cgThings.append(CGJSImplClearCachedValueMethod(descriptor, m))
properties = PropertyArrays(descriptor)
cgThings.append(CGGeneric(define=str(properties)))
cgThings.append(CGNativeProperties(descriptor, properties))
@ -13938,11 +13899,7 @@ class CGBindingRoot(CGThing):
# interface object might have a ChromeOnly constructor.
(desc.interface.hasInterfaceObject() and
(desc.interface.isJSImplemented() or
(ctor and isChromeOnly(ctor)))) or
# JS-implemented interfaces with clearable cached
# attrs have chromeonly _clearFoo methods.
(desc.interface.isJSImplemented() and
any(clearableCachedAttrs(desc))))
(ctor and isChromeOnly(ctor)))))
# XXXkhuey ugly hack but this is going away soon.
bindingHeaders['xpcprivate.h'] = webIDLFile.endswith("EventTarget.webidl")
@ -15130,27 +15087,6 @@ def callbackSetterName(attr, descriptor):
descriptor.binaryNameFor(attr.identifier.name))
class CGJSImplClearCachedValueMethod(CGAbstractBindingMethod):
def __init__(self, descriptor, attr):
if attr.getExtendedAttribute("StoreInSlot"):
raise TypeError("[StoreInSlot] is not supported for JS-implemented WebIDL. See bug 1056325.")
CGAbstractBindingMethod.__init__(self, descriptor,
MakeJSImplClearCachedValueNativeName(attr),
JSNativeArguments())
self.attr = attr
def generate_code(self):
return CGGeneric(fill(
"""
${bindingNamespace}::${fnName}(self);
args.rval().setUndefined();
return true;
""",
bindingNamespace=toBindingNamespace(self.descriptor.name),
fnName=MakeClearCachedValueNativeName(self.attr)))
class CGJSImplGetter(CGJSImplMember):
"""
Class for generating code for the getters of attributes for a JS-implemented

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

@ -121,7 +121,7 @@ struct PrefableDisablers {
// globals; our IDL parser enforces that. So as long as we check our
// exposure set before checking "enabled" we will be ok.
if (nonExposedGlobals &&
IsNonExposedGlobal(cx, js::GetGlobalForObjectCrossCompartment(obj),
IsNonExposedGlobal(cx, JS::GetNonCCWObjectGlobal(obj),
nonExposedGlobals)) {
return false;
}
@ -131,8 +131,7 @@ struct PrefableDisablers {
if (secureContext && !IsSecureContextOrObjectIsFromSecureContext(cx, obj)) {
return false;
}
if (enabledFunc &&
!enabledFunc(cx, js::GetGlobalForObjectCrossCompartment(obj))) {
if (enabledFunc && !enabledFunc(cx, JS::GetNonCCWObjectGlobal(obj))) {
return false;
}
return true;

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

@ -1045,6 +1045,12 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
(member.getExtendedAttribute("StoreInSlot") or
member.getExtendedAttribute("Cached"))) or
member.isMaplikeOrSetlike()):
if self.isJSImplemented() and not member.isMaplikeOrSetlike():
raise WebIDLError("Interface %s is JS-implemented and we "
"don't support [Cached] or [StoreInSlot] "
"on JS-implemented interfaces" %
self.identifier.name,
[self.location, member.location])
if member.slotIndices is None:
member.slotIndices = dict()
member.slotIndices[self.identifier.name] = self.totalMembersInSlots

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

@ -23,18 +23,17 @@ TestInterfaceJS.prototype = {
this._anyArg = anyArg;
this._objectArg = objectArg;
this._dictionaryArg = dictionaryArg;
this._cachedAttr = 15;
},
get anyArg() { return this._anyArg; },
get objectArg() { return this._objectArg; },
get dictionaryArg() { return this._dictionaryArg; },
getDictionaryArg: function() { return this._dictionaryArg; },
get anyAttr() { return this._anyAttr; },
set anyAttr(val) { this._anyAttr = val; },
get objectAttr() { return this._objectAttr; },
set objectAttr(val) { this._objectAttr = val; },
get dictionaryAttr() { return this._dictionaryAttr; },
set dictionaryAttr(val) { this._dictionaryAttr = val; },
getDictionaryAttr: function() { return this._dictionaryAttr; },
setDictionaryAttr: function(val) { this._dictionaryAttr = val; },
pingPongAny: function(any) { return any; },
pingPongObject: function(obj) { return obj; },
pingPongObjectOrString: function(objectOrString) { return objectOrString; },
@ -54,10 +53,6 @@ TestInterfaceJS.prototype = {
pingPongNullableUnion: function(x) { return x; },
returnBadUnion: function(x) { return 3; },
get cachedAttr() { return this._cachedAttr; },
setCachedAttr: function(n) { this._cachedAttr = n; },
clearCachedAttrCache: function () { this.__DOM_IMPL__._clearCachedCachedAttrValue(); },
testSequenceOverload: function(arg) {},
testSequenceUnion: function(arg) {},

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

@ -41,12 +41,13 @@ interface TestJSImplInterface {
void passNullableByte(byte? arg);
void passOptionalNullableByte(optional byte? arg);
void passVariadicByte(byte... arg);
[Cached, Pure]
readonly attribute byte cachedByte;
[Cached, Constant]
readonly attribute byte cachedConstantByte;
[Cached, Pure]
attribute byte cachedWritableByte;
// [Cached] is not supported in JS-implemented WebIDL.
//[Cached, Pure]
//readonly attribute byte cachedByte;
//[Cached, Constant]
//readonly attribute byte cachedConstantByte;
//[Cached, Pure]
//attribute byte cachedWritableByte;
[Affects=Nothing]
attribute byte sideEffectFreeByte;
[Affects=Nothing, DependsOn=DOMState]
@ -160,8 +161,9 @@ interface TestJSImplInterface {
void passNullableSelf(TestJSImplInterface? arg);
attribute TestJSImplInterface nonNullSelf;
attribute TestJSImplInterface? nullableSelf;
[Cached, Pure]
readonly attribute TestJSImplInterface cachedSelf;
// [Cached] is not supported in JS-implemented WebIDL.
//[Cached, Pure]
//readonly attribute TestJSImplInterface cachedSelf;
// Optional arguments
void passOptionalSelf(optional TestJSImplInterface? arg);
void passOptionalNonNullSelf(optional TestJSImplInterface arg);
@ -230,16 +232,17 @@ interface TestJSImplInterface {
void passConsequentialInterface(IndirectlyImplementedInterface arg);
// Sequence types
[Cached, Pure]
readonly attribute sequence<long> readonlySequence;
[Cached, Pure]
readonly attribute sequence<Dict> readonlySequenceOfDictionaries;
[Cached, Pure]
readonly attribute sequence<Dict>? readonlyNullableSequenceOfDictionaries;
[Cached, Pure, Frozen]
readonly attribute sequence<long> readonlyFrozenSequence;
[Cached, Pure, Frozen]
readonly attribute sequence<long>? readonlyFrozenNullableSequence;
// [Cached] is not supported in JS-implemented WebIDL.
//[Cached, Pure]
//readonly attribute sequence<long> readonlySequence;
//[Cached, Pure]
//readonly attribute sequence<Dict> readonlySequenceOfDictionaries;
//[Cached, Pure]
//readonly attribute sequence<Dict>? readonlyNullableSequenceOfDictionaries;
//[Cached, Pure, Frozen]
//readonly attribute sequence<long> readonlyFrozenSequence;
//[Cached, Pure, Frozen]
//readonly attribute sequence<long>? readonlyFrozenNullableSequence;
sequence<long> receiveSequence();
sequence<long>? receiveNullableSequence();
sequence<long?> receiveSequenceOfNullableInts();
@ -602,18 +605,19 @@ interface TestJSImplInterface {
void passDictionary(optional Dict x);
void passDictionary2(Dict x);
[Cached, Pure]
readonly attribute Dict readonlyDictionary;
[Cached, Pure]
readonly attribute Dict? readonlyNullableDictionary;
[Cached, Pure]
attribute Dict writableDictionary;
[Cached, Pure, Frozen]
readonly attribute Dict readonlyFrozenDictionary;
[Cached, Pure, Frozen]
readonly attribute Dict? readonlyFrozenNullableDictionary;
[Cached, Pure, Frozen]
attribute Dict writableFrozenDictionary;
// [Cached] is not supported in JS-implemented WebIDL.
//[Cached, Pure]
//readonly attribute Dict readonlyDictionary;
//[Cached, Pure]
//readonly attribute Dict? readonlyNullableDictionary;
//[Cached, Pure]
//attribute Dict writableDictionary;
//[Cached, Pure, Frozen]
//readonly attribute Dict readonlyFrozenDictionary;
//[Cached, Pure, Frozen]
//readonly attribute Dict? readonlyFrozenNullableDictionary;
//[Cached, Pure, Frozen]
//attribute Dict writableFrozenDictionary;
Dict receiveDictionary();
Dict? receiveNullableDictionary();
void passOtherDictionary(optional GrandparentDict x);
@ -854,6 +858,7 @@ interface TestCImplementedInterface2 {
[NoInterfaceObject,
JSImplementation="@mozilla.org/test-js-impl-interface;2"]
interface TestJSImplNoInterfaceObject {
[Cached, Pure]
readonly attribute byte cachedByte;
// [Cached] is not supported in JS-implemented WebIDL.
//[Cached, Pure]
//readonly attribute byte cachedByte;
};

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

@ -20,8 +20,6 @@ support-files =
[test_bug862092.html]
[test_bug1036214.html]
skip-if = debug == false
[test_bug963382.html]
skip-if = debug == false
[test_bug1041646.html]
[test_bug1123875.html]
[test_barewordGetsWindow.html]

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

@ -48,15 +48,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1036214
is(Object.getPrototypeOf(t), TestInterfaceJS.prototype, "Prototype setup works correctly");
is(t.anyArg, any, "anyArg is correct");
is(t.objectArg, obj, "objectArg is correct");
is(t.dictionaryArg.anyMember, 42, "dictionaryArg looks correct");
is(t.dictionaryArg.objectMember.answer, 42, "dictionaryArg looks correct");
is(t.getDictionaryArg().anyMember, 42, "dictionaryArg looks correct");
is(t.getDictionaryArg().objectMember.answer, 42, "dictionaryArg looks correct");
t.anyAttr = 2;
is(t.anyAttr, 2, "ping-pong any attribute works");
t.objAttr = obj2;
is(t.objAttr, obj2, "ping-pong object attribute works");
t.dictionaryAttr = myDict;
is(t.dictionaryAttr.anyMember, 42, "ping-pong dictionary attribute works");
is(t.dictionaryAttr.objectMember.answer, 42, "ping-pong dictionary attribute works");
t.setDictionaryAttr(myDict);
is(t.getDictionaryAttr().anyMember, 42, "ping-pong dictionary works");
is(t.getDictionaryAttr().objectMember.answer, 42, "ping-pong dictionary works");
is(any, t.pingPongAny(any), "ping-pong works with any");
is(obj, t.pingPongObject(obj), "ping-pong works with obj");
@ -88,8 +88,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1036214
checkThrows(() => new TestInterfaceJS(undefined, undefined, { innerDictionary: { innerObject: xoObj } }), "inner dict param for constructor");
checkThrows(() => t.anyAttr = xoObj, "anyAttr");
checkThrows(() => t.objectAttr = xoObj, "objAttr");
checkThrows(() => t.dictionaryAttr = { anyMember: xoObj }, "dictionaryAttr any");
checkThrows(() => t.dictionaryAttr = { objectMember: xoObj }, "dictionaryAttr object");
checkThrows(() => t.setDictionaryAttr({ anyMember: xoObj }), "dictionaryAttr any");
checkThrows(() => t.setDictionaryAttr({ objectMember: xoObj }), "dictionaryAttr object");
checkThrows(() => t.pingPongAny(xoObj), "pingpong any");
checkThrows(() => t.pingPongObject(xoObj), "pingpong obj");
checkThrows(() => t.pingPongObjectOrString(xoObj), "pingpong union");

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

@ -1,43 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=963382
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 963382</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for clearing cache attributes in JS-implemented WebIDL implementations. **/
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, go);
function go() {
var t = new TestInterfaceJS();
// Test [Cached] attribute clearing.
is(t.cachedAttr, 15, "Initial value of number");
t.setCachedAttr(3);
is(t.cachedAttr, 15, "Setting the number on the inner JS object should not affect cached value");
t.clearCachedAttrCache();
is(t.cachedAttr, 3, "Setting the number on the inner JS object should affect cached value after clearing the cache.");
SimpleTest.finish();
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=963382">Mozilla Bug 963382</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

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

@ -3997,6 +3997,12 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
CanvasBidiProcessor()
: nsBidiPresUtils::BidiProcessor()
, mCtx(nullptr)
, mFontgrp(nullptr)
, mAppUnitsPerDevPixel(0)
, mOp(CanvasRenderingContext2D::TextDrawOperation::FILL)
, mTextRunFlags()
, mDoMeasureBoundingBox(false)
{
if (Preferences::GetBool(GFX_MISSING_FONTS_NOTIFY_PREF)) {
mMissingFonts = new gfxMissingFontRecorder();

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

@ -1012,9 +1012,9 @@ private:
realGLboolean mDitherEnabled;
realGLboolean mRasterizerDiscardEnabled;
realGLboolean mScissorTestEnabled;
realGLboolean mDepthTestEnabled;
realGLboolean mDepthTestEnabled = 0;
realGLboolean mStencilTestEnabled;
GLenum mGenerateMipmapHint;
GLenum mGenerateMipmapHint = 0;
bool ValidateCapabilityEnum(GLenum cap, const char* info);
realGLboolean* GetStateTrackingSlot(GLenum cap);
@ -1299,7 +1299,7 @@ protected:
// -----------------------------------------------------------------------------
// Vertices Feature (WebGLContextVertices.cpp)
GLenum mPrimRestartTypeBytes;
GLenum mPrimRestartTypeBytes = 0;
public:
void DrawArrays(GLenum mode, GLint first, GLsizei count) {
@ -1455,9 +1455,9 @@ protected:
template<typename WebGLObjectType>
void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array);
GLuint mActiveTexture;
GLenum mDefaultFB_DrawBuffer0;
GLenum mDefaultFB_ReadBuffer;
GLuint mActiveTexture = 0;
GLenum mDefaultFB_DrawBuffer0 = 0;
GLenum mDefaultFB_ReadBuffer = 0;
// glGetError sources:
bool mEmitContextLostErrorOnce;
@ -1470,22 +1470,22 @@ protected:
webgl::ShaderValidator* CreateShaderValidator(GLenum shaderType) const;
// some GL constants
uint32_t mGLMaxTextureUnits;
uint32_t mGLMaxTextureUnits = 0;
uint32_t mGLMaxVertexAttribs;
uint32_t mGLMaxFragmentUniformVectors;
uint32_t mGLMaxVertexUniformVectors;
uint32_t mGLMaxVaryingVectors;
uint32_t mGLMaxVertexAttribs = 0;
uint32_t mGLMaxFragmentUniformVectors = 0;
uint32_t mGLMaxVertexUniformVectors = 0;
uint32_t mGLMaxVaryingVectors = 0;
uint32_t mGLMaxTransformFeedbackSeparateAttribs;
uint32_t mGLMaxUniformBufferBindings;
uint32_t mGLMaxTransformFeedbackSeparateAttribs = 0;
uint32_t mGLMaxUniformBufferBindings = 0;
uint32_t mGLMaxVertexTextureImageUnits;
uint32_t mGLMaxFragmentTextureImageUnits;
uint32_t mGLMaxCombinedTextureImageUnits;
uint32_t mGLMaxVertexTextureImageUnits = 0;
uint32_t mGLMaxFragmentTextureImageUnits = 0;
uint32_t mGLMaxCombinedTextureImageUnits = 0;
uint32_t mGLMaxColorAttachments;
uint32_t mGLMaxDrawBuffers;
uint32_t mGLMaxColorAttachments = 0;
uint32_t mGLMaxDrawBuffers = 0;
uint32_t mGLMaxViewportDims[2];
@ -1500,11 +1500,11 @@ protected:
// Texture sizes are often not actually the GL values. Let's be explicit that these
// are implementation limits.
uint32_t mGLMaxTextureSize;
uint32_t mGLMaxCubeMapTextureSize;
uint32_t mGLMax3DTextureSize;
uint32_t mGLMaxArrayTextureLayers;
uint32_t mGLMaxRenderbufferSize;
uint32_t mGLMaxTextureSize = 0;
uint32_t mGLMaxCubeMapTextureSize = 0;
uint32_t mGLMax3DTextureSize = 0;
uint32_t mGLMaxArrayTextureLayers = 0;
uint32_t mGLMaxRenderbufferSize = 0;
public:
GLuint MaxVertexAttribs() const {
@ -1854,16 +1854,16 @@ protected:
WebGLRefPtr<WebGLVertexArray> mDefaultVertexArray;
// PixelStore parameters
uint32_t mPixelStore_UnpackImageHeight;
uint32_t mPixelStore_UnpackSkipImages;
uint32_t mPixelStore_UnpackRowLength;
uint32_t mPixelStore_UnpackSkipRows;
uint32_t mPixelStore_UnpackSkipPixels;
uint32_t mPixelStore_UnpackAlignment;
uint32_t mPixelStore_PackRowLength;
uint32_t mPixelStore_PackSkipRows;
uint32_t mPixelStore_PackSkipPixels;
uint32_t mPixelStore_PackAlignment;
uint32_t mPixelStore_UnpackImageHeight = 0;
uint32_t mPixelStore_UnpackSkipImages = 0;
uint32_t mPixelStore_UnpackRowLength = 0;
uint32_t mPixelStore_UnpackSkipRows = 0;
uint32_t mPixelStore_UnpackSkipPixels = 0;
uint32_t mPixelStore_UnpackAlignment = 0;
uint32_t mPixelStore_PackRowLength = 0;
uint32_t mPixelStore_PackSkipRows = 0;
uint32_t mPixelStore_PackSkipPixels = 0;
uint32_t mPixelStore_PackAlignment = 0;
CheckedUint32 GetUnpackSize(bool isFunc3D, uint32_t width, uint32_t height,
uint32_t depth, uint8_t bytesPerPixel);
@ -1872,10 +1872,10 @@ protected:
uint8_t bytesPerPixel, uint32_t* const out_rowStride,
uint32_t* const out_endOffset);
GLenum mPixelStore_ColorspaceConversion;
bool mPixelStore_FlipY;
bool mPixelStore_PremultiplyAlpha;
bool mPixelStore_RequireFastPath;
GLenum mPixelStore_ColorspaceConversion = 0;
bool mPixelStore_FlipY = false;
bool mPixelStore_PremultiplyAlpha = false;
bool mPixelStore_RequireFastPath = false;
////////////////////////////////////
class FakeBlackTexture {
@ -1915,26 +1915,26 @@ protected:
uint8_t mGenericVertexAttrib0Data[sizeof(float) * 4];
CacheMapInvalidator mGenericVertexAttribTypeInvalidator;
GLuint mFakeVertexAttrib0BufferObject;
size_t mFakeVertexAttrib0BufferObjectSize;
bool mFakeVertexAttrib0DataDefined;
GLuint mFakeVertexAttrib0BufferObject = 0;
size_t mFakeVertexAttrib0BufferObjectSize = 0;
bool mFakeVertexAttrib0DataDefined = false;
uint8_t mFakeVertexAttrib0Data[sizeof(float) * 4];
JSObject* GetVertexAttribFloat32Array(JSContext* cx, GLuint index);
JSObject* GetVertexAttribInt32Array(JSContext* cx, GLuint index);
JSObject* GetVertexAttribUint32Array(JSContext* cx, GLuint index);
GLint mStencilRefFront;
GLint mStencilRefBack;
GLuint mStencilValueMaskFront;
GLuint mStencilValueMaskBack;
GLuint mStencilWriteMaskFront;
GLuint mStencilWriteMaskBack;
uint8_t mColorWriteMask; // bitmask
realGLboolean mDepthWriteMask;
GLint mStencilRefFront = 0;
GLint mStencilRefBack = 0;
GLuint mStencilValueMaskFront = 0;
GLuint mStencilValueMaskBack = 0;
GLuint mStencilWriteMaskFront = 0;
GLuint mStencilWriteMaskBack = 0;
uint8_t mColorWriteMask = 0; // bitmask
realGLboolean mDepthWriteMask = 0;
GLfloat mColorClearValue[4];
GLint mStencilClearValue;
GLfloat mDepthClearValue;
GLint mStencilClearValue = 0;
GLfloat mDepthClearValue = 0.0;
GLint mViewportX;
GLint mViewportY;
@ -1942,7 +1942,7 @@ protected:
GLsizei mViewportHeight;
bool mAlreadyWarnedAboutViewportLargerThanDest;
GLfloat mLineWidth;
GLfloat mLineWidth = 0.0;
WebGLContextLossHandler mContextLossHandler;
bool mAllowContextRestore;
@ -1969,13 +1969,13 @@ protected:
bool mNeedsFakeNoAlpha;
bool mNeedsFakeNoDepth;
bool mNeedsFakeNoStencil;
bool mNeedsFakeNoStencil_UserFBs;
bool mNeedsFakeNoStencil_UserFBs = false;
mutable uint8_t mDriverColorMask;
bool mDriverDepthTest;
bool mDriverStencilTest;
mutable uint8_t mDriverColorMask = 0;
bool mDriverDepthTest = false;
bool mDriverStencilTest = false;
bool mNeedsIndexValidation;
bool mNeedsIndexValidation = false;
const bool mAllowFBInvalidation;
@ -1986,7 +1986,7 @@ protected:
const uint8_t mMsaaSamples;
mutable gfx::IntSize mRequestedSize;
mutable UniquePtr<gl::MozFramebuffer> mDefaultFB;
mutable bool mDefaultFB_IsInvalid;
mutable bool mDefaultFB_IsInvalid = false;
mutable UniquePtr<gl::MozFramebuffer> mResolvedDefaultFB;
// --

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

@ -122,9 +122,7 @@ private:
public:
StrongGLenum()
#ifdef DEBUG
: mValue(NonexistantGLenum)
#endif
{
AssertOnceThatEnumValuesAreSorted();
}

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

@ -139,6 +139,7 @@ WebGLTexture::WebGLTexture(WebGLContext* webgl, GLuint tex)
, mMaxMipmapLevel(1000)
, mTexCompareMode(LOCAL_GL_NONE)
, mIsResolved(false)
, mResolved_FakeBlack(FakeBlackType::None)
, mResolved_Swizzle(nullptr)
{
mContext->mTextures.insertBack(this);

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

@ -53,6 +53,15 @@ public:
WebGLVertexAttribData()
: mDivisor(0)
, mEnabled(false)
, mIntegerFunc(false)
, mType(0)
, mBaseType(0)
, mSize(0)
, mBytesPerVertex(0)
, mNormalized(false)
, mStride(0)
, mExplicitStride(0)
, mByteOffset(0)
{
VertexAttribPointer(false, nullptr, 4, LOCAL_GL_FLOAT, false, 0, 0);
}

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

@ -4832,18 +4832,26 @@ HTMLInputElement::HandleTypeChange(uint8_t aNewType, bool aNotify)
// We're no longer an image input. Cancel our image requests, if we have
// any.
CancelImageRequests(aNotify);
} else if (aNotify && mType == NS_FORM_INPUT_IMAGE) {
// We just got switched to be an image input; we should see
// whether we have an image to load;
nsAutoString src;
if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
// Mark channel as urgent-start before load image if the image load is
// initaiated by a user interaction.
mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
LoadImage(src, false, aNotify, eImageLoadType_Normal,
mSrcTriggeringPrincipal);
// And we should update our mapped attribute mapping function.
mAttrsAndChildren.UpdateMappedAttrRuleMapper(*this);
} else if (mType == NS_FORM_INPUT_IMAGE) {
if (aNotify) {
// We just got switched to be an image input; we should see
// whether we have an image to load;
nsAutoString src;
if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
// Mark channel as urgent-start before load image if the image load is
// initaiated by a user interaction.
mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
LoadImage(src, false, aNotify, eImageLoadType_Normal,
mSrcTriggeringPrincipal);
}
}
// And we should update our mapped attribute mapping function.
mAttrsAndChildren.UpdateMappedAttrRuleMapper(*this);
}
if (mType == NS_FORM_INPUT_PASSWORD && IsInComposedDoc()) {
@ -5595,18 +5603,14 @@ HTMLInputElement::ParseAttribute(int32_t aNamespaceID,
}
void
HTMLInputElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
MappedDeclarations& aDecls)
HTMLInputElement::ImageInputMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
MappedDeclarations& aDecls)
{
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::type);
if (value && value->Type() == nsAttrValue::eEnum &&
value->GetEnumValue() == NS_FORM_INPUT_IMAGE) {
nsGenericHTMLFormElementWithState::MapImageBorderAttributeInto(aAttributes, aDecls);
nsGenericHTMLFormElementWithState::MapImageMarginAttributeInto(aAttributes, aDecls);
nsGenericHTMLFormElementWithState::MapImageSizeAttributesInto(aAttributes, aDecls);
// Images treat align as "float"
nsGenericHTMLFormElementWithState::MapImageAlignAttributeInto(aAttributes, aDecls);
}
nsGenericHTMLFormElementWithState::MapImageBorderAttributeInto(aAttributes, aDecls);
nsGenericHTMLFormElementWithState::MapImageMarginAttributeInto(aAttributes, aDecls);
nsGenericHTMLFormElementWithState::MapImageSizeAttributesInto(aAttributes, aDecls);
// Images treat align as "float"
nsGenericHTMLFormElementWithState::MapImageAlignAttributeInto(aAttributes, aDecls);
nsGenericHTMLFormElementWithState::MapCommonAttributesInto(aAttributes, aDecls);
}
@ -5645,7 +5649,6 @@ HTMLInputElement::IsAttributeMapped(const nsAtom* aAttribute) const
{
static const MappedAttributeEntry attributes[] = {
{ &nsGkAtoms::align },
{ &nsGkAtoms::type },
{ nullptr },
};
@ -5662,7 +5665,15 @@ HTMLInputElement::IsAttributeMapped(const nsAtom* aAttribute) const
nsMapRuleToAttributesFunc
HTMLInputElement::GetAttributeMappingFunction() const
{
return &MapAttributesIntoRule;
// GetAttributeChangeHint guarantees that changes to mType will trigger a
// reframe, and we update the mapping function in our mapped attrs when our
// type changes, so it's safe to condition our attribute mapping function on
// mType.
if (mType == NS_FORM_INPUT_IMAGE) {
return &ImageInputMapAttributesIntoRule;
}
return &MapCommonAttributesInto;
}

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

@ -1666,8 +1666,8 @@ protected:
bool mHasPatternAttribute : 1;
private:
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
MappedDeclarations&);
static void ImageInputMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
MappedDeclarations&);
/**
* Returns true if this input's type will fire a DOM "change" event when it

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

@ -263,8 +263,7 @@ IDBFactory::CreateForJSInternal(JSContext* aCx,
MOZ_ASSERT(aPrincipalInfo);
MOZ_ASSERT(aPrincipalInfo->type() != PrincipalInfo::T__None);
MOZ_ASSERT(aFactory);
MOZ_ASSERT(JS_GetGlobalForObject(aCx, aOwningObject) == aOwningObject,
"Not a global object!");
MOZ_ASSERT(JS_IsGlobalObject(aOwningObject));
if (aPrincipalInfo->type() != PrincipalInfo::TContentPrincipalInfo &&
aPrincipalInfo->type() != PrincipalInfo::TSystemPrincipalInfo) {

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

@ -563,10 +563,13 @@ nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType,
*outAllowsInline = false;
}
nsAutoString violatedDirective;
mPolicies[i]->getDirectiveStringForContentType(aContentType, violatedDirective);
bool reportSample = false;
mPolicies[i]->getDirectiveStringAndReportSampleForContentType(aContentType,
violatedDirective,
&reportSample);
reportInlineViolation(aContentType,
aNonce,
content,
reportSample ? content : EmptyString(),
violatedDirective,
i,
aLineNumber,
@ -613,13 +616,16 @@ nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType,
keyword, nonceOrHash, false)) \
{ \
nsAutoString violatedDirective; \
mPolicies[p]->getDirectiveStringForContentType( \
bool reportSample = false; \
mPolicies[p]->getDirectiveStringAndReportSampleForContentType( \
nsIContentPolicy::TYPE_ ## contentPolicyType, \
violatedDirective); \
violatedDirective, &reportSample); \
this->AsyncReportViolation(selfISupports, nullptr, violatedDirective, p, \
NS_LITERAL_STRING(observerTopic), \
aSourceFile, aScriptSample, aLineNum, \
aColumnNum); \
aSourceFile, \
reportSample \
? aScriptSample : EmptyString(), \
aLineNum, aColumnNum); \
} \
PR_END_MACRO; \
break
@ -1001,7 +1007,7 @@ nsCSPContext::SendReports(
report.mCsp_report.mLine_number.Value() = aViolationEventInit.mLineNumber;
}
if (aViolationEventInit.mLineNumber != 0) {
if (aViolationEventInit.mColumnNumber != 0) {
report.mCsp_report.mColumn_number.Construct();
report.mCsp_report.mColumn_number.Value() = aViolationEventInit.mColumnNumber;
}
@ -1265,7 +1271,7 @@ class CSPReportSenderRunnable final : public Runnable
rv = blockedURI->SchemeIs("data", &isData);
if (NS_SUCCEEDED(rv) && isData) {
blockedDataStr.Truncate(40);
blockedDataStr.AppendASCII("...");
blockedDataStr.AppendASCII("");
}
}
} else if (blockedString) {

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

@ -482,6 +482,10 @@ nsCSPParser::keywordSource()
return CSP_CreateHostSrcFromSelfURI(mSelfURI);
}
if (CSP_IsKeyword(mCurToken, CSP_REPORT_SAMPLE)) {
return new nsCSPKeywordSrc(CSP_UTF16KeywordToEnum(mCurToken));
}
if (CSP_IsKeyword(mCurToken, CSP_STRICT_DYNAMIC)) {
// make sure strict dynamic is enabled
if (!sStrictDynamicEnabled) {
@ -800,9 +804,10 @@ nsCSPParser::sourceList(nsTArray<nsCSPBaseSrc*>& outSrcs)
// Check if the directive contains a 'none'
if (isNone) {
// If the directive contains no other srcs, then we set the 'none'
if (outSrcs.Length() == 0) {
if (outSrcs.IsEmpty() ||
(outSrcs.Length() == 1 && outSrcs[0]->isReportSample())) {
nsCSPKeywordSrc *keyword = new nsCSPKeywordSrc(CSP_NONE);
outSrcs.AppendElement(keyword);
outSrcs.InsertElementAt(0, keyword);
}
// Otherwise, we ignore 'none' and report a warning
else {
@ -1150,9 +1155,10 @@ nsCSPParser::directive()
// If we can not parse any srcs; we let the source expression be the empty set ('none')
// see, http://www.w3.org/TR/CSP11/#source-list-parsing
if (srcs.Length() == 0) {
if (srcs.IsEmpty() ||
(srcs.Length() == 1 && srcs[0]->isReportSample())) {
nsCSPKeywordSrc *keyword = new nsCSPKeywordSrc(CSP_NONE);
srcs.AppendElement(keyword);
srcs.InsertElementAt(0, keyword);
}
// If policy contains 'strict-dynamic' invalidate all srcs within script-src.

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

@ -1264,6 +1264,18 @@ nsCSPDirective::getDirName(nsAString& outStr) const
outStr.AppendASCII(CSP_CSPDirectiveToString(mDirective));
}
bool
nsCSPDirective::hasReportSampleKeyword() const
{
for (nsCSPBaseSrc* src : mSrcs) {
if (src->isReportSample()) {
return true;
}
}
return false;
}
/* =============== nsCSPChildSrcDirective ============= */
nsCSPChildSrcDirective::nsCSPChildSrcDirective(CSPDirective aDirective)
@ -1614,13 +1626,18 @@ nsCSPPolicy::hasDirective(CSPDirective aDir) const
* for the ::permits() function family.
*/
void
nsCSPPolicy::getDirectiveStringForContentType(nsContentPolicyType aContentType,
nsAString& outDirective) const
nsCSPPolicy::getDirectiveStringAndReportSampleForContentType(nsContentPolicyType aContentType,
nsAString& outDirective,
bool* aReportSample) const
{
MOZ_ASSERT(aReportSample);
*aReportSample = false;
nsCSPDirective* defaultDir = nullptr;
for (uint32_t i = 0; i < mDirectives.Length(); i++) {
if (mDirectives[i]->restrictsContentType(aContentType)) {
mDirectives[i]->getDirName(outDirective);
*aReportSample = mDirectives[i]->hasReportSampleKeyword();
return;
}
if (mDirectives[i]->isDefaultDirective()) {
@ -1631,6 +1648,7 @@ nsCSPPolicy::getDirectiveStringForContentType(nsContentPolicyType aContentType,
// the contentType must be restricted by the default directive
if (defaultDir) {
defaultDir->getDirName(outDirective);
*aReportSample = defaultDir->hasReportSampleKeyword();
return;
}
NS_ASSERTION(false, "Can not query directive string for contentType!");

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

@ -126,6 +126,7 @@ inline CSPDirective CSP_StringToCSPDirective(const nsAString& aDir)
macro(CSP_NONE, "'none'") \
macro(CSP_NONCE, "'nonce-") \
macro(CSP_REQUIRE_SRI_FOR, "require-sri-for") \
macro(CSP_REPORT_SAMPLE, "'report-sample'") \
macro(CSP_STRICT_DYNAMIC, "'strict-dynamic'")
enum CSPKeyword {
@ -238,6 +239,9 @@ class nsCSPBaseSrc {
virtual void invalidate() const
{ mInvalidated = true; }
virtual bool isReportSample() const
{ return false; }
protected:
// invalidate srcs if 'script-dynamic' is present or also invalidate
// unsafe-inline' if nonce- or hash-source specified
@ -336,6 +340,8 @@ class nsCSPKeywordSrc : public nsCSPBaseSrc {
}
}
bool isReportSample() const override
{ return mKeyword == CSP_REPORT_SAMPLE; }
private:
CSPKeyword mKeyword;
};
@ -475,6 +481,8 @@ class nsCSPDirective {
virtual void getDirName(nsAString& outStr) const;
bool hasReportSampleKeyword() const;
protected:
CSPDirective mDirective;
nsTArray<nsCSPBaseSrc*> mSrcs;
@ -678,8 +686,9 @@ class nsCSPPolicy {
void getReportURIs(nsTArray<nsString> &outReportURIs) const;
void getDirectiveStringForContentType(nsContentPolicyType aContentType,
nsAString& outDirective) const;
void getDirectiveStringAndReportSampleForContentType(nsContentPolicyType aContentType,
nsAString& outDirective,
bool* aReportSample) const;
void getDirectiveAsString(CSPDirective aDir, nsAString& outDirective) const;

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

@ -1 +1 @@
Content-Security-Policy: default-src 'self'; img-src 'none'
Content-Security-Policy: default-src 'self' 'report-sample'; img-src 'none' 'report-sample'

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

@ -32,7 +32,7 @@ SpecialPowers.registerConsoleListener(function ConsoleMsgListener(aMsg) {
data_uri = "";
data_uri = aMsg.message.substr(data_start);
// this will either match the elipsis after the URI or the . at the end of the message
data_uri = data_uri.substr(0, data_uri.indexOf("."));
data_uri = data_uri.substr(0, data_uri.indexOf(""));
if (data_uri == "") {
return;
}

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

@ -29,10 +29,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=548193
const testfile = "tests/dom/security/test/csp/file_report.html";
const reportURI = "http://mochi.test:8888/foo.sjs";
const policy = "default-src 'none'; report-uri " + reportURI;
const policy = "default-src 'none' 'report-sample'; report-uri " + reportURI;
const docUri = "http://mochi.test:8888/tests/dom/security/test/csp/file_testserver.sjs" +
"?file=tests/dom/security/test/csp/file_report.html" +
"&csp=default-src%20%27none%27%3B%20report-uri%20http%3A//mochi.test%3A8888/foo.sjs";
"&csp=default-src%20%27none%27%20%27report-sample%27%3B%20report-uri%20http%3A//mochi.test%3A8888/foo.sjs";
window.checkResults = function(reportObj) {
var cspReport = reportObj["csp-report"];
@ -52,7 +52,7 @@ window.checkResults = function(reportObj) {
is(cspReport["violated-directive"], "default-src", "Incorrect violated-directive");
is(cspReport["original-policy"], "default-src 'none'; report-uri http://mochi.test:8888/foo.sjs",
is(cspReport["original-policy"], "default-src 'none' 'report-sample'; report-uri http://mochi.test:8888/foo.sjs",
"Incorrect original-policy");
is(cspReport["source-file"], docUri, "Incorrect source-file");

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

@ -70,7 +70,7 @@ function makeTest(id, expectedJSON, useReportOnlyPolicy, callback) {
// set up a new CSP instance for each test.
var csp = Cc["@mozilla.org/cspcontext;1"]
.createInstance(Ci.nsIContentSecurityPolicy);
var policy = "default-src 'none'; " +
var policy = "default-src 'none' 'report-sample'; " +
"report-uri " + REPORT_SERVER_URI +
":" + REPORT_SERVER_PORT +
"/test" + id;

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

@ -15,10 +15,11 @@ dictionary TestInterfaceJSUnionableDictionary {
interface TestInterfaceJS : EventTarget {
readonly attribute any anyArg;
readonly attribute object objectArg;
[Cached, Pure] readonly attribute TestInterfaceJSDictionary dictionaryArg;
TestInterfaceJSDictionary getDictionaryArg();
attribute any anyAttr;
attribute object objectAttr;
[Cached, Pure] attribute TestInterfaceJSDictionary dictionaryAttr;
TestInterfaceJSDictionary getDictionaryAttr();
void setDictionaryAttr(optional TestInterfaceJSDictionary dict);
any pingPongAny(any arg);
object pingPongObject(object obj);
any pingPongObjectOrString((object or DOMString) objOrString);
@ -38,11 +39,6 @@ interface TestInterfaceJS : EventTarget {
(TestInterfaceJS or long)? pingPongNullableUnion((TestInterfaceJS or long)? something);
(Location or TestInterfaceJS) returnBadUnion();
[Cached, Pure]
readonly attribute short cachedAttr;
void setCachedAttr(short n);
void clearCachedAttrCache();
// Test for sequence overloading and union behavior
void testSequenceOverload(sequence<DOMString> arg);
void testSequenceOverload(DOMString arg);

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

@ -903,7 +903,8 @@ Wrap(JSContext *cx, JS::HandleObject existing, JS::HandleObject obj)
MOZ_CRASH("There should be no edges from the debuggee to the debugger.");
}
JSObject* originGlobal = js::GetGlobalForObjectCrossCompartment(obj);
// Note: the JS engine unwraps CCWs before calling this callback.
JSObject* originGlobal = JS::GetNonCCWObjectGlobal(obj);
const js::Wrapper* wrapper = nullptr;
if (IsWorkerDebuggerGlobal(originGlobal) ||

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

@ -894,7 +894,7 @@ GetOrCreateMapEntryForPrototype(JSContext *cx, JS::Handle<JSObject*> proto)
// content, and the Window for chrome (whether add-ons are involved or not).
JS::Rooted<JSObject*> scope(cx, xpc::GetXBLScopeOrGlobal(cx, proto));
NS_ENSURE_TRUE(scope, nullptr);
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(scope) == scope);
MOZ_ASSERT(JS_IsGlobalObject(scope));
JS::Rooted<JSObject*> wrappedProto(cx, proto);
JSAutoRealm ar(cx, scope);

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

@ -85,7 +85,7 @@ nsXBLProtoImpl::InstallImplementation(nsXBLPrototypeBinding* aPrototypeBinding,
GetGlobalForObjectCrossCompartment(targetClassObject));
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScopeOrGlobal(cx, globalObject));
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(scopeObject) == scopeObject);
MOZ_ASSERT(JS_IsGlobalObject(scopeObject));
JSAutoRealm ar(cx, scopeObject);
// Determine the appropriate property holder.

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

@ -297,7 +297,7 @@ nsXBLProtoImplField::InstallAccessors(JSContext* aCx,
JS::Handle<JSObject*> aTargetClassObject)
{
MOZ_ASSERT(js::IsObjectInContextCompartment(aTargetClassObject, aCx));
JS::Rooted<JSObject*> globalObject(aCx, JS_GetGlobalForObject(aCx, aTargetClassObject));
JS::Rooted<JSObject*> globalObject(aCx, JS::GetNonCCWObjectGlobal(aTargetClassObject));
JS::Rooted<JSObject*> scopeObject(aCx, xpc::GetXBLScopeOrGlobal(aCx, globalObject));
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);

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

@ -101,7 +101,7 @@ nsXBLProtoImplMethod::InstallMember(JSContext* aCx,
#ifdef DEBUG
{
JS::Rooted<JSObject*> globalObject(aCx, JS_GetGlobalForObject(aCx, aTargetClassObject));
JS::Rooted<JSObject*> globalObject(aCx, JS::GetNonCCWObjectGlobal(aTargetClassObject));
MOZ_ASSERT(xpc::IsInContentXBLScope(globalObject) ||
globalObject == xpc::GetXBLScope(aCx, globalObject));
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx) == globalObject);

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

@ -127,7 +127,7 @@ nsXBLProtoImplProperty::InstallMember(JSContext *aCx,
#ifdef DEBUG
{
JS::Rooted<JSObject*> globalObject(aCx, JS_GetGlobalForObject(aCx, aTargetClassObject));
JS::Rooted<JSObject*> globalObject(aCx, JS::GetNonCCWObjectGlobal(aTargetClassObject));
MOZ_ASSERT(xpc::IsInContentXBLScope(globalObject) ||
globalObject == xpc::GetXBLScope(aCx, globalObject));
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx) == globalObject);

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

@ -93,7 +93,8 @@ NS_NewXMLContentSink(nsIXMLContentSink** aResult,
}
nsXMLContentSink::nsXMLContentSink()
: mTextLength(0)
: mState(eXMLContentSinkState_InProlog)
, mTextLength(0)
, mNotifyLevel(0)
, mPrettyPrintXML(true)
, mPrettyPrintHasSpecialRoot(0)

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

@ -18,6 +18,7 @@ class ForceDiscreteGPUHelperCGL
public:
ForceDiscreteGPUHelperCGL()
: mPixelFormatObj(nullptr)
{
// the code in this function is taken from Chromium, src/ui/gfx/gl/gl_context_cgl.cc, r122013
// BSD-style license, (c) The Chromium Authors

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

@ -248,6 +248,7 @@ GetAndInitDisplay(GLLibraryEGL& egl, void* displayType)
class AngleErrorReporting {
public:
AngleErrorReporting()
: mFailureId(nullptr)
{
// No static constructor
}

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

@ -247,6 +247,7 @@ TiledTextureImage::TiledTextureImage(GLContext* aGL,
, mCurrentImage(0)
, mIterationCallback(nullptr)
, mIterationCallbackData(nullptr)
, mTileSize(0)
, mRows(0)
, mColumns(0)
, mGL(aGL)

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

@ -99,6 +99,7 @@ ScopedBindFramebuffer::UnwrapImpl()
ScopedBindTextureUnit::ScopedBindTextureUnit(GLContext* aGL, GLenum aTexUnit)
: ScopedGLWrapper<ScopedBindTextureUnit>(aGL)
, mOldTexUnit(0)
{
MOZ_ASSERT(aTexUnit >= LOCAL_GL_TEXTURE0);
mGL->GetUIntegerv(LOCAL_GL_ACTIVE_TEXTURE, &mOldTexUnit);
@ -115,6 +116,7 @@ ScopedBindTextureUnit::UnwrapImpl() {
ScopedTexture::ScopedTexture(GLContext* aGL)
: ScopedGLWrapper<ScopedTexture>(aGL)
, mTexture(0)
{
mGL->fGenTextures(1, &mTexture);
}
@ -129,6 +131,7 @@ ScopedTexture::UnwrapImpl()
ScopedFramebuffer::ScopedFramebuffer(GLContext* aGL)
: ScopedGLWrapper<ScopedFramebuffer>(aGL)
, mFB(0)
{
mGL->fGenFramebuffers(1, &mFB);
}
@ -144,6 +147,7 @@ ScopedFramebuffer::UnwrapImpl()
ScopedRenderbuffer::ScopedRenderbuffer(GLContext* aGL)
: ScopedGLWrapper<ScopedRenderbuffer>(aGL)
, mRB(0)
{
mGL->fGenRenderbuffers(1, &mRB);
}
@ -363,6 +367,14 @@ ScopedVertexAttribPointer::ScopedVertexAttribPointer(GLContext* aGL,
GLuint buffer,
const GLvoid* pointer)
: ScopedGLWrapper<ScopedVertexAttribPointer>(aGL)
, mAttribEnabled(0)
, mAttribSize(0)
, mAttribStride(0)
, mAttribType(0)
, mAttribNormalized(0)
, mAttribBufferBinding(0)
, mAttribPointer(nullptr)
, mBoundBuffer(0)
{
WrapImpl(index);
mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, buffer);
@ -373,6 +385,14 @@ ScopedVertexAttribPointer::ScopedVertexAttribPointer(GLContext* aGL,
ScopedVertexAttribPointer::ScopedVertexAttribPointer(GLContext* aGL,
GLuint index)
: ScopedGLWrapper<ScopedVertexAttribPointer>(aGL)
, mAttribEnabled(0)
, mAttribSize(0)
, mAttribStride(0)
, mAttribType(0)
, mAttribNormalized(0)
, mAttribBufferBinding(0)
, mAttribPointer(nullptr)
, mBoundBuffer(0)
{
WrapImpl(index);
}
@ -428,6 +448,11 @@ ScopedVertexAttribPointer::UnwrapImpl()
ScopedPackState::ScopedPackState(GLContext* gl)
: ScopedGLWrapper<ScopedPackState>(gl)
, mAlignment(0)
, mPixelBuffer(0)
, mRowLength(0)
, mSkipPixels(0)
, mSkipRows(0)
{
mGL->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, &mAlignment);
@ -466,6 +491,13 @@ ScopedPackState::UnwrapImpl()
ResetUnpackState::ResetUnpackState(GLContext* gl)
: ScopedGLWrapper<ResetUnpackState>(gl)
, mAlignment(0)
, mPBO(0)
, mRowLength(0)
, mImageHeight(0)
, mSkipPixels(0)
, mSkipRows(0)
, mSkipImages(0)
{
const auto fnReset = [&](GLenum pname, GLuint val, GLuint* const out_old) {
mGL->GetUIntegerv(pname, out_old);

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

@ -260,6 +260,15 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
return true;
}
RefPtr<TextureClient>
ImageClientSingle::GetForwardedTexture()
{
if (mBuffers.Length() == 0) {
return nullptr;
}
return mBuffers[0].mTextureClient;
}
bool
ImageClientSingle::AddTextureClient(TextureClient* aTexture)
{

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

@ -73,6 +73,8 @@ public:
uint32_t GetLastUpdateGenerationCounter() { return mLastUpdateGenerationCounter; }
virtual RefPtr<TextureClient> GetForwardedTexture() { return nullptr; }
protected:
ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags,
CompositableType aType);
@ -104,6 +106,8 @@ public:
ImageClientSingle* AsImageClientSingle() override { return this; }
virtual RefPtr<TextureClient> GetForwardedTexture() override;
bool IsEmpty() { return mBuffers.IsEmpty(); }
protected:

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

@ -653,6 +653,8 @@ public:
// must only be called from the PaintThread.
void DropPaintThreadRef();
wr::MaybeExternalImageId GetExternalImageKey() { return mExternalImageId; }
private:
static void TextureClientRecycleCallback(TextureClient* aClient, void* aClosure);

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

@ -51,6 +51,12 @@ struct OpAddExternalImage {
ImageKey key;
};
struct OpAddExternalImageForTexture {
ExternalImageId externalImageId;
ImageKey key;
PTexture texture;
};
struct OpAddCompositorAnimations {
CompositorAnimations data;
};
@ -65,15 +71,14 @@ struct OpRemovePipelineIdForCompositable {
PipelineId pipelineId;
};
struct OpAddExternalImageIdForCompositable {
ExternalImageId externalImageId;
CompositableHandle handle;
};
struct OpRemoveExternalImageId {
ExternalImageId externalImageId;
};
struct OpReleaseTextureOfImage {
ImageKey key;
};
struct OpUpdateAsyncImagePipeline {
PipelineId pipelineId;
LayoutDeviceRect scBounds;
@ -86,8 +91,8 @@ struct OpUpdateAsyncImagePipeline {
union WebRenderParentCommand {
OpAddPipelineIdForCompositable;
OpRemovePipelineIdForCompositable;
OpAddExternalImageIdForCompositable;
OpRemoveExternalImageId;
OpReleaseTextureOfImage;
OpUpdateAsyncImagePipeline;
CompositableOperation;
OpAddCompositorAnimations;
@ -171,6 +176,7 @@ union OpUpdateResource {
OpAddFontInstance;
OpDeleteFontInstance;
OpAddExternalImage;
OpAddExternalImageForTexture;
};
} // namespace

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

@ -9,6 +9,7 @@
#include <algorithm>
#include "mozilla/Maybe.h"
#include "mozilla/ipc/SharedMemory.h"
#include "mozilla/layers/PTextureChild.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
namespace mozilla {
@ -279,6 +280,17 @@ IpcResourceUpdateQueue::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKe
mUpdates.AppendElement(layers::OpAddExternalImage(aExtId, aKey));
}
void
IpcResourceUpdateQueue::AddExternalImageForTexture(wr::ExternalImageId aExtId,
wr::ImageKey aKey,
layers::TextureClient* aTexture)
{
MOZ_ASSERT(aTexture);
MOZ_ASSERT(aTexture->GetIPDLActor());
MOZ_RELEASE_ASSERT(aTexture->GetIPDLActor()->GetIPCChannel() == mWriter.WrBridge()->GetIPCChannel());
mUpdates.AppendElement(layers::OpAddExternalImageForTexture(aExtId, aKey, nullptr, aTexture->GetIPDLActor()));
}
bool
IpcResourceUpdateQueue::UpdateImageBuffer(ImageKey aKey,
const ImageDescriptor& aDescriptor,

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

@ -37,6 +37,8 @@ public:
void Clear();
bool IsEmpty() const;
layers::WebRenderBridgeChild* WrBridge() const { return mShmAllocator; }
protected:
bool AllocChunk();
layers::OffsetRange AllocLargeChunk(size_t aSize);
@ -83,6 +85,10 @@ public:
void AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey);
void AddExternalImageForTexture(wr::ExternalImageId aExtId,
wr::ImageKey aKey,
layers::TextureClient* aTexture);
bool UpdateImageBuffer(wr::ImageKey aKey,
const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes);

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

@ -221,15 +221,6 @@ WebRenderBridgeChild::GetNextExternalImageId()
return id.value();
}
wr::ExternalImageId
WebRenderBridgeChild::AllocExternalImageIdForCompositable(CompositableClient* aCompositable)
{
wr::ExternalImageId imageId = GetNextExternalImageId();
AddWebRenderParentCommand(
OpAddExternalImageIdForCompositable(imageId, aCompositable->GetIPCHandle()));
return imageId;
}
void
WebRenderBridgeChild::DeallocExternalImageId(const wr::ExternalImageId& aImageId)
{
@ -237,6 +228,13 @@ WebRenderBridgeChild::DeallocExternalImageId(const wr::ExternalImageId& aImageId
OpRemoveExternalImageId(aImageId));
}
void
WebRenderBridgeChild::ReleaseTextureOfImage(const wr::ImageKey& aKey)
{
AddWebRenderParentCommand(
OpReleaseTextureOfImage(aKey));
}
struct FontFileDataSink
{
wr::FontKey* mFontKey;

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

@ -100,9 +100,12 @@ public:
const CompositableHandle& aHandlee);
void RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId);
wr::ExternalImageId AllocExternalImageIdForCompositable(CompositableClient* aCompositable);
void DeallocExternalImageId(const wr::ExternalImageId& aImageId);
/// Release TextureClient that is bounded to ImageKey.
/// It is used for recycling TextureClient.
void ReleaseTextureOfImage(const wr::ImageKey& aKey);
/**
* Clean this up, finishing with SendShutDown() which will cause __delete__
* to be sent from the parent side.

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

@ -344,6 +344,15 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
}
break;
}
case OpUpdateResource::TOpAddExternalImageForTexture: {
const auto& op = cmd.get_OpAddExternalImageForTexture();
CompositableTextureHostRef texture;
texture = TextureHost::AsTextureHost(op.textureParent());
if (!AddExternalImageForTexture(op.externalImageId(), op.key(), texture, aUpdates)) {
return false;
}
break;
}
case OpUpdateResource::TOpAddRawFont: {
const auto& op = cmd.get_OpAddRawFont();
wr::Vec<uint8_t> bytes;
@ -426,29 +435,54 @@ WebRenderBridgeParent::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey
return true;
}
} else {
MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(aExtId)).get());
RefPtr<WebRenderImageHost> host = mExternalImageIds.Get(wr::AsUint64(aExtId));
if (!host) {
gfxCriticalNote << "CompositableHost does not exist for extId:" << wr::AsUint64(aExtId);
return false;
}
if (!gfxEnv::EnableWebRenderRecording()) {
TextureHost* texture = host->GetAsTextureHostForComposite();
if (!texture) {
gfxCriticalNote << "TextureHost does not exist for extId:" << wr::AsUint64(aExtId);
return false;
}
WebRenderTextureHost* wrTexture = texture->AsWebRenderTextureHost();
if (wrTexture) {
wrTexture->PushResourceUpdates(aResources, TextureHost::ADD_IMAGE, keys,
wrTexture->GetExternalImageKey());
return true;
}
}
dSurf = host->GetAsSurface();
gfxCriticalNote << "DataSourceSurface of SharedSurfaces does not exist for extId:" << wr::AsUint64(aExtId);
return false;
}
DataSourceSurface::MappedSurface map;
if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
gfxCriticalNote << "DataSourceSurface failed to map for Image for extId:" << wr::AsUint64(aExtId);
return false;
}
IntSize size = dSurf->GetSize();
wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat());
wr::Vec<uint8_t> data;
data.PushBytes(Range<uint8_t>(map.mData, size.height * map.mStride));
aResources.AddImage(keys[0], descriptor, data);
dSurf->Unmap();
return true;
}
bool
WebRenderBridgeParent::AddExternalImageForTexture(wr::ExternalImageId aExtId,
wr::ImageKey aKey,
TextureHost* aTexture,
wr::TransactionBuilder& aResources)
{
Range<wr::ImageKey> keys(&aKey, 1);
// Check if key is obsoleted.
if (keys[0].mNamespace != mIdNamespace) {
return true;
}
if(!aTexture) {
gfxCriticalNote << "TextureHost does not exist for extId:" << wr::AsUint64(aExtId);
return false;
}
if (!gfxEnv::EnableWebRenderRecording()) {
WebRenderTextureHost* wrTexture = aTexture->AsWebRenderTextureHost();
if (wrTexture) {
wrTexture->PushResourceUpdates(aResources, TextureHost::ADD_IMAGE, keys,
wrTexture->GetExternalImageKey());
MOZ_ASSERT(!mTextureHosts.Get(wr::AsUint64(aKey), nullptr));
mTextureHosts.Put(wr::AsUint64(aKey), CompositableTextureHostRef(aTexture));
return true;
}
}
RefPtr<DataSourceSurface> dSurf = aTexture->GetAsSurface();
if (!dSurf) {
gfxCriticalNote << "TextureHost does not return DataSourceSurface for extId:" << wr::AsUint64(aExtId);
return false;
@ -847,17 +881,16 @@ WebRenderBridgeParent::ProcessWebRenderParentCommands(const InfallibleTArray<Web
RemovePipelineIdForCompositable(op.pipelineId(), aTxn);
break;
}
case WebRenderParentCommand::TOpAddExternalImageIdForCompositable: {
const OpAddExternalImageIdForCompositable& op = cmd.get_OpAddExternalImageIdForCompositable();
AddExternalImageIdForCompositable(op.externalImageId(),
op.handle());
break;
}
case WebRenderParentCommand::TOpRemoveExternalImageId: {
const OpRemoveExternalImageId& op = cmd.get_OpRemoveExternalImageId();
RemoveExternalImageId(op.externalImageId());
break;
}
case WebRenderParentCommand::TOpReleaseTextureOfImage: {
const OpReleaseTextureOfImage& op = cmd.get_OpReleaseTextureOfImage();
ReleaseTextureOfImage(op.key());
break;
}
case WebRenderParentCommand::TOpUpdateAsyncImagePipeline: {
const OpUpdateAsyncImagePipeline& op = cmd.get_OpUpdateAsyncImagePipeline();
mAsyncImageManager->UpdateAsyncImagePipeline(op.pipelineId(),
@ -1064,33 +1097,6 @@ WebRenderBridgeParent::RemovePipelineIdForCompositable(const wr::PipelineId& aPi
return;
}
void
WebRenderBridgeParent::AddExternalImageIdForCompositable(const ExternalImageId& aImageId,
const CompositableHandle& aHandle)
{
if (mDestroyed) {
return;
}
MOZ_ASSERT(!mExternalImageIds.Get(wr::AsUint64(aImageId)).get());
RefPtr<CompositableHost> host = FindCompositable(aHandle);
WebRenderImageHost* wrHost = host->AsWebRenderImageHost();
MOZ_ASSERT(wrHost);
if (!wrHost) {
gfxCriticalNote << "Incompatible CompositableHost for external image at WebRenderBridgeParent.";
}
if (!wrHost) {
return;
}
wrHost->SetWrBridge(this);
mExternalImageIds.Put(wr::AsUint64(aImageId), wrHost);
return;
}
void
WebRenderBridgeParent::RemoveExternalImageId(const ExternalImageId& aImageId)
{
@ -1101,18 +1107,27 @@ WebRenderBridgeParent::RemoveExternalImageId(const ExternalImageId& aImageId)
uint64_t imageId = wr::AsUint64(aImageId);
if (mSharedSurfaceIds.EnsureRemoved(imageId)) {
mAsyncImageManager->HoldExternalImage(mPipelineId, mWrEpoch, aImageId);
}
}
void
WebRenderBridgeParent::ReleaseTextureOfImage(const wr::ImageKey& aKey)
{
if (mDestroyed) {
return;
}
WebRenderImageHost* wrHost = mExternalImageIds.Get(imageId).get();
if (!wrHost) {
return;
uint64_t id = wr::AsUint64(aKey);
CompositableTextureHostRef texture;
WebRenderTextureHost* wrTexture = nullptr;
if (mTextureHosts.Get(id, &texture)) {
wrTexture = texture->AsWebRenderTextureHost();
}
wrHost->ClearWrBridge();
mExternalImageIds.Remove(imageId);
return;
if (wrTexture) {
mAsyncImageManager->HoldExternalImage(mPipelineId, mWrEpoch, wrTexture);
}
mTextureHosts.Remove(id);
}
mozilla::ipc::IPCResult
@ -1639,10 +1654,14 @@ WebRenderBridgeParent::ClearResources()
// Schedule generate frame to clean up Pipeline
ScheduleGenerateFrame();
// WrFontKeys and WrImageKeys are deleted during WebRenderAPI destruction.
for (auto iter = mExternalImageIds.Iter(); !iter.Done(); iter.Next()) {
iter.Data()->ClearWrBridge();
for (auto iter = mTextureHosts.Iter(); !iter.Done(); iter.Next()) {
WebRenderTextureHost* wrTexture = iter.Data()->AsWebRenderTextureHost();
MOZ_ASSERT(wrTexture);
if (wrTexture) {
mAsyncImageManager->HoldExternalImage(mPipelineId, wrEpoch, wrTexture);
}
}
mExternalImageIds.Clear();
mTextureHosts.Clear();
for (auto iter = mAsyncCompositables.Iter(); !iter.Done(); iter.Next()) {
wr::PipelineId pipelineId = wr::AsPipelineId(iter.Key());
RefPtr<WebRenderImageHost> host = iter.Data();

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

@ -209,15 +209,19 @@ private:
bool AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey,
wr::TransactionBuilder& aResources);
bool AddExternalImageForTexture(wr::ExternalImageId aExtId,
wr::ImageKey aKey,
TextureHost* aTexture,
wr::TransactionBuilder& aResources);
void AddPipelineIdForCompositable(const wr::PipelineId& aPipelineIds,
const CompositableHandle& aHandle,
const bool& aAsync);
void RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId,
wr::TransactionBuilder& aTxn);
void AddExternalImageIdForCompositable(const ExternalImageId& aImageId,
const CompositableHandle& aHandle);
void RemoveExternalImageId(const ExternalImageId& aImageId);
void ReleaseTextureOfImage(const wr::ImageKey& aKey);
LayersId GetLayersId() const;
void ProcessWebRenderParentCommands(const InfallibleTArray<WebRenderParentCommand>& aCommands,
@ -291,7 +295,7 @@ private:
// destroyed abnormally and Tab move between different windows.
std::unordered_set<uint64_t> mActiveAnimations;
nsDataHashtable<nsUint64HashKey, RefPtr<WebRenderImageHost>> mAsyncCompositables;
nsDataHashtable<nsUint64HashKey, RefPtr<WebRenderImageHost>> mExternalImageIds;
nsDataHashtable<nsUint64HashKey, CompositableTextureHostRef> mTextureHosts;
nsTHashtable<nsUint64HashKey> mSharedSurfaceIds;
TimeDuration mVsyncRate;

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

@ -196,20 +196,6 @@ WebRenderImageHost::SetCurrentTextureHost(TextureHost* aTexture)
return;
}
if (mWrBridge &&
!mUseAsyncImagePipeline &&
!!mCurrentTextureHost &&
mCurrentTextureHost != aTexture &&
mCurrentTextureHost->AsWebRenderTextureHost()) {
MOZ_ASSERT(mWrBridge->AsyncImageManager());
wr::PipelineId piplineId = mWrBridge->PipelineId();
wr::Epoch epoch = mWrBridge->WrEpoch();
mWrBridge->AsyncImageManager()->HoldExternalImage(
piplineId,
epoch,
mCurrentTextureHost->AsWebRenderTextureHost());
}
mCurrentTextureHost = aTexture;
}

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

@ -78,10 +78,6 @@ WebRenderImageData::~WebRenderImageData()
{
ClearImageKey();
if (mExternalImageId) {
WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
}
if (mPipelineId) {
WrBridge()->RemovePipelineIdForCompositable(mPipelineId.ref());
}
@ -95,10 +91,15 @@ WebRenderImageData::ClearImageKey()
// key when appropriate.
if (mOwnsKey) {
mWRManager->AddImageKeyForDiscard(mKey.value());
if (mTextureOfImage) {
WrBridge()->ReleaseTextureOfImage(mKey.value());
mTextureOfImage = nullptr;
}
}
mKey.reset();
}
mOwnsKey = false;
MOZ_ASSERT(!mTextureOfImage);
}
Maybe<wr::ImageKey>
@ -132,9 +133,7 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer,
}
CreateImageClientIfNeeded();
CreateExternalImageIfNeeded();
if (!mImageClient || !mExternalImageId) {
if (!mImageClient) {
return Nothing();
}
@ -144,7 +143,8 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer,
uint32_t oldCounter = imageClient->GetLastUpdateGenerationCounter();
bool ret = imageClient->UpdateImage(aContainer, /* unused */0);
if (!ret || imageClient->IsEmpty()) {
RefPtr<TextureClient> currentTexture = imageClient->GetForwardedTexture();
if (!ret || !currentTexture) {
// Delete old key
ClearImageKey();
return Nothing();
@ -159,8 +159,13 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer,
// TODO(nical): noooo... we need to reuse image keys.
ClearImageKey();
wr::MaybeExternalImageId extId = currentTexture->GetExternalImageKey();
MOZ_RELEASE_ASSERT(extId.isSome());
MOZ_ASSERT(!mTextureOfImage);
key = WrBridge()->GetNextImageKey();
aResources.AddExternalImage(mExternalImageId.value(), key);
aResources.AddExternalImageForTexture(extId.ref(), key, currentTexture);
mTextureOfImage = currentTexture;
mKey = Some(key);
mOwnsKey = true;
@ -212,7 +217,6 @@ WebRenderImageData::CreateAsyncImageWebRenderCommands(mozilla::wr::DisplayListBu
mContainer = aContainer;
}
MOZ_ASSERT(!mImageClient);
MOZ_ASSERT(!mExternalImageId);
// Push IFrame for async image pipeline.
//
@ -248,14 +252,6 @@ WebRenderImageData::CreateImageClientIfNeeded()
}
}
void
WebRenderImageData::CreateExternalImageIfNeeded()
{
if (!mExternalImageId) {
mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
}
}
WebRenderFallbackData::WebRenderFallbackData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
: WebRenderImageData(aWRManager, aItem)
, mInvalid(false)

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

@ -151,9 +151,8 @@ public:
protected:
void ClearImageKey();
void CreateExternalImageIfNeeded();
wr::MaybeExternalImageId mExternalImageId;
RefPtr<TextureClient> mTextureOfImage;
Maybe<wr::ImageKey> mKey;
RefPtr<ImageClient> mImageClient;
Maybe<wr::PipelineId> mPipelineId;

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

@ -50,11 +50,11 @@ JSDebugger::AddClass(JS::Handle<JS::Value> global, JSContext* cx)
return NS_ERROR_FAILURE;
}
JSAutoRealm ar(cx, obj);
if (JS_GetGlobalForObject(cx, obj) != obj) {
if (!JS_IsGlobalObject(obj)) {
return NS_ERROR_INVALID_ARG;
}
JSAutoRealm ar(cx, obj);
if (!JS_DefineDebuggerObject(cx, obj)) {
return NS_ERROR_FAILURE;
}

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

@ -143,7 +143,7 @@ class JS_FRIEND_API(Wrapper) : public ForwardingProxyHandler
static JSObject* Renew(JSObject* existing, JSObject* obj, const Wrapper* handler);
static const Wrapper* wrapperHandler(const JSObject* wrapper);
static inline const Wrapper* wrapperHandler(const JSObject* wrapper);
static JSObject* wrappedObject(JSObject* wrapper);
@ -340,6 +340,20 @@ IsWrapper(const JSObject* obj)
return IsProxy(obj) && GetProxyHandler(obj)->family() == &Wrapper::family;
}
inline bool
IsCrossCompartmentWrapper(const JSObject* obj)
{
return IsWrapper(obj) &&
(Wrapper::wrapperHandler(obj)->flags() & Wrapper::CROSS_COMPARTMENT);
}
/* static */ inline const Wrapper*
Wrapper::wrapperHandler(const JSObject* wrapper)
{
MOZ_ASSERT(IsWrapper(wrapper));
return static_cast<const Wrapper*>(GetProxyHandler(wrapper));
}
// Given a JSObject, returns that object stripped of wrappers. If
// stopAtWindowProxy is true, then this returns the WindowProxy if it was
// previously wrapped. Otherwise, this returns the first object for which

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

@ -206,14 +206,17 @@ LifoAlloc::getOrCreateChunk(size_t n)
// This function is adding a new BumpChunk in which all upcoming allocation
// would be made. Thus, we protect against out-of-bounds the last chunk in
// which we did our previous allocations.
if (!chunks_.empty())
chunks_.last()->setRWUntil(Loc::Reserved);
auto protectLast = [&]() {
if (!chunks_.empty())
chunks_.last()->setRWUntil(Loc::Reserved);
};
// Look for existing unused BumpChunks to satisfy the request, and pick the
// first one which is large enough, and move it into the list of used
// chunks.
if (!unused_.empty()) {
if (unused_.begin()->canAlloc(n)) {
protectLast();
chunks_.append(unused_.popFirst());
chunks_.last()->setRWUntil(Loc::End);
return true;
@ -225,6 +228,7 @@ LifoAlloc::getOrCreateChunk(size_t n)
MOZ_ASSERT(elem->empty());
if (elem->canAlloc(n)) {
BumpChunkList temp = unused_.splitAfter(i.get());
protectLast();
chunks_.append(temp.popFirst());
unused_.appendAll(std::move(temp));
chunks_.last()->setRWUntil(Loc::End);
@ -241,6 +245,7 @@ LifoAlloc::getOrCreateChunk(size_t n)
// The last chunk in which allocations are performed should be protected
// with setRWUntil(Loc::End), but this is not necessary here because any new
// allocation should be protected as RW already.
protectLast();
chunks_.append(std::move(newChunk));
incrementCurSize(size);
return true;

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

@ -69,6 +69,8 @@ using AddDeclaredNamePtr = ParseContext::Scope::AddDeclaredNamePtr;
using BindingIter = ParseContext::Scope::BindingIter;
using UsedNamePtr = UsedNameTracker::UsedNameMap::Ptr;
using BindingNameVector = Vector<BindingName, 6>;
// Read a token. Report an error and return null() if that token doesn't match
// to the condition. Do not use MUST_MATCH_TOKEN_INTERNAL directly.
#define MUST_MATCH_TOKEN_INTERNAL(cond, modifier, errorReport) \
@ -1773,7 +1775,7 @@ NewEmptyBindingData(JSContext* cx, LifoAlloc& alloc, uint32_t numBindings)
* the location one past the newly-constructed |BindingName|s.
*/
static MOZ_MUST_USE BindingName*
FreshlyInitializeBindings(BindingName* cursor, const Vector<BindingName>& bindings)
FreshlyInitializeBindings(BindingName* cursor, const BindingNameVector& bindings)
{
return std::uninitialized_copy(bindings.begin(), bindings.end(), cursor);
}
@ -1781,9 +1783,9 @@ FreshlyInitializeBindings(BindingName* cursor, const Vector<BindingName>& bindin
Maybe<GlobalScope::Data*>
NewGlobalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
{
Vector<BindingName> vars(context);
Vector<BindingName> lets(context);
Vector<BindingName> consts(context);
BindingNameVector vars(context);
BindingNameVector lets(context);
BindingNameVector consts(context);
bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
for (BindingIter bi = scope.bindings(pc); bi; bi++) {
@ -1849,10 +1851,10 @@ ParserBase::newGlobalScopeData(ParseContext::Scope& scope)
Maybe<ModuleScope::Data*>
NewModuleScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
{
Vector<BindingName> imports(context);
Vector<BindingName> vars(context);
Vector<BindingName> lets(context);
Vector<BindingName> consts(context);
BindingNameVector imports(context);
BindingNameVector vars(context);
BindingNameVector lets(context);
BindingNameVector consts(context);
bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
for (BindingIter bi = scope.bindings(pc); bi; bi++) {
@ -1919,7 +1921,7 @@ ParserBase::newModuleScopeData(ParseContext::Scope& scope)
Maybe<EvalScope::Data*>
NewEvalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
{
Vector<BindingName> vars(context);
BindingNameVector vars(context);
for (BindingIter bi = scope.bindings(pc); bi; bi++) {
// Eval scopes only contain 'var' bindings. Make all bindings aliased
@ -1959,9 +1961,9 @@ ParserBase::newEvalScopeData(ParseContext::Scope& scope)
Maybe<FunctionScope::Data*>
NewFunctionScopeData(JSContext* context, ParseContext::Scope& scope, bool hasParameterExprs, LifoAlloc& alloc, ParseContext* pc)
{
Vector<BindingName> positionalFormals(context);
Vector<BindingName> formals(context);
Vector<BindingName> vars(context);
BindingNameVector positionalFormals(context);
BindingNameVector formals(context);
BindingNameVector vars(context);
bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
bool hasDuplicateParams = pc->functionBox()->hasDuplicateParameters;
@ -2058,7 +2060,7 @@ ParserBase::newFunctionScopeData(ParseContext::Scope& scope, bool hasParameterEx
Maybe<VarScope::Data*>
NewVarScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
{
Vector<BindingName> vars(context);
BindingNameVector vars(context);
bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
@ -2099,8 +2101,8 @@ ParserBase::newVarScopeData(ParseContext::Scope& scope)
Maybe<LexicalScope::Data*>
NewLexicalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
{
Vector<BindingName> lets(context);
Vector<BindingName> consts(context);
BindingNameVector lets(context);
BindingNameVector consts(context);
// Unlike other scopes with bindings which are body-level, it is unknown
// if pc->sc()->allBindingsClosedOver() is correct at the time of

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

@ -6,6 +6,8 @@
#include "gc/Allocator.h"
#include "mozilla/DebugOnly.h"
#include "gc/GCInternals.h"
#include "gc/GCTrace.h"
#include "gc/Nursery.h"
@ -237,7 +239,7 @@ template <typename T, AllowGC allowGC>
GCRuntime::tryNewTenuredThing(JSContext* cx, AllocKind kind, size_t thingSize)
{
// Bump allocate in the arena's current free-list span.
T* t = reinterpret_cast<T*>(cx->arenas()->allocateFromFreeList(kind, thingSize));
T* t = reinterpret_cast<T*>(cx->freeLists().allocate(kind));
if (MOZ_UNLIKELY(!t)) {
// Get the next available free list and allocate out of it. This may
// acquire a new arena, which will lock the chunk list. If there are no
@ -347,26 +349,40 @@ GCRuntime::checkIncrementalZoneState(JSContext* cx, T* t)
#endif
}
TenuredCell*
js::gc::AllocateCellInGC(Zone* zone, AllocKind thingKind)
{
void* cell = zone->arenas.allocateFromFreeList(thingKind);
if (!cell) {
AutoEnterOOMUnsafeRegion oomUnsafe;
cell = GCRuntime::refillFreeListInGC(zone, thingKind);
if (!cell)
oomUnsafe.crash(ChunkSize, "Failed not allocate new chunk during GC");
}
return TenuredCell::fromPointer(cell);
}
// /////////// Arena -> Thing Allocator //////////////////////////////////////
void
bool
GCRuntime::startBackgroundAllocTaskIfIdle()
{
AutoLockHelperThreadState helperLock;
if (allocTask.isRunningWithLockHeld(helperLock))
return;
return true;
// Join the previous invocation of the task. This will return immediately
// if the thread has never been started.
allocTask.joinWithLockHeld(helperLock);
allocTask.startWithLockHeld(helperLock);
return allocTask.startWithLockHeld(helperLock);
}
/* static */ TenuredCell*
GCRuntime::refillFreeListFromAnyThread(JSContext* cx, AllocKind thingKind)
{
cx->arenas()->checkEmptyFreeList(thingKind);
MOZ_ASSERT(cx->freeLists().isEmpty(thingKind));
if (!cx->helperThread())
return refillFreeListFromMainThread(cx, thingKind);
@ -379,10 +395,10 @@ GCRuntime::refillFreeListFromMainThread(JSContext* cx, AllocKind thingKind)
{
// It should not be possible to allocate on the main thread while we are
// inside a GC.
Zone *zone = cx->zone();
MOZ_ASSERT(!JS::RuntimeHeapIsBusy(), "allocating while under GC");
return cx->arenas()->allocateFromArena(zone, thingKind, ShouldCheckThresholds::CheckThresholds);
return cx->zone()->arenas.refillFreeListAndAllocate(cx->freeLists(), thingKind,
ShouldCheckThresholds::CheckThresholds);
}
/* static */ TenuredCell*
@ -390,37 +406,37 @@ GCRuntime::refillFreeListFromHelperThread(JSContext* cx, AllocKind thingKind)
{
// A GC may be happening on the main thread, but zones used by off thread
// tasks are never collected.
Zone* zone = cx->zone();
Zone *zone = cx->zone();
MOZ_ASSERT(!zone->wasGCStarted());
return cx->arenas()->allocateFromArena(zone, thingKind, ShouldCheckThresholds::CheckThresholds);
return zone->arenas.refillFreeListAndAllocate(cx->freeLists(), thingKind,
ShouldCheckThresholds::CheckThresholds);
}
/* static */ TenuredCell*
GCRuntime::refillFreeListInGC(Zone* zone, AllocKind thingKind)
{
/*
* Called by compacting GC to refill a free list while we are in a GC.
*/
zone->arenas.checkEmptyFreeList(thingKind);
mozilla::DebugOnly<JSRuntime*> rt = zone->runtimeFromMainThread();
// Called by compacting GC to refill a free list while we are in a GC.
MOZ_ASSERT(JS::RuntimeHeapIsCollecting());
MOZ_ASSERT_IF(!JS::RuntimeHeapIsMinorCollecting(), !rt->gc.isBackgroundSweeping());
MOZ_ASSERT_IF(!JS::RuntimeHeapIsMinorCollecting(),
!zone->runtimeFromMainThread()->gc.isBackgroundSweeping());
return zone->arenas.allocateFromArena(zone, thingKind, ShouldCheckThresholds::DontCheckThresholds);
return zone->arenas.refillFreeListAndAllocate(zone->arenas.freeLists(), thingKind,
ShouldCheckThresholds::DontCheckThresholds);
}
TenuredCell*
ArenaLists::allocateFromArena(JS::Zone* zone, AllocKind thingKind,
ShouldCheckThresholds checkThresholds)
ArenaLists::refillFreeListAndAllocate(FreeLists& freeLists, AllocKind thingKind,
ShouldCheckThresholds checkThresholds)
{
JSRuntime* rt = zone->runtimeFromAnyThread();
MOZ_ASSERT(freeLists.isEmpty(thingKind));
JSRuntime* rt = runtimeFromAnyThread();
mozilla::Maybe<AutoLockGCBgAlloc> maybeLock;
// See if we can proceed without taking the GC lock.
if (backgroundFinalizeState(thingKind) != BFS_DONE)
if (concurrentUse(thingKind) != ConcurrentUse::None)
maybeLock.emplace(rt);
ArenaList& al = arenaLists(thingKind);
@ -429,7 +445,7 @@ ArenaLists::allocateFromArena(JS::Zone* zone, AllocKind thingKind,
// Empty arenas should be immediately freed.
MOZ_ASSERT(!arena->isEmpty());
return allocateFromArenaInner(zone, arena, thingKind);
return freeLists.setArenaAndAllocate(arena, thingKind);
}
// Parallel threads have their own ArenaLists, but chunks are shared;
@ -443,40 +459,46 @@ ArenaLists::allocateFromArena(JS::Zone* zone, AllocKind thingKind,
// Although our chunk should definitely have enough space for another arena,
// there are other valid reasons why Chunk::allocateArena() may fail.
arena = rt->gc.allocateArena(chunk, zone, thingKind, checkThresholds, maybeLock.ref());
arena = rt->gc.allocateArena(chunk, zone_, thingKind, checkThresholds, maybeLock.ref());
if (!arena)
return nullptr;
MOZ_ASSERT(al.isCursorAtEnd());
al.insertBeforeCursor(arena);
return allocateFromArenaInner(zone, arena, thingKind);
return freeLists.setArenaAndAllocate(arena, thingKind);
}
inline TenuredCell*
ArenaLists::allocateFromArenaInner(JS::Zone* zone, Arena* arena, AllocKind kind)
FreeLists::setArenaAndAllocate(Arena* arena, AllocKind kind)
{
size_t thingSize = Arena::thingSize(kind);
#ifdef DEBUG
auto old = freeLists_[kind];
if (!old->isEmpty())
old->getArena()->checkNoMarkedFreeCells();
#endif
setFreeList(kind, arena->getFirstFreeSpan());
FreeSpan* span = arena->getFirstFreeSpan();
freeLists_[kind] = span;
if (MOZ_UNLIKELY(zone->wasGCStarted()))
zone->runtimeFromAnyThread()->gc.arenaAllocatedDuringGC(zone, arena);
TenuredCell* thing = freeList(kind)->allocate(thingSize);
if (MOZ_UNLIKELY(arena->zone->wasGCStarted()))
arena->arenaAllocatedDuringGC();
TenuredCell* thing = span->allocate(Arena::thingSize(kind));
MOZ_ASSERT(thing); // This allocation is infallible.
return thing;
}
void
GCRuntime::arenaAllocatedDuringGC(JS::Zone* zone, Arena* arena)
Arena::arenaAllocatedDuringGC()
{
// Ensure that anything allocated during the mark or sweep phases of an
// incremental GC will be marked black by pre-marking all free cells in the
// arena we are about to allocate from.
if (zone->needsIncrementalBarrier() || zone->isGCSweeping()) {
for (ArenaFreeCellIter iter(arena); !iter.done(); iter.next()) {
for (ArenaFreeCellIter iter(this); !iter.done(); iter.next()) {
TenuredCell* cell = iter.getCell();
MOZ_ASSERT(!cell->isMarkedAny());
cell->markBlack();
@ -484,6 +506,28 @@ GCRuntime::arenaAllocatedDuringGC(JS::Zone* zone, Arena* arena)
}
}
void
GCRuntime::setParallelAtomsAllocEnabled(bool enabled)
{
atomsZone->arenas.setParallelAllocEnabled(enabled);
}
void
ArenaLists::setParallelAllocEnabled(bool enabled)
{
MOZ_ASSERT(zone_->isAtomsZone());
static const ConcurrentUse states[2] = {
ConcurrentUse::None,
ConcurrentUse::ParallelAlloc
};
for (auto kind : AllAllocKinds()) {
MOZ_ASSERT(concurrentUse(kind) == states[!enabled]);
concurrentUse(kind) = states[enabled];
}
}
// /////////// Chunk -> Arena Allocator //////////////////////////////////////

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

@ -237,26 +237,63 @@ js::gc::SortedArenaList::toArenaList()
return ArenaList(segments[0]);
}
void
js::gc::ArenaLists::setFreeList(AllocKind i, FreeSpan* span)
{
#ifdef DEBUG
auto old = freeList(i);
if (!old->isEmpty())
old->getArena()->checkNoMarkedFreeCells();
bool
js::gc::FreeLists::allEmpty() const
{
for (auto i : AllAllocKinds()) {
if (!isEmpty(i))
return false;
}
return true;
}
bool
js::gc::FreeLists::isEmpty(AllocKind kind) const
{
return freeLists_[kind]->isEmpty();
}
#endif
freeLists()[i] = span;
void
js::gc::FreeLists::clear()
{
for (auto i : AllAllocKinds()) {
#ifdef DEBUG
auto old = freeLists_[i];
if (!old->isEmpty())
old->getArena()->checkNoMarkedFreeCells();
#endif
freeLists_[i] = &emptySentinel;
}
}
js::gc::TenuredCell*
js::gc::FreeLists::allocate(AllocKind kind)
{
return freeLists_[kind]->allocate(Arena::thingSize(kind));
}
void
js::gc::ArenaLists::clearFreeList(AllocKind i)
js::gc::FreeLists::unmarkPreMarkedFreeCells(AllocKind kind)
{
#ifdef DEBUG
auto old = freeList(i);
if (!old->isEmpty())
old->getArena()->checkNoMarkedFreeCells();
#endif
freeLists()[i] = &emptySentinel;
FreeSpan* freeSpan = freeLists_[kind];
if (!freeSpan->isEmpty())
freeSpan->getArena()->unmarkPreMarkedFreeCells();
}
JSRuntime*
js::gc::ArenaLists::runtime()
{
return zone_->runtimeFromMainThread();
}
JSRuntime*
js::gc::ArenaLists::runtimeFromAnyThread()
{
return zone_->runtimeFromAnyThread();
}
js::gc::Arena*
@ -293,7 +330,7 @@ js::gc::ArenaLists::arenaListsAreEmpty() const
* The arena cannot be empty if the background finalization is not yet
* done.
*/
if (backgroundFinalizeState(i) != BFS_DONE)
if (concurrentUse(i) == ConcurrentUse::BackgroundFinalize)
return false;
if (!arenaLists(i).isEmpty())
return false;
@ -306,7 +343,7 @@ js::gc::ArenaLists::unmarkAll()
{
for (auto i : AllAllocKinds()) {
/* The background finalization must have stopped at this point. */
MOZ_ASSERT(backgroundFinalizeState(i) == BFS_DONE);
MOZ_ASSERT(concurrentUse(i) == ConcurrentUse::None);
for (Arena* arena = arenaLists(i).head(); arena; arena = arena->next)
arena->unmarkAll();
}
@ -315,42 +352,38 @@ js::gc::ArenaLists::unmarkAll()
bool
js::gc::ArenaLists::doneBackgroundFinalize(AllocKind kind) const
{
return backgroundFinalizeState(kind) == BFS_DONE;
return concurrentUse(kind) != ConcurrentUse::BackgroundFinalize;
}
bool
js::gc::ArenaLists::needBackgroundFinalizeWait(AllocKind kind) const
{
return backgroundFinalizeState(kind) != BFS_DONE;
return concurrentUse(kind) == ConcurrentUse::BackgroundFinalize;
}
void
js::gc::ArenaLists::clearFreeLists()
{
for (auto i : AllAllocKinds())
clearFreeList(i);
}
bool
js::gc::ArenaLists::arenaIsInUse(Arena* arena, AllocKind kind) const
{
MOZ_ASSERT(arena);
return arena == freeList(kind)->getArenaUnchecked();
freeLists().clear();
}
MOZ_ALWAYS_INLINE js::gc::TenuredCell*
js::gc::ArenaLists::allocateFromFreeList(AllocKind thingKind, size_t thingSize)
js::gc::ArenaLists::allocateFromFreeList(AllocKind thingKind)
{
return freeList(thingKind)->allocate(thingSize);
return freeLists().allocate(thingKind);
}
void
js::gc::ArenaLists::unmarkPreMarkedFreeCells()
{
for (auto i : AllAllocKinds())
freeLists().unmarkPreMarkedFreeCells(i);
}
void
js::gc::ArenaLists::checkEmptyFreeLists()
{
#ifdef DEBUG
for (auto i : AllAllocKinds())
checkEmptyFreeList(i);
#endif
MOZ_ASSERT(freeLists().allEmpty());
}
bool
@ -366,10 +399,4 @@ js::gc::ArenaLists::checkEmptyArenaLists()
return empty;
}
void
js::gc::ArenaLists::checkEmptyFreeList(AllocKind kind)
{
MOZ_ASSERT(freeList(kind)->isEmpty());
}
#endif // gc_ArenaList_inl_h

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