merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2015-11-20 13:13:07 +01:00
Родитель b9490dccae 538ef0460d
Коммит e59d6747c1
128 изменённых файлов: 2965 добавлений и 2256 удалений

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

@ -1343,8 +1343,10 @@ pref("browser.newtabpage.directory.source", "https://tiles.services.mozilla.com/
// endpoint to send newtab click and view pings
pref("browser.newtabpage.directory.ping", "https://tiles.services.mozilla.com/v3/links/");
// activates the remote-hosted newtab page
#ifndef RELEASE_BUILD
// if true, it activates the remote-hosted newtab page
pref("browser.newtabpage.remote", false);
#endif
// Enable the DOM fullscreen API.
pref("full-screen-api.enabled", true);
@ -1666,4 +1668,4 @@ pref("toolkit.pageThumbs.minHeight", 190);
#ifdef NIGHTLY_BUILD
// Enable speech synthesis, only Nightly for now
pref("media.webspeech.synth.enabled", true);
#endif
#endif

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

@ -11,7 +11,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/NotificationDB.jsm");
Cu.import("resource:///modules/RecentWindow.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
"resource://gre/modules/Preferences.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
@ -34,8 +33,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "GMPInstallManager",
"resource://gre/modules/GMPInstallManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils",
"resource://gre/modules/NewTabUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RemoteNewTabUtils",
"resource:///modules/RemoteNewTabUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ContentSearch",
"resource:///modules/ContentSearch.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AboutHome",
@ -3564,11 +3561,8 @@ const BrowserSearch = {
if (!aSearchBar || document.activeElement != aSearchBar.textbox.inputField) {
let url = gBrowser.currentURI.spec.toLowerCase();
let mm = gBrowser.selectedBrowser.messageManager;
let newTabRemoted = Services.prefs.getBoolPref("browser.newtabpage.remote");
if (url === "about:home" ||
(url === "about:newtab" &&
((!newTabRemoted && NewTabUtils.allPages.enabled) ||
(newTabRemoted && RemoteNewTabUtils.allPages.enabled)))) {
(url === "about:newtab" && NewTabUtils.allPages.enabled)) {
ContentSearch.focusInput(mm);
} else {
openUILinkIn("about:home", "current");

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

@ -90,9 +90,11 @@ static RedirEntry kRedirMap[] = {
nsIAboutModule::ENABLE_INDEXED_DB },
{ "newtab", "chrome://browser/content/newtab/newTab.xhtml",
nsIAboutModule::ALLOW_SCRIPT },
#ifndef RELEASE_BUILD
{ "remote-newtab", "chrome://browser/content/remote-newtab/newTab.xhtml",
nsIAboutModule::URI_MUST_LOAD_IN_CHILD |
nsIAboutModule::ALLOW_SCRIPT },
#endif
{ "preferences", "chrome://browser/content/preferences/in-content/preferences.xul",
nsIAboutModule::ALLOW_SCRIPT },
{ "downloads", "chrome://browser/content/downloads/contentAreaDownloadsView.xul",

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

@ -4,17 +4,18 @@
# 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/.
BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
if not CONFIG['RELEASE_BUILD']:
BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
XPCSHELL_TESTS_MANIFESTS += [
'tests/xpcshell/xpcshell.ini',
]
XPCSHELL_TESTS_MANIFESTS += [
'tests/xpcshell/xpcshell.ini',
]
EXTRA_JS_MODULES += [
'NewTabPrefsProvider.jsm',
'NewTabURL.jsm',
'PlacesProvider.jsm',
'RemoteAboutNewTab.jsm',
'RemoteNewTabLocation.jsm',
'RemoteNewTabUtils.jsm',
]
EXTRA_JS_MODULES += [
'NewTabPrefsProvider.jsm',
'NewTabURL.jsm',
'PlacesProvider.jsm',
'RemoteAboutNewTab.jsm',
'RemoteNewTabLocation.jsm',
'RemoteNewTabUtils.jsm',
]

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

@ -14,6 +14,9 @@ const POLARIS_ENABLED = "browser.polaris.enabled";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
"resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AboutHome",
"resource:///modules/AboutHome.jsm");
@ -26,14 +29,16 @@ XPCOMUtils.defineLazyModuleGetter(this, "DirectoryLinksProvider",
XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils",
"resource://gre/modules/NewTabUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RemoteAboutNewTab",
"resource:///modules/RemoteAboutNewTab.jsm");
if(!AppConstants.RELEASE_BUILD) {
XPCOMUtils.defineLazyModuleGetter(this, "RemoteAboutNewTab",
"resource:///modules/RemoteAboutNewTab.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RemoteNewTabUtils",
"resource:///modules/RemoteNewTabUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RemoteNewTabUtils",
"resource:///modules/RemoteNewTabUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
"resource:///modules/NewTabPrefsProvider.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
"resource:///modules/NewTabPrefsProvider.jsm");
}
XPCOMUtils.defineLazyModuleGetter(this, "UITour",
"resource:///modules/UITour.jsm");
@ -181,9 +186,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager",
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionManagement",
"resource://gre/modules/ExtensionManagement.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
"resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "WindowsUIUtils",
"@mozilla.org/windows-ui-utils;1", "nsIWindowsUIUtils");
@ -849,10 +851,12 @@ BrowserGlue.prototype = {
NewTabUtils.links.addProvider(DirectoryLinksProvider);
AboutNewTab.init();
RemoteNewTabUtils.init();
RemoteNewTabUtils.links.addProvider(DirectoryLinksProvider);
RemoteAboutNewTab.init();
NewTabPrefsProvider.prefs.init();
if(!AppConstants.RELEASE_BUILD) {
RemoteNewTabUtils.init();
RemoteNewTabUtils.links.addProvider(DirectoryLinksProvider);
RemoteAboutNewTab.init();
NewTabPrefsProvider.prefs.init();
}
SessionStore.init();
BrowserUITelemetry.init();
@ -1173,8 +1177,10 @@ BrowserGlue.prototype = {
CustomizationTabPreloader.uninit();
WebappManager.uninit();
RemoteAboutNewTab.uninit();
NewTabPrefsProvider.prefs.uninit();
if (!AppConstants.RELEASE_BUILD) {
RemoteAboutNewTab.uninit();
NewTabPrefsProvider.prefs.uninit();
}
AboutNewTab.uninit();
#ifdef NIGHTLY_BUILD
if (Services.prefs.getBoolPref("dom.identity.enabled")) {
@ -2585,9 +2591,11 @@ AboutNewTabService.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutNewTabService]),
get newTabURL() {
if (Services.prefs.getBoolPref("browser.newtabpage.remote")) {
if (!AppConstants.RELEASE_BUILD && Services.prefs.getBoolPref("browser.newtabpage.remote")) {
return "about:remote-newtab";
}
return this._newTabURL;
},

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

@ -17,6 +17,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/Timer.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm")
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
"resource://gre/modules/NetUtil.jsm");
@ -31,8 +32,13 @@ XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
XPCOMUtils.defineLazyServiceGetter(this, "eTLD",
"@mozilla.org/network/effective-tld-service;1",
"nsIEffectiveTLDService");
XPCOMUtils.defineLazyModuleGetter(this, "RemoteNewTabUtils",
"resource:///modules/RemoteNewTabUtils.jsm");
// ensure remote new tab doesn't go beyond aurora
if (!AppConstants.RELEASE_BUILD) {
XPCOMUtils.defineLazyModuleGetter(this, "RemoteNewTabUtils",
"resource:///modules/RemoteNewTabUtils.jsm");
}
XPCOMUtils.defineLazyGetter(this, "gTextDecoder", () => {
return new TextDecoder();
});
@ -760,8 +766,12 @@ var DirectoryLinksProvider = {
NewTabUtils.placesProvider.addObserver(this);
NewTabUtils.links.addObserver(this);
RemoteNewTabUtils.placesProvider.addObserver(this);
RemoteNewTabUtils.links.addObserver(this);
// ensure remote new tab doesn't go beyond aurora
if (!AppConstants.RELEASE_BUILD) {
RemoteNewTabUtils.placesProvider.addObserver(this);
RemoteNewTabUtils.links.addObserver(this);
}
return Task.spawn(function() {
// get the last modified time of the links file if it exists

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

@ -42,6 +42,7 @@ public:
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
uint64_t Root() const { return mDominatorTree.root().identifier(); }
};
} // namespace devtools

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

@ -117,6 +117,13 @@ function saveNewHeapSnapshot(opts = { runtime: true }) {
return filePath;
}
function readHeapSnapshot(filePath) {
const snapshot = ChromeUtils.readHeapSnapshot(filePath);
ok(snapshot, "Should have read a heap snapshot back from " + filePath);
ok(snapshot instanceof HeapSnapshot, "snapshot should be an instance of HeapSnapshot");
return snapshot;
}
/**
* Save a heap snapshot to the file with the given name in the current
* directory, read it back as a HeapSnapshot instance, and then take a census of
@ -138,18 +145,40 @@ function saveNewHeapSnapshot(opts = { runtime: true }) {
*/
function saveHeapSnapshotAndTakeCensus(dbg=null, censusOptions=undefined) {
const snapshotOptions = dbg ? { debugger: dbg } : { runtime: true };
const filePath = ChromeUtils.saveHeapSnapshot(snapshotOptions);
ok(filePath, "Should get a file path to save the core dump to.");
ok(true, "Should have saved a heap snapshot to " + filePath);
const snapshot = ChromeUtils.readHeapSnapshot(filePath);
ok(snapshot, "Should have read a heap snapshot back from " + filePath);
ok(snapshot instanceof HeapSnapshot, "snapshot should be an instance of HeapSnapshot");
const filePath = saveNewHeapSnapshot(snapshotOptions);
const snapshot = readHeapSnapshot(filePath);
equal(typeof snapshot.takeCensus, "function", "snapshot should have a takeCensus method");
return snapshot.takeCensus(censusOptions);
}
/**
* Save a heap snapshot to disk, read it back as a HeapSnapshot instance, and
* then compute its dominator tree.
*
* @param {Debugger|null} dbg
* If a Debugger object is given, only serialize the subgraph covered by
* the Debugger's debuggees. If null, serialize the whole heap graph.
*
* @returns {DominatorTree}
*/
function saveHeapSnapshotAndComputeDominatorTree(dbg = null) {
const snapshotOptions = dbg ? { debugger: dbg } : { runtime: true };
const filePath = saveNewHeapSnapshot(snapshotOptions);
const snapshot = readHeapSnapshot(filePath);
equal(typeof snapshot.computeDominatorTree, "function",
"snapshot should have a `computeDominatorTree` method");
const dominatorTree = snapshot.computeDominatorTree();
ok(dominatorTree, "Should be able to compute a dominator tree");
ok(dominatorTree instanceof DominatorTree, "Should be an instance of DominatorTree");
return dominatorTree;
}
function isSavedFrame(obj) {
return Object.prototype.toString.call(obj) === "[object SavedFrame]";
}

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

@ -0,0 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that we can get the root of dominator trees.
function run_test() {
const dominatorTree = saveHeapSnapshotAndComputeDominatorTree();
equal(typeof dominatorTree.root, "number", "root should be a number");
equal(Math.floor(dominatorTree.root), dominatorTree.root, "root should be an integer");
ok(dominatorTree.root >= 0, "root should be positive");
ok(dominatorTree.root <= Math.pow(2, 48), "root should be less than or equal to 2^48");
do_test_finished();
}

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

@ -30,6 +30,7 @@ support-files =
[test_census-tree-node-08.js]
[test_DominatorTree_01.js]
[test_DominatorTree_02.js]
[test_DominatorTree_03.js]
[test_HeapAnalyses_getCreationTime_01.js]
[test_HeapAnalyses_readHeapSnapshot_01.js]
[test_HeapAnalyses_takeCensusDiff_01.js]

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

@ -1450,7 +1450,7 @@ addAsyncAnimTest("tree_ordering", { observe: div, subtree: true }, function*() {
});
// Run the tests.
SimpleTest.requestLongerTimeout(2);
SimpleTest.waitForExplicitFinish();
runAllAsyncTests().then(function() {

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

@ -935,15 +935,15 @@ PerformanceBase::TranslateTime(DOMHighResTimeStamp aTime,
}
otherCreationTimeStamp = performance->CreationTimeStamp();
} else if (aTimeSource.IsWorker()) {
otherCreationTimeStamp = aTimeSource.GetAsWorker().NowBaseTimeStamp();
otherCreationTimeStamp = aTimeSource.GetAsWorker().CreationTimeStamp();
} else if (aTimeSource.IsSharedWorker()) {
SharedWorker& sharedWorker = aTimeSource.GetAsSharedWorker();
WorkerPrivate* workerPrivate = sharedWorker.GetWorkerPrivate();
otherCreationTimeStamp = workerPrivate->NowBaseTimeStamp();
otherCreationTimeStamp = workerPrivate->CreationTimeStamp();
} else if (aTimeSource.IsServiceWorker()) {
ServiceWorker& serviceWorker = aTimeSource.GetAsServiceWorker();
WorkerPrivate* workerPrivate = serviceWorker.GetWorkerPrivate();
otherCreationTimeStamp = workerPrivate->NowBaseTimeStamp();
otherCreationTimeStamp = workerPrivate->CreationTimeStamp();
} else {
MOZ_CRASH("This should not be possible.");
}

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

@ -127,23 +127,6 @@ function testHasRun() {
}
}
function createFileWithData(fileData) {
var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"].getService(SpecialPowers.Ci.nsIProperties);
var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
testFile.append("fileAPItestfile2-" + fileNum);
fileNum++;
var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].createInstance(SpecialPowers.Ci.nsIFileOutputStream);
outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
0666, 0);
outStream.write(fileData, fileData.length);
outStream.close();
var fileList = document.getElementById('fileList');
SpecialPowers.wrap(fileList).value = testFile.path;
return fileList.files[0];
}
function gc() {
window.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
.getInterface(SpecialPowers.Ci.nsIDOMWindowUtils)

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

@ -742,7 +742,7 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 904183 # b2g(bug 904183
[test_encodeToStringWithMaxLength.html]
[test_fileapi.html]
[test_fileapi_slice.html]
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s #bug 775227
skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 775227
[test_getElementById.html]
[test_html_colors_quirks.html]
[test_html_colors_standards.html]

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

@ -54,31 +54,6 @@ cx.fill();
cx.closePath();
var fileData =
atob(cx.canvas.toDataURL("image/png").substring("data:text/png;base64,".length + 1));
var memFile = cx.canvas.mozGetAsFile("image/png");
var fileFile = createFileWithData(fileData);
var size = fileData.length;
// This might fail if we dramatically improve the png encoder. If that happens
// please increase the complexity or size of the image generated above to ensure
// that we're testing with files that are large enough.
ok(size > 65536, "test data sufficiently large");
// Test that basic properties work
testSlice(memFile, size, "image/png", fileData, "memFile");
testSlice(fileFile, size, "", fileData, "fileFile");
// Try loading directly from slice into an image
var testBinaryData = "";
for (var i = 0; i < 256; i++) {
testBinaryData += String.fromCharCode(i);
}
while (testBinaryData.length < 20000) {
testBinaryData += testBinaryData;
}
function imageLoadHandler(event) {
var origcanvas = $("canvas");
var testcanvas = $("testcanvas");
@ -100,37 +75,93 @@ function imageLoadHandler(event) {
testHasRun();
}
// image in the middle
var imgfile = createFileWithData(testBinaryData + fileData + testBinaryData);
is(imgfile.size, size + testBinaryData.length * 2, "correct file size (middle)");
var img = new Image;
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size));
img.onload = imageLoadHandler;
expectedTestCount++;
var fileData =
atob(cx.canvas.toDataURL("image/png").substring("data:text/png;base64,".length + 1));
var size = fileData.length;
var testBinaryData = "";
// image at start
var imgfile = createFileWithData(fileData + testBinaryData);
is(imgfile.size, size + testBinaryData.length, "correct file size (start)");
var img = new Image;
img.src = URL.createObjectURL(imgfile.slice(0, size));
img.onload = imageLoadHandler;
expectedTestCount++;
// This might fail if we dramatically improve the png encoder. If that happens
// please increase the complexity or size of the image generated above to ensure
// that we're testing with files that are large enough.
ok(size > 65536, "test data sufficiently large");
// image at end
var imgfile = createFileWithData(testBinaryData + fileData);
is(imgfile.size, size + testBinaryData.length, "correct file size (end)");
var img = new Image;
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size));
img.onload = imageLoadHandler;
expectedTestCount++;
SpecialPowers.createFiles([{name: "basicTestFile", data: fileData}],
basicTest);
function basicTest(files) {
var fileFile = files[0];
// Test that basic properties work
var memFile = cx.canvas.mozGetAsFile("image/png");
testSlice(memFile, size, "image/png", fileData, "memFile");
testSlice(fileFile, size, "", fileData, "fileFile");
// Try loading directly from slice into an image
for (var i = 0; i < 256; i++) {
testBinaryData += String.fromCharCode(i);
}
while (testBinaryData.length < 20000) {
testBinaryData += testBinaryData;
}
// image in the middle
SpecialPowers.createFiles([{name: "middleTestFile",
data: testBinaryData + fileData + testBinaryData}],
imageMiddleTest);
}
function imageMiddleTest(files) {
var imgfile = files[0];
is(imgfile.size, size + testBinaryData.length * 2, "correct file size (middle)");
var img = new Image;
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size));
img.onload = imageLoadHandler;
expectedTestCount++;
// image at start
SpecialPowers.createFiles([{name: "startTestFile",
data: fileData + testBinaryData}],
imageStartTest);
}
function imageStartTest(files) {
var imgfile = files[0];
is(imgfile.size, size + testBinaryData.length, "correct file size (start)");
var img = new Image;
img.src = URL.createObjectURL(imgfile.slice(0, size));
img.onload = imageLoadHandler;
expectedTestCount++;
// image at end
SpecialPowers.createFiles([{name: "endTestFile",
data: testBinaryData + fileData}],
imageEndTest);
}
function imageEndTest(files) {
var imgfile = files[0];
is(imgfile.size, size + testBinaryData.length, "correct file size (end)");
var img = new Image;
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size));
img.onload = imageLoadHandler;
expectedTestCount++;
// image past end
SpecialPowers.createFiles([{name: "pastEndTestFile",
data: testBinaryData + fileData}],
imagePastEndTest);
}
function imagePastEndTest(files) {
var imgfile = files[0];
is(imgfile.size, size + testBinaryData.length, "correct file size (past end)");
var img = new Image;
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size + 1000));
img.onload = imageLoadHandler;
expectedTestCount++;
}
// image past end
var imgfile = createFileWithData(testBinaryData + fileData);
is(imgfile.size, size + testBinaryData.length, "correct file size (past end)");
var img = new Image;
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size + 1000));
img.onload = imageLoadHandler;
expectedTestCount++;
</script>
</pre>
</body> </html>
</body>
</html>

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

@ -43,7 +43,7 @@ function testWorker() {
var w = new Worker('empty_worker.js');
var a = performance.translateTime(0, w);
// bug 1226147
todo (a >= now, "Time has been translated from a Worker that started loading later than we did");
ok (a >= now, "Time has been translated from a Worker that started loading later than we did");
next();
}

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

@ -495,6 +495,7 @@ DOMInterfaces = {
'ExtendableEvent': {
'headerFile': 'mozilla/dom/ServiceWorkerEvents.h',
'nativeType': 'mozilla::dom::workers::ExtendableEvent',
'implicitJSContext': [ 'waitUntil' ],
},
'ExtendableMessageEvent': {

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

@ -2281,7 +2281,9 @@ public:
}
// unref stored DBusMessages before clearing the hashtable
sPairingReqTable->EnumerateRead(UnrefDBusMessage, nullptr);
for (auto iter = sPairingReqTable->Iter(); !iter.Done(); iter.Next()) {
dbus_message_unref(iter.UserData());
}
sPairingReqTable->Clear();
sIsPairing = 0;
@ -2299,14 +2301,6 @@ public:
BT_WARNING("Failed to dispatch to BT thread!");
}
}
private:
static PLDHashOperator
UnrefDBusMessage(const BluetoothAddress& key, DBusMessage* value, void* arg)
{
dbus_message_unref(value);
return PL_DHASH_NEXT;
}
};
class StopBluetoothRunnable final : public nsRunnable

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

@ -1118,7 +1118,7 @@ Event::TimeStamp() const
MOZ_ASSERT(workerPrivate);
TimeDuration duration =
mEvent->timeStamp - workerPrivate->NowBaseTimeStamp();
mEvent->timeStamp - workerPrivate->CreationTimeStamp();
return duration.ToMilliseconds();
}

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

@ -74,8 +74,9 @@ function testWorkerEvents() {
var worker = new Worker(window.URL.createObjectURL(blob));
worker.onmessage = function(evt) {
var timeAfterEvent = window.performance.now();
ok(evt.data > timeBeforeEvent &&
evt.data < timeAfterEvent,
var time = window.performance.translateTime(evt.data, worker);
ok(time >= timeBeforeEvent &&
time <= timeAfterEvent,
"Event timestamp in dedicated worker (" + evt.data +
") is in expected range: (" +
timeBeforeEvent + ", " + timeAfterEvent + ")");

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

@ -404,7 +404,7 @@ nsGenericHTMLElement::GetOffsetRect(CSSIntRect& aRect)
// Subtract the parent border unless it uses border-box sizing.
if (parent &&
parent->StylePosition()->mBoxSizing != NS_STYLE_BOX_SIZING_BORDER) {
parent->StylePosition()->mBoxSizing != StyleBoxSizing::Border) {
const nsStyleBorder* border = parent->StyleBorder();
origin.x -= border->GetComputedBorderWidth(NS_SIDE_LEFT);
origin.y -= border->GetComputedBorderWidth(NS_SIDE_TOP);

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

@ -50,14 +50,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=388794
SimpleTest.waitForExplicitFinish();
var pendingLoads = 0;
/* Use regex due to rounding error in Fennec with C++APZ enabled */
var hrefs = {
test1: "data:text/html,?testImage.x=0&testImage.y=0",
test2: "data:text/html,?x=0&y=0",
test3: "data:text/html,?testImage.x=0&testImage.y=0",
test4: "data:text/html,?x=0&y=0",
test5: "data:text/html,?testImage.x=5&testImage.y=5",
test6: "data:text/html,?x=5&y=5",
test1: /data:text\/html,\?testImage\.x=0&testImage\.y=0/,
test2: /data:text\/html,\?x=0&y=0/,
test3: /data:text\/html,\?testImage\.x=0&testImage\.y=0/,
test4: /data:text\/html,\?x=0&y=0/,
test5: /data:text\/html,\?testImage\.x=[4-6]&testImage\.y=[4-6]/,
test6: /data:text\/html,\?x=[4-6]&y=[4-6]/,
};
function submitForm(idNum) {
@ -91,8 +91,8 @@ addLoadEvent(function() {
});
function frameLoaded(frame) {
is(frame.contentWindow.location.href, hrefs[frame.name],
"Unexpected href for frame " + frame.name);
ok(hrefs[frame.name].test(frame.contentWindow.location.href),
"Unexpected href for frame " + frame.name, "expected to match: " + hrefs[frame.name].toString() + " got: " + frame.contentWindow.location.href);
if (--pendingLoads == 0) {
SimpleTest.finish();
}

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

@ -93,7 +93,9 @@ public:
if (mozilla::IsInfinite<double>(aValue)) {
return FromInfinity();
}
double val = aValue * USECS_PER_S;
// Due to internal double representation, this
// operation is not commutative, do not attempt to simplify.
double val = (aValue + .0000005) * USECS_PER_S;
if (val >= double(INT64_MAX)) {
return FromMicroseconds(INT64_MAX);
} else if (val <= double(INT64_MIN)) {

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

@ -0,0 +1,22 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "TimeUnits.h"
#include <algorithm>
#include <vector>
using namespace mozilla;
TEST(TimeUnit, Rounding)
{
int64_t usecs = 66261715;
double seconds = media::TimeUnit::FromMicroseconds(usecs).ToSeconds();
EXPECT_EQ(media::TimeUnit::FromSeconds(seconds).ToMicroseconds(), usecs);
seconds = 4.169470;
usecs = 4169470;
EXPECT_EQ(media::TimeUnit::FromSeconds(seconds).ToMicroseconds(), usecs);
}

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

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -263,18 +264,6 @@ MessagePortService::ClosePort(MessagePortParent* aParent)
return true;
}
#ifdef DEBUG
PLDHashOperator
MessagePortService::CloseAllDebugCheck(const nsID& aID,
MessagePortServiceData* aData,
void* aPtr)
{
nsID* id = static_cast<nsID*>(aPtr);
MOZ_ASSERT(!id->Equals(aID));
return PL_DHASH_NEXT;
}
#endif
void
MessagePortService::CloseAll(const nsID& aUUID, bool aForced)
{
@ -319,7 +308,9 @@ MessagePortService::CloseAll(const nsID& aUUID, bool aForced)
}
#ifdef DEBUG
mPorts.EnumerateRead(CloseAllDebugCheck, const_cast<nsID*>(&aUUID));
for (auto iter = mPorts.Iter(); !iter.Done(); iter.Next()) {
MOZ_ASSERT(!aUUID.Equals(iter.Key()));
}
#endif
MaybeShutdown();

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

@ -151,19 +151,6 @@ DOMStorageCache::Persist(const DOMStorage* aStorage) const
!aStorage->IsPrivate();
}
namespace {
PLDHashOperator
CloneSetData(const nsAString& aKey, const nsString aValue, void* aArg)
{
DOMStorageCache::Data* target = static_cast<DOMStorageCache::Data*>(aArg);
target->mKeys.Put(aKey, aValue);
return PL_DHASH_NEXT;
}
} // namespace
DOMStorageCache::Data&
DOMStorageCache::DataSet(const DOMStorage* aStorage)
{
@ -178,7 +165,9 @@ DOMStorageCache::DataSet(const DOMStorage* aStorage)
Data& defaultSet = mData[kDefaultSet];
Data& sessionSet = mData[kSessionSet];
defaultSet.mKeys.EnumerateRead(CloneSetData, &sessionSet);
for (auto iter = defaultSet.mKeys.Iter(); !iter.Done(); iter.Next()) {
sessionSet.mKeys.Put(iter.Key(), iter.UserData());
}
mSessionOnlyDataSetActive = true;
@ -363,36 +352,6 @@ DOMStorageCache::GetLength(const DOMStorage* aStorage, uint32_t* aRetval)
return NS_OK;
}
namespace {
class IndexFinderData
{
public:
IndexFinderData(uint32_t aIndex, nsAString& aRetval)
: mIndex(aIndex), mKey(aRetval)
{
mKey.SetIsVoid(true);
}
uint32_t mIndex;
nsAString& mKey;
};
PLDHashOperator
FindKeyOrder(const nsAString& aKey, const nsString aValue, void* aArg)
{
IndexFinderData* data = static_cast<IndexFinderData*>(aArg);
if (data->mIndex--) {
return PL_DHASH_NEXT;
}
data->mKey = aKey;
return PL_DHASH_STOP;
}
} // namespace
nsresult
DOMStorageCache::GetKey(const DOMStorage* aStorage, uint32_t aIndex, nsAString& aRetval)
{
@ -407,24 +366,18 @@ DOMStorageCache::GetKey(const DOMStorage* aStorage, uint32_t aIndex, nsAString&
}
}
IndexFinderData data(aIndex, aRetval);
DataSet(aStorage).mKeys.EnumerateRead(FindKeyOrder, &data);
aRetval.SetIsVoid(true);
for (auto iter = DataSet(aStorage).mKeys.Iter(); !iter.Done(); iter.Next()) {
if (aIndex == 0) {
aRetval = iter.Key();
break;
}
aIndex--;
}
return NS_OK;
}
namespace {
static PLDHashOperator
KeysArrayBuilder(const nsAString& aKey, const nsString aValue, void* aArg)
{
nsTArray<nsString>* keys = static_cast<nsTArray<nsString>* >(aArg);
keys->AppendElement(aKey);
return PL_DHASH_NEXT;
}
} // namespace
void
DOMStorageCache::GetKeys(const DOMStorage* aStorage, nsTArray<nsString>& aKeys)
{
@ -436,7 +389,9 @@ DOMStorageCache::GetKeys(const DOMStorage* aStorage, nsTArray<nsString>& aKeys)
return;
}
DataSet(aStorage).mKeys.EnumerateRead(KeysArrayBuilder, &aKeys);
for (auto iter = DataSet(aStorage).mKeys.Iter(); !iter.Done(); iter.Next()) {
aKeys.AppendElement(iter.Key());
}
}
nsresult
@ -598,7 +553,9 @@ DOMStorageCache::CloneFrom(const DOMStorageCache* aThat)
mSessionOnlyDataSetActive = aThat->mSessionOnlyDataSetActive;
for (uint32_t i = 0; i < kDataSetCount; ++i) {
aThat->mData[i].mKeys.EnumerateRead(CloneSetData, &mData[i]);
for (auto it = aThat->mData[i].mKeys.ConstIter(); !it.Done(); it.Next()) {
mData[i].mKeys.Put(it.Key(), it.UserData());
}
ProcessUsageDelta(i, aThat->mData[i].mOriginQuotaUsage);
}
}

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

@ -1253,40 +1253,25 @@ DOMStorageDBThread::PendingOperations::Finalize(nsresult aRv)
namespace {
class FindPendingOperationForScopeData
bool
FindPendingClearForScope(const nsACString& aScope,
DOMStorageDBThread::DBOperation* aPendingOperation)
{
public:
explicit FindPendingOperationForScopeData(const nsACString& aScope) : mScope(aScope), mFound(false) {}
nsCString mScope;
bool mFound;
};
PLDHashOperator
FindPendingClearForScope(const nsACString& aMapping,
DOMStorageDBThread::DBOperation* aPendingOperation,
void* aArg)
{
FindPendingOperationForScopeData* data =
static_cast<FindPendingOperationForScopeData*>(aArg);
if (aPendingOperation->Type() == DOMStorageDBThread::DBOperation::opClearAll) {
data->mFound = true;
return PL_DHASH_STOP;
return true;
}
if (aPendingOperation->Type() == DOMStorageDBThread::DBOperation::opClear &&
data->mScope == aPendingOperation->Scope()) {
data->mFound = true;
return PL_DHASH_STOP;
aScope == aPendingOperation->Scope()) {
return true;
}
if (aPendingOperation->Type() == DOMStorageDBThread::DBOperation::opClearMatchingScope &&
StringBeginsWith(data->mScope, aPendingOperation->Scope())) {
data->mFound = true;
return PL_DHASH_STOP;
StringBeginsWith(aScope, aPendingOperation->Scope())) {
return true;
}
return PL_DHASH_NEXT;
return false;
}
} // namespace
@ -1296,17 +1281,14 @@ DOMStorageDBThread::PendingOperations::IsScopeClearPending(const nsACString& aSc
{
// Called under the lock
FindPendingOperationForScopeData data(aScope);
mClears.EnumerateRead(FindPendingClearForScope, &data);
if (data.mFound) {
return true;
for (auto iter = mClears.Iter(); !iter.Done(); iter.Next()) {
if (FindPendingClearForScope(aScope, iter.UserData())) {
return true;
}
}
for (uint32_t i = 0; i < mExecList.Length(); ++i) {
DOMStorageDBThread::DBOperation* task = mExecList[i];
FindPendingClearForScope(EmptyCString(), task, &data);
if (data.mFound) {
if (FindPendingClearForScope(aScope, mExecList[i])) {
return true;
}
}
@ -1316,23 +1298,18 @@ DOMStorageDBThread::PendingOperations::IsScopeClearPending(const nsACString& aSc
namespace {
PLDHashOperator
FindPendingUpdateForScope(const nsACString& aMapping,
DOMStorageDBThread::DBOperation* aPendingOperation,
void* aArg)
bool
FindPendingUpdateForScope(const nsACString& aScope,
DOMStorageDBThread::DBOperation* aPendingOperation)
{
FindPendingOperationForScopeData* data =
static_cast<FindPendingOperationForScopeData*>(aArg);
if ((aPendingOperation->Type() == DOMStorageDBThread::DBOperation::opAddItem ||
aPendingOperation->Type() == DOMStorageDBThread::DBOperation::opUpdateItem ||
aPendingOperation->Type() == DOMStorageDBThread::DBOperation::opRemoveItem) &&
data->mScope == aPendingOperation->Scope()) {
data->mFound = true;
return PL_DHASH_STOP;
aScope == aPendingOperation->Scope()) {
return true;
}
return PL_DHASH_NEXT;
return false;
}
} // namespace
@ -1342,17 +1319,14 @@ DOMStorageDBThread::PendingOperations::IsScopeUpdatePending(const nsACString& aS
{
// Called under the lock
FindPendingOperationForScopeData data(aScope);
mUpdates.EnumerateRead(FindPendingUpdateForScope, &data);
if (data.mFound) {
return true;
for (auto iter = mUpdates.Iter(); !iter.Done(); iter.Next()) {
if (FindPendingUpdateForScope(aScope, iter.UserData())) {
return true;
}
}
for (uint32_t i = 0; i < mExecList.Length(); ++i) {
DOMStorageDBThread::DBOperation* task = mExecList[i];
FindPendingUpdateForScope(EmptyCString(), task, &data);
if (data.mFound) {
if (FindPendingUpdateForScope(aScope, mExecList[i])) {
return true;
}
}

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

@ -4,6 +4,8 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
typedef unsigned long long NodeId;
/**
* In a directed graph with a root node `R`, a node `A` is said to "dominate" a
* node `B` iff every path from `R` to `B` contains `A`. A node `A` is said to
@ -37,5 +39,10 @@
*/
[ChromeOnly, Exposed=(Window,System,Worker)]
interface DominatorTree {
/**
* The `NodeId` for the root of the dominator tree. This is a "meta-root" in
* that it has an edge to each GC root in the heap snapshot this dominator
* tree was created from.
*/
readonly attribute NodeId root;
};

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

@ -10,7 +10,6 @@
* W3C liability, trademark and document use rules apply.
*/
enum IsTypeSupportedResult { "" /* empty string */, "maybe", "probably" };
enum SessionType { "temporary", "persistent" };
[Pref="media.eme.apiVisible"]

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

@ -32,13 +32,8 @@ DOMHighResTimeStamp
Performance::Now() const
{
TimeDuration duration =
TimeStamp::Now() - mWorkerPrivate->NowBaseTimeStamp();
double nowTime = duration.ToMilliseconds();
// Round down to the nearest 5us, because if the timer is too accurate people
// can do nasty timing attacks with it. See similar code in the non-worker
// Performance implementation.
const double maxResolutionMs = 0.005;
return floor(nowTime / maxResolutionMs) * maxResolutionMs;
TimeStamp::Now() - mWorkerPrivate->CreationTimeStamp();
return RoundTime(duration.ToMilliseconds());
}
// To be removed once bug 1124165 lands
@ -57,7 +52,7 @@ Performance::GetPerformanceTimingFromString(const nsAString& aProperty)
}
if (aProperty.EqualsLiteral("navigationStart")) {
return mWorkerPrivate->NowBaseTimeHighRes();
return mWorkerPrivate->CreationTime();
}
MOZ_CRASH("IsPerformanceTimingAttribute and GetPerformanceTimingFromString are out of sync");
@ -82,13 +77,13 @@ Performance::InsertUserEntry(PerformanceEntry* aEntry)
TimeStamp
Performance::CreationTimeStamp() const
{
return mWorkerPrivate->NowBaseTimeStamp();
return mWorkerPrivate->CreationTimeStamp();
}
DOMHighResTimeStamp
Performance::CreationTime() const
{
return mWorkerPrivate->NowBaseTimeHighRes();
return mWorkerPrivate->CreationTime();
}
void

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

@ -697,7 +697,9 @@ FetchEvent::RespondWith(JSContext* aCx, Promise& aArg, ErrorResult& aRv)
spec, line, column);
aArg.AppendNativeHandler(handler);
WaitUntil(aArg, aRv);
// Append directly to the lifecycle promises array. Don't call WaitUntil()
// because that will lead to double-reporting any errors.
mPromises.AppendElement(&aArg);
}
void
@ -739,6 +741,94 @@ FetchEvent::ReportCanceled()
NS_LITERAL_CSTRING("InterceptionCanceledWithURL"), &requestURL);
}
namespace {
class WaitUntilHandler final : public PromiseNativeHandler
{
WorkerPrivate* mWorkerPrivate;
const nsCString mScope;
nsCString mSourceSpec;
uint32_t mLine;
uint32_t mColumn;
nsString mRejectValue;
~WaitUntilHandler()
{
}
public:
NS_DECL_THREADSAFE_ISUPPORTS
WaitUntilHandler(WorkerPrivate* aWorkerPrivate, JSContext* aCx)
: mWorkerPrivate(aWorkerPrivate)
, mScope(mWorkerPrivate->WorkerName())
, mLine(0)
, mColumn(0)
{
mWorkerPrivate->AssertIsOnWorkerThread();
// Save the location of the waitUntil() call itself as a fallback
// in case the rejection value does not contain any location info.
nsJSUtils::GetCallingLocation(aCx, mSourceSpec, &mLine, &mColumn);
}
void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
{
// do nothing, we are only here to report errors
}
void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
{
mWorkerPrivate->AssertIsOnWorkerThread();
nsCString spec;
uint32_t line = 0;
uint32_t column = 0;
ExtractErrorValues(aCx, aValue, spec, &line, &column, mRejectValue);
// only use the extracted location if we found one
if (!spec.IsEmpty()) {
mSourceSpec = spec;
mLine = line;
mColumn = column;
}
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableMethod(this, &WaitUntilHandler::ReportOnMainThread);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
NS_DispatchToMainThread(runnable.forget())));
}
void
ReportOnMainThread()
{
AssertIsOnMainThread();
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
// TODO: Make the error message a localized string. (bug 1222720)
nsString message;
message.AppendLiteral("Service worker event waitUntil() was passed a "
"promise that rejected with '");
message.Append(mRejectValue);
message.AppendLiteral("'.");
// Note, there is a corner case where this won't report to the window
// that triggered the error. Consider a navigation fetch event that
// rejects waitUntil() without holding respondWith() open. In this case
// there is no controlling document yet, the window did call .register()
// because there is no documeny yet, and the navigation is no longer
// being intercepted.
swm->ReportToAllClients(mScope, message, NS_ConvertUTF8toUTF16(mSourceSpec),
EmptyString(), mLine, mColumn,
nsIScriptError::errorFlag);
}
};
NS_IMPL_ISUPPORTS0(WaitUntilHandler)
} // anonymous namespace
NS_IMPL_ADDREF_INHERITED(FetchEvent, ExtendableEvent)
NS_IMPL_RELEASE_INHERITED(FetchEvent, ExtendableEvent)
@ -753,7 +843,7 @@ ExtendableEvent::ExtendableEvent(EventTarget* aOwner)
}
void
ExtendableEvent::WaitUntil(Promise& aPromise, ErrorResult& aRv)
ExtendableEvent::WaitUntil(JSContext* aCx, Promise& aPromise, ErrorResult& aRv)
{
MOZ_ASSERT(!NS_IsMainThread());
@ -762,6 +852,12 @@ ExtendableEvent::WaitUntil(Promise& aPromise, ErrorResult& aRv)
return;
}
// Append our handler to each waitUntil promise separately so we
// can record the location in script where waitUntil was called.
RefPtr<WaitUntilHandler> handler =
new WaitUntilHandler(GetCurrentThreadWorkerPrivate(), aCx);
aPromise.AppendNativeHandler(handler);
mPromises.AppendElement(&aPromise);
}

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

@ -51,9 +51,9 @@ public:
class ExtendableEvent : public Event
{
protected:
nsTArray<RefPtr<Promise>> mPromises;
protected:
explicit ExtendableEvent(mozilla::dom::EventTarget* aOwner);
~ExtendableEvent() {}
@ -90,7 +90,7 @@ public:
}
void
WaitUntil(Promise& aPromise, ErrorResult& aRv);
WaitUntil(JSContext* aCx, Promise& aPromise, ErrorResult& aRv);
already_AddRefed<Promise>
GetPromise();

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

@ -945,10 +945,10 @@ public:
mRegistration = swm->GetRegistration(mPrincipal, mScope);
if (mRegistration) {
mRegistration->mPendingUninstall = false;
RefPtr<ServiceWorkerInfo> newest = mRegistration->Newest();
if (newest && mScriptSpec.Equals(newest->ScriptSpec()) &&
mScriptSpec.Equals(mRegistration->mScriptSpec)) {
mRegistration->mPendingUninstall = false;
swm->StoreRegistration(mPrincipal, mRegistration);
Succeed();

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

@ -406,21 +406,10 @@ public:
NS_RUNTIMEABORT("Failed to dispatch life cycle event handler.");
}
JS::Rooted<JSObject*> obj(aCx, workerPrivate->GlobalScope()->GetWrapper());
JS::ExposeValueToActiveJS(aValue);
js::ErrorReport report(aCx);
if (NS_WARN_IF(!report.init(aCx, aValue))) {
JS_ClearPendingException(aCx);
return;
}
RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
xpcReport->Init(report.report(), report.message(),
/* aIsChrome = */ false, workerPrivate->WindowID());
RefPtr<AsyncErrorReporter> aer = new AsyncErrorReporter(xpcReport);
NS_DispatchToMainThread(aer);
// Note, all WaitUntil() rejections are reported to client consoles
// by the WaitUntilHandler in ServiceWorkerEvents. This ensures that
// errors in non-lifecycle events like FetchEvent and PushEvent are
// reported properly.
}
};

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

@ -2192,24 +2192,11 @@ WorkerPrivateParent<Derived>::WorkerPrivateParent(
aParent->CopyJSSettings(mJSSettings);
MOZ_ASSERT(IsDedicatedWorker());
mNowBaseTimeStamp = aParent->NowBaseTimeStamp();
mNowBaseTimeHighRes = aParent->NowBaseTimeHighRes();
}
else {
AssertIsOnMainThread();
RuntimeService::GetDefaultJSSettings(mJSSettings);
if (IsDedicatedWorker() && mLoadInfo.mWindow &&
mLoadInfo.mWindow->GetPerformance()) {
mNowBaseTimeStamp = mLoadInfo.mWindow->GetPerformance()->GetDOMTiming()->
GetNavigationStartTimeStamp();
mNowBaseTimeHighRes = mLoadInfo.mWindow->GetPerformance()->GetDOMTiming()->
GetNavigationStartHighRes();
} else {
mNowBaseTimeStamp = CreationTimeStamp();
mNowBaseTimeHighRes = CreationTimeHighRes();
}
}
}

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

@ -191,8 +191,6 @@ private:
WorkerType mWorkerType;
TimeStamp mCreationTimeStamp;
DOMHighResTimeStamp mCreationTimeHighRes;
TimeStamp mNowBaseTimeStamp;
DOMHighResTimeStamp mNowBaseTimeHighRes;
protected:
// The worker is owned by its thread, which is represented here. This is set
@ -549,21 +547,11 @@ public:
return mCreationTimeStamp;
}
DOMHighResTimeStamp CreationTimeHighRes() const
DOMHighResTimeStamp CreationTime() const
{
return mCreationTimeHighRes;
}
TimeStamp NowBaseTimeStamp() const
{
return mNowBaseTimeStamp;
}
DOMHighResTimeStamp NowBaseTimeHighRes() const
{
return mNowBaseTimeHighRes;
}
nsIPrincipal*
GetPrincipal() const
{

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

@ -472,6 +472,9 @@ DrawTargetD2D::DrawSurfaceWithShadow(SourceSurface *aSurface,
}
srView = static_cast<SourceSurfaceD2DTarget*>(aSurface)->GetSRView();
if (!srView) {
return;
}
EnsureViews();
@ -759,6 +762,11 @@ DrawTargetD2D::DrawSurfaceWithShadow(SourceSurface *aSurface,
mDevice->Draw(4, 0);
srView = static_cast<SourceSurfaceD2DTarget*>(aSurface)->GetSRView();
if (!srView) {
return;
}
mPrivateData->mEffect->GetVariableByName("QuadDesc")->AsVector()->
SetFloatVector(ShaderConstantRectD3D10(-1.0f + ((aDest.x / mSize.width) * 2.0f),
1.0f - (aDest.y / mSize.height * 2.0f),

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

@ -230,30 +230,15 @@ PathBuilderD2D::Arc(const Point &aOrigin, Float aRadius, Float aStartAngle,
aEndAngle = oldStart;
}
const Float kSmallRadius = 0.007f;
Float midAngle = 0;
bool smallFullCircle = false;
// XXX - Workaround for now, D2D does not appear to do the desired thing when
// the angle sweeps a complete circle.
bool fullCircle = false;
if (aEndAngle - aStartAngle >= 2 * M_PI) {
if (aRadius > kSmallRadius) {
aEndAngle = Float(aStartAngle + M_PI * 1.9999);
}
else {
smallFullCircle = true;
midAngle = Float(aStartAngle + M_PI);
aEndAngle = Float(aStartAngle + 2 * M_PI);
}
fullCircle = true;
aEndAngle = Float(aStartAngle + M_PI * 1.9999);
} else if (aStartAngle - aEndAngle >= 2 * M_PI) {
if (aRadius > kSmallRadius) {
aStartAngle = Float(aEndAngle + M_PI * 1.9999);
}
else {
smallFullCircle = true;
midAngle = Float(aEndAngle + M_PI);
aStartAngle = Float(aEndAngle + 2 * M_PI);
}
fullCircle = true;
aStartAngle = Float(aEndAngle + M_PI * 1.9999);
}
Point startPoint;
@ -275,7 +260,12 @@ PathBuilderD2D::Arc(const Point &aOrigin, Float aRadius, Float aStartAngle,
aAntiClockwise ? D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE :
D2D1_SWEEP_DIRECTION_CLOCKWISE;
if (!smallFullCircle) {
// if startPoint and endPoint of our circle are too close there are D2D issues
// with drawing the circle as a single arc
const Float kEpsilon = 1e-5f;
if (!fullCircle ||
(std::abs(startPoint.x - endPoint.x) +
std::abs(startPoint.y - endPoint.y) > kEpsilon)) {
if (aAntiClockwise) {
if (aStartAngle - aEndAngle > M_PI) {
@ -294,7 +284,10 @@ PathBuilderD2D::Arc(const Point &aOrigin, Float aRadius, Float aStartAngle,
arcSize));
}
else {
// draw small circles as two half-circles
// our first workaround attempt didn't work, so instead draw the circle as
// two half-circles
Float midAngle = aEndAngle > aStartAngle ?
Float(aStartAngle + M_PI) : Float(aEndAngle + M_PI);
Point midPoint;
midPoint.x = aOrigin.x + aRadius * cosf(midAngle);
midPoint.y = aOrigin.y + aRadius * sinf(midAngle);
@ -305,7 +298,9 @@ PathBuilderD2D::Arc(const Point &aOrigin, Float aRadius, Float aStartAngle,
direction,
arcSize));
mSink->AddArc(D2D1::ArcSegment(D2DPoint(endPoint),
// if the adjusted endPoint computed above is used here and endPoint !=
// startPoint then this half of the circle won't render...
mSink->AddArc(D2D1::ArcSegment(D2DPoint(startPoint),
D2D1::SizeF(aRadius, aRadius),
0.0f,
direction,

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

@ -96,6 +96,11 @@ SourceSurfaceD2DTarget::GetSRView()
return mSRView;
}
if (!Factory::GetDirect3D10Device()) {
gfxCriticalError() << "Invalid D3D10 device in D2D target surface";
return nullptr;
}
HRESULT hr = Factory::GetDirect3D10Device()->CreateShaderResourceView(mTexture, nullptr, getter_AddRefs(mSRView));
if (FAILED(hr)) {

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

@ -40,15 +40,8 @@ RectTriangles::addRect(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
static GLfloat
WrapTexCoord(GLfloat v)
{
// fmodf gives negative results for negative numbers;
// that is, fmodf(0.75, 1.0) == 0.75, but
// fmodf(-0.75, 1.0) == -0.75. For the negative case,
// the result we need is 0.25, so we add 1.0f.
if (v < 0.0f) {
return 1.0f + fmodf(v, 1.0f);
}
return fmodf(v, 1.0f);
// This should return values in range [0, 1.0)
return v - floorf(v);
}
void

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

@ -200,15 +200,8 @@ Compositor::FillRect(const gfx::Rect& aRect, const gfx::Color& aColor,
static float
WrapTexCoord(float v)
{
// fmodf gives negative results for negative numbers;
// that is, fmodf(0.75, 1.0) == 0.75, but
// fmodf(-0.75, 1.0) == -0.75. For the negative case,
// the result we need is 0.25, so we add 1.0f.
if (v < 0.0f) {
return 1.0f + fmodf(v, 1.0f);
}
return fmodf(v, 1.0f);
// This should return values in range [0, 1.0)
return v - floorf(v);
}
static void

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

@ -1220,14 +1220,16 @@ APZCTreeManager::UpdateZoomConstraints(const ScrollableLayerGuid& aGuid,
}
if (node && aConstraints) {
ForEachNode(node.get(),
[&aConstraints, this](HitTestingTreeNode* aNode)
[&aConstraints, &node, this](HitTestingTreeNode* aNode)
{
if (AsyncPanZoomController* childApzc = aNode->GetApzc()) {
// We can have subtrees with their own zoom constraints or separate layers
// id - leave these alone.
if (childApzc->HasNoParentWithSameLayersId() ||
this->mZoomConstraints.find(childApzc->GetGuid()) != this->mZoomConstraints.end()) {
return TraversalFlag::Skip;
if (aNode != node) {
if (AsyncPanZoomController* childApzc = aNode->GetApzc()) {
// We can have subtrees with their own zoom constraints or separate layers
// id - leave these alone.
if (childApzc->HasNoParentWithSameLayersId() ||
this->mZoomConstraints.find(childApzc->GetGuid()) != this->mZoomConstraints.end()) {
return TraversalFlag::Skip;
}
}
}
if (aNode->IsPrimaryHolder()) {

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

@ -168,7 +168,10 @@ ContainerRenderVR(ContainerT* aContainer,
if (!aContainer->mVRRenderTargetSet || aContainer->mVRRenderTargetSet->size != surfaceRect.Size()) {
aContainer->mVRRenderTargetSet = vrRendering->CreateRenderTargetSet(compositor, surfaceRect.Size());
}
if (!aContainer->mVRRenderTargetSet) {
NS_WARNING("CreateRenderTargetSet failed");
return;
}
surface = aContainer->mVRRenderTargetSet->GetNextRenderTarget();
if (!surface) {
NS_WARNING("GetNextRenderTarget failed");

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

@ -370,6 +370,9 @@ TextureClientD3D11::Unlock()
if (NS_IsMainThread() && mReadbackSink && mTexture10) {
ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
if (!device) {
return;
}
D3D10_TEXTURE2D_DESC desc;
mTexture10->GetDesc(&desc);
@ -588,6 +591,9 @@ TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlag
}
} else {
ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
if (!device) {
return false;
}
CD3D10_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
aSize.width, aSize.height, 1, 1,
@ -1235,6 +1241,9 @@ SyncObjectD3D11::FinalizeFrame()
if (!mD3D10Texture && mD3D10SyncedTextures.size()) {
ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
if (!device) {
return;
}
hr = device->OpenSharedResource(mHandle, __uuidof(ID3D10Texture2D), (void**)(ID3D10Texture2D**)getter_AddRefs(mD3D10Texture));
@ -1305,6 +1314,9 @@ SyncObjectD3D11::FinalizeFrame()
box.back = box.bottom = box.right = 1;
ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
if (!device) {
return;
}
for (auto iter = mD3D10SyncedTextures.begin(); iter != mD3D10SyncedTextures.end(); iter++) {
device->CopySubresourceRegion(mD3D10Texture, 0, 0, 0, 0, *iter, 0, &box);

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

@ -0,0 +1,17 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg"
width="100%" height="100%">
<title>Testcase for small radius circle with large center coordinates</title>
<!--From https://bugzilla.mozilla.org/show_bug.cgi?id=1131264 -->
<rect width="100%" height="100%" fill="lime"/>
<circle r="5" cx="40" cy="40" fill="red" />
<circle r="1" cx="10004" cy="10004" fill="lime"
transform="scale(10 10) translate(-10000 -10000)"/>
</svg>

После

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

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

@ -6,3 +6,4 @@ skip-if(!asyncPan) == 1086723.html 1086723-ref.html
== 853889-1.html 853889-1-ref.html
skip-if(Android) == 1143303-1.svg pass.svg
fuzzy(100,30) == 1149923.html 1149923-ref.html # use fuzzy due to few distorted pixels caused by border-radius
== 1131264-1.svg pass.svg

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

@ -29,6 +29,7 @@
#ifdef MOZ_WIDGET_GTK
#include <gdk/gdk.h>
#include "gfxPlatformGtk.h"
#endif
using namespace mozilla;
@ -400,6 +401,21 @@ gfxFontconfigFontEntry::~gfxFontconfigFontEntry()
{
}
static bool
PatternHasLang(const FcPattern *aPattern, const FcChar8 *aLang)
{
FcLangSet *langset;
if (FcPatternGetLangSet(aPattern, FC_LANG, 0, &langset) != FcResultMatch) {
return false;
}
if (FcLangSetHasLang(langset, aLang) != FcLangDifferentLang) {
return true;
}
return false;
}
bool
gfxFontconfigFontEntry::SupportsLangGroup(nsIAtom *aLangGroup) const
{
@ -415,16 +431,7 @@ gfxFontconfigFontEntry::SupportsLangGroup(nsIAtom *aLangGroup) const
}
// is lang included in the underlying pattern?
FcLangSet *langset;
if (FcPatternGetLangSet(mFontPattern, FC_LANG, 0, &langset) != FcResultMatch) {
return false;
}
if (FcLangSetHasLang(langset, (FcChar8 *)fcLang.get()) != FcLangDifferentLang) {
return true;
}
return false;
return PatternHasLang(mFontPattern, ToFcChar8Ptr(fcLang.get()));
}
nsresult
@ -1551,7 +1558,7 @@ gfxFcPlatformFontList::AddGenericFonts(mozilla::FontFamilyType aGenericType,
void
gfxFcPlatformFontList::ClearLangGroupPrefFonts()
{
mGenericMappings.Clear();
ClearGenericMappings();
gfxPlatformFontList::ClearLangGroupPrefFonts();
mAlwaysUseFontconfigGenerics = PrefFontListsUseOnlyGenerics();
}
@ -1596,9 +1603,6 @@ gfxFcPlatformFontList::GetFTLibrary()
return sCairoFTLibrary;
}
// a given generic will map to at most this many families
const uint32_t kMaxGenericFamilies = 3;
gfxPlatformFontList::PrefFontList*
gfxFcPlatformFontList::FindGenericFamilies(const nsAString& aGeneric,
nsIAtom* aLanguage)
@ -1651,6 +1655,8 @@ gfxFcPlatformFontList::FindGenericFamilies(const nsAString& aGeneric,
// -- select the fonts to be used for the generic
prefFonts = new PrefFontList; // can be empty but in practice won't happen
uint32_t limit = gfxPlatformGtk::GetPlatform()->MaxGenericSubstitions();
bool foundFontWithLang = false;
for (int i = 0; i < faces->nfont; i++) {
FcPattern* font = faces->fonts[i];
FcChar8* mappedGeneric = nullptr;
@ -1668,14 +1674,25 @@ gfxFcPlatformFontList::FindGenericFamilies(const nsAString& aGeneric,
gfxFontFamily* genericFamily =
gfxPlatformFontList::FindFamily(mappedGenericName);
if (genericFamily && !prefFonts->Contains(genericFamily)) {
//printf("generic %s ==> %s\n", genericLang.get(), (const char*)mappedGeneric);
prefFonts->AppendElement(genericFamily);
if (prefFonts->Length() >= kMaxGenericFamilies) {
bool foundLang = !fcLang.IsEmpty() &&
PatternHasLang(font, ToFcChar8Ptr(fcLang.get()));
foundFontWithLang = foundFontWithLang || foundLang;
// stop at the first family for which the lang matches (or
// when there is no lang)
if (fcLang.IsEmpty() ||
prefFonts->Length() >= limit || foundLang) {
break;
}
}
}
}
// if no font in the list matches the lang, trim all but the first one
if (!prefFonts->IsEmpty() && !foundFontWithLang) {
prefFonts->TruncateLength(1);
}
mGenericMappings.Put(genericLang, prefFonts);
return prefFonts;
}

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

@ -239,6 +239,11 @@ public:
void ClearLangGroupPrefFonts() override;
// clear out cached generic-lang ==> family-list mappings
void ClearGenericMappings() {
mGenericMappings.Clear();
}
void GetSampleLangForGroup(nsIAtom* aLanguage, nsACString& aLangStr);
static FT_Library GetFTLibrary();

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

@ -1772,8 +1772,8 @@ gfxPlatform::GetBidiNumeralOption()
return mBidiNumeralOption;
}
static void
FlushFontAndWordCaches()
/* static */ void
gfxPlatform::FlushFontAndWordCaches()
{
gfxFontCache *fontCache = gfxFontCache::GetCache();
if (fontCache) {

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

@ -514,6 +514,9 @@ public:
int32_t GetBidiNumeralOption();
static void
FlushFontAndWordCaches();
/**
* Returns a 1x1 surface that can be used to create graphics contexts
* for measuring text etc as if they will be rendered to the screen

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

@ -47,6 +47,8 @@
#define GDK_PIXMAP_SIZE_MAX 32767
#define GFX_PREF_MAX_GENERIC_SUBSTITUTIONS "gfx.font_rendering.fontconfig.max_generic_substitutions"
using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::unicode;
@ -72,6 +74,8 @@ gfxPlatformGtk::gfxPlatformGtk()
sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
}
mMaxGenericSubstitutions = UNINITIALIZED_VALUE;
#ifdef MOZ_X11
sUseXRender = (GDK_IS_X11_DISPLAY(gdk_display_get_default())) ?
mozilla::Preferences::GetBool("gfx.xrender.enabled") : false;
@ -364,6 +368,35 @@ gfxPlatformGtk::GetOffscreenFormat()
return gfxImageFormat::RGB24;
}
void gfxPlatformGtk::FontsPrefsChanged(const char *aPref)
{
// only checking for generic substitions, pass other changes up
if (strcmp(GFX_PREF_MAX_GENERIC_SUBSTITUTIONS, aPref)) {
gfxPlatform::FontsPrefsChanged(aPref);
return;
}
mMaxGenericSubstitutions = UNINITIALIZED_VALUE;
if (sUseFcFontList) {
gfxFcPlatformFontList* pfl = gfxFcPlatformFontList::PlatformFontList();
pfl->ClearGenericMappings();
FlushFontAndWordCaches();
}
}
uint32_t gfxPlatformGtk::MaxGenericSubstitions()
{
if (mMaxGenericSubstitutions == UNINITIALIZED_VALUE) {
mMaxGenericSubstitutions =
Preferences::GetInt(GFX_PREF_MAX_GENERIC_SUBSTITUTIONS, 3);
if (mMaxGenericSubstitutions < 0) {
mMaxGenericSubstitutions = 3;
}
}
return uint32_t(mMaxGenericSubstitutions);
}
void
gfxPlatformGtk::GetPlatformCMSOutputProfile(void *&mem, size_t &size)
{

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

@ -126,9 +126,16 @@ public:
return true;
}
void FontsPrefsChanged(const char *aPref) override;
// maximum number of fonts to substitute for a generic
uint32_t MaxGenericSubstitions();
protected:
static gfxFontconfigUtils *sFontconfigUtils;
int8_t mMaxGenericSubstitutions;
private:
virtual void GetPlatformCMSOutputProfile(void *&mem,
size_t &size) override;

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

@ -4,8 +4,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef gc_HashTable_h
#define gc_HashTable_h
#ifndef GCHashTable_h
#define GCHashTable_h
#include "js/HashTable.h"
#include "js/RootingAPI.h"
@ -18,36 +18,48 @@ template <typename Key, typename Value>
struct DefaultMapGCPolicy {
using KeyPolicy = DefaultGCPolicy<Key>;
using ValuePolicy = DefaultGCPolicy<Value>;
static bool needsSweep(Key* key, Value* value) {
return KeyPolicy::needsSweep(key) || ValuePolicy::needsSweep(value);
}
};
// A TraceableHashMap is a HashMap with an additional trace method that knows
// how to visit all keys and values in the table. HashMaps that contain GC
// pointers that must be traced to be kept alive will generally want to use
// this TraceableHashMap specializeation in lieu of HashMap.
// A GCHashMap is a GC-aware HashMap, meaning that it has additional trace and
// sweep methods that know how to visit all keys and values in the table.
// HashMaps that contain GC pointers will generally want to use this GCHashMap
// specialization in lieu of HashMap, either because those pointers must be
// traced to be kept alive -- in which case, KeyPolicy and/or ValuePolicy
// should do the appropriate tracing -- or because those pointers are weak and
// must be swept during a GC -- in which case needsSweep should be set
// appropriately.
//
// Most types of GC pointers as keys and values can be traced with no extra
// infrastructure. For structs and non-gc-pointer members, ensure that there
// is a specialization of DefaultGCPolicy<T> with an appropriate trace method
// available to handle the custom type. Generic helpers can be found in
// js/public/TracingAPI.h.
// infrastructure. For structs, the DefaultGCPolicy<T> will call a trace()
// method on the struct. For other structs and non-gc-pointer members, ensure
// that there is a specialization of DefaultGCPolicy<T> with an appropriate
// trace() static method available to handle the custom type. Generic helpers
// can be found in js/public/TracingAPI.h.
//
// Note that this HashMap only knows *how* to trace and sweep (and the tracing
// can handle keys that move), but it does not itself cause tracing or sweeping
// to be invoked. For tracing, it must be used with Rooted or PersistentRooted,
// or barriered and traced manually. For sweeping, currently it requires an
// explicit call to <map>.sweep().
//
// Note that although this HashMap's trace will deal correctly with moved keys,
// it does not itself know when to barrier or trace keys. To function properly
// it must either be used with Rooted, or barriered and traced manually.
template <typename Key,
typename Value,
typename HashPolicy = DefaultHasher<Key>,
typename AllocPolicy = TempAllocPolicy,
typename GCPolicy = DefaultMapGCPolicy<Key, Value>>
class TraceableHashMap : public HashMap<Key, Value, HashPolicy, AllocPolicy>,
public JS::Traceable
class GCHashMap : public HashMap<Key, Value, HashPolicy, AllocPolicy>,
public JS::Traceable
{
using Base = HashMap<Key, Value, HashPolicy, AllocPolicy>;
public:
explicit TraceableHashMap(AllocPolicy a = AllocPolicy()) : Base(a) {}
explicit GCHashMap(AllocPolicy a = AllocPolicy()) : Base(a) {}
static void trace(TraceableHashMap* map, JSTracer* trc) { map->trace(trc); }
static void trace(GCHashMap* map, JSTracer* trc) { map->trace(trc); }
void trace(JSTracer* trc) {
if (!this->initialized())
return;
@ -60,23 +72,33 @@ class TraceableHashMap : public HashMap<Key, Value, HashPolicy, AllocPolicy>,
}
}
// TraceableHashMap is movable
TraceableHashMap(TraceableHashMap&& rhs) : Base(mozilla::Forward<TraceableHashMap>(rhs)) {}
void operator=(TraceableHashMap&& rhs) {
void sweep() {
if (!this->initialized())
return;
for (typename Base::Enum e(*this); !e.empty(); e.popFront()) {
if (GCPolicy::needsSweep(&e.front().mutableKey(), &e.front().value()))
e.removeFront();
}
}
// GCHashMap is movable
GCHashMap(GCHashMap&& rhs) : Base(mozilla::Forward<GCHashMap>(rhs)) {}
void operator=(GCHashMap&& rhs) {
MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited");
Base::operator=(mozilla::Forward<TraceableHashMap>(rhs));
Base::operator=(mozilla::Forward<GCHashMap>(rhs));
}
private:
// TraceableHashMap is not copyable or assignable
TraceableHashMap(const TraceableHashMap& hm) = delete;
TraceableHashMap& operator=(const TraceableHashMap& hm) = delete;
// GCHashMap is not copyable or assignable
GCHashMap(const GCHashMap& hm) = delete;
GCHashMap& operator=(const GCHashMap& hm) = delete;
};
template <typename Outer, typename... Args>
class TraceableHashMapOperations
class GCHashMapOperations
{
using Map = TraceableHashMap<Args...>;
using Map = GCHashMap<Args...>;
using Lookup = typename Map::Lookup;
using Ptr = typename Map::Ptr;
using AddPtr = typename Map::AddPtr;
@ -98,10 +120,10 @@ class TraceableHashMapOperations
};
template <typename Outer, typename... Args>
class MutableTraceableHashMapOperations
: public TraceableHashMapOperations<Outer, Args...>
class MutableGCHashMapOperations
: public GCHashMapOperations<Outer, Args...>
{
using Map = TraceableHashMap<Args...>;
using Map = GCHashMap<Args...>;
using Lookup = typename Map::Lookup;
using Ptr = typename Map::Ptr;
using AddPtr = typename Map::AddPtr;
@ -145,24 +167,22 @@ class MutableTraceableHashMapOperations
};
template <typename A, typename B, typename C, typename D, typename E>
class RootedBase<TraceableHashMap<A,B,C,D,E>>
: public MutableTraceableHashMapOperations<JS::Rooted<TraceableHashMap<A,B,C,D,E>>, A,B,C,D,E>
class RootedBase<GCHashMap<A,B,C,D,E>>
: public MutableGCHashMapOperations<JS::Rooted<GCHashMap<A,B,C,D,E>>, A,B,C,D,E>
{};
template <typename A, typename B, typename C, typename D, typename E>
class MutableHandleBase<TraceableHashMap<A,B,C,D,E>>
: public MutableTraceableHashMapOperations<JS::MutableHandle<TraceableHashMap<A,B,C,D,E>>,
A,B,C,D,E>
class MutableHandleBase<GCHashMap<A,B,C,D,E>>
: public MutableGCHashMapOperations<JS::MutableHandle<GCHashMap<A,B,C,D,E>>, A,B,C,D,E>
{};
template <typename A, typename B, typename C, typename D, typename E>
class HandleBase<TraceableHashMap<A,B,C,D,E>>
: public TraceableHashMapOperations<JS::Handle<TraceableHashMap<A,B,C,D,E>>, A,B,C,D,E>
class HandleBase<GCHashMap<A,B,C,D,E>>
: public GCHashMapOperations<JS::Handle<GCHashMap<A,B,C,D,E>>, A,B,C,D,E>
{};
// A TraceableHashSet is a HashSet with an additional trace method that knows
// how to visit all set elements. HashSets that contain GC pointers that must
// be traced to be kept alive will generally want to use this TraceableHashSet
// A GCHashSet is a HashSet with an additional trace method that knows
// be traced to be kept alive will generally want to use this GCHashSet
// specializeation in lieu of HashSet.
//
// Most types of GC pointers can be traced with no extra infrastructure. For
@ -178,15 +198,15 @@ template <typename T,
typename HashPolicy = DefaultHasher<T>,
typename AllocPolicy = TempAllocPolicy,
typename GCPolicy = DefaultGCPolicy<T>>
class TraceableHashSet : public HashSet<T, HashPolicy, AllocPolicy>,
public JS::Traceable
class GCHashSet : public HashSet<T, HashPolicy, AllocPolicy>,
public JS::Traceable
{
using Base = HashSet<T, HashPolicy, AllocPolicy>;
public:
explicit TraceableHashSet(AllocPolicy a = AllocPolicy()) : Base(a) {}
explicit GCHashSet(AllocPolicy a = AllocPolicy()) : Base(a) {}
static void trace(TraceableHashSet* set, JSTracer* trc) { set->trace(trc); }
static void trace(GCHashSet* set, JSTracer* trc) { set->trace(trc); }
void trace(JSTracer* trc) {
if (!this->initialized())
return;
@ -198,23 +218,32 @@ class TraceableHashSet : public HashSet<T, HashPolicy, AllocPolicy>,
}
}
// TraceableHashSet is movable
TraceableHashSet(TraceableHashSet&& rhs) : Base(mozilla::Forward<TraceableHashSet>(rhs)) {}
void operator=(TraceableHashSet&& rhs) {
void sweep() {
if (!this->initialized())
return;
for (typename Base::Enum e(*this); !e.empty(); e.popFront()) {
if (GCPolicy::needsSweep(&e.mutableFront()))
e.removeFront();
}
}
// GCHashSet is movable
GCHashSet(GCHashSet&& rhs) : Base(mozilla::Forward<GCHashSet>(rhs)) {}
void operator=(GCHashSet&& rhs) {
MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited");
Base::operator=(mozilla::Forward<TraceableHashSet>(rhs));
Base::operator=(mozilla::Forward<GCHashSet>(rhs));
}
private:
// TraceableHashSet is not copyable or assignable
TraceableHashSet(const TraceableHashSet& hs) = delete;
TraceableHashSet& operator=(const TraceableHashSet& hs) = delete;
// GCHashSet is not copyable or assignable
GCHashSet(const GCHashSet& hs) = delete;
GCHashSet& operator=(const GCHashSet& hs) = delete;
};
template <typename Outer, typename... Args>
class TraceableHashSetOperations
class GCHashSetOperations
{
using Set = TraceableHashSet<Args...>;
using Set = GCHashSet<Args...>;
using Lookup = typename Set::Lookup;
using Ptr = typename Set::Ptr;
using AddPtr = typename Set::AddPtr;
@ -236,10 +265,10 @@ class TraceableHashSetOperations
};
template <typename Outer, typename... Args>
class MutableTraceableHashSetOperations
: public TraceableHashSetOperations<Outer, Args...>
class MutableGCHashSetOperations
: public GCHashSetOperations<Outer, Args...>
{
using Set = TraceableHashSet<Args...>;
using Set = GCHashSet<Args...>;
using Lookup = typename Set::Lookup;
using Ptr = typename Set::Ptr;
using AddPtr = typename Set::AddPtr;
@ -281,44 +310,42 @@ class MutableTraceableHashSetOperations
};
template <typename T, typename HP, typename AP, typename GP>
class RootedBase<TraceableHashSet<T, HP, AP, GP>>
: public MutableTraceableHashSetOperations<JS::Rooted<TraceableHashSet<T, HP, AP, GP>>,
T, HP, AP, GP>
class RootedBase<GCHashSet<T, HP, AP, GP>>
: public MutableGCHashSetOperations<JS::Rooted<GCHashSet<T, HP, AP, GP>>, T, HP, AP, GP>
{
using Set = TraceableHashSet<T, HP, AP, GP>;
using Set = GCHashSet<T, HP, AP, GP>;
friend class TraceableHashSetOperations<JS::Rooted<Set>, T, HP, AP, GP>;
friend class GCHashSetOperations<JS::Rooted<Set>, T, HP, AP, GP>;
const Set& extract() const { return *static_cast<const JS::Rooted<Set>*>(this)->address(); }
friend class MutableTraceableHashSetOperations<JS::Rooted<Set>, T, HP, AP, GP>;
friend class MutableGCHashSetOperations<JS::Rooted<Set>, T, HP, AP, GP>;
Set& extract() { return *static_cast<JS::Rooted<Set>*>(this)->address(); }
};
template <typename T, typename HP, typename AP, typename GP>
class MutableHandleBase<TraceableHashSet<T, HP, AP, GP>>
: public MutableTraceableHashSetOperations<JS::MutableHandle<TraceableHashSet<T, HP, AP, GP>>,
T, HP, AP, GP>
class MutableHandleBase<GCHashSet<T, HP, AP, GP>>
: public MutableGCHashSetOperations<JS::MutableHandle<GCHashSet<T, HP, AP, GP>>, T, HP, AP, GP>
{
using Set = TraceableHashSet<T, HP, AP, GP>;
using Set = GCHashSet<T, HP, AP, GP>;
friend class TraceableHashSetOperations<JS::MutableHandle<Set>, T, HP, AP, GP>;
friend class GCHashSetOperations<JS::MutableHandle<Set>, T, HP, AP, GP>;
const Set& extract() const {
return *static_cast<const JS::MutableHandle<Set>*>(this)->address();
}
friend class MutableTraceableHashSetOperations<JS::MutableHandle<Set>, T, HP, AP, GP>;
friend class MutableGCHashSetOperations<JS::MutableHandle<Set>, T, HP, AP, GP>;
Set& extract() { return *static_cast<JS::MutableHandle<Set>*>(this)->address(); }
};
template <typename T, typename HP, typename AP, typename GP>
class HandleBase<TraceableHashSet<T, HP, AP, GP>>
: public TraceableHashSetOperations<JS::Handle<TraceableHashSet<T, HP, AP, GP>>, T, HP, AP, GP>
class HandleBase<GCHashSet<T, HP, AP, GP>>
: public GCHashSetOperations<JS::Handle<GCHashSet<T, HP, AP, GP>>, T, HP, AP, GP>
{
using Set = TraceableHashSet<T, HP, AP, GP>;
friend class TraceableHashSetOperations<JS::Handle<Set>, T, HP, AP, GP>;
using Set = GCHashSet<T, HP, AP, GP>;
friend class GCHashSetOperations<JS::Handle<Set>, T, HP, AP, GP>;
const Set& extract() const { return *static_cast<const JS::Handle<Set>*>(this)->address(); }
};
} /* namespace js */
#endif /* gc_HashTable_h */
#endif /* GCHashTable_h */

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

@ -374,12 +374,17 @@ struct StructGCPolicy {
// trace method.
t->trace(trc);
}
static bool needsSweep(T* t) {
return t->needsSweep();
}
};
// This policy ignores any GC interaction, e.g. for non-GC types.
template <typename T>
struct IgnoreGCPolicy {
static void trace(JSTracer* trc, uint32_t* id, const char* name) {}
static void trace(JSTracer* trc, T* t, const char* name) {}
static bool needsSweep(T* v) { return false; }
};
// The default policy when no other more specific policy fits (e.g. for a

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

@ -69,19 +69,227 @@ namespace ubi {
class JS_PUBLIC_API(DominatorTree)
{
private:
// Type aliases.
// Types.
using NodeSet = js::HashSet<Node, js::DefaultHasher<Node>, js::SystemAllocPolicy>;
using NodeSetPtr = mozilla::UniquePtr<NodeSet, JS::DeletePolicy<NodeSet>>;
using PredecessorSets = js::HashMap<Node, NodeSetPtr, js::DefaultHasher<Node>,
js::SystemAllocPolicy>;
using NodeToIndexMap = js::HashMap<Node, uint32_t, js::DefaultHasher<Node>,
js::SystemAllocPolicy>;
class DominatedSets;
public:
class DominatedSetRange;
/**
* A pointer to an immediately dominated node.
*
* Don't use this type directly; it is no safer than regular pointers. This
* is only for use indirectly with range-based for loops and
* `DominatedSetRange`.
*
* @see JS::ubi::DominatorTree::getDominatedSet
*/
class DominatedNodePtr
{
friend class DominatedSetRange;
const mozilla::Vector<Node>& postOrder;
const uint32_t* ptr;
DominatedNodePtr(const mozilla::Vector<Node>& postOrder, const uint32_t* ptr)
: postOrder(postOrder)
, ptr(ptr)
{ }
public:
bool operator!=(const DominatedNodePtr& rhs) const { return ptr != rhs.ptr; }
void operator++() { ptr++; }
const Node& operator*() const { return postOrder[*ptr]; }
};
/**
* A range of immediately dominated `JS::ubi::Node`s for use with
* range-based for loops.
*
* @see JS::ubi::DominatorTree::getDominatedSet
*/
class DominatedSetRange
{
friend class DominatedSets;
const mozilla::Vector<Node>& postOrder;
const uint32_t* beginPtr;
const uint32_t* endPtr;
DominatedSetRange(mozilla::Vector<Node>& postOrder, const uint32_t* begin, const uint32_t* end)
: postOrder(postOrder)
, beginPtr(begin)
, endPtr(end)
{
MOZ_ASSERT(begin <= end);
}
public:
DominatedNodePtr begin() const {
MOZ_ASSERT(beginPtr <= endPtr);
return DominatedNodePtr(postOrder, beginPtr);
}
DominatedNodePtr end() const {
return DominatedNodePtr(postOrder, endPtr);
}
/**
* Safely skip ahead `n` dominators in the range, in O(1) time.
*
* Example usage:
*
* mozilla::Maybe<DominatedSetRange> range = myDominatorTree.getDominatedSet(myNode);
* if (range.isNothing()) {
* // Handle unknown nodes however you see fit...
* return false;
* }
*
* // Don't care about the first ten, for whatever reason.
* range->skip(10);
* for (const JS::ubi::Node& dominatedNode : *range) {
* // ...
* }
*/
void skip(size_t n) {
beginPtr += n;
if (beginPtr > endPtr)
beginPtr = endPtr;
}
};
private:
/**
* The set of all dominated sets in a dominator tree.
*
* Internally stores the sets in a contiguous array, with a side table of
* indices into that contiguous array to denote the start index of each
* individual set.
*/
class DominatedSets
{
mozilla::Vector<uint32_t> dominated;
mozilla::Vector<uint32_t> indices;
DominatedSets(mozilla::Vector<uint32_t>&& dominated, mozilla::Vector<uint32_t>&& indices)
: dominated(mozilla::Move(dominated))
, indices(mozilla::Move(indices))
{ }
public:
// DominatedSets is not copy-able.
DominatedSets(const DominatedSets& rhs) = delete;
DominatedSets& operator=(const DominatedSets& rhs) = delete;
// DominatedSets is move-able.
DominatedSets(DominatedSets&& rhs)
: dominated(mozilla::Move(rhs.dominated))
, indices(mozilla::Move(rhs.indices))
{
MOZ_ASSERT(this != &rhs, "self-move not allowed");
}
DominatedSets& operator=(DominatedSets&& rhs) {
this->~DominatedSets();
new (this) DominatedSets(mozilla::Move(rhs));
return *this;
}
/**
* Create the DominatedSets given the mapping of a node index to its
* immediate dominator. Returns `Some` on success, `Nothing` on OOM
* failure.
*/
static mozilla::Maybe<DominatedSets> Create(const mozilla::Vector<uint32_t>& doms) {
auto length = doms.length();
MOZ_ASSERT(length < UINT32_MAX);
// Create a vector `dominated` holding a flattened set of buckets of
// immediately dominated children nodes, with a lookup table
// `indices` mapping from each node to the beginning of its bucket.
//
// This has three phases:
//
// 1. Iterate over the full set of nodes and count up the size of
// each bucket. These bucket sizes are temporarily stored in the
// `indices` vector.
//
// 2. Convert the `indices` vector to store the cumulative sum of
// the sizes of all buckets before each index, resulting in a
// mapping from node index to one past the end of that node's
// bucket.
//
// 3. Iterate over the full set of nodes again, filling in bucket
// entries from the end of the bucket's range to its
// beginning. This decrements each index as a bucket entry is
// filled in. After having filled in all of a bucket's entries,
// the index points to the start of the bucket.
mozilla::Vector<uint32_t> dominated;
mozilla::Vector<uint32_t> indices;
if (!dominated.growBy(length) || !indices.growBy(length))
return mozilla::Nothing();
// 1
memset(indices.begin(), 0, length * sizeof(uint32_t));
for (uint32_t i = 0; i < length; i++)
indices[doms[i]]++;
// 2
uint32_t sumOfSizes = 0;
for (uint32_t i = 0; i < length; i++) {
sumOfSizes += indices[i];
MOZ_ASSERT(sumOfSizes <= length);
indices[i] = sumOfSizes;
}
// 3
for (uint32_t i = 0; i < length; i++) {
auto idxOfDom = doms[i];
indices[idxOfDom]--;
dominated[indices[idxOfDom]] = i;
}
#ifdef DEBUG
// Assert that our buckets are non-overlapping and don't run off the
// end of the vector.
uint32_t lastIndex = 0;
for (uint32_t i = 0; i < length; i++) {
MOZ_ASSERT(indices[i] >= lastIndex);
MOZ_ASSERT(indices[i] < length);
lastIndex = indices[i];
}
#endif
return mozilla::Some(DominatedSets(mozilla::Move(dominated), mozilla::Move(indices)));
}
/**
* Get the set of nodes immediately dominated by the node at
* `postOrder[nodeIndex]`.
*/
DominatedSetRange dominatedSet(mozilla::Vector<Node>& postOrder, uint32_t nodeIndex) const {
MOZ_ASSERT(postOrder.length() == indices.length());
MOZ_ASSERT(nodeIndex < indices.length());
auto end = nodeIndex == indices.length() - 1
? dominated.end()
: &dominated[indices[nodeIndex + 1]];
return DominatedSetRange(postOrder, &dominated[indices[nodeIndex]], end);
}
};
private:
// Data members.
mozilla::Vector<Node> postOrder;
NodeToIndexMap nodeToPostOrderIndex;
mozilla::Vector<uint32_t> doms;
DominatedSets dominatedSets;
private:
// We use `UNDEFINED` as a sentinel value in the `doms` vector to signal
@ -90,10 +298,11 @@ class JS_PUBLIC_API(DominatorTree)
static const uint32_t UNDEFINED = UINT32_MAX;
DominatorTree(mozilla::Vector<Node>&& postOrder, NodeToIndexMap&& nodeToPostOrderIndex,
mozilla::Vector<uint32_t>&& doms)
mozilla::Vector<uint32_t>&& doms, DominatedSets&& dominatedSets)
: postOrder(mozilla::Move(postOrder))
, nodeToPostOrderIndex(mozilla::Move(nodeToPostOrderIndex))
, doms(mozilla::Move(doms))
, dominatedSets(mozilla::Move(dominatedSets))
{ }
static uint32_t intersect(mozilla::Vector<uint32_t>& doms, uint32_t finger1, uint32_t finger2) {
@ -218,6 +427,7 @@ class JS_PUBLIC_API(DominatorTree)
: postOrder(mozilla::Move(rhs.postOrder))
, nodeToPostOrderIndex(mozilla::Move(rhs.nodeToPostOrderIndex))
, doms(mozilla::Move(rhs.doms))
, dominatedSets(mozilla::Move(rhs.dominatedSets))
{
MOZ_ASSERT(this != &rhs, "self-move is not allowed");
}
@ -326,9 +536,21 @@ class JS_PUBLIC_API(DominatorTree)
}
}
auto maybeDominatedSets = DominatedSets::Create(doms);
if (maybeDominatedSets.isNothing())
return mozilla::Nothing();
return mozilla::Some(DominatorTree(mozilla::Move(postOrder),
mozilla::Move(nodeToPostOrderIndex),
mozilla::Move(doms)));
mozilla::Move(doms),
mozilla::Move(*maybeDominatedSets)));
}
/**
* Get the root node for this dominator tree.
*/
const Node& root() const {
return postOrder[postOrder.length() - 1];
}
/**
@ -346,6 +568,33 @@ class JS_PUBLIC_API(DominatorTree)
MOZ_ASSERT(idx < postOrder.length());
return postOrder[doms[idx]];
}
/**
* Get the set of nodes immediately dominated by the given `node`. If `node`
* is not a member of this dominator tree, return `Nothing`.
*
* Example usage:
*
* mozilla::Maybe<DominatedSetRange> range = myDominatorTree.getDominatedSet(myNode);
* if (range.isNothing()) {
* // Handle unknown node however you see fit...
* return false;
* }
*
* for (const JS::ubi::Node& dominatedNode : *range) {
* // Do something with each immediately dominated node...
* }
*/
mozilla::Maybe<DominatedSetRange> getDominatedSet(const Node& node) {
assertSanity();
auto ptr = nodeToPostOrderIndex.lookup(node);
if (!ptr)
return mozilla::Nothing();
auto idx = ptr->value();
MOZ_ASSERT(idx < postOrder.length());
return mozilla::Some(dominatedSets.dominatedSet(postOrder, idx));
};
};
} // namespace ubi

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

@ -1918,7 +1918,7 @@ EmitExtractLane(FunctionCompiler& f, AsmType type, MDefinition** def)
}
static AsmType
AsmSimdTypeToScalarType(AsmType simd)
AsmSimdTypeToLaneType(AsmType simd)
{
switch (simd) {
case AsmType::Int32x4: return AsmType::Int32;
@ -1952,7 +1952,7 @@ EmitSimdReplaceLane(FunctionCompiler& f, AsmType simdType, MDefinition** def)
}
MDefinition* scalar;
if (!EmitExpr(f, AsmSimdTypeToScalarType(simdType), &scalar))
if (!EmitExpr(f, AsmSimdTypeToLaneType(simdType), &scalar))
return false;
*def = f.insertElementSimd(vector, scalar, lane, MIRTypeFromAsmType(simdType));
return true;
@ -2055,7 +2055,7 @@ static bool
EmitSimdSplat(FunctionCompiler& f, AsmType type, MDefinition** def)
{
MDefinition* in;
if (!EmitExpr(f, AsmSimdTypeToScalarType(type), &in))
if (!EmitExpr(f, AsmSimdTypeToLaneType(type), &in))
return false;
*def = f.splatSimd(in, MIRTypeFromAsmType(type));
return true;

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

@ -30,6 +30,10 @@
#define ATTR_NONCONFIGURABLE 0x10
#define ATTR_NONWRITABLE 0x20
// The extended slot in which the self-hosted name for self-hosted builtins is
// stored.
#define LAZY_FUNCTION_NAME_SLOT 0
// Stores the private WeakMap slot used for WeakSets
#define WEAKSET_MAP_SLOT 0

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

@ -27,7 +27,7 @@
// Assertions, defined here instead of in the header above to make `assert`
// invisible to C++.
#ifdef DEBUG
#define assert(b, info) if (!(b)) AssertionFailed(info)
#define assert(b, info) if (!(b)) AssertionFailed(__FILE__ + ":" + __LINE__ + ": " + info)
#else
#define assert(b, info) // Elided assertion.
#endif

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

@ -14,7 +14,7 @@
#include "prlink.h"
#include "ctypes/typedefs.h"
#include "js/TraceableHashTable.h"
#include "js/GCHashTable.h"
#include "js/Vector.h"
#include "vm/String.h"
@ -283,8 +283,7 @@ struct FieldHashPolicy : DefaultHasher<JSFlatString*>
}
};
typedef TraceableHashMap<JSFlatString*, FieldInfo, FieldHashPolicy, SystemAllocPolicy>
FieldInfoHash;
using FieldInfoHash = GCHashMap<JSFlatString*, FieldInfo, FieldHashPolicy, SystemAllocPolicy>;
void
TraceFieldInfoHash(JSTracer* trc, FieldInfoHash* fields);

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

@ -462,6 +462,46 @@ template<typename T>
void
CheckTracedThing(JSTracer* trc, T thing);
// Define a default Policy for all pointer types. This may fail to link if this
// policy gets used on a non-GC typed pointer by accident.
template <typename T>
struct DefaultGCPolicy<T*>
{
static void trace(JSTracer* trc, T** t, const char* name) {
// If linking is failing here, it likely means that you need to define
// or use a non-default GC policy for your non-gc-pointer type.
TraceManuallyBarrieredEdge(trc, t, name);
}
static bool needsSweep(T** t) {
return gc::IsAboutToBeFinalizedUnbarriered(t);
}
};
// RelocatablePtr is only defined for GC pointer types, so this default policy
// should work in all cases.
template <typename T>
struct DefaultGCPolicy<RelocatablePtr<T*>>
{
static void trace(JSTracer* trc, RelocatablePtr<T*> t, const char* name) {
TraceEdge(trc, t, name);
}
static bool needsSweep(RelocatablePtr<T*>* thingp) {
return gc::IsAboutToBeFinalizedUnbarriered(thingp);
}
};
template <typename T>
struct DefaultGCPolicy<ReadBarriered<T>>
{
static void trace(JSTracer* trc, ReadBarriered<T> t, const char* name) {
TraceEdge(trc, t, name);
}
static bool needsSweep(ReadBarriered<T>* thingp) {
return gc::IsAboutToBeFinalized(thingp);
}
};
} /* namespace js */
#endif /* gc_Marking_h */

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

@ -10,7 +10,7 @@
#include "jsfriendapi.h"
#include "gc/Barrier.h"
#include "js/TraceableHashTable.h"
#include "js/GCHashTable.h"
namespace js {
@ -137,29 +137,6 @@ void
TraceCycleCollectorChildren(JS::CallbackTracer* trc, ObjectGroup* group);
} // namespace gc
// Define a default Policy for all pointer types. This may fail to link if this
// policy gets used on a non-GC typed pointer by accident.
template <typename T>
struct DefaultGCPolicy<T*>
{
static void trace(JSTracer* trc, T** t, const char* name) {
// If linking is failing here, it likely means that you need to define
// or use a non-default GC policy for your non-gc-pointer type.
TraceManuallyBarrieredEdge(trc, t, name);
}
};
// RelocatablePtr is only defined for GC pointer types, so this default policy
// should work in all cases.
template <typename T>
struct DefaultGCPolicy<RelocatablePtr<T*>>
{
static void trace(JSTracer* trc, RelocatablePtr<T*> t, const char* name) {
TraceEdge(trc, t, name);
}
};
} // namespace js
#endif /* js_Tracer_h */

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

@ -644,8 +644,10 @@ ScalarTypeToLength(Scalar::Type type)
MOZ_CRASH("unexpected SIMD kind");
}
// Get the type of the individual lanes in a SIMD type.
// For example, Int32x4 -> Int32, FLoat32x4 -> Float32 etc.
static inline MIRType
SimdTypeToScalarType(MIRType type)
SimdTypeToLaneType(MIRType type)
{
MOZ_ASSERT(IsSimdType(type));
static_assert(MIRType_Last <= ELEMENT_TYPE_MASK,

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

@ -23,15 +23,15 @@
// Call into cross-jitted code by following the ABI of the simulated architecture.
#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
(js::jit::Simulator::Current()->call( \
JS_FUNC_TO_DATA_PTR(uint8_t*, entry), 8, p0, p1, p2, p3, p4, p5, p6, p7) & 0xffffffff)
JS_FUNC_TO_DATA_PTR(uint8_t*, entry), 8, p0, p1, p2, p3, p4, p5, p6, p7))
#define CALL_GENERATED_1(entry, p0) \
(js::jit::Simulator::Current()->call( \
JS_FUNC_TO_DATA_PTR(uint8_t*, entry), 1, p0) & 0xffffffff)
JS_FUNC_TO_DATA_PTR(uint8_t*, entry), 1, p0))
#define CALL_GENERATED_2(entry, p0, p1) \
(js::jit::Simulator::Current()->call( \
JS_FUNC_TO_DATA_PTR(uint8_t*, entry), 2, p0, p1) & 0xffffffff)
JS_FUNC_TO_DATA_PTR(uint8_t*, entry), 2, p0, p1))
#else

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

@ -3234,13 +3234,13 @@ IonBuilder::inlineConstructSimdObject(CallInfo& callInfo, SimdTypeDescr* descr)
// containing the coercion of 'undefined' to the right type.
MConstant* defVal = nullptr;
if (callInfo.argc() < SimdTypeToLength(simdType)) {
MIRType scalarType = SimdTypeToScalarType(simdType);
if (scalarType == MIRType_Int32) {
MIRType laneType = SimdTypeToLaneType(simdType);
if (laneType == MIRType_Int32) {
defVal = constant(Int32Value(0));
} else {
MOZ_ASSERT(IsFloatingPointType(scalarType));
MOZ_ASSERT(IsFloatingPointType(laneType));
defVal = constant(DoubleNaNValue());
defVal->setResultType(scalarType);
defVal->setResultType(laneType);
}
}
@ -3369,9 +3369,9 @@ IonBuilder::inlineSimdExtractLane(CallInfo& callInfo, JSNative native, SimdTypeD
// See comment in inlineBinarySimd
MIRType vecType = SimdTypeDescrToMIRType(type);
MIRType scalarType = SimdTypeToScalarType(vecType);
MIRType laneType = SimdTypeToLaneType(vecType);
MSimdExtractElement* ins = MSimdExtractElement::New(alloc(), callInfo.getArg(0),
vecType, scalarType, SimdLane(lane));
vecType, laneType, SimdLane(lane));
current->add(ins);
current->push(ins);
callInfo.setImplicitlyUsedUnchecked();
@ -3473,8 +3473,10 @@ IonBuilder::inlineSimdShuffle(CallInfo& callInfo, JSNative native, SimdTypeDescr
return boxSimd(callInfo, ins, templateObj);
}
// Get the typed array element type corresponding to the lanes in a SIMD vector type.
// This only applies to SIMD types that can be loaded and stored to a typed array.
static Scalar::Type
SimdTypeToScalarType(SimdTypeDescr::Type type)
SimdTypeToArrayElementType(SimdTypeDescr::Type type)
{
switch (type) {
case SimdTypeDescr::Float32x4: return Scalar::Float32x4;
@ -3538,7 +3540,7 @@ IonBuilder::inlineSimdLoad(CallInfo& callInfo, JSNative native, SimdTypeDescr::T
if (!checkInlineSimd(callInfo, native, type, 2, &templateObj))
return InliningStatus_NotInlined;
Scalar::Type simdType = SimdTypeToScalarType(type);
Scalar::Type simdType = SimdTypeToArrayElementType(type);
MDefinition* index = nullptr;
MInstruction* elements = nullptr;
@ -3561,7 +3563,7 @@ IonBuilder::inlineSimdStore(CallInfo& callInfo, JSNative native, SimdTypeDescr::
if (!checkInlineSimd(callInfo, native, type, 3, &templateObj))
return InliningStatus_NotInlined;
Scalar::Type simdType = SimdTypeToScalarType(type);
Scalar::Type simdType = SimdTypeToArrayElementType(type);
MDefinition* index = nullptr;
MInstruction* elements = nullptr;

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

@ -906,13 +906,13 @@ MConstant::canProduceFloat32() const
MDefinition*
MSimdValueX4::foldsTo(TempAllocator& alloc)
{
DebugOnly<MIRType> scalarType = SimdTypeToScalarType(type());
DebugOnly<MIRType> laneType = SimdTypeToLaneType(type());
bool allConstants = true;
bool allSame = true;
for (size_t i = 0; i < 4; ++i) {
MDefinition* op = getOperand(i);
MOZ_ASSERT(op->type() == scalarType);
MOZ_ASSERT(op->type() == laneType);
if (!op->isConstantValue())
allConstants = false;
if (i > 0 && op != getOperand(i - 1))
@ -952,11 +952,11 @@ MSimdValueX4::foldsTo(TempAllocator& alloc)
MDefinition*
MSimdSplatX4::foldsTo(TempAllocator& alloc)
{
DebugOnly<MIRType> scalarType = SimdTypeToScalarType(type());
DebugOnly<MIRType> laneType = SimdTypeToLaneType(type());
MDefinition* op = getOperand(0);
if (!op->isConstantValue())
return this;
MOZ_ASSERT(op->type() == scalarType);
MOZ_ASSERT(op->type() == laneType);
SimdConstant cst;
switch (type()) {

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

@ -1401,16 +1401,16 @@ class MSimdValueX4
static MSimdValueX4* NewAsmJS(TempAllocator& alloc, MIRType type, MDefinition* x,
MDefinition* y, MDefinition* z, MDefinition* w)
{
mozilla::DebugOnly<MIRType> scalarType = SimdTypeToScalarType(type);
MOZ_ASSERT(scalarType == x->type());
MOZ_ASSERT(scalarType == y->type());
MOZ_ASSERT(scalarType == z->type());
MOZ_ASSERT(scalarType == w->type());
mozilla::DebugOnly<MIRType> laneType = SimdTypeToLaneType(type);
MOZ_ASSERT(laneType == x->type());
MOZ_ASSERT(laneType == y->type());
MOZ_ASSERT(laneType == z->type());
MOZ_ASSERT(laneType == w->type());
return MSimdValueX4::New(alloc, type, x, y, z, w);
}
bool canConsumeFloat32(MUse* use) const override {
return SimdTypeToScalarType(type()) == MIRType_Float32;
return SimdTypeToLaneType(type()) == MIRType_Float32;
}
AliasSet getAliasSet() const override {
@ -1445,7 +1445,7 @@ class MSimdSplatX4
static MSimdSplatX4* NewAsmJS(TempAllocator& alloc, MDefinition* v, MIRType type)
{
MOZ_ASSERT(SimdTypeToScalarType(type) == v->type());
MOZ_ASSERT(SimdTypeToLaneType(type) == v->type());
return new(alloc) MSimdSplatX4(type, v);
}
@ -1455,7 +1455,7 @@ class MSimdSplatX4
}
bool canConsumeFloat32(MUse* use) const override {
return SimdTypeToScalarType(type()) == MIRType_Float32;
return SimdTypeToLaneType(type()) == MIRType_Float32;
}
AliasSet getAliasSet() const override {
@ -1596,17 +1596,17 @@ class MSimdExtractElement
protected:
SimdLane lane_;
MSimdExtractElement(MDefinition* obj, MIRType vecType, MIRType scalarType, SimdLane lane)
MSimdExtractElement(MDefinition* obj, MIRType vecType, MIRType laneType, SimdLane lane)
: MUnaryInstruction(obj), lane_(lane)
{
MOZ_ASSERT(IsSimdType(vecType));
MOZ_ASSERT(uint32_t(lane) < SimdTypeToLength(vecType));
MOZ_ASSERT(!IsSimdType(scalarType));
MOZ_ASSERT(SimdTypeToScalarType(vecType) == scalarType);
MOZ_ASSERT(!IsSimdType(laneType));
MOZ_ASSERT(SimdTypeToLaneType(vecType) == laneType);
setMovable();
specialization_ = vecType;
setResultType(scalarType);
setResultType(laneType);
}
public:
@ -1665,7 +1665,7 @@ class MSimdInsertElement
MIRType type, SimdLane lane)
{
MOZ_ASSERT(vec->type() == type);
MOZ_ASSERT(SimdTypeToScalarType(type) == val->type());
MOZ_ASSERT(SimdTypeToLaneType(type) == val->type());
return new(alloc) MSimdInsertElement(vec, val, type, lane);
}
@ -1696,7 +1696,7 @@ class MSimdInsertElement
}
bool canConsumeFloat32(MUse* use) const override {
return use == getUseFor(1) && SimdTypeToScalarType(type()) == MIRType_Float32;
return use == getUseFor(1) && SimdTypeToLaneType(type()) == MIRType_Float32;
}
AliasSet getAliasSet() const override {

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

@ -567,17 +567,17 @@ bool
SimdScalarPolicy<Op>::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins)
{
MOZ_ASSERT(IsSimdType(ins->type()));
MIRType scalarType = SimdTypeToScalarType(ins->type());
MIRType laneType = SimdTypeToLaneType(ins->type());
MDefinition* in = ins->getOperand(Op);
if (in->type() == scalarType)
if (in->type() == laneType)
return true;
MInstruction* replace;
if (scalarType == MIRType_Int32) {
if (laneType == MIRType_Int32) {
replace = MTruncateToInt32::New(alloc, in);
} else {
MOZ_ASSERT(scalarType == MIRType_Float32);
MOZ_ASSERT(laneType == MIRType_Float32);
replace = MToFloat32::New(alloc, in);
}

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

@ -4597,7 +4597,7 @@ Simulator::callInternal(uint8_t* entry)
}
}
int64_t
int32_t
Simulator::call(uint8_t* entry, int argument_count, ...)
{
va_list parameters;
@ -4634,7 +4634,7 @@ Simulator::call(uint8_t* entry, int argument_count, ...)
MOZ_ASSERT(entry_stack == get_register(sp));
set_register(sp, original_stack);
int64_t result = (int64_t(get_register(r1)) << 32) | get_register(r0);
int32_t result = get_register(r0);
return result;
}

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

@ -181,7 +181,7 @@ class Simulator
void execute();
// Sets up the simulator state and grabs the result on return.
int64_t call(uint8_t* entry, int argument_count, ...);
int32_t call(uint8_t* entry, int argument_count, ...);
// Debugger input.
void setLastDebuggerInput(char* input);

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

@ -3426,7 +3426,7 @@ Simulator::callInternal(uint8_t* entry)
setRegister(fp, fp_val);
}
int64_t
int32_t
Simulator::call(uint8_t* entry, int argument_count, ...)
{
va_list parameters;
@ -3462,7 +3462,7 @@ Simulator::call(uint8_t* entry, int argument_count, ...)
MOZ_ASSERT(entry_stack == getRegister(sp));
setRegister(sp, original_stack);
int64_t result = (int64_t(getRegister(v1)) << 32) | getRegister(v0);
int32_t result = getRegister(v0);
return result;
}

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

@ -201,7 +201,7 @@ class Simulator {
void execute();
// Sets up the simulator state and grabs the result on return.
int64_t call(uint8_t* entry, int argument_count, ...);
int32_t call(uint8_t* entry, int argument_count, ...);
// Push an address onto the JS stack.
uintptr_t pushAddress(uintptr_t address);

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

@ -6,8 +6,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ds/TraceableFifo.h"
#include "js/GCHashTable.h"
#include "js/RootingAPI.h"
#include "js/TraceableHashTable.h"
#include "js/TraceableVector.h"
#include "jsapi-tests/tests.h"
@ -122,7 +122,7 @@ BEGIN_TEST(testGCRootedStaticStructInternalStackStorageAugmented)
}
END_TEST(testGCRootedStaticStructInternalStackStorageAugmented)
using MyHashMap = js::TraceableHashMap<js::Shape*, JSObject*>;
using MyHashMap = js::GCHashMap<js::Shape*, JSObject*>;
BEGIN_TEST(testGCRootedHashMap)
{

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

@ -519,58 +519,68 @@ BEGIN_TEST(test_JS_ubi_DominatorTree)
// graph when computing the dominator tree.
FakeNode m('m');
CHECK(tree.getImmediateDominator(&m) == JS::ubi::Node());
CHECK(tree.getDominatedSet(&m).isNothing());
fprintf(stderr, "r's immediate dominator is %c\n",
tree.getImmediateDominator(&r).as<FakeNode>()->name);
CHECK(tree.getImmediateDominator(&r) == JS::ubi::Node(&r));
struct {
FakeNode& dominated;
FakeNode& dominator;
} domination[] = {
{r, r},
{a, r},
{b, r},
{c, r},
{d, r},
{e, r},
{f, c},
{g, c},
{h, r},
{i, r},
{j, g},
{k, r},
{l, d}
};
fprintf(stderr, "a's immediate dominator is %c\n",
tree.getImmediateDominator(&a).as<FakeNode>()->name);
CHECK(tree.getImmediateDominator(&a) == JS::ubi::Node(&r));
for (auto& relation : domination) {
// Test immediate dominator.
fprintf(stderr,
"%c's immediate dominator is %c\n",
relation.dominated.name,
tree.getImmediateDominator(&relation.dominator).as<FakeNode>()->name);
CHECK(tree.getImmediateDominator(&relation.dominated) == JS::ubi::Node(&relation.dominator));
fprintf(stderr, "b's immediate dominator is %c\n",
tree.getImmediateDominator(&b).as<FakeNode>()->name);
CHECK(tree.getImmediateDominator(&b) == JS::ubi::Node(&r));
// Test the dominated set. Build up the expected dominated set based on
// the set of nodes immediately dominated by this one in `domination`,
// then iterate over the actual dominated set and check against the
// expected set.
fprintf(stderr, "c's immediate dominator is %c\n",
tree.getImmediateDominator(&c).as<FakeNode>()->name);
CHECK(tree.getImmediateDominator(&c) == JS::ubi::Node(&r));
auto& node = relation.dominated;
fprintf(stderr, "Checking %c's dominated set:\n", node.name);
fprintf(stderr, "d's immediate dominator is %c\n",
tree.getImmediateDominator(&d).as<FakeNode>()->name);
CHECK(tree.getImmediateDominator(&d) == JS::ubi::Node(&r));
js::HashSet<char> expectedDominatedSet(cx);
CHECK(expectedDominatedSet.init());
for (auto& rel : domination) {
if (&rel.dominator == &node) {
fprintf(stderr, " Expecting %c\n", rel.dominated.name);
CHECK(expectedDominatedSet.putNew(rel.dominated.name));
}
}
fprintf(stderr, "e's immediate dominator is %c\n",
tree.getImmediateDominator(&e).as<FakeNode>()->name);
CHECK(tree.getImmediateDominator(&e) == JS::ubi::Node(&r));
auto maybeActualDominatedSet = tree.getDominatedSet(&node);
CHECK(maybeActualDominatedSet.isSome());
auto& actualDominatedSet = *maybeActualDominatedSet;
fprintf(stderr, "f's immediate dominator is %c\n",
tree.getImmediateDominator(&f).as<FakeNode>()->name);
CHECK(tree.getImmediateDominator(&f) == JS::ubi::Node(&c));
for (const auto& dominated : actualDominatedSet) {
fprintf(stderr, " Found %c\n", dominated.as<FakeNode>()->name);
CHECK(expectedDominatedSet.has(dominated.as<FakeNode>()->name));
expectedDominatedSet.remove(dominated.as<FakeNode>()->name);
}
fprintf(stderr, "g's immediate dominator is %c\n",
tree.getImmediateDominator(&g).as<FakeNode>()->name);
CHECK(tree.getImmediateDominator(&g) == JS::ubi::Node(&c));
// Ensure we found them all and aren't still expecting nodes we never
// got.
CHECK(expectedDominatedSet.count() == 0);
fprintf(stderr, "h's immediate dominator is %c\n",
tree.getImmediateDominator(&h).as<FakeNode>()->name);
CHECK(tree.getImmediateDominator(&h) == JS::ubi::Node(&r));
fprintf(stderr, "i's immediate dominator is %c\n",
tree.getImmediateDominator(&i).as<FakeNode>()->name);
CHECK(tree.getImmediateDominator(&i) == JS::ubi::Node(&r));
fprintf(stderr, "j's immediate dominator is %c\n",
tree.getImmediateDominator(&j).as<FakeNode>()->name);
CHECK(tree.getImmediateDominator(&j) == JS::ubi::Node(&g));
fprintf(stderr, "k's immediate dominator is %c\n",
tree.getImmediateDominator(&k).as<FakeNode>()->name);
CHECK(tree.getImmediateDominator(&k) == JS::ubi::Node(&r));
fprintf(stderr, "l's immediate dominator is %c\n",
tree.getImmediateDominator(&l).as<FakeNode>()->name);
CHECK(tree.getImmediateDominator(&l) == JS::ubi::Node(&d));
fprintf(stderr, "Done checking %c's dominated set.\n\n", node.name);
}
return true;
}

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

@ -2090,7 +2090,6 @@ DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, HandleValue val
{
RootedAtom atom(cx, JSID_IS_ATOM(id) ? JSID_TO_ATOM(id) : nullptr);
if (getter && !(attrs & JSPROP_GETTER)) {
RootedObject global(cx, (JSObject*) &obj->global());
JSFunction* getobj = NewNativeFunction(cx, (Native) getter, 0, atom);
if (!getobj)
return false;
@ -2104,7 +2103,6 @@ DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, HandleValue val
if (setter && !(attrs & JSPROP_SETTER)) {
// Root just the getter, since the setter is not yet a JSObject.
AutoRooterGetterSetter getRoot(cx, JSPROP_GETTER, &getter, nullptr);
RootedObject global(cx, (JSObject*) &obj->global());
JSFunction* setobj = NewNativeFunction(cx, (Native) setter, 1, atom);
if (!setobj)
return false;
@ -3453,8 +3451,13 @@ IsFunctionCloneable(HandleFunction fun)
if (IsStaticGlobalLexicalScope(scope))
return true;
// 'eval' and non-syntactic scopes are always scoped immediately under
// a non-extensible lexical scope.
// If the script already deals with non-syntactic scopes, we can clone
// it.
if (scope->is<StaticNonSyntacticScopeObjects>())
return true;
// 'eval' scopes are always scoped immediately under a non-extensible
// lexical scope.
if (scope->is<StaticBlockObject>()) {
StaticBlockObject& block = scope->as<StaticBlockObject>();
if (block.needsClone())
@ -3466,11 +3469,6 @@ IsFunctionCloneable(HandleFunction fun)
// under the global, we can clone it.
if (enclosing->is<StaticEvalObject>())
return !enclosing->as<StaticEvalObject>().isNonGlobal();
// If the script already deals with a non-syntactic scope, we can
// clone it.
if (enclosing->is<StaticNonSyntacticScopeObjects>())
return true;
}
// Any other enclosing static scope (e.g., function, block) cannot be
@ -3536,7 +3534,16 @@ CloneFunctionObject(JSContext* cx, HandleObject funobj, HandleObject dynamicScop
return CloneFunctionReuseScript(cx, fun, dynamicScope, fun->getAllocKind());
}
return CloneFunctionAndScript(cx, fun, dynamicScope, staticScope, fun->getAllocKind());
JSFunction* clone = CloneFunctionAndScript(cx, fun, dynamicScope, staticScope,
fun->getAllocKind());
#ifdef DEBUG
// The cloned function should itself be cloneable.
RootedFunction cloneRoot(cx, clone);
MOZ_ASSERT_IF(cloneRoot, IsFunctionCloneable(cloneRoot));
#endif
return clone;
}
namespace JS {

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

@ -1461,7 +1461,7 @@ JSFunction::createScriptForLazilyInterpretedFunction(JSContext* cx, HandleFuncti
/* Lazily cloned self-hosted script. */
MOZ_ASSERT(fun->isSelfHostedBuiltin());
RootedAtom funAtom(cx, &fun->getExtendedSlot(0).toString()->asAtom());
RootedAtom funAtom(cx, &fun->getExtendedSlot(LAZY_FUNCTION_NAME_SLOT).toString()->asAtom());
if (!funAtom)
return false;
Rooted<PropertyName*> funName(cx, funAtom->asPropertyName());
@ -1507,7 +1507,7 @@ JSFunction::maybeRelazify(JSRuntime* rt)
} else {
MOZ_ASSERT(isSelfHostedBuiltin());
MOZ_ASSERT(isExtended());
MOZ_ASSERT(getExtendedSlot(0).toString()->isAtom());
MOZ_ASSERT(getExtendedSlot(LAZY_FUNCTION_NAME_SLOT).toString()->isAtom());
}
}

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

@ -136,7 +136,7 @@ class StringifyContext
: sb(sb),
gap(gap),
replacer(cx, replacer),
stack(cx, TraceableHashSet<JSObject*, MovableCellHasher<JSObject*>>(cx)),
stack(cx, GCHashSet<JSObject*, MovableCellHasher<JSObject*>>(cx)),
propertyList(propertyList),
depth(0)
{}
@ -148,7 +148,7 @@ class StringifyContext
StringBuffer& sb;
const StringBuffer& gap;
RootedObject replacer;
Rooted<TraceableHashSet<JSObject*, MovableCellHasher<JSObject*>>> stack;
Rooted<GCHashSet<JSObject*, MovableCellHasher<JSObject*>>> stack;
const AutoIdVector& propertyList;
uint32_t depth;
};
@ -324,7 +324,7 @@ class CycleDetector
}
private:
MutableHandle<TraceableHashSet<JSObject*, MovableCellHasher<JSObject*>>> stack;
MutableHandle<GCHashSet<JSObject*, MovableCellHasher<JSObject*>>> stack;
HandleObject obj_;
};

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

@ -111,6 +111,7 @@ EXPORTS.js += [
'../public/Date.h',
'../public/Debug.h',
'../public/GCAPI.h',
'../public/GCHashTable.h',
'../public/HashTable.h',
'../public/HeapAPI.h',
'../public/Id.h',
@ -125,7 +126,6 @@ EXPORTS.js += [
'../public/RootingAPI.h',
'../public/SliceBudget.h',
'../public/StructuredClone.h',
'../public/TraceableHashTable.h',
'../public/TraceableVector.h',
'../public/TraceKind.h',
'../public/TracingAPI.h',

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

@ -667,7 +667,7 @@ GlobalObject::getSelfHostedFunction(JSContext* cx, Handle<GlobalObject*> global,
if (!fun)
return false;
fun->setIsSelfHostedBuiltin();
fun->setExtendedSlot(0, StringValue(selfHostedName));
fun->setExtendedSlot(LAZY_FUNCTION_NAME_SLOT, StringValue(selfHostedName));
funVal.setObject(*fun);
return GlobalObject::addIntrinsicValue(cx, global, selfHostedName, funVal);

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

@ -2027,7 +2027,7 @@ CloneObject(JSContext* cx, HandleNativeObject selfHostedObject)
// different thread than the clone target. In theory, these objects are all
// tenured and will not be compacted; however, we simply avoid the issue
// altogether by skipping the cycle-detection when off the main thread.
Maybe<AutoCycleDetector> detect;
mozilla::Maybe<AutoCycleDetector> detect;
if (js::CurrentThreadCanAccessZone(selfHostedObject->zoneFromAnyThread())) {
detect.emplace(cx, selfHostedObject);
if (!detect->init())
@ -2195,7 +2195,8 @@ js::SelfHostedFunction(JSContext* cx, HandlePropertyName propName)
bool
js::IsSelfHostedFunctionWithName(JSFunction* fun, JSAtom* name)
{
return fun->isSelfHostedBuiltin() && fun->getExtendedSlot(0).toString() == name;
return fun->isSelfHostedBuiltin() &&
fun->getExtendedSlot(LAZY_FUNCTION_NAME_SLOT).toString() == name;
}
static_assert(JSString::MAX_LENGTH <= INT32_MAX,

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

@ -41,7 +41,7 @@
#include "builtin/MapObject.h"
#include "js/Date.h"
#include "js/TraceableHashTable.h"
#include "js/GCHashTable.h"
#include "vm/SavedFrame.h"
#include "vm/SharedArrayObject.h"
#include "vm/TypedArrayObject.h"
@ -342,7 +342,7 @@ struct JSStructuredCloneWriter {
// The "memory" list described in the HTML5 internal structured cloning algorithm.
// memory is a superset of objs; items are never removed from Memory
// until a serialization operation is finished
using CloneMemory = TraceableHashMap<JSObject*, uint32_t, MovableCellHasher<JSObject*>>;
using CloneMemory = GCHashMap<JSObject*, uint32_t, MovableCellHasher<JSObject*>>;
Rooted<CloneMemory> memory;
// The user defined callbacks that will be used for cloning.

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

@ -133,7 +133,7 @@ TraceLoggerThread::init()
{
if (!pointerMap.init())
return false;
if (!extraTextId.init())
if (!textIdPayloads.init())
return false;
if (!events.init())
return false;
@ -187,8 +187,8 @@ TraceLoggerThread::~TraceLoggerThread()
graph = nullptr;
}
if (extraTextId.initialized()) {
for (TextIdHashMap::Range r = extraTextId.all(); !r.empty(); r.popFront())
if (textIdPayloads.initialized()) {
for (TextIdHashMap::Range r = textIdPayloads.all(); !r.empty(); r.popFront())
js_delete(r.front().value());
}
}
@ -297,7 +297,7 @@ TraceLoggerThread::eventText(uint32_t id)
if (id < TraceLogger_Last)
return TLTextIdString(static_cast<TraceLoggerTextId>(id));
TextIdHashMap::Ptr p = extraTextId.lookup(id);
TextIdHashMap::Ptr p = textIdPayloads.lookup(id);
MOZ_ASSERT(p);
return p->value()->string();
@ -351,13 +351,13 @@ TraceLoggerThread::extractScriptDetails(uint32_t textId, const char** filename,
TraceLoggerEventPayload*
TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId textId)
{
TextIdHashMap::AddPtr p = extraTextId.lookupForAdd(textId);
TextIdHashMap::AddPtr p = textIdPayloads.lookupForAdd(textId);
if (p)
return p->value();
TraceLoggerEventPayload* payload = js_new<TraceLoggerEventPayload>(textId, (char*)nullptr);
if (!extraTextId.add(p, textId, payload))
if (!textIdPayloads.add(p, textId, payload))
return nullptr;
return payload;
@ -379,7 +379,7 @@ TraceLoggerThread::getOrCreateEventPayload(const char* text)
MOZ_ASSERT(ret == len);
MOZ_ASSERT(strlen(str) == len);
uint32_t textId = extraTextId.count() + TraceLogger_Last;
uint32_t textId = nextTextId;
TraceLoggerEventPayload* payload = js_new<TraceLoggerEventPayload>(textId, str);
if (!payload) {
@ -387,7 +387,7 @@ TraceLoggerThread::getOrCreateEventPayload(const char* text)
return nullptr;
}
if (!extraTextId.putNew(textId, payload)) {
if (!textIdPayloads.putNew(textId, payload)) {
js_delete(payload);
return nullptr;
}
@ -398,6 +398,8 @@ TraceLoggerThread::getOrCreateEventPayload(const char* text)
if (graph.get())
graph->addTextId(textId, str);
nextTextId++;
return payload;
}
@ -438,14 +440,14 @@ TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId type, const char* f
MOZ_ASSERT(ret == len);
MOZ_ASSERT(strlen(str) == len);
uint32_t textId = extraTextId.count() + TraceLogger_Last;
uint32_t textId = nextTextId;
TraceLoggerEventPayload* payload = js_new<TraceLoggerEventPayload>(textId, str);
if (!payload) {
js_free(str);
return nullptr;
}
if (!extraTextId.putNew(textId, payload)) {
if (!textIdPayloads.putNew(textId, payload)) {
js_delete(payload);
return nullptr;
}
@ -456,6 +458,8 @@ TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId type, const char* f
if (graph.get())
graph->addTextId(textId, str);
nextTextId++;
return payload;
}
@ -566,7 +570,7 @@ TraceLoggerThread::log(uint32_t id)
}
// Free all TextEvents that have no uses anymore.
for (TextIdHashMap::Enum e(extraTextId); !e.empty(); e.popFront()) {
for (TextIdHashMap::Enum e(textIdPayloads); !e.empty(); e.popFront()) {
if (e.front().value()->uses() == 0) {
js_delete(e.front().value());
e.removeFront();

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

@ -166,7 +166,8 @@ class TraceLoggerThread
mozilla::UniquePtr<TraceLoggerGraph> graph;
PointerHashMap pointerMap;
TextIdHashMap extraTextId;
TextIdHashMap textIdPayloads;
uint32_t nextTextId;
ContinuousSpace<EventEntry> events;
@ -181,6 +182,7 @@ class TraceLoggerThread
: enabled(0),
failed(false),
graph(),
nextTextId(TraceLogger_Last),
iteration_(0),
top(nullptr)
{ }

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

@ -205,11 +205,11 @@ GridEnabledPrefChangeCallback(const char* aPrefName, void* aClosure)
// OK -- now, stomp on or restore the "grid" entries in kDisplayKTable,
// depending on whether the grid pref is enabled vs. disabled.
if (sIndexOfGridInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfGridInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfGridInDisplayTable].mKeyword =
isGridEnabled ? eCSSKeyword_grid : eCSSKeyword_UNKNOWN;
}
if (sIndexOfInlineGridInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfInlineGridInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfInlineGridInDisplayTable].mKeyword =
isGridEnabled ? eCSSKeyword_inline_grid : eCSSKeyword_UNKNOWN;
}
}
@ -265,23 +265,23 @@ RubyEnabledPrefChangeCallback(const char* aPrefName, void* aClosure)
// OK -- now, stomp on or restore the "ruby" entries in kDisplayKTable,
// depending on whether the ruby pref is enabled vs. disabled.
if (sIndexOfRubyInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfRubyInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfRubyInDisplayTable].mKeyword =
isRubyEnabled ? eCSSKeyword_ruby : eCSSKeyword_UNKNOWN;
}
if (sIndexOfRubyBaseInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfRubyBaseInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfRubyBaseInDisplayTable].mKeyword =
isRubyEnabled ? eCSSKeyword_ruby_base : eCSSKeyword_UNKNOWN;
}
if (sIndexOfRubyBaseContainerInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfRubyBaseContainerInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfRubyBaseContainerInDisplayTable].mKeyword =
isRubyEnabled ? eCSSKeyword_ruby_base_container : eCSSKeyword_UNKNOWN;
}
if (sIndexOfRubyTextInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfRubyTextInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfRubyTextInDisplayTable].mKeyword =
isRubyEnabled ? eCSSKeyword_ruby_text : eCSSKeyword_UNKNOWN;
}
if (sIndexOfRubyTextContainerInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfRubyTextContainerInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfRubyTextContainerInDisplayTable].mKeyword =
isRubyEnabled ? eCSSKeyword_ruby_text_container : eCSSKeyword_UNKNOWN;
}
}
@ -315,7 +315,7 @@ StickyEnabledPrefChangeCallback(const char* aPrefName, void* aClosure)
// OK -- now, stomp on or restore the "sticky" entry in kPositionKTable,
// depending on whether the sticky pref is enabled vs. disabled.
nsCSSProps::kPositionKTable[sIndexOfStickyInPositionTable] =
nsCSSProps::kPositionKTable[sIndexOfStickyInPositionTable].mKeyword =
isStickyEnabled ? eCSSKeyword_sticky : eCSSKeyword_UNKNOWN;
}
@ -344,7 +344,7 @@ DisplayContentsEnabledPrefChangeCallback(const char* aPrefName, void* aClosure)
// OK -- now, stomp on or restore the "contents" entry in kDisplayKTable,
// depending on whether the pref is enabled vs. disabled.
if (sIndexOfContentsInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfContentsInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfContentsInDisplayTable].mKeyword =
isDisplayContentsEnabled ? eCSSKeyword_contents : eCSSKeyword_UNKNOWN;
}
}
@ -379,10 +379,10 @@ TextAlignTrueEnabledPrefChangeCallback(const char* aPrefName, void* aClosure)
// OK -- now, stomp on or restore the "true" entry in the keyword tables,
// depending on whether the pref is enabled vs. disabled.
MOZ_ASSERT(sIndexOfTrueInTextAlignTable >= 0);
nsCSSProps::kTextAlignKTable[sIndexOfTrueInTextAlignTable] =
nsCSSProps::kTextAlignKTable[sIndexOfTrueInTextAlignTable].mKeyword =
isTextAlignTrueEnabled ? eCSSKeyword_true : eCSSKeyword_UNKNOWN;
MOZ_ASSERT(sIndexOfTrueInTextAlignLastTable >= 0);
nsCSSProps::kTextAlignLastKTable[sIndexOfTrueInTextAlignLastTable] =
nsCSSProps::kTextAlignLastKTable[sIndexOfTrueInTextAlignLastTable].mKeyword =
isTextAlignTrueEnabled ? eCSSKeyword_true : eCSSKeyword_UNKNOWN;
}
@ -428,16 +428,16 @@ FloatLogicalValuesEnabledPrefChangeCallback(const char* aPrefName,
// OK -- now, stomp on or restore the logical entries in the keyword tables,
// depending on whether the pref is enabled vs. disabled.
MOZ_ASSERT(sIndexOfInlineStartInFloatTable >= 0);
nsCSSProps::kFloatKTable[sIndexOfInlineStartInFloatTable] =
nsCSSProps::kFloatKTable[sIndexOfInlineStartInFloatTable].mKeyword =
isFloatLogicalValuesEnabled ? eCSSKeyword_inline_start : eCSSKeyword_UNKNOWN;
MOZ_ASSERT(sIndexOfInlineEndInFloatTable >= 0);
nsCSSProps::kFloatKTable[sIndexOfInlineEndInFloatTable] =
nsCSSProps::kFloatKTable[sIndexOfInlineEndInFloatTable].mKeyword =
isFloatLogicalValuesEnabled ? eCSSKeyword_inline_end : eCSSKeyword_UNKNOWN;
MOZ_ASSERT(sIndexOfInlineStartInClearTable >= 0);
nsCSSProps::kClearKTable[sIndexOfInlineStartInClearTable] =
nsCSSProps::kClearKTable[sIndexOfInlineStartInClearTable].mKeyword =
isFloatLogicalValuesEnabled ? eCSSKeyword_inline_start : eCSSKeyword_UNKNOWN;
MOZ_ASSERT(sIndexOfInlineEndInClearTable >= 0);
nsCSSProps::kClearKTable[sIndexOfInlineEndInClearTable] =
nsCSSProps::kClearKTable[sIndexOfInlineEndInClearTable].mKeyword =
isFloatLogicalValuesEnabled ? eCSSKeyword_inline_end : eCSSKeyword_UNKNOWN;
}
@ -4507,7 +4507,7 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext,
nsIFrame* aFrame,
const nsIFrame::IntrinsicISizeOffsetData& aOffsets,
nsLayoutUtils::IntrinsicISizeType aType,
uint8_t aBoxSizing,
StyleBoxSizing aBoxSizing,
nscoord aContentSize,
nscoord aContentMinSize,
const nsStyleCoord& aStyleSize,
@ -4528,7 +4528,7 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext,
coordOutsideSize += aOffsets.hPadding;
pctOutsideSize += aOffsets.hPctPadding;
if (aBoxSizing == NS_STYLE_BOX_SIZING_PADDING) {
if (aBoxSizing == StyleBoxSizing::Padding) {
min += coordOutsideSize;
result = NSCoordSaturatingAdd(result, coordOutsideSize);
pctTotal += pctOutsideSize;
@ -4540,7 +4540,7 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext,
coordOutsideSize += aOffsets.hBorder;
if (aBoxSizing == NS_STYLE_BOX_SIZING_BORDER) {
if (aBoxSizing == StyleBoxSizing::Border) {
min += coordOutsideSize;
result = NSCoordSaturatingAdd(result, coordOutsideSize);
pctTotal += pctOutsideSize;
@ -4668,7 +4668,7 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis,
// so we work in the parent's writing mode; but if aFrame is orthogonal to
// its parent, we'll need to look at its BSize instead of min/pref-ISize.
const nsStylePosition* stylePos = aFrame->StylePosition();
uint8_t boxSizing = stylePos->mBoxSizing;
StyleBoxSizing boxSizing = stylePos->mBoxSizing;
const nsStyleCoord& styleMinISize =
horizontalAxis ? stylePos->mMinWidth : stylePos->mMinHeight;
@ -4725,7 +4725,7 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis,
// widths just like auto.
// For -moz-max-content and -moz-min-content, we handle them like
// specified widths, but ignore box-sizing.
boxSizing = NS_STYLE_BOX_SIZING_CONTENT;
boxSizing = StyleBoxSizing::Content;
} else if (!styleISize.ConvertsToLength() &&
!(haveFixedMinISize && haveFixedMaxISize && maxISize <= minISize)) {
#ifdef DEBUG_INTRINSIC_WIDTH
@ -4787,14 +4787,14 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis,
nscoord bSizeTakenByBoxSizing = 0;
switch (boxSizing) {
case NS_STYLE_BOX_SIZING_BORDER: {
case StyleBoxSizing::Border: {
const nsStyleBorder* styleBorder = aFrame->StyleBorder();
bSizeTakenByBoxSizing +=
horizontalAxis ? styleBorder->GetComputedBorder().TopBottom()
: styleBorder->GetComputedBorder().LeftRight();
// fall through
}
case NS_STYLE_BOX_SIZING_PADDING: {
case StyleBoxSizing::Padding: {
if (!(aFlags & IGNORE_PADDING)) {
const nsStyleSides& stylePadding =
aFrame->StylePadding()->mPadding;
@ -4814,7 +4814,7 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis,
}
// fall through
}
case NS_STYLE_BOX_SIZING_CONTENT:
case StyleBoxSizing::Content:
default:
break;
}
@ -5191,11 +5191,15 @@ nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(WritingMode aWM,
LogicalSize boxSizingAdjust(aWM);
switch (stylePos->mBoxSizing) {
case NS_STYLE_BOX_SIZING_BORDER:
case StyleBoxSizing::Border:
boxSizingAdjust += aBorder;
// fall through
case NS_STYLE_BOX_SIZING_PADDING:
case StyleBoxSizing::Padding:
boxSizingAdjust += aPadding;
// fall through
case StyleBoxSizing::Content:
// nothing
break;
}
nscoord boxSizingToMarginEdgeISize =
aMargin.ISize(aWM) + aBorder.ISize(aWM) + aPadding.ISize(aWM) -

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

@ -693,6 +693,9 @@ nsBlockFrame::GetMinISize(nsRenderingContext *aRenderingContext)
curFrame->LazyMarkLinesDirty();
}
if (RenumberLists(PresContext())) {
AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN);
}
if (GetStateBits() & NS_BLOCK_NEEDS_BIDI_RESOLUTION)
ResolveBidi();
InlineMinISizeData data;
@ -778,6 +781,9 @@ nsBlockFrame::GetPrefISize(nsRenderingContext *aRenderingContext)
curFrame->LazyMarkLinesDirty();
}
if (RenumberLists(PresContext())) {
AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN);
}
if (GetStateBits() & NS_BLOCK_NEEDS_BIDI_RESOLUTION)
ResolveBidi();
InlinePrefISizeData data;

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

@ -4304,11 +4304,15 @@ nsFrame::ComputeSize(nsRenderingContext *aRenderingContext,
const nsStylePosition *stylePos = StylePosition();
switch (stylePos->mBoxSizing) {
case NS_STYLE_BOX_SIZING_BORDER:
case StyleBoxSizing::Border:
boxSizingAdjust += aBorder;
// fall through
case NS_STYLE_BOX_SIZING_PADDING:
case StyleBoxSizing::Padding:
boxSizingAdjust += aPadding;
// fall through
case StyleBoxSizing::Content:
// nothing
break;
}
nscoord boxSizingToMarginEdgeISize =
aMargin.ISize(aWM) + aBorder.ISize(aWM) + aPadding.ISize(aWM) -

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

@ -251,19 +251,22 @@ nsCSSOffsetState::ComputeISizeValue(nscoord aContainingBlockISize,
nscoord
nsCSSOffsetState::ComputeISizeValue(nscoord aContainingBlockISize,
uint8_t aBoxSizing,
StyleBoxSizing aBoxSizing,
const nsStyleCoord& aCoord)
{
WritingMode wm = GetWritingMode();
nscoord inside = 0, outside = ComputedLogicalBorderPadding().IStartEnd(wm) +
ComputedLogicalMargin().IStartEnd(wm);
switch (aBoxSizing) {
case NS_STYLE_BOX_SIZING_BORDER:
case StyleBoxSizing::Border:
inside = ComputedLogicalBorderPadding().IStartEnd(wm);
break;
case NS_STYLE_BOX_SIZING_PADDING:
case StyleBoxSizing::Padding:
inside = ComputedLogicalPadding().IStartEnd(wm);
break;
case StyleBoxSizing::Content:
// nothing
break;
}
outside -= inside;
@ -273,18 +276,21 @@ nsCSSOffsetState::ComputeISizeValue(nscoord aContainingBlockISize,
nscoord
nsCSSOffsetState::ComputeBSizeValue(nscoord aContainingBlockBSize,
uint8_t aBoxSizing,
StyleBoxSizing aBoxSizing,
const nsStyleCoord& aCoord)
{
WritingMode wm = GetWritingMode();
nscoord inside = 0;
switch (aBoxSizing) {
case NS_STYLE_BOX_SIZING_BORDER:
case StyleBoxSizing::Border:
inside = ComputedLogicalBorderPadding().BStartEnd(wm);
break;
case NS_STYLE_BOX_SIZING_PADDING:
case StyleBoxSizing::Padding:
inside = ComputedLogicalPadding().BStartEnd(wm);
break;
case StyleBoxSizing::Content:
// nothing
break;
}
return nsLayoutUtils::ComputeBSizeValue(aContainingBlockBSize,
inside, aCoord);
@ -1133,11 +1139,15 @@ nsHTMLReflowState::CalculateBorderPaddingMargin(
nscoord outside = paddingStartEnd + borderStartEnd + marginStartEnd;
nscoord inside = 0;
switch (mStylePosition->mBoxSizing) {
case NS_STYLE_BOX_SIZING_BORDER:
case StyleBoxSizing::Border:
inside += borderStartEnd;
// fall through
case NS_STYLE_BOX_SIZING_PADDING:
case StyleBoxSizing::Padding:
inside += paddingStartEnd;
// fall through
case StyleBoxSizing::Content:
// nothing
break;
}
outside -= inside;
*aInsideBoxSizing = inside;
@ -1456,8 +1466,8 @@ nsHTMLReflowState::CalculateHypotheticalPosition
// We need to compute it. It's important we do this, because if it's
// percentage-based this computed value may be different from the
// computed value calculated using the absolute containing block height.
boxBSize = ComputeBSizeValue(blockContentSize.BSize(wm),
insideBoxSizing, styleBSize) +
boxBSize = nsLayoutUtils::ComputeBSizeValue(blockContentSize.BSize(wm),
insideBoxSizing, styleBSize) +
insideBoxSizing + outsideBoxSizing;
}

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

@ -250,11 +250,11 @@ protected:
// same as previous, but using mComputedBorderPadding, mComputedPadding,
// and mComputedMargin
nscoord ComputeISizeValue(nscoord aContainingBlockISize,
uint8_t aBoxSizing,
mozilla::StyleBoxSizing aBoxSizing,
const nsStyleCoord& aCoord);
nscoord ComputeBSizeValue(nscoord aContainingBlockBSize,
uint8_t aBoxSizing,
mozilla::StyleBoxSizing aBoxSizing,
const nsStyleCoord& aCoord);
};

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

@ -577,17 +577,13 @@ static void GetKeywordsForProperty(const nsCSSProperty aProperty,
// Shorthand props have no keywords.
return;
}
const nsCSSProps::KTableValue *keywordTable =
const nsCSSProps::KTableEntry* keywordTable =
nsCSSProps::kKeywordTableTable[aProperty];
if (keywordTable) {
size_t i = 0;
while (nsCSSKeyword(keywordTable[i]) != eCSSKeyword_UNKNOWN) {
nsCSSKeyword word = nsCSSKeyword(keywordTable[i]);
for (size_t i = 0; keywordTable[i].mKeyword != eCSSKeyword_UNKNOWN; ++i) {
nsCSSKeyword word = keywordTable[i].mKeyword;
InsertNoDuplicates(aArray,
NS_ConvertASCIItoUTF16(nsCSSKeywords::GetStringValue(word)));
// Increment counter by 2, because in this table every second
// element is a nsCSSKeyword.
i += 2;
}
}
}

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

@ -548,7 +548,7 @@ RenderFrameParent::SetTargetAPZC(uint64_t aInputBlockId,
= &APZCTreeManager::SetTargetAPZC;
APZThreadUtils::RunOnControllerThread(NewRunnableMethod(
GetApzcTreeManager(), setTargetApzcFunc,
aInputBlockId, nsTArray<ScrollableLayerGuid>(aTargets)));
aInputBlockId, aTargets));
}
}
@ -559,7 +559,7 @@ RenderFrameParent::SetAllowedTouchBehavior(uint64_t aInputBlockId,
if (GetApzcTreeManager()) {
APZThreadUtils::RunOnControllerThread(NewRunnableMethod(
GetApzcTreeManager(), &APZCTreeManager::SetAllowedTouchBehavior,
aInputBlockId, nsTArray<TouchBehaviorFlags>(aFlags)));
aInputBlockId, aFlags));
}
}

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

@ -50,8 +50,8 @@ skip-if(B2G||Mulet) fails-if(Android) random-if(gtkWidget) == src-list-local-ps.
random-if(!cocoaWidget) == helveticaneue-ultra.html helveticaneue-ultra-ref.html
HTTP(..) == order-1.html order-1-ref.html
pref(layout.css.unicode-range.enabled,true) random-if(gtkWidget) HTTP(..) == order-2.html order-2-ref.html # enable new linux font backend, bug 1180560
pref(layout.css.unicode-range.enabled,true) random-if(gtkWidget) HTTP(..) == order-3.html order-3-ref.html # enable new linux font backend, bug 1180560
pref(layout.css.unicode-range.enabled,true) HTTP(..) == order-2.html order-2-ref.html
pref(layout.css.unicode-range.enabled,true) HTTP(..) == order-3.html order-3-ref.html
HTTP(..) == multiple-in-family-1.html multiple-in-family-1-ref.html
HTTP(..) == multiple-in-family-1b.html multiple-in-family-1-ref.html
HTTP(..) != multiple-in-family-1.html multiple-in-family-1-notref.html

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

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bug 994418</title>
</head>
<body>
MMMCMXCIX. sometext
</body>
</html>

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

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bug 994418</title>
<style>
ol {
display: inline-block;
list-style: upper-roman inside;
padding: 0; margin: 0;
}
</style>
</head>
<body>
<ol start="3999"><li></ol>sometext
</body>
</html>

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

@ -8,3 +8,4 @@ asserts(1) == ol-reversed-1b.html ol-reversed-1-ref.html # bug 478135
== bullet-space-1.html bullet-space-1-ref.html
== bullet-space-2.html bullet-space-2-ref.html
== bullet-intrinsic-isize-1.html bullet-intrinsic-isize-1-ref.html
== bullet-intrinsic-isize-2.html bullet-intrinsic-isize-2-ref.html

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

@ -30,4 +30,19 @@
<circle cx="250" cy="205" r="11" fill="lime"/>
<circle cx="206" cy="225" r="11" fill="lime"/>
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1131264 -->
<!-- small circles take a different code path -->
<!-- Test circle element dashes cover two red circles -->
<circle cx="125" cy="325" r="8" fill="red"/>
<circle cx="50" cy="380" r="8" fill="red"/>
<circle cx="0" cy="0" r=".0008" fill="none" stroke="lime" stroke-width=".0003" stroke-dasharray=".0005 .0005 .0005 100"
transform="translate(50, 300) scale(1e5, 1e5)"/>
<!-- Sanity test to check that two circles cover circle element dashes (i.e. that the previous check didn't pass because the stroke was solid) -->
<circle cx="0" cy="0" r=".0008" fill="none" stroke="red" stroke-width=".0001" stroke-dasharray=".0001 .0005 .0001 100"
transform="translate(180, 300) scale(1e5, 1e5)"/>
<circle cx="260" cy="305" r="11" fill="lime"/>
<circle cx="235" cy="358" r="11" fill="lime"/>
</svg>

До

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

После

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

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

@ -18,7 +18,7 @@
*/
#define CSS_KEY(_name,_id) eCSSKeyword_##_id,
enum nsCSSKeyword {
enum nsCSSKeyword : int16_t {
eCSSKeyword_UNKNOWN = -1,
#include "nsCSSKeywordList.h"
eCSSKeyword_COUNT

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

@ -53,7 +53,7 @@
using namespace mozilla;
typedef nsCSSProps::KTableValue KTableValue;
typedef nsCSSProps::KTableEntry KTableEntry;
// pref-backed bool values (hooked up in nsCSSParser::Startup)
static bool sOpentypeSVGEnabled;
@ -791,7 +791,7 @@ protected:
// property (like "display") for which we emulate a vendor-prefixed value
// (like "-webkit-box").
nsCSSKeyword LookupKeywordPrefixAware(nsAString& aKeywordStr,
const KTableValue aKeywordTable[]);
const KTableEntry aKeywordTable[]);
bool ShouldUseUnprefixingService() const;
bool ParsePropertyWithUnprefixingService(const nsAString& aPropertyName,
@ -964,7 +964,7 @@ protected:
// parsing 'align/justify-items/self' from the css-align spec
bool ParseAlignJustifyPosition(nsCSSValue& aResult,
const KTableValue aTable[]);
const KTableEntry aTable[]);
bool ParseJustifyItems();
bool ParseAlignItemsSelfJustifySelf(nsCSSProperty aPropID);
// parsing 'align/justify-content' from the css-align spec
@ -984,7 +984,7 @@ protected:
bool MergeBitmaskValue(int32_t aNewValue, const int32_t aMasks[],
int32_t& aMergedValue);
bool ParseBitmaskValues(nsCSSValue& aValue,
const KTableValue aKeywordTable[],
const KTableEntry aKeywordTable[],
const int32_t aMasks[]);
bool ParseFontVariantEastAsian(nsCSSValue& aValue);
bool ParseFontVariantLigatures(nsCSSValue& aValue);
@ -1008,7 +1008,7 @@ protected:
bool ParsePadding();
bool ParseQuotes();
bool ParseTextAlign(nsCSSValue& aValue,
const KTableValue aTable[]);
const KTableEntry aTable[]);
bool ParseTextAlign(nsCSSValue& aValue);
bool ParseTextAlignLast(nsCSSValue& aValue);
bool ParseTextDecoration();
@ -1119,28 +1119,28 @@ protected:
bool ParseColorOpacity(uint8_t& aOpacity);
bool ParseColorOpacity(float& aOpacity);
bool ParseEnum(nsCSSValue& aValue,
const KTableValue aKeywordTable[]);
const KTableEntry aKeywordTable[]);
// Variant parsing methods
CSSParseResult ParseVariant(nsCSSValue& aValue,
int32_t aVariantMask,
const KTableValue aKeywordTable[]);
const KTableEntry aKeywordTable[]);
CSSParseResult ParseVariantWithRestrictions(nsCSSValue& aValue,
int32_t aVariantMask,
const KTableValue aKeywordTable[],
const KTableEntry aKeywordTable[],
uint32_t aRestrictions);
CSSParseResult ParseNonNegativeVariant(nsCSSValue& aValue,
int32_t aVariantMask,
const KTableValue aKeywordTable[]);
const KTableEntry aKeywordTable[]);
CSSParseResult ParseOneOrLargerVariant(nsCSSValue& aValue,
int32_t aVariantMask,
const KTableValue aKeywordTable[]);
const KTableEntry aKeywordTable[]);
// Variant parsing methods that are guaranteed to UngetToken any token
// consumed on failure
bool ParseSingleTokenVariant(nsCSSValue& aValue,
int32_t aVariantMask,
const KTableValue aKeywordTable[])
const KTableEntry aKeywordTable[])
{
MOZ_ASSERT(!(aVariantMask & VARIANT_MULTIPLE_TOKENS),
"use ParseVariant for variants in VARIANT_MULTIPLE_TOKENS");
@ -1151,7 +1151,7 @@ protected:
bool ParseSingleTokenVariantWithRestrictions(
nsCSSValue& aValue,
int32_t aVariantMask,
const KTableValue aKeywordTable[],
const KTableEntry aKeywordTable[],
uint32_t aRestrictions)
{
MOZ_ASSERT(!(aVariantMask & VARIANT_MULTIPLE_TOKENS),
@ -1165,7 +1165,7 @@ protected:
}
bool ParseSingleTokenNonNegativeVariant(nsCSSValue& aValue,
int32_t aVariantMask,
const KTableValue aKeywordTable[])
const KTableEntry aKeywordTable[])
{
MOZ_ASSERT(!(aVariantMask & VARIANT_MULTIPLE_TOKENS),
"use ParseNonNegativeVariant for variants in "
@ -1177,7 +1177,7 @@ protected:
}
bool ParseSingleTokenOneOrLargerVariant(nsCSSValue& aValue,
int32_t aVariantMask,
const KTableValue aKeywordTable[])
const KTableEntry aKeywordTable[])
{
MOZ_ASSERT(!(aVariantMask & VARIANT_MULTIPLE_TOKENS),
"use ParseOneOrLargerVariant for variants in "
@ -1209,12 +1209,12 @@ protected:
// that ends with a eCSSKeyword_UNKNOWN marker.
//
// |aPropertyKTable| can be used if some of the keywords to exclude
// also appear in an existing nsCSSProps::KTableValue,
// also appear in an existing nsCSSProps::KTableEntry,
// to avoid duplicating them.
bool ParseCustomIdent(nsCSSValue& aValue,
const nsAutoString& aIdentValue,
const nsCSSKeyword aExcludedKeywords[] = nullptr,
const nsCSSProps::KTableValue aPropertyKTable[] = nullptr);
const nsCSSProps::KTableEntry aPropertyKTable[] = nullptr);
bool ParseCounter(nsCSSValue& aValue);
bool ParseAttr(nsCSSValue& aValue);
bool ParseSymbols(nsCSSValue& aValue);
@ -6807,7 +6807,7 @@ CSSParserImpl::ParseTreePseudoElement(nsAtomList **aPseudoElementArgs)
nsCSSKeyword
CSSParserImpl::LookupKeywordPrefixAware(nsAString& aKeywordStr,
const KTableValue aKeywordTable[])
const KTableEntry aKeywordTable[])
{
nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(aKeywordStr);
@ -7219,7 +7219,7 @@ static const nsCSSProperty kColumnRuleIDs[] = {
bool
CSSParserImpl::ParseEnum(nsCSSValue& aValue,
const KTableValue aKeywordTable[])
const KTableEntry aKeywordTable[])
{
nsSubstring* ident = NextIdent();
if (nullptr == ident) {
@ -7364,7 +7364,7 @@ CSSParserImpl::TranslateDimension(nsCSSValue& aValue,
CSSParseResult
CSSParserImpl::ParseVariantWithRestrictions(nsCSSValue& aValue,
int32_t aVariantMask,
const KTableValue aKeywordTable[],
const KTableEntry aKeywordTable[],
uint32_t aRestrictions)
{
switch (aRestrictions) {
@ -7386,7 +7386,7 @@ CSSParserImpl::ParseVariantWithRestrictions(nsCSSValue& aValue,
CSSParseResult
CSSParserImpl::ParseNonNegativeVariant(nsCSSValue& aValue,
int32_t aVariantMask,
const KTableValue aKeywordTable[])
const KTableEntry aKeywordTable[])
{
// The variant mask must only contain non-numeric variants or the ones
// that we specifically handle.
@ -7428,7 +7428,7 @@ CSSParserImpl::ParseNonNegativeVariant(nsCSSValue& aValue,
CSSParseResult
CSSParserImpl::ParseOneOrLargerVariant(nsCSSValue& aValue,
int32_t aVariantMask,
const KTableValue aKeywordTable[])
const KTableEntry aKeywordTable[])
{
// The variant mask must only contain non-numeric variants or the ones
// that we specifically handle.
@ -7458,7 +7458,7 @@ CSSParserImpl::ParseOneOrLargerVariant(nsCSSValue& aValue,
CSSParseResult
CSSParserImpl::ParseVariant(nsCSSValue& aValue,
int32_t aVariantMask,
const KTableValue aKeywordTable[])
const KTableEntry aKeywordTable[])
{
NS_ASSERTION(!(mHashlessColorQuirk && (aVariantMask & VARIANT_COLOR)) ||
!(aVariantMask & VARIANT_NUMBER),
@ -7764,7 +7764,7 @@ bool
CSSParserImpl::ParseCustomIdent(nsCSSValue& aValue,
const nsAutoString& aIdentValue,
const nsCSSKeyword aExcludedKeywords[],
const nsCSSProps::KTableValue aPropertyKTable[])
const nsCSSProps::KTableEntry aPropertyKTable[])
{
nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(aIdentValue);
if (keyword == eCSSKeyword_UNKNOWN) {
@ -9459,7 +9459,7 @@ CSSParserImpl::ParseGridGap()
// $aTable is for <content-position> or <self-position>
bool
CSSParserImpl::ParseAlignJustifyPosition(nsCSSValue& aResult,
const KTableValue aTable[])
const KTableEntry aTable[])
{
nsCSSValue pos, overflowPos;
int32_t value = 0;
@ -10804,7 +10804,7 @@ CSSParserImpl::ParseBoxProperty(nsCSSValue& aValue,
return CSSParseResult::NotFound;
}
const KTableValue* kwtable = nsCSSProps::kKeywordTableTable[aPropID];
const KTableEntry* kwtable = nsCSSProps::kKeywordTableTable[aPropID];
uint32_t restrictions = nsCSSProps::ValueRestrictions(aPropID);
return ParseVariantWithRestrictions(aValue, variant, kwtable, restrictions);
@ -10910,7 +10910,7 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
return CSSParseResult::NotFound;
}
const KTableValue* kwtable = nsCSSProps::kKeywordTableTable[aPropID];
const KTableEntry* kwtable = nsCSSProps::kKeywordTableTable[aPropID];
uint32_t restrictions = nsCSSProps::ValueRestrictions(aPropID);
return ParseVariantWithRestrictions(aValue, variant, kwtable, restrictions);
}
@ -12539,27 +12539,28 @@ CSSParserImpl::ParseContent()
{
// We need to divide the 'content' keywords into two classes for
// ParseVariant's sake, so we can't just use nsCSSProps::kContentKTable.
static const KTableValue kContentListKWs[] = {
eCSSKeyword_open_quote, NS_STYLE_CONTENT_OPEN_QUOTE,
eCSSKeyword_close_quote, NS_STYLE_CONTENT_CLOSE_QUOTE,
eCSSKeyword_no_open_quote, NS_STYLE_CONTENT_NO_OPEN_QUOTE,
eCSSKeyword_no_close_quote, NS_STYLE_CONTENT_NO_CLOSE_QUOTE,
eCSSKeyword_UNKNOWN,-1
static const KTableEntry kContentListKWs[] = {
{ eCSSKeyword_open_quote, NS_STYLE_CONTENT_OPEN_QUOTE },
{ eCSSKeyword_close_quote, NS_STYLE_CONTENT_CLOSE_QUOTE },
{ eCSSKeyword_no_open_quote, NS_STYLE_CONTENT_NO_OPEN_QUOTE },
{ eCSSKeyword_no_close_quote, NS_STYLE_CONTENT_NO_CLOSE_QUOTE },
{ eCSSKeyword_UNKNOWN, -1 }
};
static const KTableValue kContentSolitaryKWs[] = {
eCSSKeyword__moz_alt_content, NS_STYLE_CONTENT_ALT_CONTENT,
eCSSKeyword_UNKNOWN,-1
static const KTableEntry kContentSolitaryKWs[] = {
{ eCSSKeyword__moz_alt_content, NS_STYLE_CONTENT_ALT_CONTENT },
{ eCSSKeyword_UNKNOWN, -1 }
};
// Verify that these two lists add up to the size of
// nsCSSProps::kContentKTable.
MOZ_ASSERT(nsCSSProps::kContentKTable[
ArrayLength(kContentListKWs) +
ArrayLength(kContentSolitaryKWs) - 4] == eCSSKeyword_UNKNOWN &&
ArrayLength(kContentSolitaryKWs) - 2].mKeyword ==
eCSSKeyword_UNKNOWN &&
nsCSSProps::kContentKTable[
ArrayLength(kContentListKWs) +
ArrayLength(kContentSolitaryKWs) - 3] == -1,
ArrayLength(kContentSolitaryKWs) - 2].mValue == -1,
"content keyword tables out of sync");
nsCSSValue value;
@ -13031,7 +13032,7 @@ CSSParserImpl::MergeBitmaskValue(int32_t aNewValue,
bool
CSSParserImpl::ParseBitmaskValues(nsCSSValue& aValue,
const KTableValue aKeywordTable[],
const KTableEntry aKeywordTable[],
const int32_t aMasks[])
{
// Parse at least one keyword
@ -14009,7 +14010,7 @@ CSSParserImpl::ParseTextDecoration()
}
bool
CSSParserImpl::ParseTextAlign(nsCSSValue& aValue, const KTableValue aTable[])
CSSParserImpl::ParseTextAlign(nsCSSValue& aValue, const KTableEntry aTable[])
{
if (ParseSingleTokenVariant(aValue, VARIANT_INHERIT, nullptr)) {
// 'inherit', 'initial' and 'unset' must be alone
@ -15688,16 +15689,16 @@ CSSParserImpl::ParsePaintOrder()
((1 << NS_STYLE_PAINT_ORDER_BITWIDTH) > NS_STYLE_PAINT_ORDER_LAST_VALUE,
"bitfield width insufficient for paint-order constants");
static const KTableValue kPaintOrderKTable[] = {
eCSSKeyword_normal, NS_STYLE_PAINT_ORDER_NORMAL,
eCSSKeyword_fill, NS_STYLE_PAINT_ORDER_FILL,
eCSSKeyword_stroke, NS_STYLE_PAINT_ORDER_STROKE,
eCSSKeyword_markers, NS_STYLE_PAINT_ORDER_MARKERS,
eCSSKeyword_UNKNOWN,-1
static const KTableEntry kPaintOrderKTable[] = {
{ eCSSKeyword_normal, NS_STYLE_PAINT_ORDER_NORMAL },
{ eCSSKeyword_fill, NS_STYLE_PAINT_ORDER_FILL },
{ eCSSKeyword_stroke, NS_STYLE_PAINT_ORDER_STROKE },
{ eCSSKeyword_markers, NS_STYLE_PAINT_ORDER_MARKERS },
{ eCSSKeyword_UNKNOWN, -1 }
};
static_assert(MOZ_ARRAY_LENGTH(kPaintOrderKTable) ==
2 * (NS_STYLE_PAINT_ORDER_LAST_VALUE + 2),
NS_STYLE_PAINT_ORDER_LAST_VALUE + 2,
"missing paint-order values in kPaintOrderKTable");
nsCSSValue value;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -307,7 +307,10 @@ enum nsStyleAnimType {
class nsCSSProps {
public:
typedef int16_t KTableValue;
struct KTableEntry {
nsCSSKeyword mKeyword;
int16_t mValue;
};
static void AddRefTable(void);
static void ReleaseTable(void);
@ -387,22 +390,22 @@ public:
// otherwise, returns -1.
// NOTE: Generally, clients should call FindKeyword() instead of this method.
static int32_t FindIndexOfKeyword(nsCSSKeyword aKeyword,
const KTableValue aTable[]);
const KTableEntry aTable[]);
// Find |aKeyword| in |aTable|, if found set |aValue| to its corresponding value.
// If not found, return false and do not set |aValue|.
static bool FindKeyword(nsCSSKeyword aKeyword, const KTableValue aTable[],
static bool FindKeyword(nsCSSKeyword aKeyword, const KTableEntry aTable[],
int32_t& aValue);
// Return the first keyword in |aTable| that has the corresponding value |aValue|.
// Return |eCSSKeyword_UNKNOWN| if not found.
static nsCSSKeyword ValueToKeywordEnum(int32_t aValue,
const KTableValue aTable[]);
const KTableEntry aTable[]);
// Ditto but as a string, return "" when not found.
static const nsAFlatCString& ValueToKeyword(int32_t aValue,
const KTableValue aTable[]);
const KTableEntry aTable[]);
static const nsStyleStructID kSIDTable[eCSSProperty_COUNT_no_shorthands];
static const KTableValue* const kKeywordTableTable[eCSSProperty_COUNT_no_shorthands];
static const KTableEntry* const kKeywordTableTable[eCSSProperty_COUNT_no_shorthands];
static const nsStyleAnimType kAnimTypeTable[eCSSProperty_COUNT_no_shorthands];
static const ptrdiff_t
kStyleStructOffsetTable[eCSSProperty_COUNT_no_shorthands];
@ -627,180 +630,180 @@ public:
if (nsCSSProps::IsEnabled(*it_, (nsCSSProps::EnabledState) es_))
// Keyword/Enum value tables
static const KTableValue kAnimationDirectionKTable[];
static const KTableValue kAnimationFillModeKTable[];
static const KTableValue kAnimationIterationCountKTable[];
static const KTableValue kAnimationPlayStateKTable[];
static const KTableValue kAnimationTimingFunctionKTable[];
static const KTableValue kAppearanceKTable[];
static const KTableValue kAzimuthKTable[];
static const KTableValue kBackfaceVisibilityKTable[];
static const KTableValue kTransformStyleKTable[];
static const KTableValue kBackgroundAttachmentKTable[];
static const KTableValue kBackgroundOriginKTable[];
static const KTableValue kBackgroundPositionKTable[];
static const KTableValue kBackgroundRepeatKTable[];
static const KTableValue kBackgroundRepeatPartKTable[];
static const KTableValue kBackgroundSizeKTable[];
static const KTableValue kBlendModeKTable[];
static const KTableValue kBorderCollapseKTable[];
static const KTableValue kBorderColorKTable[];
static const KTableValue kBorderImageRepeatKTable[];
static const KTableValue kBorderImageSliceKTable[];
static const KTableValue kBorderStyleKTable[];
static const KTableValue kBorderWidthKTable[];
static const KTableValue kBoxAlignKTable[];
static const KTableValue kBoxDecorationBreakKTable[];
static const KTableValue kBoxDirectionKTable[];
static const KTableValue kBoxOrientKTable[];
static const KTableValue kBoxPackKTable[];
static const KTableValue kClipShapeSizingKTable[];
static const KTableValue kCounterRangeKTable[];
static const KTableValue kCounterSpeakAsKTable[];
static const KTableValue kCounterSymbolsSystemKTable[];
static const KTableValue kCounterSystemKTable[];
static const KTableValue kDominantBaselineKTable[];
static const KTableValue kShapeRadiusKTable[];
static const KTableValue kFillRuleKTable[];
static const KTableValue kFilterFunctionKTable[];
static const KTableValue kImageRenderingKTable[];
static const KTableValue kShapeRenderingKTable[];
static const KTableValue kStrokeLinecapKTable[];
static const KTableValue kStrokeLinejoinKTable[];
static const KTableValue kStrokeContextValueKTable[];
static const KTableValue kVectorEffectKTable[];
static const KTableValue kTextAnchorKTable[];
static const KTableValue kTextRenderingKTable[];
static const KTableValue kColorInterpolationKTable[];
static const KTableValue kColumnFillKTable[];
static const KTableValue kBoxPropSourceKTable[];
static const KTableValue kBoxShadowTypeKTable[];
static const KTableValue kBoxSizingKTable[];
static const KTableValue kCaptionSideKTable[];
static const KTableEntry kAnimationDirectionKTable[];
static const KTableEntry kAnimationFillModeKTable[];
static const KTableEntry kAnimationIterationCountKTable[];
static const KTableEntry kAnimationPlayStateKTable[];
static const KTableEntry kAnimationTimingFunctionKTable[];
static const KTableEntry kAppearanceKTable[];
static const KTableEntry kAzimuthKTable[];
static const KTableEntry kBackfaceVisibilityKTable[];
static const KTableEntry kTransformStyleKTable[];
static const KTableEntry kBackgroundAttachmentKTable[];
static const KTableEntry kBackgroundOriginKTable[];
static const KTableEntry kBackgroundPositionKTable[];
static const KTableEntry kBackgroundRepeatKTable[];
static const KTableEntry kBackgroundRepeatPartKTable[];
static const KTableEntry kBackgroundSizeKTable[];
static const KTableEntry kBlendModeKTable[];
static const KTableEntry kBorderCollapseKTable[];
static const KTableEntry kBorderColorKTable[];
static const KTableEntry kBorderImageRepeatKTable[];
static const KTableEntry kBorderImageSliceKTable[];
static const KTableEntry kBorderStyleKTable[];
static const KTableEntry kBorderWidthKTable[];
static const KTableEntry kBoxAlignKTable[];
static const KTableEntry kBoxDecorationBreakKTable[];
static const KTableEntry kBoxDirectionKTable[];
static const KTableEntry kBoxOrientKTable[];
static const KTableEntry kBoxPackKTable[];
static const KTableEntry kClipShapeSizingKTable[];
static const KTableEntry kCounterRangeKTable[];
static const KTableEntry kCounterSpeakAsKTable[];
static const KTableEntry kCounterSymbolsSystemKTable[];
static const KTableEntry kCounterSystemKTable[];
static const KTableEntry kDominantBaselineKTable[];
static const KTableEntry kShapeRadiusKTable[];
static const KTableEntry kFillRuleKTable[];
static const KTableEntry kFilterFunctionKTable[];
static const KTableEntry kImageRenderingKTable[];
static const KTableEntry kShapeRenderingKTable[];
static const KTableEntry kStrokeLinecapKTable[];
static const KTableEntry kStrokeLinejoinKTable[];
static const KTableEntry kStrokeContextValueKTable[];
static const KTableEntry kVectorEffectKTable[];
static const KTableEntry kTextAnchorKTable[];
static const KTableEntry kTextRenderingKTable[];
static const KTableEntry kColorInterpolationKTable[];
static const KTableEntry kColumnFillKTable[];
static const KTableEntry kBoxPropSourceKTable[];
static const KTableEntry kBoxShadowTypeKTable[];
static const KTableEntry kBoxSizingKTable[];
static const KTableEntry kCaptionSideKTable[];
// Not const because we modify its entries when the pref
// "layout.css.float-logical-values.enabled" changes:
static KTableValue kClearKTable[];
static const KTableValue kColorKTable[];
static const KTableValue kContentKTable[];
static const KTableValue kControlCharacterVisibilityKTable[];
static const KTableValue kCursorKTable[];
static const KTableValue kDirectionKTable[];
static KTableEntry kClearKTable[];
static const KTableEntry kColorKTable[];
static const KTableEntry kContentKTable[];
static const KTableEntry kControlCharacterVisibilityKTable[];
static const KTableEntry kCursorKTable[];
static const KTableEntry kDirectionKTable[];
// Not const because we modify its entries when various
// "layout.css.*.enabled" prefs changes:
static KTableValue kDisplayKTable[];
static const KTableValue kElevationKTable[];
static const KTableValue kEmptyCellsKTable[];
static KTableEntry kDisplayKTable[];
static const KTableEntry kElevationKTable[];
static const KTableEntry kEmptyCellsKTable[];
// -- tables for the align-/justify-content/items/self properties --
static const KTableValue kAlignAllKeywords[];
static const KTableValue kAlignOverflowPosition[]; // <overflow-position>
static const KTableValue kAlignSelfPosition[]; // <self-position>
static const KTableValue kAlignLegacy[]; // 'legacy'
static const KTableValue kAlignLegacyPosition[]; // 'left/right/center'
static const KTableValue kAlignAutoStretchBaseline[]; // 'auto/stretch/baseline/last-baseline'
static const KTableValue kAlignAutoBaseline[]; // 'auto/baseline/last-baseline'
static const KTableValue kAlignContentDistribution[]; // <content-distribution>
static const KTableValue kAlignContentPosition[]; // <content-position>
static const KTableValue kAlignSelfKTable[];
static const KTableValue kJustifyContentKTable[];
static const KTableEntry kAlignAllKeywords[];
static const KTableEntry kAlignOverflowPosition[]; // <overflow-position>
static const KTableEntry kAlignSelfPosition[]; // <self-position>
static const KTableEntry kAlignLegacy[]; // 'legacy'
static const KTableEntry kAlignLegacyPosition[]; // 'left/right/center'
static const KTableEntry kAlignAutoStretchBaseline[]; // 'auto/stretch/baseline/last-baseline'
static const KTableEntry kAlignAutoBaseline[]; // 'auto/baseline/last-baseline'
static const KTableEntry kAlignContentDistribution[]; // <content-distribution>
static const KTableEntry kAlignContentPosition[]; // <content-position>
static const KTableEntry kAlignSelfKTable[];
static const KTableEntry kJustifyContentKTable[];
// ------------------------------------------------------------------
static const KTableValue kFlexDirectionKTable[];
static const KTableValue kFlexWrapKTable[];
static const KTableEntry kFlexDirectionKTable[];
static const KTableEntry kFlexWrapKTable[];
// Not const because we modify its entries when the pref
// "layout.css.float-logical-values.enabled" changes:
static KTableValue kFloatKTable[];
static const KTableValue kFloatEdgeKTable[];
static const KTableValue kFontKTable[];
static const KTableValue kFontKerningKTable[];
static const KTableValue kFontSizeKTable[];
static const KTableValue kFontSmoothingKTable[];
static const KTableValue kFontStretchKTable[];
static const KTableValue kFontStyleKTable[];
static const KTableValue kFontSynthesisKTable[];
static const KTableValue kFontVariantKTable[];
static const KTableValue kFontVariantAlternatesKTable[];
static const KTableValue kFontVariantAlternatesFuncsKTable[];
static const KTableValue kFontVariantCapsKTable[];
static const KTableValue kFontVariantEastAsianKTable[];
static const KTableValue kFontVariantLigaturesKTable[];
static const KTableValue kFontVariantNumericKTable[];
static const KTableValue kFontVariantPositionKTable[];
static const KTableValue kFontWeightKTable[];
static const KTableValue kGridAutoFlowKTable[];
static const KTableValue kGridTrackBreadthKTable[];
static const KTableValue kHyphensKTable[];
static const KTableValue kImageOrientationKTable[];
static const KTableValue kImageOrientationFlipKTable[];
static const KTableValue kIsolationKTable[];
static const KTableValue kIMEModeKTable[];
static const KTableValue kLineHeightKTable[];
static const KTableValue kListStylePositionKTable[];
static const KTableValue kListStyleKTable[];
static const KTableValue kMaskTypeKTable[];
static const KTableValue kMathVariantKTable[];
static const KTableValue kMathDisplayKTable[];
static const KTableValue kContainKTable[];
static const KTableValue kContextOpacityKTable[];
static const KTableValue kContextPatternKTable[];
static const KTableValue kObjectFitKTable[];
static const KTableValue kOrientKTable[];
static const KTableValue kOutlineStyleKTable[];
static const KTableValue kOutlineColorKTable[];
static const KTableValue kOverflowKTable[];
static const KTableValue kOverflowSubKTable[];
static const KTableValue kOverflowClipBoxKTable[];
static const KTableValue kPageBreakKTable[];
static const KTableValue kPageBreakInsideKTable[];
static const KTableValue kPageMarksKTable[];
static const KTableValue kPageSizeKTable[];
static const KTableValue kPitchKTable[];
static const KTableValue kPointerEventsKTable[];
static KTableEntry kFloatKTable[];
static const KTableEntry kFloatEdgeKTable[];
static const KTableEntry kFontKTable[];
static const KTableEntry kFontKerningKTable[];
static const KTableEntry kFontSizeKTable[];
static const KTableEntry kFontSmoothingKTable[];
static const KTableEntry kFontStretchKTable[];
static const KTableEntry kFontStyleKTable[];
static const KTableEntry kFontSynthesisKTable[];
static const KTableEntry kFontVariantKTable[];
static const KTableEntry kFontVariantAlternatesKTable[];
static const KTableEntry kFontVariantAlternatesFuncsKTable[];
static const KTableEntry kFontVariantCapsKTable[];
static const KTableEntry kFontVariantEastAsianKTable[];
static const KTableEntry kFontVariantLigaturesKTable[];
static const KTableEntry kFontVariantNumericKTable[];
static const KTableEntry kFontVariantPositionKTable[];
static const KTableEntry kFontWeightKTable[];
static const KTableEntry kGridAutoFlowKTable[];
static const KTableEntry kGridTrackBreadthKTable[];
static const KTableEntry kHyphensKTable[];
static const KTableEntry kImageOrientationKTable[];
static const KTableEntry kImageOrientationFlipKTable[];
static const KTableEntry kIsolationKTable[];
static const KTableEntry kIMEModeKTable[];
static const KTableEntry kLineHeightKTable[];
static const KTableEntry kListStylePositionKTable[];
static const KTableEntry kListStyleKTable[];
static const KTableEntry kMaskTypeKTable[];
static const KTableEntry kMathVariantKTable[];
static const KTableEntry kMathDisplayKTable[];
static const KTableEntry kContainKTable[];
static const KTableEntry kContextOpacityKTable[];
static const KTableEntry kContextPatternKTable[];
static const KTableEntry kObjectFitKTable[];
static const KTableEntry kOrientKTable[];
static const KTableEntry kOutlineStyleKTable[];
static const KTableEntry kOutlineColorKTable[];
static const KTableEntry kOverflowKTable[];
static const KTableEntry kOverflowSubKTable[];
static const KTableEntry kOverflowClipBoxKTable[];
static const KTableEntry kPageBreakKTable[];
static const KTableEntry kPageBreakInsideKTable[];
static const KTableEntry kPageMarksKTable[];
static const KTableEntry kPageSizeKTable[];
static const KTableEntry kPitchKTable[];
static const KTableEntry kPointerEventsKTable[];
// Not const because we modify its entries when the pref
// "layout.css.sticky.enabled" changes:
static KTableValue kPositionKTable[];
static const KTableValue kRadialGradientShapeKTable[];
static const KTableValue kRadialGradientSizeKTable[];
static const KTableValue kRadialGradientLegacySizeKTable[];
static const KTableValue kResizeKTable[];
static const KTableValue kRubyAlignKTable[];
static const KTableValue kRubyPositionKTable[];
static const KTableValue kScrollBehaviorKTable[];
static const KTableValue kScrollSnapTypeKTable[];
static const KTableValue kSpeakKTable[];
static const KTableValue kSpeakHeaderKTable[];
static const KTableValue kSpeakNumeralKTable[];
static const KTableValue kSpeakPunctuationKTable[];
static const KTableValue kSpeechRateKTable[];
static const KTableValue kStackSizingKTable[];
static const KTableValue kTableLayoutKTable[];
static KTableEntry kPositionKTable[];
static const KTableEntry kRadialGradientShapeKTable[];
static const KTableEntry kRadialGradientSizeKTable[];
static const KTableEntry kRadialGradientLegacySizeKTable[];
static const KTableEntry kResizeKTable[];
static const KTableEntry kRubyAlignKTable[];
static const KTableEntry kRubyPositionKTable[];
static const KTableEntry kScrollBehaviorKTable[];
static const KTableEntry kScrollSnapTypeKTable[];
static const KTableEntry kSpeakKTable[];
static const KTableEntry kSpeakHeaderKTable[];
static const KTableEntry kSpeakNumeralKTable[];
static const KTableEntry kSpeakPunctuationKTable[];
static const KTableEntry kSpeechRateKTable[];
static const KTableEntry kStackSizingKTable[];
static const KTableEntry kTableLayoutKTable[];
// Not const because we modify its entries when the pref
// "layout.css.text-align-true-value.enabled" changes:
static KTableValue kTextAlignKTable[];
static KTableValue kTextAlignLastKTable[];
static const KTableValue kTextCombineUprightKTable[];
static const KTableValue kTextDecorationLineKTable[];
static const KTableValue kTextDecorationStyleKTable[];
static const KTableValue kTextOrientationKTable[];
static const KTableValue kTextOverflowKTable[];
static const KTableValue kTextTransformKTable[];
static const KTableValue kTouchActionKTable[];
static const KTableValue kTopLayerKTable[];
static const KTableValue kTransformBoxKTable[];
static const KTableValue kTransitionTimingFunctionKTable[];
static const KTableValue kUnicodeBidiKTable[];
static const KTableValue kUserFocusKTable[];
static const KTableValue kUserInputKTable[];
static const KTableValue kUserModifyKTable[];
static const KTableValue kUserSelectKTable[];
static const KTableValue kVerticalAlignKTable[];
static const KTableValue kVisibilityKTable[];
static const KTableValue kVolumeKTable[];
static const KTableValue kWhitespaceKTable[];
static const KTableValue kWidthKTable[]; // also min-width, max-width
static const KTableValue kWindowDraggingKTable[];
static const KTableValue kWindowShadowKTable[];
static const KTableValue kWordBreakKTable[];
static const KTableValue kWordWrapKTable[];
static const KTableValue kWritingModeKTable[];
static KTableEntry kTextAlignKTable[];
static KTableEntry kTextAlignLastKTable[];
static const KTableEntry kTextCombineUprightKTable[];
static const KTableEntry kTextDecorationLineKTable[];
static const KTableEntry kTextDecorationStyleKTable[];
static const KTableEntry kTextOrientationKTable[];
static const KTableEntry kTextOverflowKTable[];
static const KTableEntry kTextTransformKTable[];
static const KTableEntry kTouchActionKTable[];
static const KTableEntry kTopLayerKTable[];
static const KTableEntry kTransformBoxKTable[];
static const KTableEntry kTransitionTimingFunctionKTable[];
static const KTableEntry kUnicodeBidiKTable[];
static const KTableEntry kUserFocusKTable[];
static const KTableEntry kUserInputKTable[];
static const KTableEntry kUserModifyKTable[];
static const KTableEntry kUserSelectKTable[];
static const KTableEntry kVerticalAlignKTable[];
static const KTableEntry kVisibilityKTable[];
static const KTableEntry kVolumeKTable[];
static const KTableEntry kWhitespaceKTable[];
static const KTableEntry kWidthKTable[]; // also min-width, max-width
static const KTableEntry kWindowDraggingKTable[];
static const KTableEntry kWindowShadowKTable[];
static const KTableEntry kWordBreakKTable[];
static const KTableEntry kWordWrapKTable[];
static const KTableEntry kWritingModeKTable[];
};
inline nsCSSProps::EnabledState operator|(nsCSSProps::EnabledState a,

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

@ -533,12 +533,15 @@ nsComputedDOMStyle::GetAdjustedValuesForBoxSizing()
nsMargin adjustment;
switch(stylePos->mBoxSizing) {
case NS_STYLE_BOX_SIZING_BORDER:
case StyleBoxSizing::Border:
adjustment += mInnerFrame->GetUsedBorder();
// fall through
case NS_STYLE_BOX_SIZING_PADDING:
case StyleBoxSizing::Padding:
adjustment += mInnerFrame->GetUsedPadding();
// fall through
case StyleBoxSizing::Content:
// nothing
break;
}
return adjustment;
@ -1791,7 +1794,7 @@ nsComputedDOMStyle::DoGetFontVariantPosition()
CSSValue*
nsComputedDOMStyle::GetBackgroundList(uint8_t nsStyleBackground::Layer::* aMember,
uint32_t nsStyleBackground::* aCount,
const KTableValue aTable[])
const KTableEntry aTable[])
{
const nsStyleBackground* bg = StyleBackground();
@ -3310,7 +3313,7 @@ nsComputedDOMStyle::DoGetVerticalAlign()
CSSValue*
nsComputedDOMStyle::CreateTextAlignValue(uint8_t aAlign, bool aAlignTrue,
const KTableValue aTable[])
const KTableEntry aTable[])
{
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
val->SetIdent(nsCSSProps::ValueToKeywordEnum(aAlign, aTable));
@ -3779,7 +3782,7 @@ nsComputedDOMStyle::DoGetBoxSizing()
{
nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue;
val->SetIdent(
nsCSSProps::ValueToKeywordEnum(StylePosition()->mBoxSizing,
nsCSSProps::ValueToKeywordEnum(uint8_t(StylePosition()->mBoxSizing),
nsCSSProps::kBoxSizingKTable));
return val;
}
@ -4866,7 +4869,7 @@ nsComputedDOMStyle::SetValueToCoord(nsROCSSPrimitiveValue* aValue,
const nsStyleCoord& aCoord,
bool aClampNegativeCalc,
PercentageBaseGetter aPercentageBaseGetter,
const KTableValue aTable[],
const KTableEntry aTable[],
nscoord aMinAppUnits,
nscoord aMaxAppUnits)
{

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

@ -48,7 +48,7 @@ class nsComputedDOMStyle final : public nsDOMCSSDeclaration
, public nsStubMutationObserver
{
public:
typedef nsCSSProps::KTableValue KTableValue;
typedef nsCSSProps::KTableEntry KTableEntry;
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsComputedDOMStyle,
@ -127,7 +127,7 @@ private:
// Helper method for DoGetTextAlign[Last].
mozilla::dom::CSSValue* CreateTextAlignValue(uint8_t aAlign,
bool aAlignTrue,
const KTableValue aTable[]);
const KTableEntry aTable[]);
// This indicates error by leaving mStyleContext null.
void UpdateCurrentStyleSources(bool aNeedsLayoutFlush);
void ClearCurrentStyleSources();
@ -190,7 +190,7 @@ private:
mozilla::dom::CSSValue* GetBackgroundList(uint8_t nsStyleBackground::Layer::* aMember,
uint32_t nsStyleBackground::* aCount,
const KTableValue aTable[]);
const KTableEntry aTable[]);
void GetCSSGradientString(const nsStyleGradient* aGradient,
nsAString& aString);
@ -568,7 +568,7 @@ private:
const nsStyleCoord& aCoord,
bool aClampNegativeCalc,
PercentageBaseGetter aPercentageBaseGetter = nullptr,
const KTableValue aTable[] = nullptr,
const KTableEntry aTable[] = nullptr,
nscoord aMinAppUnits = nscoord_MIN,
nscoord aMaxAppUnits = nscoord_MAX);

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