Merge inbound to central, a=merge

This commit is contained in:
Wes Kocher 2015-11-05 18:44:24 -08:00
commit 22c6858903
195 changed files with 1701 additions and 1236 deletions

View File

@ -282,6 +282,7 @@ EXTRA_JS_MODULES.commonjs.sdk.deprecated.events += [
]
EXTRA_JS_MODULES.commonjs.sdk.dom += [
'source/lib/sdk/dom/events-shimmed.js',
'source/lib/sdk/dom/events.js',
]
@ -408,6 +409,7 @@ EXTRA_JS_MODULES.commonjs.sdk.stylesheet += [
EXTRA_JS_MODULES.commonjs.sdk.system += [
'source/lib/sdk/system/child_process.js',
'source/lib/sdk/system/environment.js',
'source/lib/sdk/system/events-shimmed.js',
'source/lib/sdk/system/events.js',
'source/lib/sdk/system/globals.js',
'source/lib/sdk/system/process.js',

View File

@ -34,6 +34,8 @@ cpmm.addMessageListener('sdk/remote/process/load', ({ data: { modulePath, loader
if (addons.has(loaderID))
return;
options.waiveInterposition = true;
let loader = Loader.Loader(options);
let addon = {
loader,

View File

@ -18,8 +18,7 @@ const { on: domOn, removeListener: domOff } = require('../dom/events');
const { isRegExp, isUndefined } = require('../lang/type');
const { merge } = require('../util/object');
const { isBrowser, getFrames } = require('../window/utils');
const { getTabs, getTabContentWindow, getTabForContentWindow,
getURI: getTabURI } = require('../tabs/utils');
const { getTabs, getURI: getTabURI } = require('../tabs/utils');
const { ignoreWindow } = require('../private-browsing/utils');
const { Style } = require("../stylesheet/style");
const { attach, detach } = require("../content/mod");

View File

@ -18,7 +18,7 @@ const timer = require('../timers');
const { URL } = require('../url');
const { sandbox, evaluate, load } = require('../loader/sandbox');
const { merge } = require('../util/object');
const { getTabForContentWindow } = require('../tabs/utils');
const { getTabForContentWindowNoShim } = require('../tabs/utils');
const { getInnerId } = require('../window/utils');
const { PlainTextConsole } = require('../console/plain-text');
const { data } = require('../self');const { isChildLoader } = require('../remote/core');
@ -57,7 +57,7 @@ function isWindowInTab(window) {
}
else {
// The deprecated sync worker API still does everything in the main process
return getTabForContentWindow(window);
return getTabForContentWindowNoShim(window);
}
}

View File

@ -14,11 +14,11 @@ const { method } = require('../lang/functional');
const { getInnerId } = require('../window/utils');
const { EventTarget } = require('../event/target');
const { isPrivate } = require('../private-browsing/utils');
const { getTabForBrowser, getTabForContentWindow, getBrowserForTab } = require('../tabs/utils');
const { getTabForBrowser, getTabForContentWindowNoShim, getBrowserForTab } = require('../tabs/utils');
const { attach, connect, detach, destroy, makeChildOptions } = require('./utils');
const { ensure } = require('../system/unload');
const { on: observe } = require('../system/events');
const { Ci } = require('chrome');
const { Ci, Cu } = require('chrome');
const { modelFor: tabFor } = require('sdk/model/core');
const { remoteRequire, processes, frames } = require('../remote/parent');
remoteRequire('sdk/content/worker-child');
@ -117,13 +117,18 @@ exports.Worker = Worker;
attach.define(Worker, function(worker, window) {
// This method of attaching should be deprecated
if (Cu.isCrossProcessWrapper(window))
throw new Error("Attaching worker to a window from another " +
"process directly is not supported.");
let model = modelFor(worker);
if (model.attached)
detach(worker);
model.window = window;
let frame = null;
let tab = getTabForContentWindow(window.top);
let tab = getTabForContentWindowNoShim(window);
if (tab)
frame = frames.getFrameForBrowser(getBrowserForTab(tab));

View File

@ -9,14 +9,17 @@ module.metadata = {
};
const { Cc, Ci, Cr } = require("chrome");
const { Cc, Ci, Cr, Cu } = require("chrome");
const { Class } = require("./heritage");
const { isWeak } = require("./reference");
const method = require("../../method/core");
const { addObserver, removeObserver } = Cc['@mozilla.org/observer-service;1'].
getService(Ci.nsIObserverService);
const observerService = Cc['@mozilla.org/observer-service;1'].
getService(Ci.nsIObserverService);
const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm");
const addObserver = ShimWaiver.getProperty(observerService, "addObserver");
const removeObserver = ShimWaiver.getProperty(observerService, "removeObserver");
// This is a method that will be invoked when notification observer
// subscribed to occurs.

View File

@ -0,0 +1,18 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
module.metadata = {
'stability': 'unstable'
};
const events = require('./events.js');
exports.emit = (element, type, obj) => events.emit(element, type, obj, true);
exports.on = (element, type, listener, capture) => events.on(element, type, listener, capture, true);
exports.once = (element, type, listener, capture) => events.once(element, type, listener, capture, true);
exports.removeListener = (element, type, listener, capture) => events.removeListener(element, type, listener, capture, true);
exports.removed = events.removed;
exports.when = (element, eventName, capture) => events.when(element, eventName, capture ? capture : false, true);

View File

@ -8,6 +8,9 @@ module.metadata = {
"stability": "unstable"
};
const { Cu } = require("chrome");
const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm");
// Utility function that returns copy of the given `text` with last character
// removed if it is `"s"`.
function singularify(text) {
@ -44,10 +47,14 @@ function getInitializerName(category) {
* See [DOM Level 3 Events](http://www.w3.org/TR/DOM-Level-3-Events/#event-flow)
* for a detailed explanation.
*/
function on(element, type, listener, capture) {
function on(element, type, listener, capture, shimmed = false) {
// `capture` defaults to `false`.
capture = capture || false;
element.addEventListener(type, listener, capture);
if (shimmed) {
element.addEventListener(type, listener, capture);
} else {
ShimWaiver.getProperty(element, "addEventListener")(type, listener, capture);
}
}
exports.on = on;
@ -73,11 +80,11 @@ exports.on = on;
* See [DOM Level 3 Events](http://www.w3.org/TR/DOM-Level-3-Events/#event-flow)
* for a detailed explanation.
*/
function once(element, type, listener, capture) {
function once(element, type, listener, capture, shimmed = false) {
on(element, type, function selfRemovableListener(event) {
removeListener(element, type, selfRemovableListener, capture);
removeListener(element, type, selfRemovableListener, capture, shimmed);
listener.apply(this, arguments);
}, capture);
}, capture, shimmed);
}
exports.once = once;
@ -103,8 +110,12 @@ exports.once = once;
* See [DOM Level 3 Events](http://www.w3.org/TR/DOM-Level-3-Events/#event-flow)
* for a detailed explanation.
*/
function removeListener(element, type, listener, capture) {
element.removeEventListener(type, listener, capture);
function removeListener(element, type, listener, capture, shimmed = false) {
if (shimmed) {
element.removeEventListener(type, listener, capture);
} else {
ShimWaiver.getProperty(element, "removeEventListener")(type, listener, capture);
}
}
exports.removeListener = removeListener;
@ -128,13 +139,17 @@ exports.removeListener = removeListener;
* initializer after firs `type` argument.
* @see https://developer.mozilla.org/En/DOM/Document.createEvent
*/
function emit(element, type, { category, initializer, settings }) {
function emit(element, type, { category, initializer, settings }, shimmed = false) {
category = category || "UIEvents";
initializer = initializer || getInitializerName(category);
let document = element.ownerDocument;
let event = document.createEvent(category);
event[initializer].apply(event, [type].concat(settings));
element.dispatchEvent(event);
if (shimmed) {
element.dispatchEvent(event);
} else {
ShimWaiver.getProperty(element, "dispatchEvent")(event);
}
};
exports.emit = emit;
@ -158,12 +173,20 @@ const removed = element => {
};
exports.removed = removed;
const when = (element, eventName, capture=false) => new Promise(resolve => {
const when = (element, eventName, capture=false, shimmed=false) => new Promise(resolve => {
const listener = event => {
element.removeEventListener(eventName, listener, capture);
if (shimmed) {
element.removeEventListener(eventName, listener, capture);
} else {
ShimWaiver.getProperty(element, "removeEventListener")(eventName, listener, capture);
}
resolve(event);
};
element.addEventListener(eventName, listener, capture);
if (shimmed) {
element.addEventListener(eventName, listener, capture);
} else {
ShimWaiver.getProperty(element, "addEventListener")(eventName, listener, capture);
}
});
exports.when = when;

View File

@ -8,10 +8,15 @@ module.metadata = {
"stability": "unstable"
};
const { Cc, Ci, Cr } = require("chrome");
const { Cc, Ci, Cr, Cu } = require("chrome");
const { emit, on, off } = require("./core");
const { addObserver, removeObserver } = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
var observerService = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm");
const addObserver = ShimWaiver.getProperty(observerService, "addObserver");
const removeObserver = ShimWaiver.getProperty(observerService, "removeObserver");
const { when: unload } = require("../system/unload");
// Simple class that can be used to instantiate event channel that

View File

@ -14,6 +14,9 @@ var { emit } = require("./core");
var { when: unload } = require("../system/unload");
var listeners = new Map();
const { Cu } = require("chrome");
const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm");
var getWindowFrom = x =>
x instanceof Ci.nsIDOMWindow ? x :
x instanceof Ci.nsIDOMDocument ? x.defaultView :
@ -21,7 +24,7 @@ var getWindowFrom = x =>
null;
function removeFromListeners() {
this.removeEventListener("DOMWindowClose", removeFromListeners);
ShimWaiver.getProperty(this, "removeEventListener")("DOMWindowClose", removeFromListeners);
for (let cleaner of listeners.get(this))
cleaner();
@ -56,11 +59,11 @@ function open(target, type, options) {
// We need to remove from our map the `window` once is closed, to prevent
// memory leak
window.addEventListener("DOMWindowClose", removeFromListeners);
ShimWaiver.getProperty(window, "addEventListener")("DOMWindowClose", removeFromListeners);
}
cleaners.push(() => target.removeEventListener(type, listener, capture));
target.addEventListener(type, listener, capture);
cleaners.push(() => ShimWaiver.getProperty(target, "removeEventListener")(type, listener, capture));
ShimWaiver.getProperty(target, "addEventListener")(type, listener, capture);
return output;
}

View File

@ -9,8 +9,12 @@ const { once, off } = require("../event/core");
const { id: addonID } = require("../self");
const unloadMessage = require("@loader/unload");
const { addObserver, removeObserver } = Cc['@mozilla.org/observer-service;1'].
getService(Ci.nsIObserverService);
const observerService = Cc['@mozilla.org/observer-service;1'].
getService(Ci.nsIObserverService);
const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm");
const addObserver = ShimWaiver.getProperty(observerService, "addObserver");
const removeObserver = ShimWaiver.getProperty(observerService, "removeObserver");
const addonUnloadTopic = "sdk:loader:destroy";

View File

@ -50,7 +50,8 @@ const Observer = Class({
* Keyboard event being emitted.
*/
handleEvent(event) {
emit(this, event.type, event, event.target.ownerDocument.defaultView);
emit(this, event.type, event, event.target.ownerDocument ? event.target.ownerDocument.defaultView
: undefined);
}
});

View File

@ -12,7 +12,7 @@ const systemPrincipal = CC('@mozilla.org/systemprincipal;1', 'nsIPrincipal')();
const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1'].
getService(Ci.mozIJSSubScriptLoader);
const self = require('sdk/self');
const { getTabId, getTabForContentWindow } = require('../tabs/utils');
const { getTabId } = require('../tabs/utils');
const { getInnerId } = require('../window/utils');
const { devtools } = Cu.import("resource://devtools/shared/Loader.jsm", {});

View File

@ -20,7 +20,7 @@ const { Ci, Cc } = require("chrome"),
{ ns } = require("./core/namespace"),
{ when: unload } = require("./system/unload"),
{ ignoreWindow } = require('./private-browsing/utils'),
{ getTabs, getTabContentWindow, getTabForContentWindow,
{ getTabs, getTabForContentWindow,
getAllTabContentWindows } = require('./tabs/utils'),
winUtils = require("./window/utils"),
events = require("./system/events");

View File

@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
module.metadata = {
'stability': 'unstable'
};
const events = require('./events.js');
exports.emit = (type, event) => events.emit(type, event, true);
exports.on = (type, listener, strong) => events.on(type, listener, strong, true);
exports.once = (type, listener) => events.once(type, listener, true);
exports.off = (type, listener) => events.off(type, listener, true);

View File

@ -12,8 +12,13 @@ const { Cc, Ci, Cu } = require('chrome');
const { Unknown } = require('../platform/xpcom');
const { Class } = require('../core/heritage');
const { ns } = require('../core/namespace');
const { addObserver, removeObserver, notifyObservers } =
const observerService =
Cc['@mozilla.org/observer-service;1'].getService(Ci.nsIObserverService);
const { addObserver, removeObserver, notifyObservers } = observerService;
const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm");
const addObserverNoShim = ShimWaiver.getProperty(observerService, "addObserver");
const removeObserverNoShim = ShimWaiver.getProperty(observerService, "removeObserver");
const notifyObserversNoShim = ShimWaiver.getProperty(observerService, "notifyObservers");
const unloadSubject = require('@loader/unload');
const Subject = Class({
@ -33,7 +38,7 @@ const Subject = Class({
getInterfaces: function() {}
});
function emit(type, event) {
function emit(type, event, shimmed = false) {
// From bug 910599
// We must test to see if 'subject' or 'data' is a defined property
// of the event object, but also allow primitives to be passed in,
@ -48,7 +53,11 @@ function emit(type, event) {
// All other types return themselves (and cast to strings/null
// via observer service)
event;
notifyObservers(subject, type, data);
if (shimmed) {
notifyObservers(subject, type, data);
} else {
notifyObserversNoShim(subject, type, data);
}
}
exports.emit = emit;
@ -83,7 +92,7 @@ const Observer = Class({
const subscribers = ns();
function on(type, listener, strong) {
function on(type, listener, strong, shimmed = false) {
// Unless last optional argument is `true` we use a weak reference to a
// listener.
let weak = !strong;
@ -94,29 +103,34 @@ function on(type, listener, strong) {
if (!(type in observers)) {
let observer = Observer(listener);
observers[type] = observer;
addObserver(observer, type, weak);
if (shimmed) {
addObserver(observer, type, weak);
} else {
addObserverNoShim(observer, type, weak);
}
// WeakRef gymnastics to remove all alive observers on unload
let ref = Cu.getWeakReference(observer);
weakRefs.set(observer, ref);
stillAlive.set(ref, type);
wasShimmed.set(ref, shimmed);
}
}
exports.on = on;
function once(type, listener) {
function once(type, listener, shimmed = false) {
// Note: this code assumes order in which listeners are called, which is fine
// as long as dispatch happens in same order as listener registration which
// is the case now. That being said we should be aware that this may break
// in a future if order will change.
on(type, listener);
on(type, listener, shimmed);
on(type, function cleanup() {
off(type, listener);
off(type, cleanup);
}, true);
off(type, listener, shimmed);
off(type, cleanup, shimmed);
}, true, shimmed);
}
exports.once = once;
function off(type, listener) {
function off(type, listener, shimmed = false) {
// Take list of observers as with the given `listener`.
let observers = subscribers(listener);
// If `observer` for the given `type` is registered, then
@ -124,8 +138,13 @@ function off(type, listener) {
if (type in observers) {
let observer = observers[type];
delete observers[type];
removeObserver(observer, type);
if (shimmed) {
removeObserver(observer, type);
} else {
removeObserverNoShim(observer, type);
}
stillAlive.delete(weakRefs.get(observer));
wasShimmed.delete(weakRefs.get(observer));
}
}
exports.off = off;
@ -134,12 +153,14 @@ exports.off = off;
var weakRefs = new WeakMap();
// and we're out of beta, we're releasing on time!
var stillAlive = new Map();
var stillAlive = new Map();
var wasShimmed = new Map();
on('sdk:loader:destroy', function onunload({ subject, data: reason }) {
// using logic from ./unload, to avoid a circular module reference
if (subject.wrappedJSObject === unloadSubject) {
off('sdk:loader:destroy', onunload);
off('sdk:loader:destroy', onunload, false);
// don't bother
if (reason === 'shutdown')
@ -147,9 +168,14 @@ on('sdk:loader:destroy', function onunload({ subject, data: reason }) {
stillAlive.forEach( (type, ref) => {
let observer = ref.get();
if (observer)
removeObserver(observer, type);
if (observer) {
if (wasShimmed.get(ref)) {
removeObserver(observer, type);
} else {
removeObserverNoShim(observer, type);
}
}
})
}
// a strong reference
}, true);
}, true, false);

View File

@ -11,7 +11,7 @@ module.metadata = {
// NOTE: This file should only export Tab instances
const { getTabForContentWindow, getTabForBrowser: getRawTabForBrowser } = require('./utils');
const { getTabForBrowser: getRawTabForBrowser } = require('./utils');
const { modelFor } = require('../model/core');
exports.getTabForRawTab = modelFor;

View File

@ -11,10 +11,11 @@ module.metadata = {
// NOTE: This file should only deal with xul/native tabs
const { Ci } = require('chrome');
const { Ci, Cu } = require('chrome');
const { defer } = require("../lang/functional");
const { windows, isBrowser } = require('../window/utils');
const { isPrivateBrowsingSupported } = require('../self');
const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm");
// Bug 834961: ignore private windows when they are not supported
function getWindows() {
@ -262,6 +263,16 @@ function getTabForContentWindow(window) {
}
exports.getTabForContentWindow = getTabForContentWindow;
// only sdk/selection.js is relying on shims
function getTabForContentWindowNoShim(window) {
function getTabContentWindowNoShim(tab) {
let browser = getBrowserForTab(tab);
return ShimWaiver.getProperty(browser, "contentWindow");
}
return getTabs().find(tab => getTabContentWindowNoShim(tab) === window.top) || null;
}
exports.getTabForContentWindowNoShim = getTabForContentWindowNoShim;
function getTabURL(tab) {
return String(getBrowserForTab(tab).currentURI.spec);
}

View File

@ -238,7 +238,8 @@ const Sandbox = iced(function Sandbox(options) {
sandboxPrototype: 'prototype' in options ? options.prototype : {},
invisibleToDebugger: 'invisibleToDebugger' in options ?
options.invisibleToDebugger : false,
metadata: 'metadata' in options ? options.metadata : {}
metadata: 'metadata' in options ? options.metadata : {},
waiveIntereposition: !!options.waiveIntereposition
};
if (options.metadata && options.metadata.addonID) {
@ -791,7 +792,7 @@ Loader.unload = unload;
function Loader(options) {
let {
modules, globals, resolve, paths, rootURI, manifest, requireMap, isNative,
metadata, sharedGlobal, sharedGlobalBlacklist, checkCompatibility
metadata, sharedGlobal, sharedGlobalBlacklist, checkCompatibility, waiveIntereposition
} = override({
paths: {},
modules: {},
@ -811,7 +812,8 @@ function Loader(options) {
// Make the returned resolve function have the same signature
(id, requirer) => Loader.nodeResolve(id, requirer, { rootURI: rootURI }) :
Loader.resolve,
sharedGlobalBlacklist: ["sdk/indexed-db"]
sharedGlobalBlacklist: ["sdk/indexed-db"],
waiveIntereposition: false
}, options);
// Create overrides defaults, none at the moment

View File

@ -17,7 +17,7 @@
"preferences-service": "sdk/preferences/service",
"promise": "sdk/core/promise",
"system": "sdk/system",
"system/events": "sdk/system/events",
"system/events": "sdk/system/events-shimmed",
"tabs/tab": "sdk/tabs/tab",
"tabs/utils": "sdk/tabs/utils",
"timer": "sdk/timers",
@ -40,7 +40,7 @@
"app-strings": "sdk/deprecated/app-strings",
"environment": "sdk/system/environment",
"keyboard/utils": "sdk/keyboard/utils",
"dom/events": "sdk/dom/events",
"dom/events": "sdk/dom/events-shimmed",
"utils/data": "sdk/io/data",
"test/assert": "sdk/test/assert",
"hidden-frame": "sdk/frame/hidden-frame",

View File

@ -142,7 +142,7 @@ exports["test compatibility"] = function(assert) {
require("sdk/tabs/utils"), "sdk/tabs/utils -> tabs/utils");
assert.equal(require("dom/events"),
require("sdk/dom/events"), "sdk/dom/events -> dom/events");
require("sdk/dom/events-shimmed"), "sdk/dom/events-shimmed -> dom/events");
assert.equal(require("tabs/tab.js"),
require("sdk/tabs/tab"), "sdk/tabs/tab -> tabs/tab.js");

View File

@ -42,86 +42,6 @@ var close = function(tab) {
return promise;
}
exports["test multiple tabs"] = function(assert, done) {
let loader = Loader(module);
let { events } = loader.require("sdk/content/events");
let { on, off } = loader.require("sdk/event/core");
let actual = [];
on(events, "data", handler);
function handler ({type, target, timeStamp}) {
eventFilter(type, target, () => {
actual.push(type + " -> " + target.URL)
});
}
let window = getMostRecentBrowserWindow();
let firstTab = open("data:text/html,first-tab", window);
when("pageshow", firstTab).
then(close).
then(use(window)).
then(open("data:text/html,second-tab")).
then(when("pageshow")).
then(close).
then(function() {
assert.deepEqual(actual, [
"document-element-inserted -> data:text/html,first-tab",
"DOMContentLoaded -> data:text/html,first-tab",
"load -> data:text/html,first-tab",
"pageshow -> data:text/html,first-tab",
"document-element-inserted -> data:text/html,second-tab",
"DOMContentLoaded -> data:text/html,second-tab",
"load -> data:text/html,second-tab",
"pageshow -> data:text/html,second-tab"
], "all events dispatche as expeced")
}, function(reason) {
assert.fail(Error(reason));
}).then(function() {
loader.unload();
off(events, "data", handler);
done();
});
};
exports["test nested frames"] = function(assert, done) {
let loader = Loader(module);
let { events } = loader.require("sdk/content/events");
let { on, off } = loader.require("sdk/event/core");
let actual = [];
on(events, "data", handler);
function handler ({type, target, timeStamp}) {
eventFilter(type, target, () => {
actual.push(type + " -> " + target.URL)
});
}
let window = getMostRecentBrowserWindow();
let uri = encodeURI("data:text/html,<iframe src='data:text/html,iframe'>");
let tab = open(uri, window);
when("pageshow", tab).
then(close).
then(function() {
assert.deepEqual(actual, [
"document-element-inserted -> " + uri,
"DOMContentLoaded -> " + uri,
"document-element-inserted -> data:text/html,iframe",
"DOMContentLoaded -> data:text/html,iframe",
"load -> data:text/html,iframe",
"pageshow -> data:text/html,iframe",
"load -> " + uri,
"pageshow -> " + uri
], "events where dispatched")
}, function(reason) {
assert.fail(Error(reason))
}).then(function() {
loader.unload();
off(events, "data", handler);
done();
});
};
exports["test dead object errors"] = function(assert, done) {
let system = require("sdk/system/events");
let loader = Loader(module);

View File

@ -14,7 +14,7 @@ const { Panel } = require("dev/panel");
const { Class } = require("sdk/core/heritage");
const { openToolbox, closeToolbox, getCurrentPanel } = require("dev/utils");
const { MessageChannel } = require("sdk/messaging");
const { when } = require("sdk/dom/events");
const { when } = require("sdk/dom/events-shimmed");
const { viewFor } = require("sdk/view/core");
const { createView } = require("dev/panel/view");

View File

@ -12,16 +12,20 @@ const {when} = require("sdk/dom/events");
var observerService = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm");
const addObserver = ShimWaiver.getProperty(observerService, "addObserver");
const removeObserver = ShimWaiver.getProperty(observerService, "removeObserver");
const getActiveTab = (window=getMostRecentBrowserWindow()) =>
tabUtils.getActiveTab(window)
const openWindow = () => {
const window = open();
return new Promise((resolve) => {
observerService.addObserver({
addObserver({
observe(subject, topic) {
if (subject === window) {
observerService.removeObserver(this, topic);
removeObserver(this, topic);
resolve(subject);
}
}

View File

@ -1025,7 +1025,6 @@ pref("apz.fling_curve_function_x2", "0.80");
pref("apz.fling_curve_function_y2", "1.0");
pref("apz.fling_curve_threshold_inches_per_ms", "0.01");
pref("apz.fling_friction", "0.0019");
pref("apz.fling_snap_friction", "0.015");
pref("apz.max_velocity_inches_per_ms", "0.07");
pref("apz.touch_start_tolerance", "0.1");

View File

@ -104,7 +104,6 @@ skip-if = e10s
[browser_sessionHistory.js]
[browser_sessionStorage.js]
[browser_swapDocShells.js]
skip-if = e10s # See bug 918634
[browser_switch_remoteness.js]
run-if = e10s
[browser_upgrade_backup.js]

View File

@ -47,60 +47,40 @@ support-files =
[browser_bug1206879.js]
[browser_bug134911.js]
skip-if = e10s # Bug ?????? - BrowserSetForcedCharacterSet() in browser.js references docShell
[browser_bug234628-1.js]
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_bug234628-10.js]
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_bug234628-11.js]
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_bug234628-2.js]
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_bug234628-3.js]
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_bug234628-4.js]
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_bug234628-5.js]
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_bug234628-6.js]
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_bug234628-7.js]
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_bug234628-8.js]
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_bug234628-9.js]
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_bug349769.js]
skip-if = e10s # Bug ?????? - test touches content (newBrowser.contentDocument.nodePrincipal)
[browser_bug388121-1.js]
skip-if = e10s # Bug ?????? - test touches content (newBrowser.contentDocument.nodePrincipal)
[browser_bug388121-2.js]
skip-if = e10s # Bug ?????? - test touches content (newBrowser.contentDocument.nodePrincipal)
[browser_bug420605.js]
skip-if = e10s # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly
[browser_bug422543.js]
skip-if = e10s # Bug ?????? - obscure test failures (shistory has a new entry - Got initial, expected newentry)
skip-if = e10s # Bug 1220927 - Test tries to do addSHistoryListener on content.
[browser_bug441169.js]
skip-if = buildapp == 'mulet'
[browser_bug503832.js]
skip-if = buildapp == 'mulet'
[browser_bug554155.js]
[browser_bug655270.js]
skip-if = e10s # Bug ?????? - PlacesUtils.history.addObserver notifications don't seem to fire
[browser_bug655273.js]
[browser_bug670318.js]
skip-if = e10s # Bug 916974 - browser.sessionHistory is null
skip-if = e10s # Bug 1220927 - Test tries to do addSHistoryListener on content.
[browser_bug673467.js]
skip-if = e10s # Bug ?????? - test touches content (adds event listener to content document's iframe)
[browser_bug852909.js]
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_bug92473.js]
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_uriFixupIntegration.js]
[browser_loadDisallowInherit.js]
skip-if = e10s
[browser_loadURI.js]
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_multiple_pushState.js]
[browser_onbeforeunload_navigation.js]
skip-if = e10s

View File

@ -13,7 +13,7 @@ function image(event) {
}
gBrowser.selectedBrowser.removeEventListener("load", image, true);
ok(!gBrowser.docShell.mayEnableCharacterEncodingMenu, "Docshell should say the menu should be disabled for images.");
ok(!gBrowser.selectedTab.mayEnableCharacterEncodingMenu, "Docshell should say the menu should be disabled for images.");
gBrowser.removeCurrentTab();
gBrowser.selectedTab = gBrowser.addTab(rootDir + "file_bug852909.pdf");
@ -26,7 +26,7 @@ function pdf(event) {
}
gBrowser.selectedBrowser.removeEventListener("load", pdf, true);
ok(!gBrowser.docShell.mayEnableCharacterEncodingMenu, "Docshell should say the menu should be disabled for PDF.js.");
ok(!gBrowser.selectedTab.mayEnableCharacterEncodingMenu, "Docshell should say the menu should be disabled for PDF.js.");
gBrowser.removeCurrentTab();
finish();

View File

@ -18,7 +18,7 @@ function f2(stdlib, foreign, buffer) {
}
if (this.jsFuns)
ok(jsFuns.isAsmJSModule(f2), "f2 is an asm.js module");
var i32 = new Int32Array(1024);
var i32 = new Int32Array(16384); // Smallest allowed buffer size is 64KBy
for (var i = 0; i < i32.length; i++)
i32[i] = i;
var f2Main = f2(this, null, i32.buffer);

View File

@ -332,13 +332,6 @@ nsIdentifierMapEntry::RemoveContentChangeCallback(nsIDocument::IDTargetObserver
}
}
// XXX Workaround for bug 980560 to maintain the existing broken semantics
template<>
struct nsIStyleRule::COMTypeInfo<css::Rule, void> {
static const nsIID kIID;
};
const nsIID nsIStyleRule::COMTypeInfo<css::Rule, void>::kIID = NS_ISTYLE_RULE_IID;
namespace mozilla {
namespace dom {
@ -2499,11 +2492,6 @@ nsDocument::FillStyleSet(nsStyleSet* aStyleSet)
NS_PRECONDITION(aStyleSet->SheetCount(SheetType::Doc) == 0,
"Style set already has document sheets?");
// We could consider moving this to nsStyleSet::Init, to match its
// handling of the eAnimationSheet and eTransitionSheet levels.
aStyleSet->DirtyRuleProcessors(SheetType::PresHint);
aStyleSet->DirtyRuleProcessors(SheetType::StyleAttr);
int32_t i;
for (i = mStyleSheets.Count() - 1; i >= 0; --i) {
nsIStyleSheet* sheet = mStyleSheets[i];
@ -5241,51 +5229,51 @@ nsDocument::DocumentStatesChanged(EventStates aStateMask)
void
nsDocument::StyleRuleChanged(nsIStyleSheet* aSheet,
nsIStyleRule* aOldStyleRule,
nsIStyleRule* aNewStyleRule)
css::Rule* aOldStyleRule,
css::Rule* aNewStyleRule)
{
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleChanged,
(this, aSheet,
aOldStyleRule, aNewStyleRule));
if (StyleSheetChangeEventsEnabled()) {
nsCOMPtr<css::Rule> rule = do_QueryInterface(aNewStyleRule);
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
"StyleRuleChanged",
mRule,
rule ? rule->GetDOMRule() : nullptr);
aNewStyleRule ? aNewStyleRule->GetDOMRule()
: nullptr);
}
}
void
nsDocument::StyleRuleAdded(nsIStyleSheet* aSheet,
nsIStyleRule* aStyleRule)
css::Rule* aStyleRule)
{
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleAdded,
(this, aSheet, aStyleRule));
if (StyleSheetChangeEventsEnabled()) {
nsCOMPtr<css::Rule> rule = do_QueryInterface(aStyleRule);
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
"StyleRuleAdded",
mRule,
rule ? rule->GetDOMRule() : nullptr);
aStyleRule ? aStyleRule->GetDOMRule()
: nullptr);
}
}
void
nsDocument::StyleRuleRemoved(nsIStyleSheet* aSheet,
nsIStyleRule* aStyleRule)
css::Rule* aStyleRule)
{
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleRemoved,
(this, aSheet, aStyleRule));
if (StyleSheetChangeEventsEnabled()) {
nsCOMPtr<css::Rule> rule = do_QueryInterface(aStyleRule);
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
"StyleRuleRemoved",
mRule,
rule ? rule->GetDOMRule() : nullptr);
aStyleRule ? aStyleRule->GetDOMRule()
: nullptr);
}
}

View File

@ -900,12 +900,12 @@ public:
mozilla::EventStates aStateMask) override;
virtual void StyleRuleChanged(nsIStyleSheet* aStyleSheet,
nsIStyleRule* aOldStyleRule,
nsIStyleRule* aNewStyleRule) override;
mozilla::css::Rule* aOldStyleRule,
mozilla::css::Rule* aNewStyleRule) override;
virtual void StyleRuleAdded(nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) override;
mozilla::css::Rule* aStyleRule) override;
virtual void StyleRuleRemoved(nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) override;
mozilla::css::Rule* aStyleRule) override;
virtual void FlushPendingNotifications(mozFlushType aType) override;
virtual void FlushExternalResources(mozFlushType aType) override;

View File

@ -51,6 +51,7 @@
#include "mozilla/dom/EncodingUtils.h"
#include "nsContainerFrame.h"
#include "nsBlockFrame.h"
#include "nsComputedDOMStyle.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -1428,10 +1429,6 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
return NS_ERROR_NULL_POINTER;
range->GetCommonAncestorContainer(getter_AddRefs(commonParent));
// Thunderbird's msg compose code abuses the HTML copy encoder and gets
// confused if mIsTextWidget ends up becoming true, so for now we skip
// this logic in Thunderbird.
#ifndef MOZ_THUNDERBIRD
for (nsCOMPtr<nsIContent> selContent(do_QueryInterface(commonParent));
selContent;
selContent = selContent->GetParent())
@ -1442,6 +1439,20 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
mIsTextWidget = true;
break;
}
#ifdef MOZ_THUNDERBIRD
else if (selContent->IsElement()) {
nsRefPtr<nsStyleContext> styleContext =
nsComputedDOMStyle::GetStyleContextForElementNoFlush(
selContent->AsElement(), nullptr, nullptr);
if (styleContext) {
const nsStyleText* textStyle = styleContext->StyleText();
if (textStyle->mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP) {
mIsTextWidget = true;
}
}
}
break;
#endif
}
// normalize selection if we are not in a widget
@ -1451,7 +1462,6 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
mMimeType.AssignLiteral("text/plain");
return NS_OK;
}
#endif
// also consider ourselves in a text widget if we can't find an html document
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);

View File

@ -72,7 +72,6 @@ class nsIRequest;
class nsIRunnable;
class nsIStreamListener;
class nsIStructuredCloneContainer;
class nsIStyleRule;
class nsIStyleSheet;
class nsIURI;
class nsIVariant;
@ -101,6 +100,7 @@ template<typename> class OwningNonNull;
namespace css {
class Loader;
class ImageLoader;
class Rule;
} // namespace css
namespace gfx {
@ -156,8 +156,8 @@ typedef CallbackObjectHolder<NodeFilter, nsIDOMNodeFilter> NodeFilterHolder;
} // namespace mozilla
#define NS_IDOCUMENT_IID \
{ 0x5f51e18c, 0x9e0e, 0x4dc0, \
{ 0x9f, 0x08, 0x7a, 0x32, 0x65, 0x52, 0xea, 0x11 } }
{ 0x4307abe8, 0x5386, 0x4024, \
{ 0xa2, 0xfe, 0x4a, 0x80, 0xe8, 0x47, 0x46, 0x90 } }
// Enum for requesting a particular type of document when creating a doc
enum DocumentFlavor {
@ -1273,12 +1273,12 @@ public:
// Observation hooks for style data to propagate notifications
// to document observers
virtual void StyleRuleChanged(nsIStyleSheet* aStyleSheet,
nsIStyleRule* aOldStyleRule,
nsIStyleRule* aNewStyleRule) = 0;
mozilla::css::Rule* aOldStyleRule,
mozilla::css::Rule* aNewStyleRule) = 0;
virtual void StyleRuleAdded(nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) = 0;
mozilla::css::Rule* aStyleRule) = 0;
virtual void StyleRuleRemoved(nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) = 0;
mozilla::css::Rule* aStyleRule) = 0;
/**
* Flush notifications for this document and its parent documents

View File

@ -12,12 +12,17 @@
class nsIContent;
class nsIStyleSheet;
class nsIStyleRule;
class nsIDocument;
namespace mozilla {
namespace css {
class Rule;
} // namespace css
} // namespace mozilla
#define NS_IDOCUMENT_OBSERVER_IID \
{ 0x900bc4bc, 0x8b6c, 0x4cba, \
{ 0x82, 0xfa, 0x56, 0x8a, 0x80, 0xff, 0xfd, 0x3e } }
{ 0xce1d53d0, 0x4739, 0x44e5, \
{ 0xb4, 0xae, 0x60, 0xe8, 0x82, 0xcb, 0x73, 0x1b } }
typedef uint32_t nsUpdateType;
@ -156,8 +161,8 @@ public:
*/
virtual void StyleRuleChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aOldStyleRule,
nsIStyleRule* aNewStyleRule) = 0;
mozilla::css::Rule* aOldStyleRule,
mozilla::css::Rule* aNewStyleRule) = 0;
/**
* A StyleRule has just been added to a style sheet.
@ -172,7 +177,7 @@ public:
*/
virtual void StyleRuleAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) = 0;
mozilla::css::Rule* aStyleRule) = 0;
/**
* A StyleRule has just been removed from a style sheet.
@ -187,7 +192,7 @@ public:
*/
virtual void StyleRuleRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) = 0;
mozilla::css::Rule* aStyleRule) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID)
@ -232,18 +237,18 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID)
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULECHANGED \
virtual void StyleRuleChanged(nsIDocument* aDocument, \
nsIStyleSheet* aStyleSheet, \
nsIStyleRule* aOldStyleRule, \
nsIStyleRule* aNewStyleRule) override;
mozilla::css::Rule* aOldStyleRule, \
mozilla::css::Rule* aNewStyleRule) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEADDED \
virtual void StyleRuleAdded(nsIDocument* aDocument, \
nsIStyleSheet* aStyleSheet, \
nsIStyleRule* aStyleRule) override;
mozilla::css::Rule* aStyleRule) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEREMOVED \
virtual void StyleRuleRemoved(nsIDocument* aDocument, \
nsIStyleSheet* aStyleSheet, \
nsIStyleRule* aStyleRule) override;
mozilla::css::Rule* aStyleRule) override;
#define NS_DECL_NSIDOCUMENTOBSERVER \
NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE \
@ -321,20 +326,20 @@ _class::StyleSheetApplicableStateChanged(nsIDocument* aDocument, \
void \
_class::StyleRuleChanged(nsIDocument* aDocument, \
nsIStyleSheet* aStyleSheet, \
nsIStyleRule* aOldStyleRule, \
nsIStyleRule* aNewStyleRule) \
mozilla::css::Rule* aOldStyleRule, \
mozilla::css::Rule* aNewStyleRule) \
{ \
} \
void \
_class::StyleRuleAdded(nsIDocument* aDocument, \
nsIStyleSheet* aStyleSheet, \
nsIStyleRule* aStyleRule) \
mozilla::css::Rule* aStyleRule) \
{ \
} \
void \
_class::StyleRuleRemoved(nsIDocument* aDocument, \
nsIStyleSheet* aStyleSheet, \
nsIStyleRule* aStyleRule) \
mozilla::css::Rule* aStyleRule) \
{ \
}

View File

@ -22,6 +22,7 @@
#include "mozilla/MemoryReporting.h"
#include "mozilla/Telemetry.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/css/StyleRule.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/ShadowRoot.h"

View File

@ -24,5 +24,5 @@ skip-if = e10s # this tests non-e10s behavior. it's not expected to work in e10s
# skip-if = e10s # Bug ?????? - content-document-* notifications come while document's URI is still about:blank, but test expects real URL.
skip-if = true # Intermittent failures - bug 987493. Restore the skip-if above once fixed
[browser_bug1058164.js]
skip-if = e10s # We need bug 918634 to land before this can be tested with e10s.
skip-if = e10s # Bug 1220752.
[browser_use_counters.js]

View File

@ -802,7 +802,6 @@ skip-if = buildapp == 'b2g' || toolkit == 'android'
[test_websocket_permessage_deflate.html]
skip-if = buildapp == 'b2g' || toolkit == 'android'
[test_x-frame-options.html]
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # b2g(observerservice issue) b2g-debug(observerservice issue) b2g-desktop(observerservice issue)
[test_xbl_userdata.xhtml]
[test_xhr_abort_after_load.html]
skip-if = toolkit == 'android'

View File

@ -14,38 +14,6 @@
<iframe style="width:100%;height:300px;" id="harness"></iframe>
<script class="testbody" type="text/javascript">
function examiner() {
SpecialPowers.addObserver(this, "http-on-examine-response", false);
}
examiner.prototype = {
observe: function(subject, topic, data) {
subject = SpecialPowers.wrap(subject);
if(!subject.QueryInterface)
return;
if (topic == "http-on-examine-response") {
var chan = subject.QueryInterface(SpecialPowers.Ci.nsIHttpChannel);
var uri = chan.URI
if (!uri.path.match(/^\/tests\/content\/base\/test\/file_x-frame-options_page\.sjs/))
return;
dump(">>>> PATH: "+uri.path+"\n");
dump(">>> REQUEST:\n>>> "+chan.requestMethod+" "+uri.asciiSpec+"\n");
dump(">>> RESPONSE HEADERS:\n");
chan.visitResponseHeaders({
visitHeader: function(header, value) {
dump(">>> "+header+": "+value+"\n");
}
});
}
},
remove: function() {
SpecialPowers.removeObserver(this, "http-on-examine-response");
}
}
window.examiner = new examiner();
var path = "/tests/dom/base/test/";
var testFramesLoaded = function() {
@ -171,8 +139,6 @@ var testFrameInDataURI = function() {
ok(test != null, "frame under data: URL should have loaded.");
win.close();
// finalize test
window.examiner.remove();
SimpleTest.finish();
}
win.location.href = "data:text/html,"+html;

View File

@ -2135,8 +2135,8 @@ CanvasRenderingContext2D::SetShadowColor(const nsAString& shadowColor)
// filters
//
static already_AddRefed<StyleRule>
CreateStyleRule(nsINode* aNode,
static already_AddRefed<Declaration>
CreateDeclaration(nsINode* aNode,
const nsCSSProperty aProp1, const nsAString& aValue1, bool* aChanged1,
const nsCSSProperty aProp2, const nsAString& aValue2, bool* aChanged2,
ErrorResult& error)
@ -2169,19 +2169,19 @@ CreateStyleRule(nsINode* aNode,
rule->GetDeclaration(), aChanged2, false);
}
rule->RuleMatched();
return rule.forget();
RefPtr<Declaration> declaration = rule->GetDeclaration();
declaration->SetImmutable();
return declaration.forget();
}
static already_AddRefed<StyleRule>
CreateFontStyleRule(const nsAString& aFont,
nsINode* aNode,
bool* aOutFontChanged,
ErrorResult& error)
static already_AddRefed<Declaration>
CreateFontDeclaration(const nsAString& aFont,
nsINode* aNode,
bool* aOutFontChanged,
ErrorResult& error)
{
bool lineHeightChanged;
return CreateStyleRule(aNode,
return CreateDeclaration(aNode,
eCSSProperty_font, aFont, aOutFontChanged,
eCSSProperty_line_height, NS_LITERAL_STRING("normal"), &lineHeightChanged,
error);
@ -2205,9 +2205,9 @@ GetFontParentStyleContext(Element* aElement, nsIPresShell* presShell,
// otherwise inherit from default (10px sans-serif)
bool changed;
RefPtr<css::StyleRule> parentRule =
CreateFontStyleRule(NS_LITERAL_STRING("10px sans-serif"),
presShell->GetDocument(), &changed, error);
RefPtr<css::Declaration> parentRule =
CreateFontDeclaration(NS_LITERAL_STRING("10px sans-serif"),
presShell->GetDocument(), &changed, error);
if (error.Failed()) {
return nullptr;
@ -2226,13 +2226,12 @@ GetFontParentStyleContext(Element* aElement, nsIPresShell* presShell,
}
static bool
PropertyIsInheritOrInitial(StyleRule* aRule, const nsCSSProperty aProperty)
PropertyIsInheritOrInitial(Declaration* aDeclaration, const nsCSSProperty aProperty)
{
css::Declaration* declaration = aRule->GetDeclaration();
// We know the declaration is not !important, so we can use
// GetNormalBlock().
const nsCSSValue* filterVal =
declaration->GetNormalBlock()->ValueFor(aProperty);
aDeclaration->GetNormalBlock()->ValueFor(aProperty);
return (!filterVal || (filterVal->GetUnit() == eCSSUnit_Unset ||
filterVal->GetUnit() == eCSSUnit_Inherit ||
filterVal->GetUnit() == eCSSUnit_Initial));
@ -2245,9 +2244,9 @@ GetFontStyleContext(Element* aElement, const nsAString& aFont,
ErrorResult& error)
{
bool fontParsedSuccessfully = false;
RefPtr<css::StyleRule> rule =
CreateFontStyleRule(aFont, presShell->GetDocument(),
&fontParsedSuccessfully, error);
RefPtr<css::Declaration> decl =
CreateFontDeclaration(aFont, presShell->GetDocument(),
&fontParsedSuccessfully, error);
if (error.Failed()) {
return nullptr;
@ -2262,7 +2261,7 @@ GetFontStyleContext(Element* aElement, const nsAString& aFont,
// 'inherit' and 'initial'. The easiest way to check for this is to look
// at font-size-adjust, which the font shorthand resets to either 'none' or
// '-moz-system-font'.
if (PropertyIsInheritOrInitial(rule, eCSSProperty_font_size_adjust)) {
if (PropertyIsInheritOrInitial(decl, eCSSProperty_font_size_adjust)) {
return nullptr;
}
@ -2283,7 +2282,7 @@ GetFontStyleContext(Element* aElement, const nsAString& aFont,
"GetFontParentStyleContext should have returned an error if the presshell is being destroyed.");
nsTArray<nsCOMPtr<nsIStyleRule>> rules;
rules.AppendElement(rule);
rules.AppendElement(decl);
// add a rule to prevent text zoom from affecting the style
rules.AppendElement(new nsDisableTextZoomStyleRule);
@ -2295,34 +2294,34 @@ GetFontStyleContext(Element* aElement, const nsAString& aFont,
// parsed (including having line-height removed). (Older drafts of
// the spec required font sizes be converted to pixels, but that no
// longer seems to be required.)
rule->GetDeclaration()->GetValue(eCSSProperty_font, aOutUsedFont);
decl->GetValue(eCSSProperty_font, aOutUsedFont);
return sc.forget();
}
static already_AddRefed<StyleRule>
CreateFilterStyleRule(const nsAString& aFilter,
nsINode* aNode,
bool* aOutFilterChanged,
ErrorResult& error)
static already_AddRefed<Declaration>
CreateFilterDeclaration(const nsAString& aFilter,
nsINode* aNode,
bool* aOutFilterChanged,
ErrorResult& error)
{
bool dummy;
return CreateStyleRule(aNode,
return CreateDeclaration(aNode,
eCSSProperty_filter, aFilter, aOutFilterChanged,
eCSSProperty_UNKNOWN, EmptyString(), &dummy,
error);
}
static already_AddRefed<nsStyleContext>
ResolveStyleForFilterRule(const nsAString& aFilterString,
nsIPresShell* aPresShell,
nsStyleContext* aParentContext,
ErrorResult& error)
ResolveStyleForFilter(const nsAString& aFilterString,
nsIPresShell* aPresShell,
nsStyleContext* aParentContext,
ErrorResult& error)
{
nsIDocument* document = aPresShell->GetDocument();
bool filterChanged = false;
RefPtr<css::StyleRule> rule =
CreateFilterStyleRule(aFilterString, document, &filterChanged, error);
RefPtr<css::Declaration> decl =
CreateFilterDeclaration(aFilterString, document, &filterChanged, error);
if (error.Failed()) {
return nullptr;
@ -2335,12 +2334,12 @@ ResolveStyleForFilterRule(const nsAString& aFilterString,
// In addition to unparseable values, the spec says we need to reject
// 'inherit' and 'initial'.
if (PropertyIsInheritOrInitial(rule, eCSSProperty_filter)) {
if (PropertyIsInheritOrInitial(decl, eCSSProperty_filter)) {
return nullptr;
}
nsTArray<nsCOMPtr<nsIStyleRule>> rules;
rules.AppendElement(rule);
rules.AppendElement(decl);
RefPtr<nsStyleContext> sc =
aPresShell->StyleSet()->ResolveStyleForRules(aParentContext, rules);
@ -2375,7 +2374,7 @@ CanvasRenderingContext2D::ParseFilter(const nsAString& aString,
}
RefPtr<nsStyleContext> sc =
ResolveStyleForFilterRule(aString, presShell, parentContext, error);
ResolveStyleForFilter(aString, presShell, parentContext, error);
if (!sc) {
return false;

View File

@ -1,5 +1,5 @@
[DEFAULT]
skip-if = (buildapp != "browser") || e10s
skip-if = (buildapp != "browser")
support-files =
head.js
browser_forgetThisSiteAdd.html
@ -16,6 +16,7 @@ support-files =
[browser_forgetThisSite.js]
[browser_permissionsPromptAllow.js]
[browser_permissionsPromptDeny.js]
skip-if = e10s # bug 1220748 - Attempts to touch content docshell to set usePrivateBrowsing.
[browser_permissionsPromptWorker.js]
[browser_perwindow_privateBrowsing.js]
[browser_bug839193.js]

View File

@ -21,17 +21,24 @@ interface nsIServiceWorkerUnregisterCallback : nsISupports
void unregisterFailed();
};
[scriptable, builtinclass, uuid(f222dcad-3081-4699-bbc6-5615e20749C8)]
[scriptable, builtinclass, uuid(1a1e71dd-0f78-4e2e-a2db-a946fe02cddf)]
interface nsIServiceWorkerInfo : nsISupports
{
readonly attribute DOMString scriptSpec;
readonly attribute DOMString cacheName;
};
[scriptable, builtinclass, uuid(e908bc07-0a4c-443f-a546-2109bf1f4A01)]
interface nsIServiceWorkerRegistrationInfo : nsISupports
{
readonly attribute nsIPrincipal principal;
readonly attribute DOMString scope;
readonly attribute DOMString scriptSpec;
readonly attribute DOMString currentWorkerURL;
readonly attribute DOMString activeCacheName;
readonly attribute DOMString waitingCacheName;
readonly attribute nsIServiceWorkerInfo installingWorker;
readonly attribute nsIServiceWorkerInfo waitingWorker;
readonly attribute nsIServiceWorkerInfo activeWorker;
};
[scriptable, uuid(9e523e7c-ad6f-4df0-8077-c74aebbc679d)]

View File

@ -2417,6 +2417,7 @@ MediaInputPort::Init()
void
MediaInputPort::Disconnect()
{
GraphImpl()->AssertOnGraphThreadOrNotRunning();
NS_ASSERTION(!mSource == !mDest,
"mSource must either both be null or both non-null");
if (!mSource)

View File

@ -557,7 +557,6 @@ AudioDestinationNode::WindowAudioCaptureChanged()
mCaptureStreamPort =
mStream->Graph()->ConnectToCaptureStream(id, mStream);
} else {
mCaptureStreamPort->Disconnect();
mCaptureStreamPort->Destroy();
}
mCaptured = captured;

View File

@ -260,6 +260,13 @@ DOMSVGLengthList::InsertItemBefore(DOMSVGLength& newItem,
error.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
if (AnimListMirrorsBaseList()) {
if (!mAList->mAnimVal->mItems.SetCapacity(
mAList->mAnimVal->mItems.Length() + 1, fallible)) {
error.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
}
AutoChangeLengthListNotifier notifier(this);
// Now that we know we're inserting, keep animVal list in sync as necessary.

View File

@ -244,6 +244,13 @@ DOMSVGNumberList::InsertItemBefore(DOMSVGNumber& aItem,
error.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
if (AnimListMirrorsBaseList()) {
if (!mAList->mAnimVal->mItems.SetCapacity(
mAList->mAnimVal->mItems.Length() + 1, fallible)) {
error.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
}
AutoChangeNumberListNotifier notifier(this);
// Now that we know we're inserting, keep animVal list in sync as necessary.

View File

@ -382,6 +382,15 @@ DOMSVGPathSegList::InsertItemBefore(DOMSVGPathSeg& aNewItem,
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
if (AnimListMirrorsBaseList()) {
DOMSVGPathSegList *animVal =
GetDOMWrapperIfExists(InternalAList().GetAnimValKey());
if (!animVal->mItems.SetCapacity(
animVal->mItems.Length() + 1, fallible)) {
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
}
AutoChangePathSegListNotifier notifier(this);
// Now that we know we're inserting, keep animVal list in sync as necessary.

View File

@ -318,6 +318,15 @@ DOMSVGPointList::InsertItemBefore(nsISVGPoint& aNewItem, uint32_t aIndex,
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
if (AnimListMirrorsBaseList()) {
DOMSVGPointList *animVal =
GetDOMWrapperIfExists(InternalAList().GetAnimValKey());
if (!animVal->mItems.SetCapacity(
animVal->mItems.Length() + 1, fallible)) {
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
}
AutoChangePointListNotifier notifier(this);
// Now that we know we're inserting, keep animVal list in sync as necessary.

View File

@ -252,6 +252,13 @@ DOMSVGTransformList::InsertItemBefore(SVGTransform& newItem,
error.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
if (AnimListMirrorsBaseList()) {
if (!mAList->mAnimVal->mItems.SetCapacity(
mAList->mAnimVal->mItems.Length() + 1, fallible)) {
error.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
}
AutoChangeTransformListNotifier notifier(this);
// Now that we know we're inserting, keep animVal list in sync as necessary.

View File

@ -903,8 +903,9 @@ nsSVGElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
UpdateContentStyleRule();
if (mContentStyleRule) {
mContentStyleRule->RuleMatched();
aRuleWalker->Forward(mContentStyleRule);
css::Declaration* declaration = mContentStyleRule->GetDeclaration();
declaration->SetImmutable();
aRuleWalker->Forward(declaration);
}
return NS_OK;
@ -927,8 +928,9 @@ nsSVGElement::WalkAnimatedContentStyleRules(nsRuleWalker* aRuleWalker)
animContentStyleRule = GetAnimatedContentStyleRule();
}
if (animContentStyleRule) {
animContentStyleRule->RuleMatched();
aRuleWalker->Forward(animContentStyleRule);
css::Declaration* declaration = animContentStyleRule->GetDeclaration();
declaration->SetImmutable();
aRuleWalker->Forward(declaration);
}
}
}

View File

@ -213,10 +213,8 @@ ServiceWorkerContainer::Register(const nsAString& aScriptURL,
// The spec says that the "client" passed to Register() must be the global
// where the ServiceWorkerContainer was retrieved from.
nsCOMPtr<nsPIDOMWindow> window = GetOwner();
MOZ_ASSERT(window);
aRv = swm->Register(window, scopeURI, scriptURI, getter_AddRefs(promise));
if (aRv.Failed()) {
aRv = swm->Register(GetOwner(), scopeURI, scriptURI, getter_AddRefs(promise));
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
@ -328,7 +326,19 @@ ServiceWorkerContainer::GetScopeForUrl(const nsAString& aUrl,
return;
}
aRv = swm->GetScopeForUrl(GetOwner()->GetExtantDoc()->NodePrincipal(),
nsCOMPtr<nsPIDOMWindow> window = GetOwner();
if (NS_WARN_IF(!window)) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
if (NS_WARN_IF(!doc)) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
aRv = swm->GetScopeForUrl(doc->NodePrincipal(),
aUrl, aScope);
}

View File

@ -409,32 +409,29 @@ ServiceWorkerRegistrationInfo::GetScriptSpec(nsAString& aScriptSpec)
}
NS_IMETHODIMP
ServiceWorkerRegistrationInfo::GetCurrentWorkerURL(nsAString& aCurrentWorkerURL)
ServiceWorkerRegistrationInfo::GetInstallingWorker(nsIServiceWorkerInfo **aResult)
{
AssertIsOnMainThread();
if (mActiveWorker) {
CopyUTF8toUTF16(mActiveWorker->ScriptSpec(), aCurrentWorkerURL);
}
nsCOMPtr<nsIServiceWorkerInfo> info = do_QueryInterface(mInstallingWorker);
info.forget(aResult);
return NS_OK;
}
NS_IMETHODIMP
ServiceWorkerRegistrationInfo::GetActiveCacheName(nsAString& aActiveCacheName)
ServiceWorkerRegistrationInfo::GetWaitingWorker(nsIServiceWorkerInfo **aResult)
{
AssertIsOnMainThread();
if (mActiveWorker) {
aActiveCacheName = mActiveWorker->CacheName();
}
nsCOMPtr<nsIServiceWorkerInfo> info = do_QueryInterface(mWaitingWorker);
info.forget(aResult);
return NS_OK;
}
NS_IMETHODIMP
ServiceWorkerRegistrationInfo::GetWaitingCacheName(nsAString& aWaitingCacheName)
ServiceWorkerRegistrationInfo::GetActiveWorker(nsIServiceWorkerInfo **aResult)
{
AssertIsOnMainThread();
if (mWaitingWorker) {
aWaitingCacheName = mWaitingWorker->CacheName();
}
nsCOMPtr<nsIServiceWorkerInfo> info = do_QueryInterface(mActiveWorker);
info.forget(aResult);
return NS_OK;
}
@ -1470,7 +1467,9 @@ ServiceWorkerManager::Register(nsIDOMWindow* aWindow,
AssertIsOnMainThread();
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
MOZ_ASSERT(window);
if (NS_WARN_IF(!window)) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
if (!doc) {
@ -1775,14 +1774,15 @@ ServiceWorkerManager::GetRegistrations(nsIDOMWindow* aWindow,
nsISupports** aPromise)
{
AssertIsOnMainThread();
MOZ_ASSERT(aWindow);
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
MOZ_ASSERT(window);
if (NS_WARN_IF(!window)) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
if (!doc) {
return NS_ERROR_FAILURE;
if (NS_WARN_IF(!doc)) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
// Don't allow service workers to register when the *document* is chrome for
@ -1879,14 +1879,15 @@ ServiceWorkerManager::GetRegistration(nsIDOMWindow* aWindow,
nsISupports** aPromise)
{
AssertIsOnMainThread();
MOZ_ASSERT(aWindow);
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
MOZ_ASSERT(window);
if (NS_WARN_IF(!window)) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
if (!doc) {
return NS_ERROR_FAILURE;
if (NS_WARN_IF(!doc)) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
// Don't allow service workers to register when the *document* is chrome for
@ -2032,13 +2033,14 @@ ServiceWorkerManager::GetReadyPromise(nsIDOMWindow* aWindow,
nsISupports** aPromise)
{
AssertIsOnMainThread();
MOZ_ASSERT(aWindow);
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
MOZ_ASSERT(window);
if (NS_WARN_IF(!window)) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
if (!doc) {
if (NS_WARN_IF(!doc)) {
return NS_ERROR_FAILURE;
}
@ -2977,7 +2979,7 @@ ServiceWorkerManager::GetServiceWorkerForScope(nsIDOMWindow* aWindow,
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
if (NS_WARN_IF(!window)) {
return NS_ERROR_FAILURE;
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
@ -3242,7 +3244,7 @@ ServiceWorkerManager::GetDocumentController(nsIDOMWindow* aWindow,
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
MOZ_ASSERT(window);
if (!window || !window->GetExtantDoc()) {
return NS_ERROR_FAILURE;
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
@ -4052,6 +4054,24 @@ ServiceWorkerManager::NotifyListenersOnUnregister(
}
}
NS_IMPL_ISUPPORTS(ServiceWorkerInfo, nsIServiceWorkerInfo)
NS_IMETHODIMP
ServiceWorkerInfo::GetScriptSpec(nsAString& aScriptSpec)
{
AssertIsOnMainThread();
CopyUTF8toUTF16(mScriptSpec, aScriptSpec);
return NS_OK;
}
NS_IMETHODIMP
ServiceWorkerInfo::GetCacheName(nsAString& aCacheName)
{
AssertIsOnMainThread();
aCacheName = mCacheName;
return NS_OK;
}
void
ServiceWorkerInfo::AppendWorker(ServiceWorker* aWorker)
{

View File

@ -168,7 +168,7 @@ public:
* _GetNewestWorker(serviceWorkerRegistration)", we represent the description
* by this class and spawn a ServiceWorker in the right global when required.
*/
class ServiceWorkerInfo final
class ServiceWorkerInfo final : public nsIServiceWorkerInfo
{
private:
const ServiceWorkerRegistrationInfo* mRegistration;
@ -197,7 +197,8 @@ private:
GetNextID() const;
public:
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerInfo)
NS_DECL_ISUPPORTS
NS_DECL_NSISERVICEWORKERINFO
class ServiceWorkerPrivate*
WorkerPrivate() const

View File

@ -689,7 +689,6 @@ ServiceWorkerRegistrationMainThread::ShowNotification(JSContext* aCx,
ErrorResult& aRv)
{
AssertIsOnMainThread();
MOZ_ASSERT(GetOwner());
nsCOMPtr<nsPIDOMWindow> window = GetOwner();
if (NS_WARN_IF(!window)) {
aRv.Throw(NS_ERROR_FAILURE);
@ -724,6 +723,10 @@ ServiceWorkerRegistrationMainThread::GetNotifications(const GetNotificationOptio
{
AssertIsOnMainThread();
nsCOMPtr<nsPIDOMWindow> window = GetOwner();
if (NS_WARN_IF(!window)) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
return Notification::Get(window, aOptions, mScope, aRv);
}

View File

@ -2347,7 +2347,7 @@ void AsyncPanZoomController::AcceptFling(ParentLayerPoint& aVelocity,
aOverscrollHandoffChain,
!aHandoff); // only apply acceleration if this is an initial fling
float friction = gfxPrefs::APZFlingSnapFriction();
float friction = gfxPrefs::APZFlingFriction();
ParentLayerPoint velocity(mX.GetVelocity(), mY.GetVelocity());
ParentLayerPoint predictedDelta;
// "-velocity / log(1.0 - friction)" is the integral of the deceleration
@ -2692,8 +2692,11 @@ bool AsyncPanZoomController::SnapBackIfOverscrolled() {
return true;
}
// If we don't kick off an overscroll animation, we still need to ask the
// main thread to snap to any nearby snap points.
RequestSnap();
// main thread to snap to any nearby snap points, assuming we haven't already
// done so when we started this fling
if (mState != FLING) {
RequestSnap();
}
return false;
}
@ -2741,8 +2744,11 @@ void AsyncPanZoomController::RequestContentRepaint(FrameMetrics& aFrameMetrics,
fabsf(mLastPaintRequestMetrics.GetScrollOffset().y -
aFrameMetrics.GetScrollOffset().y) < EPSILON &&
aFrameMetrics.GetZoom() == mLastPaintRequestMetrics.GetZoom() &&
fabsf(aFrameMetrics.GetViewport().width - mLastPaintRequestMetrics.GetViewport().width) < EPSILON &&
fabsf(aFrameMetrics.GetViewport().height - mLastPaintRequestMetrics.GetViewport().height) < EPSILON) {
fabsf(aFrameMetrics.GetViewport().width -
mLastPaintRequestMetrics.GetViewport().width) < EPSILON &&
fabsf(aFrameMetrics.GetViewport().height -
mLastPaintRequestMetrics.GetViewport().height) < EPSILON &&
aFrameMetrics.GetScrollGeneration() == mLastPaintRequestMetrics.GetScrollGeneration()) {
return;
}
@ -3190,8 +3196,14 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
Stringify(mFrameMetrics.GetScrollOffset()).c_str(),
Stringify(aLayerMetrics.GetSmoothScrollOffset()).c_str());
mFrameMetrics.CopySmoothScrollInfoFrom(aLayerMetrics);
CancelAnimation();
// It's important to not send repaint requests between this
// CopySmoothScrollInfo call and the sending of the scroll update
// acknowledgement below, otherwise that repaint request will get rejected
// on the main thread but mLastPaintRequestMetrics will have the new scroll
// generation; this would leave the main thread out of date.
mFrameMetrics.CopySmoothScrollInfoFrom(aLayerMetrics);
mLastDispatchedPaintMetrics = aLayerMetrics;
StartSmoothScroll(ScrollSource::DOM);
@ -3554,6 +3566,8 @@ void AsyncPanZoomController::ShareCompositorFrameMetrics() {
void AsyncPanZoomController::RequestSnap() {
if (RefPtr<GeckoContentController> controller = GetGeckoContentController()) {
APZC_LOG("%p requesting snap near %s\n", this,
Stringify(mFrameMetrics.GetScrollOffset()).c_str());
controller->RequestFlingSnap(mFrameMetrics.GetScrollId(),
mFrameMetrics.GetScrollOffset());
}

View File

@ -439,6 +439,10 @@ CanvasClientSharedSurface::UpdateRenderer(gfx::IntSize aSize, Renderer& aRendere
void
CanvasClientSharedSurface::Updated()
{
if (!mNewFront) {
return;
}
auto forwarder = GetForwarder();
#ifndef MOZ_WIDGET_GONK

View File

@ -423,6 +423,10 @@ CompositorVsyncScheduler::Composite(TimeStamp aVsyncTimestamp)
mLastCompose = aVsyncTimestamp;
ComposeToTarget(nullptr);
mVsyncNotificationsSkipped = 0;
TimeDuration compositeFrameTotal = TimeStamp::Now() - aVsyncTimestamp;
mozilla::Telemetry::Accumulate(mozilla::Telemetry::COMPOSITE_FRAME_ROUNDTRIP_TIME,
compositeFrameTotal.ToMilliseconds());
} else if (mVsyncNotificationsSkipped++ > gfxPrefs::CompositorUnobserveCount()) {
UnobserveVsync();
}

View File

@ -449,18 +449,15 @@ CacheBlur(DrawTarget& aDT,
// Blurs a small surface and creates the mask.
static already_AddRefed<SourceSurface>
CreateBlurMask(const IntSize& aRectSize,
CreateBlurMask(const IntSize& aMinSize,
RectCornerRadii* aCornerRadii,
IntSize aBlurRadius,
IntMargin& aExtendDestBy,
IntMargin& aSliceBorder,
DrawTarget& aDestDrawTarget)
{
IntMargin slice;
gfxAlphaBoxBlur blur;
IntSize minSize =
ComputeMinSizeForShadowShape(aCornerRadii, aBlurRadius, slice, aRectSize);
IntRect minRect(IntPoint(), minSize);
IntRect minRect(IntPoint(), aMinSize);
gfxContext* blurCtx = blur.Init(ThebesRect(Rect(minRect)), IntSize(),
aBlurRadius, nullptr, nullptr);
@ -488,7 +485,7 @@ CreateBlurMask(const IntSize& aRectSize,
IntRect expandedMinRect(topLeft, result->GetSize());
aExtendDestBy = expandedMinRect - minRect;
aSliceBorder = slice + aExtendDestBy;
aSliceBorder += aExtendDestBy;
MOZ_ASSERT(aSliceBorder.LeftRight() <= expandedMinRect.width);
MOZ_ASSERT(aSliceBorder.TopBottom() <= expandedMinRect.height);
@ -513,14 +510,15 @@ CreateBoxShadow(SourceSurface* aBlurMask, const Color& aShadowColor)
return boxShadowDT->Snapshot();
}
static SourceSurface*
static already_AddRefed<SourceSurface>
GetBlur(DrawTarget& aDT,
const IntSize& aRectSize,
const IntSize& aBlurRadius,
RectCornerRadii* aCornerRadii,
const Color& aShadowColor,
IntMargin& aExtendDestBy,
IntMargin& aSlice)
IntMargin& aSlice,
gfxContext* aDestinationCtx)
{
if (!gBlurCache) {
gBlurCache = new BlurCache();
@ -529,18 +527,28 @@ GetBlur(DrawTarget& aDT,
IntSize minSize =
ComputeMinSizeForShadowShape(aCornerRadii, aBlurRadius, aSlice, aRectSize);
// We can get seams using the min size rect when drawing to the destination rect
// if we have a non-pixel aligned destination transformation. In those cases,
// fallback to just rendering the destination rect.
Matrix destMatrix = ToMatrix(aDestinationCtx->CurrentMatrix());
bool useDestRect = !destMatrix.IsRectilinear() || destMatrix.HasNonIntegerTranslation();
if (useDestRect) {
minSize = aRectSize;
}
BlurCacheData* cached = gBlurCache->Lookup(minSize, aBlurRadius,
aCornerRadii, aShadowColor,
aDT.GetBackendType());
if (cached) {
if (cached && !useDestRect) {
// See CreateBlurMask() for these values
aExtendDestBy = cached->mExtendDest;
aSlice = aSlice + aExtendDestBy;
return cached->mBlur;
RefPtr<SourceSurface> blur = cached->mBlur;
return blur.forget();
}
RefPtr<SourceSurface> blurMask =
CreateBlurMask(aRectSize, aCornerRadii, aBlurRadius, aExtendDestBy, aSlice, aDT);
CreateBlurMask(minSize, aCornerRadii, aBlurRadius, aExtendDestBy, aSlice, aDT);
if (!blurMask) {
return nullptr;
@ -551,8 +559,13 @@ GetBlur(DrawTarget& aDT,
return nullptr;
}
CacheBlur(aDT, minSize, aBlurRadius, aCornerRadii, aShadowColor, aExtendDestBy, boxShadow);
return boxShadow;
if (useDestRect) {
// Since we're just going to paint the actual rect to the destination
aSlice.SizeTo(0, 0, 0, 0);
} else {
CacheBlur(aDT, minSize, aBlurRadius, aCornerRadii, aShadowColor, aExtendDestBy, boxShadow);
}
return boxShadow.forget();
}
void
@ -698,7 +711,8 @@ gfxAlphaBoxBlur::BlurRectangle(gfxContext* aDestinationCtx,
RefPtr<SourceSurface> boxShadow = GetBlur(destDrawTarget,
rect.Size(), blurRadius,
aCornerRadii, aShadowColor,
extendDestBy, slice);
extendDestBy, slice,
aDestinationCtx);
if (!boxShadow) {
return;
}

View File

@ -162,7 +162,6 @@ private:
DECL_GFX_PREF(Live, "apz.fling_curve_threshold_inches_per_ms", APZCurveThreshold, float, -1.0f);
DECL_GFX_PREF(Once, "apz.fling_friction", APZFlingFriction, float, 0.002f);
DECL_GFX_PREF(Live, "apz.fling_repaint_interval", APZFlingRepaintInterval, int32_t, 75);
DECL_GFX_PREF(Once, "apz.fling_snap_friction", APZFlingSnapFriction, float, 0.015f);
DECL_GFX_PREF(Once, "apz.fling_stop_on_tap_threshold", APZFlingStopOnTapThreshold, float, 0.05f);
DECL_GFX_PREF(Once, "apz.fling_stopped_threshold", APZFlingStoppedThreshold, float, 0.01f);
DECL_GFX_PREF(Once, "apz.highlight_checkerboarded_areas", APZHighlightCheckerboardedAreas, bool, false);

View File

@ -17,6 +17,7 @@
#include "prprf.h"
#include "nsTArray.h"
#include "nsString.h"
#include "mozilla/UniquePtr.h"
#include <ctype.h>
@ -268,11 +269,11 @@ nsLocaleService::GetLocaleFromAcceptLanguage(const char *acceptLanguage, nsILoca
char acceptLanguageList[NSILOCALE_MAX_ACCEPT_LANGUAGE][NSILOCALE_MAX_ACCEPT_LENGTH];
nsresult result;
nsAutoArrayPtr<char> input(new char[strlen(acceptLanguage)+1]);
auto input = MakeUnique<char[]>(strlen(acceptLanguage)+1);
strcpy(input, acceptLanguage);
cPtr1 = input-1;
cPtr2 = input;
strcpy(input.get(), acceptLanguage);
cPtr1 = input.get()-1;
cPtr2 = input.get();
/* put in standard form */
while (*(++cPtr1)) {
@ -286,7 +287,7 @@ nsLocaleService::GetLocaleFromAcceptLanguage(const char *acceptLanguage, nsILoca
countLang = 0;
if (strchr(input,';')) {
if (strchr(input.get(), ';')) {
/* deal with the quality values */
float qvalue[NSILOCALE_MAX_ACCEPT_LANGUAGE];
@ -295,7 +296,7 @@ nsLocaleService::GetLocaleFromAcceptLanguage(const char *acceptLanguage, nsILoca
char* ptrLanguage[NSILOCALE_MAX_ACCEPT_LANGUAGE];
char* ptrSwap;
cPtr = nsCRT::strtok(input,",",&cPtr2);
cPtr = nsCRT::strtok(input.get(),",",&cPtr2);
while (cPtr) {
qvalue[countLang] = 1.0f;
/* add extra parens to get rid of warning */
@ -332,7 +333,7 @@ nsLocaleService::GetLocaleFromAcceptLanguage(const char *acceptLanguage, nsILoca
} else {
/* simple case: no quality values */
cPtr = nsCRT::strtok(input,",",&cPtr2);
cPtr = nsCRT::strtok(input.get(),",",&cPtr2);
while (cPtr) {
if (strlen(cPtr)<NSILOCALE_MAX_ACCEPT_LENGTH) { /* ignore if too long */
PL_strncpyz(acceptLanguageList[countLang++],cPtr,NSILOCALE_MAX_ACCEPT_LENGTH);

View File

@ -10,6 +10,7 @@
#include "nsAutoPtr.h"
#include "nsIUnicodeDecoder.h"
#include "mozilla/dom/EncodingUtils.h"
#include "mozilla/UniquePtr.h"
using mozilla::dom::EncodingUtils;
@ -40,13 +41,12 @@ ToUTF8(const nsACString &aString, const char *aCharset,
rv = unicodeDecoder->GetMaxLength(inStr.get(), srcLen, &dstLen);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoArrayPtr<char16_t> ustr(new char16_t[dstLen]);
auto ustr = mozilla::MakeUnique<char16_t[]>(dstLen);
NS_ENSURE_TRUE(ustr, NS_ERROR_OUT_OF_MEMORY);
rv = unicodeDecoder->Convert(inStr.get(), &srcLen, ustr, &dstLen);
rv = unicodeDecoder->Convert(inStr.get(), &srcLen, ustr.get(), &dstLen);
if (NS_SUCCEEDED(rv)){
// Tru64 Cxx needs an explicit get()
CopyUTF16toUTF8(Substring(ustr.get(), ustr + dstLen), aResult);
CopyUTF16toUTF8(Substring(ustr.get(), ustr.get() + dstLen), aResult);
}
return rv;
}

View File

@ -5,7 +5,7 @@
#include "unicpriv.h"
#include "nsUnicodeDecodeHelper.h"
#include "nsAutoPtr.h"
#include "mozilla/UniquePtr.h"
//----------------------------------------------------------------------
// Class nsUnicodeDecodeHelper [implementation]
@ -224,11 +224,11 @@ nsresult nsUnicodeDecodeHelper::CreateFastTable(
{
int32_t tableSize = aTableSize;
int32_t buffSize = aTableSize;
nsAutoArrayPtr<char> buff(new char [buffSize]);
auto buff = mozilla::MakeUnique<char[]>(buffSize);
char * p = buff;
char * p = buff.get();
for (int32_t i=0; i<aTableSize; i++) *(p++) = i;
return ConvertByTable(buff, &buffSize, aFastTable, &tableSize,
return ConvertByTable(buff.get(), &buffSize, aFastTable, &tableSize,
u1ByteCharset, nullptr, aMappingTable);
}

View File

@ -115,51 +115,6 @@ class ModuleCompiler
/***************************************************** Mutable interface */
bool getOrCreateFunctionEntry(uint32_t funcIndex, Label** label)
{
return compileResults_->getOrCreateFunctionEntry(funcIndex, label);
}
bool finishGeneratingFunction(AsmFunction& func, CodeGenerator& codegen,
const AsmJSFunctionLabels& labels)
{
// If we have hit OOM then invariants which we assert below may not
// hold, so abort now.
if (masm().oom())
return false;
// Code range
unsigned line = func.lineno();
unsigned column = func.column();
PropertyName* funcName = func.name();
if (!compileResults_->addCodeRange(AsmJSModule::FunctionCodeRange(funcName, line, labels)))
return false;
// Script counts
jit::IonScriptCounts* counts = codegen.extractScriptCounts();
if (counts && !compileResults_->addFunctionCounts(counts)) {
js_delete(counts);
return false;
}
// Slow functions
if (func.compileTime() >= 250) {
ModuleCompileResults::SlowFunction sf(funcName, func.compileTime(), line, column);
if (!compileResults_->slowFunctions().append(Move(sf)))
return false;
}
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
// Perf and profiling information
unsigned begin = labels.nonProfilingEntry.offset();
unsigned end = labels.endAfterOOL.offset();
AsmJSModule::ProfiledFunction profiledFunc(funcName, begin, end, line, column);
if (!compileResults_->addProfiledFunction(profiledFunc))
return false;
#endif // defined(MOZ_VTUNE) || defined(JS_ION_PERF)
return true;
}
void finish(ScopedJSDeletePtr<ModuleCompileResults>* results) {
*results = compileResults_.forget();
}
@ -191,7 +146,6 @@ class FunctionCompiler
ModuleCompiler & m_;
LifoAlloc & lifo_;
RetType retType_;
const AsmFunction & func_;
size_t pc_;
@ -217,7 +171,6 @@ class FunctionCompiler
FunctionCompiler(ModuleCompiler& m, const AsmFunction& func, LifoAlloc& lifo)
: m_(m),
lifo_(lifo),
retType_(func.returnedType()),
func_(func),
pc_(0),
alloc_(nullptr),
@ -227,10 +180,10 @@ class FunctionCompiler
curBlock_(nullptr)
{}
ModuleCompiler & m() const { return m_; }
TempAllocator & alloc() const { return *alloc_; }
LifoAlloc & lifo() const { return lifo_; }
RetType returnedType() const { return retType_; }
ModuleCompiler & m() const { return m_; }
TempAllocator & alloc() const { return *alloc_; }
LifoAlloc & lifo() const { return lifo_; }
RetType returnedType() const { return func_.returnedType(); }
bool init()
{
@ -803,7 +756,7 @@ class FunctionCompiler
return true;
}
CallSiteDesc::Kind kind = CallSiteDesc::Kind(-1); // initialize to silence GCC warning
CallSiteDesc::Kind kind = CallSiteDesc::Kind(-1);
switch (callee.which()) {
case MAsmJSCall::Callee::Internal: kind = CallSiteDesc::Relative; break;
case MAsmJSCall::Callee::Dynamic: kind = CallSiteDesc::Register; break;
@ -821,10 +774,10 @@ class FunctionCompiler
}
public:
bool internalCall(const Signature& sig, Label* entry, const Call& call, MDefinition** def)
bool internalCall(const Signature& sig, uint32_t funcIndex, const Call& call, MDefinition** def)
{
MIRType returnType = sig.retType().toMIRType();
return callPrivate(MAsmJSCall::Callee(entry), call, returnType, def);
return callPrivate(MAsmJSCall::Callee(AsmJSInternalCallee(funcIndex)), call, returnType, def);
}
bool funcPtrCall(const Signature& sig, uint32_t maskLit, uint32_t globalDataOffset, MDefinition* index,
@ -1743,13 +1696,7 @@ static bool
EmitInternalCall(FunctionCompiler& f, RetType retType, MDefinition** def)
{
uint32_t funcIndex = f.readU32();
Label* entry;
if (!f.m().getOrCreateFunctionEntry(funcIndex, &entry))
return false;
const Signature& sig = *f.readSignature();
MOZ_ASSERT_IF(sig.retType() != RetType::Void, sig.retType() == retType);
uint32_t lineno, column;
@ -1759,7 +1706,7 @@ EmitInternalCall(FunctionCompiler& f, RetType retType, MDefinition** def)
if (!EmitCallArgs(f, sig, &call))
return false;
return f.internalCall(sig, entry, call, def);
return f.internalCall(sig, funcIndex, call, def);
}
static bool
@ -3170,7 +3117,8 @@ js::GenerateAsmFunctionMIR(ModuleCompiler& m, LifoAlloc& lifo, AsmFunction& func
}
bool
js::GenerateAsmFunctionCode(ModuleCompiler& m, AsmFunction& func, MIRGenerator& mir, LIRGraph& lir)
js::GenerateAsmFunctionCode(ModuleCompiler& m, AsmFunction& func, MIRGenerator& mir, LIRGraph& lir,
FunctionCompileResults* results)
{
JitContext jitContext(m.runtime(), /* CompileCompartment = */ nullptr, &mir.alloc());
@ -3187,18 +3135,19 @@ js::GenerateAsmFunctionCode(ModuleCompiler& m, AsmFunction& func, MIRGenerator&
if (!codegen)
return false;
Label* funcEntry;
if (!m.getOrCreateFunctionEntry(func.funcIndex(), &funcEntry))
return false;
AsmJSFunctionLabels labels(*funcEntry, m.stackOverflowLabel());
Label entry;
AsmJSFunctionLabels labels(entry, m.stackOverflowLabel());
if (!codegen->generateAsmJS(&labels))
return false;
func.accumulateCompileTime((PRMJ_Now() - before) / PRMJ_USEC_PER_MSEC);
if (!m.finishGeneratingFunction(func, *codegen, labels))
return false;
PropertyName* funcName = func.name();
unsigned line = func.lineno();
// Fill in the results of the function's compilation
AsmJSModule::FunctionCodeRange codeRange(funcName, line, labels);
results->finishCodegen(func, codeRange, *codegen->extractScriptCounts());
// Unlike regular IonMonkey, which links and generates a new JitCode for
// every function, we accumulate all the functions in the module in a

View File

@ -27,6 +27,7 @@ class AsmFunction;
class LifoAlloc;
class ModuleCompiler;
class ModuleCompileResults;
class FunctionCompileResults;
namespace jit {
class LIRGraph;
@ -76,7 +77,8 @@ class MOZ_RAII AsmModuleCompilerScope
bool CreateAsmModuleCompiler(ModuleCompileInputs mci, AsmModuleCompilerScope* scope);
bool GenerateAsmFunctionMIR(ModuleCompiler& m, LifoAlloc& lifo, AsmFunction& func, jit::MIRGenerator** mir);
bool GenerateAsmFunctionCode(ModuleCompiler& m, AsmFunction& func, jit::MIRGenerator& mir, jit::LIRGraph& lir);
bool GenerateAsmFunctionCode(ModuleCompiler& m, AsmFunction& func, jit::MIRGenerator& mir,
jit::LIRGraph& lir, FunctionCompileResults* results);
void FinishAsmModuleCompilation(ModuleCompiler& m, ScopedJSDeletePtr<ModuleCompileResults>* results);
} // namespace js

View File

@ -1046,43 +1046,39 @@ class AsmFunction
}
};
const size_t LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12;
class FunctionCompileResults
{
const AsmFunction* func_;
jit::IonScriptCounts* counts_;
AsmJSModule::FunctionCodeRange codeRange_;
public:
FunctionCompileResults()
: func_(nullptr),
counts_(nullptr),
codeRange_()
{}
const AsmFunction& func() const { MOZ_ASSERT(func_); return *func_; }
const AsmJSModule::FunctionCodeRange& codeRange() const { return codeRange_; }
jit::IonScriptCounts* counts() const { return counts_; }
void finishCodegen(AsmFunction& func, AsmJSModule::FunctionCodeRange codeRange,
jit::IonScriptCounts& counts)
{
func_ = &func;
codeRange_ = codeRange;
counts_ = &counts;
}
};
class ModuleCompileResults
{
public:
struct SlowFunction
{
SlowFunction(PropertyName* name, unsigned ms, unsigned line, unsigned column)
: name(name), ms(ms), line(line), column(column)
{}
PropertyName* name;
unsigned ms;
unsigned line;
unsigned column;
};
typedef Vector<SlowFunction , 0, SystemAllocPolicy> SlowFunctionVector;
typedef Vector<jit::Label* , 8, SystemAllocPolicy> LabelVector;
typedef Vector<AsmJSModule::FunctionCodeRange, 8, SystemAllocPolicy> FunctionCodeRangeVector;
typedef Vector<jit::IonScriptCounts* , 0, SystemAllocPolicy> ScriptCountVector;
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
typedef Vector<AsmJSModule::ProfiledFunction , 0, SystemAllocPolicy> ProfiledFunctionVector;
#endif // defined(MOZ_VTUNE) || defined(JS_ION_PERF)
private:
LifoAlloc lifo_;
jit::MacroAssembler masm_;
SlowFunctionVector slowFunctions_;
LabelVector functionEntries_;
FunctionCodeRangeVector codeRanges_;
ScriptCountVector functionCounts_;
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
ProfiledFunctionVector profiledFunctions_;
#endif // defined(MOZ_VTUNE) || defined(JS_ION_PERF)
jit::NonAssertingLabel stackOverflowLabel_;
jit::NonAssertingLabel asyncInterruptLabel_;
jit::NonAssertingLabel syncInterruptLabel_;
@ -1093,8 +1089,7 @@ class ModuleCompileResults
public:
ModuleCompileResults()
: lifo_(LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
masm_(jit::MacroAssembler::AsmJSToken()),
: masm_(jit::MacroAssembler::AsmJSToken()),
usecBefore_(PRMJ_Now())
{}
@ -1106,41 +1101,6 @@ class ModuleCompileResults
jit::Label& onDetachedLabel() { return onDetachedLabel_; }
jit::Label& onConversionErrorLabel() { return onConversionErrorLabel_; }
int64_t usecBefore() { return usecBefore_; }
SlowFunctionVector& slowFunctions() { return slowFunctions_; }
size_t numFunctionEntries() const { return functionEntries_.length(); }
jit::Label* functionEntry(unsigned i) { return functionEntries_[i]; }
bool getOrCreateFunctionEntry(unsigned i, jit::Label** label) {
if (i == UINT32_MAX)
return false;
while (functionEntries_.length() <= i) {
jit::Label* newEntry = lifo_.new_<jit::Label>();
if (!newEntry || !functionEntries_.append(newEntry))
return false;
}
*label = functionEntries_[i];
return true;
}
size_t numCodeRanges() const { return codeRanges_.length(); }
bool addCodeRange(AsmJSModule::FunctionCodeRange range) { return codeRanges_.append(range); }
AsmJSModule::FunctionCodeRange& codeRange(unsigned i) { return codeRanges_[i]; }
size_t numFunctionCounts() const { return functionCounts_.length(); }
bool addFunctionCounts(jit::IonScriptCounts* counts) { return functionCounts_.append(counts); }
jit::IonScriptCounts* functionCount(unsigned i) { return functionCounts_[i]; }
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
size_t numProfiledFunctions() const { return profiledFunctions_.length(); }
bool addProfiledFunction(AsmJSModule::ProfiledFunction func) {
return profiledFunctions_.append(func);
}
AsmJSModule::ProfiledFunction& profiledFunction(unsigned i) {
return profiledFunctions_[i];
}
#endif // defined(MOZ_VTUNE) || defined(JS_ION_PERF)
};
} // namespace js

View File

@ -469,17 +469,6 @@ LinkModuleToHeap(JSContext* cx, AsmJSModule& module, Handle<ArrayBufferObjectMay
{
uint32_t heapLength = heap->byteLength();
if (IsDeprecatedAsmJSHeapLength(heapLength)) {
LinkFail(cx, "ArrayBuffer byteLengths smaller than 64KB are deprecated and "
"will cause a link-time failure in the future");
// The goal of deprecation is to give apps some time before linking
// fails. However, if warnings-as-errors is turned on (which happens as
// part of asm.js testing) an exception may be raised.
if (cx->isExceptionPending())
return false;
}
if (!IsValidAsmJSHeapLength(heapLength)) {
ScopedJSFreePtr<char> msg(
JS_smprintf("ArrayBuffer byteLength 0x%x is not a valid heap length. The next "
@ -631,7 +620,6 @@ ChangeHeap(JSContext* cx, AsmJSModule& module, const CallArgs& args)
}
MOZ_ASSERT(IsValidAsmJSHeapLength(heapLength));
MOZ_ASSERT(!IsDeprecatedAsmJSHeapLength(heapLength));
if (!ArrayBufferObject::prepareForAsmJS(cx, newBuffer, module.usesSignalHandlersForOOB()))
return false;

View File

@ -322,7 +322,9 @@ AsmJSModule::finish(ExclusiveContext* cx, TokenStream& tokenStream, MacroAssembl
heapAccesses_ = masm.extractAsmJSHeapAccesses();
// Call-site metadata used for stack unwinding.
callSites_ = masm.extractCallSites();
const CallSiteAndTargetVector& callSites = masm.callSites();
if (!callSites_.appendAll(callSites))
return false;
MOZ_ASSERT(pod.functionBytes_ % AsmJSPageSize == 0);

View File

@ -112,6 +112,10 @@ struct MOZ_STACK_CLASS AsmJSFunctionLabels
jit::Label endAfterOOL;
mozilla::Maybe<jit::Label> overflowThunk;
jit::Label& overflowExit;
private:
AsmJSFunctionLabels(const AsmJSFunctionLabels&) = delete;
AsmJSFunctionLabels& operator=(const AsmJSFunctionLabels&) = delete;
};
// Represents the type and value of an asm.js numeric literal.
@ -631,6 +635,10 @@ class AsmJSModule
PropertyName* name_;
public:
FunctionCodeRange()
: CodeRange(), name_(nullptr)
{}
FunctionCodeRange(PropertyName* name, uint32_t lineNumber, const AsmJSFunctionLabels& l)
: CodeRange(UINT32_MAX, lineNumber, l), name_(name)
{}
@ -1159,14 +1167,14 @@ class AsmJSModule
bool addCodeRange(CodeRange::Kind kind, uint32_t begin, uint32_t pret, uint32_t end) {
return codeRanges_.append(CodeRange(kind, begin, pret, end));
}
bool addFunctionCodeRange(PropertyName* name, FunctionCodeRange&& codeRange)
bool addFunctionCodeRange(PropertyName* name, FunctionCodeRange codeRange)
{
MOZ_ASSERT(!isFinished());
MOZ_ASSERT(name->isTenured());
if (names_.length() >= UINT32_MAX)
return false;
codeRange.initNameIndex(names_.length());
return names_.append(name) && codeRanges_.append(Move(codeRange));
return names_.append(name) && codeRanges_.append(codeRange);
}
bool addBuiltinThunkCodeRange(AsmJSExit::BuiltinKind builtin, uint32_t begin,
uint32_t profilingReturn, uint32_t end)

View File

@ -584,6 +584,8 @@ TypedArrayLoadType(Scalar::Type viewType)
MOZ_CRASH("Unexpected array type");
}
const size_t LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12;
namespace {
// The ModuleValidator encapsulates the entire validation of an asm.js module.
@ -885,12 +887,25 @@ class MOZ_STACK_CLASS ModuleValidator
}
};
struct SlowFunction
{
SlowFunction(PropertyName* name, unsigned ms, unsigned line, unsigned column)
: name(name), ms(ms), line(line), column(column)
{}
PropertyName* name;
unsigned ms;
unsigned line;
unsigned column;
};
private:
typedef HashMap<PropertyName*, Global*> GlobalMap;
typedef HashMap<PropertyName*, MathBuiltin> MathNameMap;
typedef HashMap<PropertyName*, AsmJSAtomicsBuiltinFunction> AtomicsNameMap;
typedef HashMap<PropertyName*, AsmJSSimdOperation> SimdOperationNameMap;
typedef Vector<ArrayView> ArrayViewVector;
typedef Vector<SlowFunction> SlowFunctionVector;
public:
typedef HashMap<ExitDescriptor, unsigned, ExitDescriptor> ExitMap;
@ -924,6 +939,9 @@ class MOZ_STACK_CLASS ModuleValidator
bool supportsSimd_;
bool atomicsPresent_;
Vector<uint32_t> functionEntryOffsets_;
SlowFunctionVector slowFunctions_;
ScopedJSDeletePtr<ModuleCompileResults> compileResults_;
DebugOnly<bool> finishedFunctionBodies_;
@ -949,6 +967,8 @@ class MOZ_STACK_CLASS ModuleValidator
hasChangeHeap_(false),
supportsSimd_(cx->jitSupportsSimd()),
atomicsPresent_(false),
functionEntryOffsets_(cx),
slowFunctions_(cx),
compileResults_(nullptr),
finishedFunctionBodies_(false)
{
@ -1399,6 +1419,9 @@ class MOZ_STACK_CLASS ModuleValidator
FuncPtrTable& funcPtrTable(unsigned i) const {
return *funcPtrTables_[i];
}
uint32_t functionEntryOffset(unsigned i) {
return functionEntryOffsets_[i];
}
const Global* lookupGlobal(PropertyName* name) const {
if (GlobalMap::Ptr p = globals_.lookup(name))
@ -1445,9 +1468,43 @@ class MOZ_STACK_CLASS ModuleValidator
Label& onDetachedLabel() { return compileResults_->onDetachedLabel(); }
Label& onOutOfBoundsLabel() { return compileResults_->onOutOfBoundsLabel(); }
Label& onConversionErrorLabel() { return compileResults_->onConversionErrorLabel(); }
Label* functionEntry(unsigned i) { return compileResults_->functionEntry(i); }
ExitMap::Range allExits() const { return exits_.all(); }
bool finishGeneratingFunction(FunctionCompileResults& results) {
const AsmFunction& func = results.func();
unsigned i = func.funcIndex();
if (functionEntryOffsets_.length() <= i && !functionEntryOffsets_.resize(i + 1))
return false;
AsmJSModule::FunctionCodeRange codeRange = results.codeRange();
functionEntryOffsets_[i] = codeRange.entry();
PropertyName* funcName = func.name();
unsigned line = func.lineno();
unsigned column = func.column();
// These must be done before the module is done with function bodies.
if (results.counts() && !module().addFunctionCounts(results.counts()))
return false;
if (!module().addFunctionCodeRange(codeRange.name(), codeRange))
return false;
unsigned compileTime = func.compileTime();
if (compileTime >= 250) {
if (!slowFunctions_.append(SlowFunction(funcName, compileTime, line, column)))
return false;
}
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
// Perf and profiling information
AsmJSModule::ProfiledFunction pf(funcName, codeRange.entry(), codeRange.end(), line, column);
if (!module().addProfiledFunction(Move(pf)))
return false;
#endif // defined(MOZ_VTUNE) || defined(JS_ION_PERF)
return true;
}
bool finishGeneratingEntry(unsigned exportIndex, Label* begin) {
MOZ_ASSERT(finishedFunctionBodies_);
module_->exportedFunction(exportIndex).initCodeOffset(begin->offset());
@ -1504,8 +1561,7 @@ class MOZ_STACK_CLASS ModuleValidator
for (unsigned elemIndex = 0; elemIndex < table.numElems(); elemIndex++) {
AsmJSModule::RelativeLink link(AsmJSModule::RelativeLink::RawPointer);
link.patchAtOffset = tableBaseOffset + elemIndex * sizeof(uint8_t*);
Label* entry = functionEntry(table.elem(elemIndex).funcIndex());
link.targetOffset = entry->offset();
link.targetOffset = functionEntryOffset(table.elem(elemIndex).funcIndex());
if (!module_->addRelativeLink(link))
return false;
}
@ -1530,24 +1586,14 @@ class MOZ_STACK_CLASS ModuleValidator
// Take ownership of compilation results
compileResults_ = compileResults->forget();
// These must be done before the module is done with function bodies.
for (size_t i = 0; i < compileResults_->numFunctionCounts(); ++i) {
if (!module().addFunctionCounts(compileResults_->functionCount(i)))
return false;
}
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
for (size_t i = 0; i < compileResults_->numProfiledFunctions(); ++i) {
if (!module().addProfiledFunction(Move(compileResults_->profiledFunction(i))))
return false;
}
#endif // defined(MOZ_VTUNE) || defined(JS_ION_PERF)
// Hand in code ranges to the AsmJSModule
for (size_t i = 0; i < compileResults_->numCodeRanges(); ++i) {
AsmJSModule::FunctionCodeRange& codeRange = compileResults_->codeRange(i);
if (!module().addFunctionCodeRange(codeRange.name(), Move(codeRange)))
return false;
// Patch internal calls to their final positions
for (auto& cs : masm().callSites()) {
if (!cs.isInternal())
continue;
MOZ_ASSERT(cs.kind() == CallSiteDesc::Relative);
uint32_t callerOffset = cs.returnAddressOffset();
uint32_t calleeOffset = functionEntryOffset(cs.targetIndex());
masm().patchCall(callerOffset, calleeOffset);
}
// When an interrupt is triggered, all function code is mprotected and,
@ -1569,19 +1615,18 @@ class MOZ_STACK_CLASS ModuleValidator
ScopedJSFreePtr<char> slowFuns;
int64_t usecAfter = PRMJ_Now();
int msTotal = (usecAfter - compileResults_->usecBefore()) / PRMJ_USEC_PER_MSEC;
ModuleCompileResults::SlowFunctionVector& slowFunctions = compileResults_->slowFunctions();
if (!slowFunctions.empty()) {
slowFuns.reset(JS_smprintf("; %d functions compiled slowly: ", slowFunctions.length()));
if (!slowFunctions_.empty()) {
slowFuns.reset(JS_smprintf("; %d functions compiled slowly: ", slowFunctions_.length()));
if (!slowFuns)
return;
for (unsigned i = 0; i < slowFunctions.length(); i++) {
ModuleCompileResults::SlowFunction& func = slowFunctions[i];
for (unsigned i = 0; i < slowFunctions_.length(); i++) {
ModuleValidator::SlowFunction& func = slowFunctions_[i];
JSAutoByteString name;
if (!AtomToPrintableString(cx_, func.name, &name))
return;
slowFuns.reset(JS_smprintf("%s%s:%u:%u (%ums)%s", slowFuns.get(),
name.ptr(), func.line, func.column, func.ms,
i+1 < slowFunctions.length() ? ", " : ""));
i+1 < slowFunctions_.length() ? ", " : ""));
if (!slowFuns)
return;
}
@ -6539,7 +6584,10 @@ CheckFunctionsSequential(ModuleValidator& m, ScopedJSDeletePtr<ModuleCompileResu
func->accumulateCompileTime((PRMJ_Now() - before) / PRMJ_USEC_PER_MSEC);
}
if (!GenerateAsmFunctionCode(mc, *func, *mir, *lir))
FunctionCompileResults results;
if (!GenerateAsmFunctionCode(mc, *func, *mir, *lir, &results))
return false;
if (!m.finishGeneratingFunction(results))
return false;
}
@ -6620,10 +6668,10 @@ GetFinishedCompilation(ModuleCompiler& m, ParallelGroupState& group)
}
static bool
GetUsedTask(ModuleCompiler& m, ParallelGroupState& group, AsmJSParallelTask** outTask)
GetUsedTask(ModuleValidator& m, ModuleCompiler& mc, ParallelGroupState& group, AsmJSParallelTask** outTask)
{
// Block until a used LifoAlloc becomes available.
AsmJSParallelTask* task = GetFinishedCompilation(m, group);
AsmJSParallelTask* task = GetFinishedCompilation(mc, group);
if (!task)
return false;
@ -6631,7 +6679,10 @@ GetUsedTask(ModuleCompiler& m, ParallelGroupState& group, AsmJSParallelTask** ou
func.accumulateCompileTime(task->compileTime);
// Perform code generation on the main thread.
if (!GenerateAsmFunctionCode(m, func, *task->mir, *task->lir))
FunctionCompileResults results;
if (!GenerateAsmFunctionCode(mc, func, *task->mir, *task->lir, &results))
return false;
if (!m.finishGeneratingFunction(results))
return false;
group.compiledJobs++;
@ -6683,7 +6734,7 @@ CheckFunctionsParallel(ModuleValidator& m, ParallelGroupState& group,
if (tk != TOK_FUNCTION)
break;
if (!task && !GetUnusedTask(group, i, &task) && !GetUsedTask(mc, group, &task))
if (!task && !GetUnusedTask(group, i, &task) && !GetUsedTask(m, mc, group, &task))
return false;
AsmFunction* func;
@ -6711,7 +6762,7 @@ CheckFunctionsParallel(ModuleValidator& m, ParallelGroupState& group,
// Block for all outstanding helpers to complete.
while (group.outstandingJobs > 0) {
AsmJSParallelTask* ignored = nullptr;
if (!GetUsedTask(mc, group, &ignored))
if (!GetUsedTask(m, mc, group, &ignored))
return false;
}
@ -7181,7 +7232,9 @@ GenerateEntry(ModuleValidator& m, unsigned exportIndex)
// Call into the real function.
masm.assertStackAlignment(AsmJSStackAlignment);
masm.call(CallSiteDesc(CallSiteDesc::Relative), m.functionEntry(func.funcIndex()));
Label funcLabel;
funcLabel.bind(m.functionEntryOffset(func.funcIndex()));
masm.call(CallSiteDesc(CallSiteDesc::Relative), &funcLabel);
// Recover the stack pointer value before dynamic alignment.
masm.loadAsmJSActivation(scratch);

View File

@ -51,9 +51,14 @@ extern bool
ValidateAsmJS(ExclusiveContext* cx, AsmJSParser& parser, frontend::ParseNode* stmtList,
bool* validated);
// The minimum heap length for asm.js.
const size_t AsmJSMinHeapLength = 64 * 1024;
// The assumed page size; dynamically checked in ValidateAsmJS.
const size_t AsmJSPageSize = 4096;
static_assert(AsmJSMinHeapLength % AsmJSPageSize == 0, "Invalid page size");
#if defined(ASMJS_MAY_USE_SIGNAL_HANDLERS_FOR_OOB)
// Targets define AsmJSImmediateRange to be the size of an address immediate,
@ -86,8 +91,8 @@ static const size_t AsmJSMappedSize = 4 * 1024ULL * 1024ULL * 1024ULL +
inline uint32_t
RoundUpToNextValidAsmJSHeapLength(uint32_t length)
{
if (length <= 4 * 1024)
return 4 * 1024;
if (length <= AsmJSMinHeapLength)
return AsmJSMinHeapLength;
if (length <= 16 * 1024 * 1024)
return mozilla::RoundUpPow2(length);
@ -99,7 +104,7 @@ RoundUpToNextValidAsmJSHeapLength(uint32_t length)
inline bool
IsValidAsmJSHeapLength(uint32_t length)
{
bool valid = length >= 4 * 1024 &&
bool valid = length >= AsmJSMinHeapLength &&
(IsPowerOfTwo(length) ||
(length & 0x00ffffff) == 0);
@ -109,14 +114,6 @@ IsValidAsmJSHeapLength(uint32_t length)
return valid;
}
// For now, power-of-2 lengths in this range are accepted, but in the future
// we'll change this to cause link-time failure.
inline bool
IsDeprecatedAsmJSHeapLength(uint32_t length)
{
return length >= 4 * 1024 && length < 64 * 1024 && IsPowerOfTwo(length);
}
// Return whether asm.js optimization is inhibited by the platform or
// dynamically disabled:
extern bool

View File

@ -101,7 +101,7 @@ function CreateListIterator(array) {
ThrowTypeError(JSMSG_INCOMPATIBLE_METHOD, "next", "method", ToString(this));
let array = UnsafeGetObjectFromReservedSlot(this, ITERATOR_SLOT_TARGET);
let index = UnsafeGetInt32FromReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX);
let index = UnsafeGetReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX);
if (index >= ToLength(array.length)) {
UnsafeSetReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX, 1/0);

View File

@ -15,7 +15,7 @@ function f(stdlib, foreign, buffer)
if (isAsmJSCompilationAvailable())
assertEq(isAsmJSModule(f), true);
var i32 = new Int32Array(4096);
var i32 = new Int32Array(65536);
var buffer = i32.buffer;
var set = f(this, null, buffer);
if (isAsmJSCompilationAvailable())

View File

@ -0,0 +1,3 @@
iter = getSelfHostedValue("CreateListIterator")([]);
iter.next();
iter.next();

View File

@ -0,0 +1,7 @@
if (!('oomTest' in this))
quit();
oomTest(() => getBacktrace({
locals: true,
thisprops: true
}));

View File

@ -13707,17 +13707,17 @@ class MAsmJSCall final
private:
Which which_;
union {
Label* internal_;
AsmJSInternalCallee internal_;
MDefinition* dynamic_;
AsmJSImmKind builtin_;
} u;
public:
Callee() {}
explicit Callee(Label* callee) : which_(Internal) { u.internal_ = callee; }
explicit Callee(AsmJSInternalCallee callee) : which_(Internal) { u.internal_ = callee; }
explicit Callee(MDefinition* callee) : which_(Dynamic) { u.dynamic_ = callee; }
explicit Callee(AsmJSImmKind callee) : which_(Builtin) { u.builtin_ = callee; }
Which which() const { return which_; }
Label* internal() const { MOZ_ASSERT(which_ == Internal); return u.internal_; }
AsmJSInternalCallee internal() const { MOZ_ASSERT(which_ == Internal); return u.internal_; }
MDefinition* dynamic() const { MOZ_ASSERT(which_ == Dynamic); return u.dynamic_; }
AsmJSImmKind builtin() const { MOZ_ASSERT(which_ == Builtin); return u.builtin_; }
};

View File

@ -79,15 +79,22 @@ MacroAssembler::PushWithPatch(ImmPtr imm)
void
MacroAssembler::call(const CallSiteDesc& desc, const Register reg)
{
call(reg);
append(desc, currentOffset(), framePushed());
CodeOffsetLabel l = call(reg);
append(desc, l, framePushed());
}
void
MacroAssembler::call(const CallSiteDesc& desc, Label* label)
{
call(label);
append(desc, currentOffset(), framePushed());
CodeOffsetLabel l = call(label);
append(desc, l, framePushed());
}
void
MacroAssembler::call(const CallSiteDesc& desc, AsmJSInternalCallee callee)
{
CodeOffsetLabel l = callWithPatch();
append(desc, l, framePushed(), callee.index);
}
// ===============================================================

View File

@ -476,9 +476,9 @@ class MacroAssembler : public MacroAssemblerSpecific
// ===============================================================
// Simple call functions.
void call(Register reg) PER_SHARED_ARCH;
CodeOffsetLabel call(Register reg) PER_SHARED_ARCH;
CodeOffsetLabel call(Label* label) PER_SHARED_ARCH;
void call(const Address& addr) DEFINED_ON(x86_shared);
void call(Label* label) PER_SHARED_ARCH;
void call(ImmWord imm) PER_SHARED_ARCH;
// Call a target native function, which is neither traceable nor movable.
void call(ImmPtr imm) PER_SHARED_ARCH;
@ -488,6 +488,10 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void call(const CallSiteDesc& desc, const Register reg);
inline void call(const CallSiteDesc& desc, Label* label);
inline void call(const CallSiteDesc& desc, AsmJSInternalCallee callee);
CodeOffsetLabel callWithPatch() PER_SHARED_ARCH;
void patchCall(uint32_t callerOffset, uint32_t calleeOffset) PER_SHARED_ARCH;
// Push the return address and make a call. On platforms where this function
// is not defined, push the link register (pushReturnAddress) at the entry

View File

@ -5098,17 +5098,19 @@ MacroAssembler::reserveStack(uint32_t amount)
// ===============================================================
// Simple call functions.
void
CodeOffsetLabel
MacroAssembler::call(Register reg)
{
as_blx(reg);
return CodeOffsetLabel(currentOffset());
}
void
CodeOffsetLabel
MacroAssembler::call(Label* label)
{
// For now, assume that it'll be nearby?
// For now, assume that it'll be nearby.
as_bl(label, Always);
return CodeOffsetLabel(currentOffset());
}
void
@ -5148,6 +5150,20 @@ MacroAssembler::call(JitCode* c)
callJitNoProfiler(scratch);
}
CodeOffsetLabel
MacroAssembler::callWithPatch()
{
// For now, assume that it'll be nearby.
as_bl(BOffImm(), Always, /* documentation */ nullptr);
return CodeOffsetLabel(currentOffset());
}
void
MacroAssembler::patchCall(uint32_t callerOffset, uint32_t calleeOffset)
{
BufferOffset inst(callerOffset - 4);
as_bl(BufferOffset(calleeOffset).diffB<BOffImm>(inst), Always, inst);
}
void
MacroAssembler::pushReturnAddress()
{
@ -5291,7 +5307,7 @@ MacroAssembler::pushFakeReturnAddress(Register scratch)
uint32_t pseudoReturnOffset = currentOffset();
leaveNoPool();
MOZ_ASSERT(pseudoReturnOffset - offsetBeforePush == 8);
MOZ_ASSERT_IF(!oom(), pseudoReturnOffset - offsetBeforePush == 8);
return pseudoReturnOffset;
}

View File

@ -502,18 +502,20 @@ MacroAssembler::reserveStack(uint32_t amount)
// ===============================================================
// Simple call functions.
void
CodeOffsetLabel
MacroAssembler::call(Register reg)
{
syncStackPtr();
Blr(ARMRegister(reg, 64));
return CodeOffsetLabel(currentOffset());
}
void
CodeOffsetLabel
MacroAssembler::call(Label* label)
{
syncStackPtr();
Bl(label);
return CodeOffsetLabel(currentOffset());
}
void
@ -551,6 +553,18 @@ MacroAssembler::call(JitCode* c)
blr(scratch64);
}
CodeOffsetLabel
MacroAssembler::callWithPatch()
{
MOZ_CRASH("NYI");
return CodeOffsetLabel();
}
void
MacroAssembler::patchCall(uint32_t callerOffset, uint32_t calleeOffset)
{
MOZ_CRASH("NYI");
}
void
MacroAssembler::pushReturnAddress()
{

View File

@ -855,17 +855,30 @@ MacroAssembler::Pop(const ValueOperand& val)
// ===============================================================
// Simple call functions.
void
CodeOffsetLabel
MacroAssembler::call(Register reg)
{
as_jalr(reg);
as_nop();
return CodeOffsetLabel(currentOffset());
}
void
CodeOffsetLabel
MacroAssembler::call(Label* label)
{
ma_bal(label);
return CodeOffsetLabel(currentOffset());
}
CodeOffsetLabel
MacroAssembler::callWithPatch()
{
MOZ_CRASH("NYI");
}
void
MacroAssembler::patchCall(uint32_t callerOffset, uint32_t calleeOffset)
{
MOZ_CRASH("NYI");
}
void

View File

@ -659,7 +659,7 @@ class CallSiteDesc
CallSiteDesc(uint32_t line, uint32_t column, Kind kind)
: line_(line), column_(column), kind_(kind)
{
MOZ_ASSERT(column <= INT32_MAX);
MOZ_ASSERT(column_ == column, "column must fit in 31 bits");
}
uint32_t line() const { return line_; }
uint32_t column() const { return column_; }
@ -694,6 +694,23 @@ class CallSite : public CallSiteDesc
typedef Vector<CallSite, 0, SystemAllocPolicy> CallSiteVector;
class CallSiteAndTarget : public CallSite
{
uint32_t targetIndex_;
public:
explicit CallSiteAndTarget(CallSite cs, uint32_t targetIndex)
: CallSite(cs), targetIndex_(targetIndex)
{ }
static const uint32_t NOT_INTERNAL = UINT32_MAX;
bool isInternal() const { return targetIndex_ != NOT_INTERNAL; }
uint32_t targetIndex() const { MOZ_ASSERT(isInternal()); return targetIndex_; }
};
typedef Vector<CallSiteAndTarget, 0, SystemAllocPolicy> CallSiteAndTargetVector;
// As an invariant across architectures, within asm.js code:
// $sp % AsmJSStackAlignment = (sizeof(AsmJSFrame) + masm.framePushed) % AsmJSStackAlignment
// Thus, AsmJSFrame represents the bytes pushed after the call (which occurred
@ -916,10 +933,24 @@ struct AsmJSAbsoluteLink
AsmJSImmKind target;
};
// Represents a call from an asm.js function to another asm.js function,
// represented by the index of the callee in the Module Validator
struct AsmJSInternalCallee
{
uint32_t index;
// Provide a default constructor for embedding it in unions
AsmJSInternalCallee() = default;
explicit AsmJSInternalCallee(uint32_t calleeIndex)
: index(calleeIndex)
{}
};
// The base class of all Assemblers for all archs.
class AssemblerShared
{
Vector<CallSite, 0, SystemAllocPolicy> callsites_;
CallSiteAndTargetVector callsites_;
Vector<AsmJSHeapAccess, 0, SystemAllocPolicy> asmJSHeapAccesses_;
Vector<AsmJSGlobalAccess, 0, SystemAllocPolicy> asmJSGlobalAccesses_;
Vector<AsmJSAbsoluteLink, 0, SystemAllocPolicy> asmJSAbsoluteLinks_;
@ -952,13 +983,15 @@ class AssemblerShared
return embedsNurseryPointers_;
}
void append(const CallSiteDesc& desc, size_t currentOffset, size_t framePushed) {
void append(const CallSiteDesc& desc, CodeOffsetLabel label, size_t framePushed,
uint32_t targetIndex = CallSiteAndTarget::NOT_INTERNAL)
{
// framePushed does not include sizeof(AsmJSFrame), so add it in here (see
// CallSite::stackDepth).
CallSite callsite(desc, currentOffset, framePushed + sizeof(AsmJSFrame));
enoughMemory_ &= callsites_.append(callsite);
CallSite callsite(desc, label.offset(), framePushed + sizeof(AsmJSFrame));
enoughMemory_ &= callsites_.append(CallSiteAndTarget(callsite, targetIndex));
}
CallSiteVector&& extractCallSites() { return Move(callsites_); }
const CallSiteAndTargetVector& callSites() const { return callsites_; }
void append(AsmJSHeapAccess access) { enoughMemory_ &= asmJSHeapAccesses_.append(access); }
AsmJSHeapAccessVector&& extractAsmJSHeapAccesses() { return Move(asmJSHeapAccesses_); }

View File

@ -990,7 +990,7 @@ class AssemblerX86Shared : public AssemblerShared
// Remove the size of the return address which is included in the frame.
masm.ret_i(n.value - sizeof(void*));
}
void call(Label* label) {
CodeOffsetLabel call(Label* label) {
if (label->bound()) {
masm.linkJump(masm.call(), JmpDst(label->offset()));
} else {
@ -998,9 +998,11 @@ class AssemblerX86Shared : public AssemblerShared
JmpSrc prev = JmpSrc(label->use(j.offset()));
masm.setNextJump(j, prev);
}
return CodeOffsetLabel(masm.currentOffset());
}
void call(Register reg) {
CodeOffsetLabel call(Register reg) {
masm.call_r(reg.encoding());
return CodeOffsetLabel(masm.currentOffset());
}
void call(const Operand& op) {
switch (op.kind()) {
@ -1015,6 +1017,14 @@ class AssemblerX86Shared : public AssemblerShared
}
}
CodeOffsetLabel callWithPatch() {
return CodeOffsetLabel(masm.call().offset());
}
void patchCall(uint32_t callerOffset, uint32_t calleeOffset) {
unsigned char* code = masm.data();
X86Encoding::SetRel32(code + callerOffset, code + calleeOffset);
}
void breakpoint() {
masm.int3();
}

View File

@ -411,16 +411,16 @@ MacroAssembler::Pop(const ValueOperand& val)
// ===============================================================
// Simple call functions.
void
CodeOffsetLabel
MacroAssembler::call(Register reg)
{
Assembler::call(reg);
return Assembler::call(reg);
}
void
CodeOffsetLabel
MacroAssembler::call(Label* label)
{
Assembler::call(label);
return Assembler::call(label);
}
void
@ -455,6 +455,17 @@ MacroAssembler::call(JitCode* target)
Assembler::call(target);
}
CodeOffsetLabel
MacroAssembler::callWithPatch()
{
return Assembler::callWithPatch();
}
void
MacroAssembler::patchCall(uint32_t callerOffset, uint32_t calleeOffset)
{
Assembler::patchCall(callerOffset, calleeOffset);
}
void
MacroAssembler::callAndPushReturnAddress(Register reg)
{

View File

@ -1025,6 +1025,7 @@ xpc::CreateSandboxObject(JSContext* cx, MutableHandleValue vp, nsISupports* prin
priv->allowWaivers = options.allowWaivers;
priv->writeToGlobalPrototype = options.writeToGlobalPrototype;
priv->isWebExtensionContentScript = options.isWebExtensionContentScript;
priv->waiveInterposition = options.waiveInterposition;
// Set up the wantXrays flag, which indicates whether xrays are desired even
// for same-origin access.
@ -1491,6 +1492,7 @@ SandboxOptions::Parse()
ParseBoolean("wantComponents", &wantComponents) &&
ParseBoolean("wantExportHelpers", &wantExportHelpers) &&
ParseBoolean("isWebExtensionContentScript", &isWebExtensionContentScript) &&
ParseBoolean("waiveInterposition", &waiveInterposition) &&
ParseString("sandboxName", sandboxName) &&
ParseObject("sameZoneAs", &sameZoneAs) &&
ParseBoolean("freshZone", &freshZone) &&

View File

@ -194,6 +194,7 @@ CompartmentPrivate::CompartmentPrivate(JSCompartment* c)
, writeToGlobalPrototype(false)
, skipWriteToGlobalPrototype(false)
, isWebExtensionContentScript(false)
, waiveInterposition(false)
, universalXPConnectEnabled(false)
, forcePermissiveCOWs(false)
, scriptability(c)

View File

@ -139,9 +139,11 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(JSContext* cx,
JSAddonId* addonId = JS::AddonIdOfObject(aGlobal);
if (gInterpositionMap) {
bool isSystem = nsContentUtils::IsSystemPrincipal(principal);
if (InterpositionMap::Ptr p = gInterpositionMap->lookup(addonId)) {
bool waiveInterposition = priv->waiveInterposition;
InterpositionMap::Ptr interposition = gInterpositionMap->lookup(addonId);
if (!waiveInterposition && interposition) {
MOZ_RELEASE_ASSERT(isSystem);
mInterposition = p->value();
mInterposition = interposition->value();
}
// We also want multiprocessCompatible add-ons to have a default interposition.
if (!mInterposition && addonId && isSystem) {

View File

@ -3475,6 +3475,7 @@ public:
, wantComponents(true)
, wantExportHelpers(false)
, isWebExtensionContentScript(false)
, waiveInterposition(false)
, proto(cx)
, addonId(cx)
, writeToGlobalPrototype(false)
@ -3492,6 +3493,7 @@ public:
bool wantComponents;
bool wantExportHelpers;
bool isWebExtensionContentScript;
bool waiveInterposition;
JS::RootedObject proto;
nsCString sandboxName;
JS::RootedString addonId;
@ -3732,6 +3734,11 @@ public:
// various bits of special compatibility behavior.
bool isWebExtensionContentScript;
// Even if an add-on needs interposition, it does not necessary need it
// for every scope. If this flag is set we waive interposition for this
// scope.
bool waiveInterposition;
// This is only ever set during mochitest runs when enablePrivilege is called.
// It's intended as a temporary stopgap measure until we can finish ripping out
// enablePrivilege. Once set, this value is never unset (i.e., it doesn't follow

View File

@ -4577,8 +4577,8 @@ PresShell::StyleSheetApplicableStateChanged(nsIDocument *aDocument,
void
PresShell::StyleRuleChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aOldStyleRule,
nsIStyleRule* aNewStyleRule)
mozilla::css::Rule* aOldStyleRule,
mozilla::css::Rule* aNewStyleRule)
{
RecordStyleSheetChange(aStyleSheet);
}
@ -4586,7 +4586,7 @@ PresShell::StyleRuleChanged(nsIDocument *aDocument,
void
PresShell::StyleRuleAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule)
mozilla::css::Rule* aStyleRule)
{
RecordStyleSheetChange(aStyleSheet);
}
@ -4594,7 +4594,7 @@ PresShell::StyleRuleAdded(nsIDocument *aDocument,
void
PresShell::StyleRuleRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule)
mozilla::css::Rule* aStyleRule)
{
RecordStyleSheetChange(aStyleSheet);
}

View File

@ -24,9 +24,12 @@
// (In some cases, there are internal (private) methods that don't do this;
// such methods should only be used by other methods that have already checked
// the writing modes.)
// The check ignores the eSidewaysMask bit of writing mode, because this does
// not affect the interpretation of logical coordinates.
#define CHECK_WRITING_MODE(param) \
NS_ASSERTION(param == GetWritingMode(), "writing-mode mismatch")
NS_ASSERTION(param.IgnoreSideways() == GetWritingMode().IgnoreSideways(), \
"writing-mode mismatch")
namespace mozilla {
@ -259,6 +262,13 @@ public:
*/
bool IsSideways() const { return !!(mWritingMode & eSidewaysMask); }
#ifdef DEBUG // Used by CHECK_WRITING_MODE to compare modes without regard
// for the eSidewaysMask flag.
WritingMode IgnoreSideways() const {
return WritingMode(mWritingMode & ~eSidewaysMask);
}
#endif
static mozilla::PhysicalAxis PhysicalAxisForLogicalAxis(
uint8_t aWritingModeValue,
LogicalAxis aAxis)

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
function boom()
{
document.documentElement.offsetHeight;
document.body.style.textOrientation = "sideways";
}
</script>
</head>
<body onload="boom();" style="writing-mode: tb-rl; display: table;">Hello</body>
</html>

View File

@ -587,6 +587,7 @@ load 1169420-2.html
load 1183431.html
load 1221112-1.html
load 1221112-2.html
load 1221874-1.html
load first-letter-638937-1.html
load first-letter-638937-2.html
pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.emPerLine,15) asserts(1-100) load font-inflation-762332.html # bug 762332

View File

@ -238,13 +238,17 @@ inDOMUtils::GetCSSStyleRules(nsIDOMElement *aElement,
NS_NewISupportsArray(getter_AddRefs(rules));
if (!rules) return NS_ERROR_OUT_OF_MEMORY;
RefPtr<mozilla::css::StyleRule> cssRule;
for ( ; !ruleNode->IsRoot(); ruleNode = ruleNode->GetParent()) {
cssRule = do_QueryObject(ruleNode->GetRule());
if (cssRule) {
nsCOMPtr<nsIDOMCSSRule> domRule = cssRule->GetDOMRule();
if (domRule)
rules->InsertElementAt(domRule, 0);
RefPtr<Declaration> decl = do_QueryObject(ruleNode->GetRule());
if (decl) {
RefPtr<mozilla::css::StyleRule> styleRule =
do_QueryObject(decl->GetOwningRule());
if (styleRule) {
nsCOMPtr<nsIDOMCSSRule> domRule = styleRule->GetDOMRule();
if (domRule) {
rules->InsertElementAt(domRule, 0);
}
}
}
}

View File

@ -0,0 +1,15 @@
<html>
<head>
<style>
div.second {
margin: 35px auto 95px auto;
box-shadow: 0px 0px 15px 0px #808080;
width: 100;
height: 116.36px;
}
</style>
</head>
<body>
<div class="second"></div>
</body>
</html>

View File

@ -0,0 +1,16 @@
<html>
<head>
<style>
div.first {
margin: 35px auto 95px auto;
box-shadow: 0px 0px 15px 0px #808080;
transform: rotate(-180deg);
width: 100;
height: 116.36px;
}
</style>
</head>
<body>
<div class="first"></div>
</body>
</html>

View File

@ -25,6 +25,7 @@ random-if(d2d) == boxshadow-threecorners.html boxshadow-threecorners-ref.html
fuzzy-if(OSX==1010,1,24) == boxshadow-large-border-radius.html boxshadow-large-border-radius-ref.html # Bug 1209649
== boxshadow-border-radius-int.html boxshadow-border-radius-int-ref.html
== boxshadow-inset-neg-spread.html about:blank
fuzzy(26,3610) == boxshadow-rotated.html boxshadow-rotated-ref.html # Bug 1211264
== overflow-not-scrollable-1.html overflow-not-scrollable-1-ref.html
== overflow-not-scrollable-1.html overflow-not-scrollable-1-ref2.html

View File

@ -1532,43 +1532,6 @@ CSSStyleSheet::AppendStyleSheet(CSSStyleSheet* aSheet)
DidDirty();
}
void
CSSStyleSheet::InsertStyleSheetAt(CSSStyleSheet* aSheet, int32_t aIndex)
{
NS_PRECONDITION(nullptr != aSheet, "null arg");
WillDirty();
RefPtr<CSSStyleSheet>* tail = &mInner->mFirstChild;
while (*tail && aIndex) {
--aIndex;
tail = &(*tail)->mNext;
}
aSheet->mNext = *tail;
*tail = aSheet;
// This is not reference counted. Our parent tells us when
// it's going away.
aSheet->mParent = this;
aSheet->mDocument = mDocument;
DidDirty();
}
void
CSSStyleSheet::PrependStyleRule(css::Rule* aRule)
{
NS_PRECONDITION(nullptr != aRule, "null arg");
WillDirty();
mInner->mOrderedRules.InsertObjectAt(aRule, 0);
aRule->SetStyleSheet(this);
DidDirty();
if (css::Rule::NAMESPACE_RULE == aRule->GetType()) {
// no api to prepend a namespace (ugh), release old ones and re-create them all
mInner->RebuildNameSpaces();
}
}
void
CSSStyleSheet::AppendStyleRule(css::Rule* aRule)
{
@ -1624,23 +1587,6 @@ CSSStyleSheet::GetStyleRuleAt(int32_t aIndex) const
return mInner->mOrderedRules.SafeObjectAt(aIndex);
}
int32_t
CSSStyleSheet::StyleSheetCount() const
{
// XXX Far from an ideal way to do this, but the hope is that
// it won't be done too often. If it is, we might want to
// consider storing the children in an array.
int32_t count = 0;
const CSSStyleSheet* child = mInner->mFirstChild;
while (child) {
count++;
child = child->mNext;
}
return count;
}
void
CSSStyleSheet::EnsureUniqueInner()
{

View File

@ -156,10 +156,8 @@ public:
#endif
void AppendStyleSheet(CSSStyleSheet* aSheet);
void InsertStyleSheetAt(CSSStyleSheet* aSheet, int32_t aIndex);
// XXX do these belong here or are they generic?
void PrependStyleRule(css::Rule* aRule);
void AppendStyleRule(css::Rule* aRule);
void ReplaceStyleRule(css::Rule* aOld, css::Rule* aNew);
@ -170,8 +168,6 @@ public:
nsresult InsertRuleIntoGroup(const nsAString& aRule, css::GroupRule* aGroup, uint32_t aIndex, uint32_t* _retval);
nsresult ReplaceRuleInGroup(css::GroupRule* aGroup, css::Rule* aOld, css::Rule* aNew);
int32_t StyleSheetCount() const;
/**
* SetURIs must be called on all sheets before parsing into them.
* SetURIs may only be called while the sheet is 1) incomplete and 2)

View File

@ -19,10 +19,35 @@
namespace mozilla {
namespace css {
Declaration::Declaration()
: mImmutable(false)
NS_IMPL_QUERY_INTERFACE(ImportantStyleData, nsIStyleRule)
NS_IMPL_ADDREF_USING_AGGREGATOR(ImportantStyleData, Declaration())
NS_IMPL_RELEASE_USING_AGGREGATOR(ImportantStyleData, Declaration())
/* virtual */ void
ImportantStyleData::MapRuleInfoInto(nsRuleData* aRuleData)
{
Declaration()->MapImportantRuleInfoInto(aRuleData);
}
#ifdef DEBUG
/* virtual */ void
ImportantStyleData::List(FILE* out, int32_t aIndent) const
{
// Indent
nsAutoCString str;
for (int32_t index = aIndent; --index >= 0; ) {
str.AppendLiteral(" ");
}
str.AppendLiteral("! important rule\n");
fprintf_stderr(out, "%s", str.get());
}
#endif
Declaration::Declaration()
: mOwningRule(nullptr)
, mImmutable(false)
{
MOZ_COUNT_CTOR(mozilla::css::Declaration);
}
Declaration::Declaration(const Declaration& aCopy)
@ -37,14 +62,37 @@ Declaration::Declaration(const Declaration& aCopy)
mImportantVariables(aCopy.mImportantVariables ?
new CSSVariableDeclarations(*aCopy.mImportantVariables) :
nullptr),
mOwningRule(nullptr),
mImmutable(false)
{
MOZ_COUNT_CTOR(mozilla::css::Declaration);
}
Declaration::~Declaration()
{
MOZ_COUNT_DTOR(mozilla::css::Declaration);
}
NS_INTERFACE_MAP_BEGIN(Declaration)
if (aIID.Equals(NS_GET_IID(mozilla::css::Declaration))) {
*aInstancePtr = this;
NS_ADDREF_THIS();
return NS_OK;
}
else
NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(Declaration)
NS_IMPL_RELEASE(Declaration)
/* virtual */ void
Declaration::MapRuleInfoInto(nsRuleData* aRuleData)
{
MOZ_ASSERT(mData, "called while expanded");
mData->MapRuleInfoInto(aRuleData);
if (mVariables) {
mVariables->MapRuleInfoInto(aRuleData);
}
}
void
@ -1339,7 +1387,7 @@ Declaration::ToString(nsAString& aString) const
}
#ifdef DEBUG
void
/* virtual */ void
Declaration::List(FILE* out, int32_t aIndent) const
{
nsAutoCString str;
@ -1381,15 +1429,17 @@ Declaration::InitializeEmpty()
mData = nsCSSCompressedDataBlock::CreateEmptyBlock();
}
Declaration*
already_AddRefed<Declaration>
Declaration::EnsureMutable()
{
MOZ_ASSERT(mData, "should only be called when not expanded");
RefPtr<Declaration> result;
if (!IsMutable()) {
return new Declaration(*this);
result = new Declaration(*this);
} else {
return this;
result = this;
}
return result.forget();
}
size_t

View File

@ -23,22 +23,61 @@
#include "nsCSSDataBlock.h"
#include "nsCSSProperty.h"
#include "nsCSSProps.h"
#include "nsIStyleRule.h"
#include "nsStringFwd.h"
#include "nsTArray.h"
#include <stdio.h>
// feec07b8-3fe6-491e-90d5-cc93f853e048
#define NS_CSS_DECLARATION_IMPL_CID \
{ 0xfeec07b8, 0x3fe6, 0x491e, \
{ 0x90, 0xd5, 0xcc, 0x93, 0xf8, 0x53, 0xe0, 0x48 } }
namespace mozilla {
namespace css {
class Rule;
class Declaration;
/**
* ImportantStyleData is the implementation of nsIStyleRule (a source of
* style data) representing the style data coming from !important rules;
* the !important declarations need a separate nsIStyleRule object since
* they fit at a different point in the cascade.
*
* ImportantStyleData is allocated only as part of a Declaration object.
*/
class ImportantStyleData final : public nsIStyleRule
{
public:
NS_DECL_ISUPPORTS
inline ::mozilla::css::Declaration* Declaration();
// nsIStyleRule interface
virtual void MapRuleInfoInto(nsRuleData* aRuleData) override;
#ifdef DEBUG
virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
#endif
private:
ImportantStyleData() {}
~ImportantStyleData() {}
friend class ::mozilla::css::Declaration;
};
// Declaration objects have unusual lifetime rules. Every declaration
// begins life in an invalid state which ends when InitializeEmpty or
// CompressFrom is called upon it. After that, it can be attached to
// exactly one style rule, and will be destroyed when that style rule
// is destroyed. A declaration becomes immutable when its style rule's
// |RuleMatched| method is called; after that, it must be copied before
// it can be modified, which is taken care of by |EnsureMutable|.
// is destroyed. A declaration becomes immutable (via a SetImmutable
// call) when it is matched (put in the rule tree); after that, it must
// be copied before it can be modified, which is taken care of by
// |EnsureMutable|.
class Declaration {
class Declaration final : public nsIStyleRule {
public:
/**
* Construct an |Declaration| that is in an invalid state (null
@ -49,8 +88,21 @@ public:
Declaration(const Declaration& aCopy);
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_DECLARATION_IMPL_CID)
NS_DECL_ISUPPORTS
private:
~Declaration();
public:
// nsIStyleRule implementation
virtual void MapRuleInfoInto(nsRuleData *aRuleData) override;
#ifdef DEBUG
virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
#endif
/**
* |ValueAppended| must be called to maintain this declaration's
* |mOrder| whenever a property is parsed into an expanded data block
@ -166,17 +218,6 @@ public:
aExpandedData->Expand(mData.forget(), mImportantData.forget());
}
/**
* Do what |nsIStyleRule::MapRuleInfoInto| needs to do for a style
* rule using this declaration for storage.
*/
void MapNormalRuleInfoInto(nsRuleData *aRuleData) const {
MOZ_ASSERT(mData, "called while expanded");
mData->MapRuleInfoInto(aRuleData);
if (mVariables) {
mVariables->MapRuleInfoInto(aRuleData);
}
}
void MapImportantRuleInfoInto(nsRuleData *aRuleData) const {
MOZ_ASSERT(mData, "called while expanded");
MOZ_ASSERT(mImportantData || mImportantVariables,
@ -243,7 +284,7 @@ public:
/**
* Copy |this|, if necessary to ensure that it can be modified.
*/
Declaration* EnsureMutable();
already_AddRefed<Declaration> EnsureMutable();
/**
* Crash if |this| cannot be modified.
@ -272,9 +313,20 @@ public:
mVariableOrder.Clear();
}
#ifdef DEBUG
void List(FILE* out = stdout, int32_t aIndent = 0) const;
#endif
void SetOwningRule(Rule* aRule) {
MOZ_ASSERT(!mOwningRule || !aRule,
"should never overwrite one rule with another");
mOwningRule = aRule;
}
Rule* GetOwningRule() { return mOwningRule; }
ImportantStyleData* GetImportantStyleData() {
if (HasImportantData()) {
return &mImportantStyleData;
}
return nullptr;
}
private:
Declaration& operator=(const Declaration& aCopy) = delete;
@ -351,11 +403,32 @@ private:
// may be null
nsAutoPtr<CSSVariableDeclarations> mImportantVariables;
// set by style rules when |RuleMatched| is called;
// The style rule that owns this declaration. May be null.
Rule* mOwningRule;
friend class ImportantStyleData;
ImportantStyleData mImportantStyleData;
// set when declaration put in the rule tree;
// also by ToString (hence the 'mutable').
mutable bool mImmutable;
};
inline ::mozilla::css::Declaration*
ImportantStyleData::Declaration()
{
union {
char* ch; /* for pointer arithmetic */
::mozilla::css::Declaration* declaration;
ImportantStyleData* importantData;
} u;
u.importantData = this;
u.ch -= offsetof(::mozilla::css::Declaration, mImportantStyleData);
return u.declaration;
}
NS_DEFINE_STATIC_IID_ACCESSOR(Declaration, NS_CSS_DECLARATION_IMPL_CID)
} // namespace css
} // namespace mozilla

View File

@ -173,8 +173,8 @@ FontFaceSet::ParseFontShorthandForMatching(
ErrorResult& aRv)
{
// Parse aFont as a 'font' property value.
Declaration declaration;
declaration.InitializeEmpty();
RefPtr<Declaration> declaration = new Declaration;
declaration->InitializeEmpty();
bool changed = false;
nsCSSParser parser;
@ -183,23 +183,23 @@ FontFaceSet::ParseFontShorthandForMatching(
mDocument->GetDocumentURI(),
mDocument->GetDocumentURI(),
mDocument->NodePrincipal(),
&declaration,
declaration,
&changed,
/* aIsImportant */ false);
// All of the properties we are interested in should have been set at once.
MOZ_ASSERT(changed == (declaration.HasProperty(eCSSProperty_font_family) &&
declaration.HasProperty(eCSSProperty_font_style) &&
declaration.HasProperty(eCSSProperty_font_weight) &&
declaration.HasProperty(eCSSProperty_font_stretch)));
MOZ_ASSERT(changed == (declaration->HasProperty(eCSSProperty_font_family) &&
declaration->HasProperty(eCSSProperty_font_style) &&
declaration->HasProperty(eCSSProperty_font_weight) &&
declaration->HasProperty(eCSSProperty_font_stretch)));
if (!changed) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
nsCSSCompressedDataBlock* data = declaration.GetNormalBlock();
MOZ_ASSERT(!declaration.GetImportantBlock());
nsCSSCompressedDataBlock* data = declaration->GetNormalBlock();
MOZ_ASSERT(!declaration->GetImportantBlock());
const nsCSSValue* family = data->ValueFor(eCSSProperty_font_family);
if (family->GetUnit() != eCSSUnit_FontFamilyList) {

View File

@ -42,14 +42,12 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS(GroupRule)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
// implement part of nsIStyleRule and Rule
// implement part of Rule
DECL_STYLE_RULE_INHERIT_NO_DOMRULE
virtual void SetStyleSheet(CSSStyleSheet* aSheet) override;
// to help implement nsIStyleRule
#ifdef DEBUG
virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
#endif
virtual void SetStyleSheet(CSSStyleSheet* aSheet) override;
public:
void AppendStyleRule(Rule* aRule);

Some files were not shown because too many files have changed in this diff Show More