This commit is contained in:
Ryan VanderMeulen 2016-09-03 11:45:27 -04:00
Родитель 6d9a4338b3 1502d18249
Коммит 740cdfc810
205 изменённых файлов: 4292 добавлений и 1721 удалений

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

@ -85,7 +85,7 @@ tasks:
# Note: This task is built server side without the context or tooling that
# exist in tree so we must hard code the version
image: 'taskcluster/decision:0.1.5'
image: 'taskcluster/decision:0.1.6'
maxRunTime: 1800

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

@ -24,9 +24,9 @@
"unpack": true
},
{
"version": "cargo 0.13.0-nightly (664125b 2016-07-19)",
"size": 3123796,
"digest": "4b9d2bcb8488b6649ba6c748e19d33bfceb25c7566e882fc7e00322392e424a5a9c5878c11c61d57cdaecf67bcc110842c6eff95e49736e8f3c83d9ce1677122",
"version": "cargo 0.13.0-nightly (e713e7f 2016-08-31)",
"size": 3245716,
"digest": "d5bb0d88ce7bb1b5a316d7a8ca6341672f5ee8008fa7754511bf53fabd54c0770e95397232896d6087547891f1143f6968d8b1e106e39800b43defeb0025c7c0",
"algorithm": "sha512",
"filename": "cargo.tar.xz",
"unpack": true

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

@ -691,7 +691,7 @@ function gKeywordURIFixup({ target: browser, data: fixupInfo }) {
}
// Ignore number-only things entirely (no decimal IPs for you!)
if (/^\d+$/.test(asciiHost))
if (/^\d+$/.test(fixupInfo.originalInput.trim()))
return;
let onLookupComplete = (request, record, status) => {

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

@ -17,7 +17,7 @@ add_task(function* closing_tab_with_dependents_should_close_window() {
let windowClosedPromise = BrowserTestUtils.windowClosed(win);
yield BrowserTestUtils.removeTab(tab);
is(openedTab.linkedBrowser, null, "Opened tab should also have closed");
is(Cu.isDeadWrapper(openedTab) || openedTab.linkedBrowser == null, true, "Opened tab should also have closed");
info("If we timeout now, the window failed to close - that shouldn't happen!");
yield windowClosedPromise;
});

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

@ -38,7 +38,7 @@ function promiseNotificationForTab(aBrowser, value, expected, tab=aBrowser.selec
return deferred.promise;
}
function* runURLBarSearchTest(valueToOpen, expectSearch, expectNotification, aWindow=window) {
function* runURLBarSearchTest({valueToOpen, expectSearch, expectNotification, aWindow=window}) {
aWindow.gURLBar.value = valueToOpen;
let expectedURI;
if (!expectSearch) {
@ -62,21 +62,33 @@ function* runURLBarSearchTest(valueToOpen, expectSearch, expectNotification, aWi
add_task(function* test_navigate_full_domain() {
let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
yield* runURLBarSearchTest("www.mozilla.org", false, false);
yield* runURLBarSearchTest({
valueToOpen: "www.mozilla.org",
expectSearch: false,
expectNotification: false,
});
gBrowser.removeTab(tab);
});
add_task(function* test_navigate_valid_numbers() {
add_task(function* test_navigate_decimal_ip() {
let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
yield* runURLBarSearchTest("1234", true, true);
yield* runURLBarSearchTest({
valueToOpen: "1234",
expectSearch: true,
expectNotification: false,
});
gBrowser.removeTab(tab);
});
add_task(function* test_navigate_invalid_numbers() {
add_task(function* test_navigate_large_number() {
let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
yield* runURLBarSearchTest("123456789012345", true, false);
yield* runURLBarSearchTest({
valueToOpen: "123456789012345",
expectSearch: true,
expectNotification: false
});
gBrowser.removeTab(tab);
});
function get_test_function_for_localhost_with_hostname(hostName, isPrivate) {
@ -96,7 +108,12 @@ function get_test_function_for_localhost_with_hostname(hostName, isPrivate) {
yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
Services.prefs.setBoolPref(pref, false);
yield* runURLBarSearchTest(hostName, true, true, win);
yield* runURLBarSearchTest({
valueToOpen: hostName,
expectSearch: true,
expectNotification: true,
aWindow: win,
});
let notificationBox = browser.getNotificationBox(tab.linkedBrowser);
let notification = notificationBox.getNotificationWithValue("keyword-uri-fixup");
@ -114,7 +131,12 @@ function get_test_function_for_localhost_with_hostname(hostName, isPrivate) {
tab = browser.selectedTab = browser.addTab("about:blank");
yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
// In a private window, the notification should appear again.
yield* runURLBarSearchTest(hostName, isPrivate, isPrivate, win);
yield* runURLBarSearchTest({
valueToOpen: hostName,
expectSearch: isPrivate,
expectNotification: isPrivate,
aWindow: win,
});
browser.removeTab(tab);
if (isPrivate) {
info("Waiting for private window to close");
@ -134,6 +156,10 @@ add_task(get_test_function_for_localhost_with_hostname("localhost", true));
add_task(function* test_navigate_invalid_url() {
let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
yield* runURLBarSearchTest("mozilla is awesome", true, false);
yield* runURLBarSearchTest({
valueToOpen: "mozilla is awesome",
expectSearch: true,
expectNotification: false,
});
gBrowser.removeTab(tab);
});

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

@ -848,7 +848,7 @@ BrowserGlue.prototype = {
if (samples >= Services.prefs.getIntPref("browser.slowStartup.maxSamples")) {
if (averageTime > Services.prefs.getIntPref("browser.slowStartup.timeThreshold"))
this._showSlowStartupNotification();
this._calculateProfileAgeInDays().then(this._showSlowStartupNotification, null);
averageTime = 0;
samples = 0;
}
@ -857,7 +857,25 @@ BrowserGlue.prototype = {
Services.prefs.setIntPref("browser.slowStartup.samples", samples);
},
_showSlowStartupNotification: function () {
_calculateProfileAgeInDays: Task.async(function* () {
let ProfileAge = Cu.import("resource://gre/modules/ProfileAge.jsm", {}).ProfileAge;
let profileAge = new ProfileAge(null, null);
let creationDate = yield profileAge.created;
let resetDate = yield profileAge.reset;
// if the profile was reset, consider the
// reset date for its age.
let profileDate = resetDate || creationDate;
const ONE_DAY = 24 * 60 * 60 * 1000;
return (Date.now() - profileDate) / ONE_DAY;
}),
_showSlowStartupNotification: function (profileAge) {
if (profileAge < 90) // 3 months
return;
let win = RecentWindow.getMostRecentBrowserWindow();
if (!win)
return;

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

@ -127,7 +127,20 @@ var gSecurityPane = {
*/
showPasswordExceptions: function ()
{
gSubDialog.open("chrome://passwordmgr/content/passwordManagerExceptions.xul");
var bundlePrefs = document.getElementById("bundlePreferences");
var params = {
blockVisible: true,
sessionVisible: false,
allowVisible: false,
hideStatusColumn: true,
prefilledHost: "",
permissionType: "login-saving",
windowTitle: bundlePrefs.getString("savedLoginsExceptions_title"),
introText: bundlePrefs.getString("savedLoginsExceptions_desc")
};
gSubDialog.open("chrome://browser/content/preferences/permissions.xul",
null, params);
},
/**

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

@ -306,7 +306,7 @@ var gPermissionManager = {
this._handleCapabilityChange();
}
else if (aData == "deleted") {
this._removePermissionFromList(permission);
this._removePermissionFromList(permission.principal);
}
}
},

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

@ -24,9 +24,9 @@
"unpack": true
},
{
"version": "cargo 0.13.0-nightly (664125b 2016-07-19)",
"size": 3123796,
"digest": "4b9d2bcb8488b6649ba6c748e19d33bfceb25c7566e882fc7e00322392e424a5a9c5878c11c61d57cdaecf67bcc110842c6eff95e49736e8f3c83d9ce1677122",
"version": "cargo 0.13.0-nightly (e713e7f 2016-08-31)",
"size": 3245716,
"digest": "d5bb0d88ce7bb1b5a316d7a8ca6341672f5ee8008fa7754511bf53fabd54c0770e95397232896d6087547891f1143f6968d8b1e106e39800b43defeb0025c7c0",
"algorithm": "sha512",
"filename": "cargo.tar.xz",
"unpack": true

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

@ -24,9 +24,9 @@
"unpack": true
},
{
"version": "cargo 0.13.0-nightly (664125b 2016-07-19)",
"size": 3123796,
"digest": "4b9d2bcb8488b6649ba6c748e19d33bfceb25c7566e882fc7e00322392e424a5a9c5878c11c61d57cdaecf67bcc110842c6eff95e49736e8f3c83d9ce1677122",
"version": "cargo 0.13.0-nightly (e713e7f 2016-08-31)",
"size": 3245716,
"digest": "d5bb0d88ce7bb1b5a316d7a8ca6341672f5ee8008fa7754511bf53fabd54c0770e95397232896d6087547891f1143f6968d8b1e106e39800b43defeb0025c7c0",
"algorithm": "sha512",
"filename": "cargo.tar.xz",
"unpack": true

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

@ -16,9 +16,9 @@
"unpack": true
},
{
"version": "cargo 0.13.0-nightly (664125b 2016-07-19)",
"size": 2571167,
"digest": "b2616459fbf15c75b54628a6bfe8cf89c0841ea08431f5096e72be4fac4c685785dfc7a2f18a03a5f7bd377e78d3c108e5029b12616842cbbd0497ff7363fdaf",
"version": "cargo 0.13.0-nightly (e713e7f 2016-08-31)",
"size": 2715131,
"digest": "f037d2bbbeccb2c95519e083d6d9eecb5cb06a510e849b5721d6933a6c2428203b93ed3d20d3f20329f4d4eee17177d762f051b1ae79fee97d93b84611f3df66",
"algorithm": "sha512",
"filename": "cargo.tar.bz2",
"unpack": true

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

@ -14,9 +14,9 @@
"unpack": true
},
{
"version": "cargo 0.13.0-nightly (664125b 2016-07-19)",
"size": 2298848,
"digest": "d3d1f7b6d195248550f98eb8ce87aa314d36a8a667c110ff2058777fe5a97b7007a41dc1c8a4605c4230e9105972768918222352d5e0fdebbc49639671de38ca",
"version": "cargo 0.13.0-nightly (e713e7f 2016-08-31)",
"size": 2402000,
"digest": "56f12f7ac437742ed717ce0ccfb0b4134160948e45d73016e48d9033567e5b01a171ac95dd7965eb007702c31da73274b5913281655f461f611ddeee37181ecc",
"algorithm": "sha512",
"filename": "cargo.tar.bz2",
"unpack": true

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

@ -15,9 +15,9 @@
"unpack": true
},
{
"version": "cargo 0.13.0-nightly (664125b 2016-07-19)",
"size": 2561498,
"digest": "d300fd06b16efe49bdb1a238d516c8797d2de0edca7efadd55249401e1dd1d775fb84649630e273f95d9e8b956d87d1f75726c0a68294d25fafe078c3b2b9ba9",
"version": "cargo 0.13.0-nightly (e713e7f 2016-08-31)",
"size": 2677831,
"digest": "eada1edd6142dcde907f14f23c08a2a0b86f108a8fb242f62be6573bbbe1d3b2a4a04c05465d561253d6a617e18cdabee3c87d8cef9a1b5bdd20fe835ef25ff1",
"algorithm": "sha512",
"filename": "cargo.tar.bz2",
"unpack": true

3
browser/extensions/e10srollout/bootstrap.js поставляемый
Просмотреть файл

@ -17,7 +17,8 @@ const TEST_THRESHOLD = {
};
const ADDON_ROLLOUT_POLICY = {
"beta" : "2a", // Set 2 + any WebExtension
"beta" : "49a", // 10 tested add-ons + any WebExtension
"release" : "49a", // 10 tested add-ons + any WebExtension
};
const PREF_COHORT_SAMPLE = "e10s.rollout.cohortSample";

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

@ -141,13 +141,6 @@
@RESPATH@/run-mozilla.sh
#endif
#endif
#ifdef XP_WIN
#ifdef _AMD64_
@BINPATH@/@DLL_PREFIX@qipcap64@DLL_SUFFIX@
#else
@BINPATH@/@DLL_PREFIX@qipcap@DLL_SUFFIX@
#endif
#endif
; [Components]
#ifdef MOZ_ARTIFACT_BUILDS

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

@ -31,6 +31,8 @@ notificationspermissionstext4=Control which websites are always or never allowed
notificationspermissionstitle=Notification Permissions
invalidURI=Please enter a valid hostname
invalidURITitle=Invalid Hostname Entered
savedLoginsExceptions_title=Exceptions - Saved Logins
savedLoginsExceptions_desc=Logins for the following sites will not be saved:
#### Block List Manager

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

@ -24,4 +24,5 @@ support-files =
[browser_taskbar_preview.js]
skip-if = os != "win"
[browser_UsageTelemetry.js]
[browser_UsageTelemetry_private_and_restore.js]
[browser_urlBar_zoom.js]

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

@ -44,15 +44,6 @@ function browserLocationChanged(browser) {
});
}
function promiseBrowserStateRestored() {
return new Promise(resolve => {
Services.obs.addObserver(function observer(aSubject, aTopic) {
Services.obs.removeObserver(observer, "sessionstore-browser-state-restored");
resolve();
}, "sessionstore-browser-state-restored", false);
});
}
/**
* An helper that checks the value of a scalar if it's expected to be > 0,
* otherwise makes sure that the scalar it's not reported.
@ -251,74 +242,3 @@ add_task(function* test_URIAndDomainCounts() {
yield BrowserTestUtils.removeTab(firstTab);
yield BrowserTestUtils.closeWindow(newWin);
});
add_task(function* test_privateMode() {
// Let's reset the counts.
Services.telemetry.clearScalars();
// Open a private window and load a website in it.
let privateWin = yield BrowserTestUtils.openNewBrowserWindow({private: true});
yield BrowserTestUtils.loadURI(privateWin.gBrowser.selectedBrowser, "http://example.com/");
yield BrowserTestUtils.browserLoaded(privateWin.gBrowser.selectedBrowser);
// Check that tab and window count is recorded.
const scalars =
Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN);
ok(!(TOTAL_URI_COUNT in scalars), "We should not track URIs in private mode.");
ok(!(UNIQUE_DOMAINS_COUNT in scalars), "We should not track unique domains in private mode.");
is(scalars[TAB_EVENT_COUNT], 1, "The number of open tab event count must match the expected value.");
is(scalars[MAX_CONCURRENT_TABS], 2, "The maximum tab count must match the expected value.");
is(scalars[WINDOW_OPEN_COUNT], 1, "The number of window open event count must match the expected value.");
is(scalars[MAX_CONCURRENT_WINDOWS], 2, "The maximum window count must match the expected value.");
// Clean up.
yield BrowserTestUtils.closeWindow(privateWin);
});
add_task(function* test_sessionRestore() {
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
registerCleanupFunction(() => {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
});
// Let's reset the counts.
Services.telemetry.clearScalars();
// The first window will be put into the already open window and the second
// window will be opened with _openWindowWithState, which is the source of the problem.
const state = {
windows: [
{
tabs: [
{ entries: [{ url: "http://example.org" }], extData: { "uniq": 3785 } }
],
selected: 1
}
]
};
// Save the current session.
let SessionStore =
Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}).SessionStore;
let backupState = SessionStore.getBrowserState();
// Load the custom state and wait for SSTabRestored, as we want to make sure
// that the URI counting code was hit.
let tabRestored = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "SSTabRestored");
SessionStore.setBrowserState(JSON.stringify(state));
yield tabRestored;
// Check that the URI is not recorded.
const scalars =
Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN);
ok(!(TOTAL_URI_COUNT in scalars), "We should not track URIs from restored sessions.");
ok(!(UNIQUE_DOMAINS_COUNT in scalars), "We should not track unique domains from restored sessions.");
// Restore the original session and cleanup.
let sessionRestored = promiseBrowserStateRestored();
SessionStore.setBrowserState(JSON.stringify(state));
yield sessionRestored;
});

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

@ -0,0 +1,88 @@
"use strict";
const MAX_CONCURRENT_TABS = "browser.engagement.max_concurrent_tab_count";
const TAB_EVENT_COUNT = "browser.engagement.tab_open_event_count";
const MAX_CONCURRENT_WINDOWS = "browser.engagement.max_concurrent_window_count";
const WINDOW_OPEN_COUNT = "browser.engagement.window_open_event_count";
const TOTAL_URI_COUNT = "browser.engagement.total_uri_count";
const UNIQUE_DOMAINS_COUNT = "browser.engagement.unique_domains_count";
function promiseBrowserStateRestored() {
return new Promise(resolve => {
Services.obs.addObserver(function observer(aSubject, aTopic) {
Services.obs.removeObserver(observer, "sessionstore-browser-state-restored");
resolve();
}, "sessionstore-browser-state-restored", false);
});
}
add_task(function* test_privateMode() {
// Let's reset the counts.
Services.telemetry.clearScalars();
// Open a private window and load a website in it.
let privateWin = yield BrowserTestUtils.openNewBrowserWindow({private: true});
yield BrowserTestUtils.loadURI(privateWin.gBrowser.selectedBrowser, "http://example.com/");
yield BrowserTestUtils.browserLoaded(privateWin.gBrowser.selectedBrowser);
// Check that tab and window count is recorded.
const scalars =
Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN);
ok(!(TOTAL_URI_COUNT in scalars), "We should not track URIs in private mode.");
ok(!(UNIQUE_DOMAINS_COUNT in scalars), "We should not track unique domains in private mode.");
is(scalars[TAB_EVENT_COUNT], 1, "The number of open tab event count must match the expected value.");
is(scalars[MAX_CONCURRENT_TABS], 2, "The maximum tab count must match the expected value.");
is(scalars[WINDOW_OPEN_COUNT], 1, "The number of window open event count must match the expected value.");
is(scalars[MAX_CONCURRENT_WINDOWS], 2, "The maximum window count must match the expected value.");
// Clean up.
yield BrowserTestUtils.closeWindow(privateWin);
});
add_task(function* test_sessionRestore() {
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
registerCleanupFunction(() => {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
});
// Let's reset the counts.
Services.telemetry.clearScalars();
// The first window will be put into the already open window and the second
// window will be opened with _openWindowWithState, which is the source of the problem.
const state = {
windows: [
{
tabs: [
{ entries: [{ url: "http://example.org" }], extData: { "uniq": 3785 } }
],
selected: 1
}
]
};
// Save the current session.
let SessionStore =
Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}).SessionStore;
let backupState = SessionStore.getBrowserState();
// Load the custom state and wait for SSTabRestored, as we want to make sure
// that the URI counting code was hit.
let tabRestored = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "SSTabRestored");
SessionStore.setBrowserState(JSON.stringify(state));
yield tabRestored;
// Check that the URI is not recorded.
const scalars =
Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN);
ok(!(TOTAL_URI_COUNT in scalars), "We should not track URIs from restored sessions.");
ok(!(UNIQUE_DOMAINS_COUNT in scalars), "We should not track unique domains from restored sessions.");
// Restore the original session and cleanup.
let sessionRestored = promiseBrowserStateRestored();
SessionStore.setBrowserState(JSON.stringify(state));
yield sessionRestored;
});

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

@ -440,12 +440,10 @@
.tabbrowser-tab::after,
.tabbrowser-tab::before {
width: 1px;
margin-top: 5px;
margin-bottom: 4px;
margin-inline-start: -1px;
background-image: linear-gradient(transparent 5px,
currentColor 5px,
currentColor calc(100% - 4px),
transparent calc(100% - 4px));
border-left: 1px solid currentColor;
opacity: 0.2;
}

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

@ -147,6 +147,7 @@ skip-if = os == "mac" # Full keyboard navigation on OSX only works if Full Keybo
[browser_inspector_search-08.js]
[browser_inspector_search-clear.js]
[browser_inspector_search-filter_context-menu.js]
subsuite = clipboard
[browser_inspector_search_keyboard_trap.js]
[browser_inspector_search-label.js]
[browser_inspector_search-reserved.js]

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

@ -1548,6 +1548,19 @@ OpenFile(nsIPrincipal* aPrincipal,
return JS::AsmJSCache_SynchronousScript;
}
// Check to see whether the principal reflects a private browsing session.
// Since AsmJSCache requires disk access at the moment, caching should be
// disabled in private browsing situations. Failing here will cause later
// read/write requests to also fail.
uint32_t pbId;
if (NS_WARN_IF(NS_FAILED(aPrincipal->GetPrivateBrowsingId(&pbId)))) {
return JS::AsmJSCache_InternalError;
}
if (pbId > 0) {
return JS::AsmJSCache_Disabled_PrivateBrowsing;
}
// We need to synchronously call into the parent to open the file and
// interact with the QuotaManager. The child can then map the file into its
// address space to perform I/O.

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

@ -185,7 +185,7 @@ public:
{
nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
if (parser) {
parser->BeginEvaluatingParserInsertedScript();
parser->PushDefinedInsertionPoint();
}
}
@ -196,7 +196,7 @@ public:
{
nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
if (parser) {
parser->EndEvaluatingParserInsertedScript();
parser->PopDefinedInsertionPoint();
}
}

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

@ -26,7 +26,15 @@ nsScriptElement::ScriptAvailable(nsresult aResult,
int32_t aLineNo)
{
if (!aIsInline && NS_FAILED(aResult)) {
return FireErrorEvent();
nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
if (parser) {
parser->PushDefinedInsertionPoint();
}
nsresult rv = FireErrorEvent();
if (parser) {
parser->PopDefinedInsertionPoint();
}
return rv;
}
return NS_OK;
}

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

@ -2524,8 +2524,16 @@ nsScriptLoader::OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
MOZ_ASSERT(!request->isInList());
mParserBlockingRequest = nullptr;
UnblockParser(request);
// Ensure that we treat request->mElement as our current parser-inserted
// script while firing onerror on it.
MOZ_ASSERT(request->mElement->GetParserCreated());
nsCOMPtr<nsIScriptElement> oldParserInsertedScript =
mCurrentParserInsertedScript;
mCurrentParserInsertedScript = request->mElement;
FireScriptAvailable(rv, request);
ContinueParserAsync(request);
mCurrentParserInsertedScript = oldParserInsertedScript;
} else {
mPreloads.RemoveElement(request, PreloadRequestComparator());
}

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

@ -1292,15 +1292,15 @@ XrayResolveAttribute(JSContext* cx, JS::Handle<JSObject*> wrapper,
desc.setAttributes(attrSpec.flags);
// They all have getters, so we can just make it.
JS::Rooted<JSObject*> funobj(cx,
XrayCreateFunction(cx, wrapper, attrSpec.getter.native, 0, id));
XrayCreateFunction(cx, wrapper, attrSpec.accessors.getter.native, 0, id));
if (!funobj)
return false;
desc.setGetterObject(funobj);
desc.attributesRef() |= JSPROP_GETTER;
if (attrSpec.setter.native.op) {
if (attrSpec.accessors.setter.native.op) {
// We have a setter! Make it.
funobj =
XrayCreateFunction(cx, wrapper, attrSpec.setter.native, 1, id);
XrayCreateFunction(cx, wrapper, attrSpec.accessors.setter.native, 1, id);
if (!funobj)
return false;
desc.setSetterObject(funobj);

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

@ -3063,15 +3063,15 @@ struct CreateGlobalOptions<nsGlobalWindow>
nsresult
RegisterDOMNames();
// The return value is whatever the ProtoHandleGetter we used
// returned. This should be the DOM prototype for the global.
// The return value is true if we created and successfully performed our part of
// the setup for the global, false otherwise.
//
// Typically this method's caller will want to ensure that
// xpc::InitGlobalObjectOptions is called before, and xpc::InitGlobalObject is
// called after, this method, to ensure that this global object and its
// compartment are consistent with other global objects.
template <class T, ProtoHandleGetter GetProto>
JS::Handle<JSObject*>
bool
CreateGlobal(JSContext* aCx, T* aNative, nsWrapperCache* aCache,
const JSClass* aClass, JS::CompartmentOptions& aOptions,
JSPrincipals* aPrincipal, bool aInitStandardClasses,
@ -3086,7 +3086,7 @@ CreateGlobal(JSContext* aCx, T* aNative, nsWrapperCache* aCache,
JS::DontFireOnNewGlobalHook, aOptions));
if (!aGlobal) {
NS_WARNING("Failed to create global");
return nullptr;
return false;
}
JSAutoCompartment ac(aCx, aGlobal);
@ -3101,31 +3101,31 @@ CreateGlobal(JSContext* aCx, T* aNative, nsWrapperCache* aCache,
CreateGlobalOptions<T>::ProtoAndIfaceCacheKind);
if (!CreateGlobalOptions<T>::PostCreateGlobal(aCx, aGlobal)) {
return nullptr;
return false;
}
}
if (aInitStandardClasses &&
!JS_InitStandardClasses(aCx, aGlobal)) {
NS_WARNING("Failed to init standard classes");
return nullptr;
return false;
}
JS::Handle<JSObject*> proto = GetProto(aCx);
if (!proto || !JS_SplicePrototype(aCx, aGlobal, proto)) {
NS_WARNING("Failed to set proto");
return nullptr;
return false;
}
bool succeeded;
if (!JS_SetImmutablePrototype(aCx, aGlobal, &succeeded)) {
return nullptr;
return false;
}
MOZ_ASSERT(succeeded,
"making a fresh global object's [[Prototype]] immutable can "
"internally fail, but it should never be unsuccessful");
return proto;
return true;
}
/*

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

@ -586,7 +586,10 @@ class CGPrototypeJSClass(CGThing):
def define(self):
prototypeID, depth = PrototypeIDAndDepth(self.descriptor)
slotCount = "DOM_INTERFACE_PROTO_SLOTS_BASE"
if self.descriptor.hasUnforgeableMembers:
# Globals handle unforgeables directly in Wrap() instead of
# via a holder.
if (self.descriptor.hasUnforgeableMembers and
not self.descriptor.isGlobal()):
slotCount += " + 1 /* slot for the JSObject holding the unforgeable properties */"
(protoGetter, _) = InterfacePrototypeObjectProtoGetter(self.descriptor)
type = "eGlobalInterfacePrototype" if self.descriptor.isGlobal() else "eInterfacePrototype"
@ -2527,7 +2530,7 @@ class AttrDefiner(PropertyDefiner):
return self.generatePrefableArray(
array, name,
lambda fields: ' { "%s", %s, %s, %s}' % fields,
lambda fields: ' { "%s", %s, { { %s, %s } } }' % fields,
' JS_PS_END',
'JSPropertySpec',
PropertyDefiner.getControllingCondition, specData, doIdArrays)
@ -2930,7 +2933,9 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
else:
defineAliases = None
if self.descriptor.hasUnforgeableMembers:
# Globals handle unforgeables directly in Wrap() instead of
# via a holder.
if self.descriptor.hasUnforgeableMembers and not self.descriptor.isGlobal():
assert needInterfacePrototypeObject
# We want to use the same JSClass and prototype as the object we'll
@ -2939,12 +2944,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
# a fast copy. In the case of proxies that's null, because the
# expando object is a vanilla object, but in the case of other DOM
# objects it's whatever our class is.
#
# Also, for a global we can't use the global's class; just use
# nullpr and when we do the copy off the holder we'll take a slower
# path. This also means that we don't need to worry about matching
# the prototype.
if self.descriptor.proxy or self.descriptor.isGlobal():
if self.descriptor.proxy:
holderClass = "nullptr"
holderProto = "nullptr"
else:
@ -3334,7 +3334,8 @@ def CreateBindingJSObject(descriptor, properties):
return objDecl + create
def InitUnforgeablePropertiesOnHolder(descriptor, properties, failureCode):
def InitUnforgeablePropertiesOnHolder(descriptor, properties, failureCode,
holderName="unforgeableHolder"):
"""
Define the unforgeable properties on the unforgeable holder for
the interface represented by descriptor.
@ -3351,18 +3352,20 @@ def InitUnforgeablePropertiesOnHolder(descriptor, properties, failureCode):
defineUnforgeableAttrs = fill(
"""
if (!DefineUnforgeableAttributes(aCx, unforgeableHolder, %s)) {
if (!DefineUnforgeableAttributes(aCx, ${holderName}, %s)) {
$*{failureCode}
}
""",
failureCode=failureCode)
failureCode=failureCode,
holderName=holderName)
defineUnforgeableMethods = fill(
"""
if (!DefineUnforgeableMethods(aCx, unforgeableHolder, %s)) {
if (!DefineUnforgeableMethods(aCx, ${holderName}, %s)) {
$*{failureCode}
}
""",
failureCode=failureCode)
failureCode=failureCode,
holderName=holderName)
unforgeableMembers = [
(defineUnforgeableAttrs, properties.unforgeableAttrs),
@ -3384,25 +3387,28 @@ def InitUnforgeablePropertiesOnHolder(descriptor, properties, failureCode):
"""
JS::RootedId toPrimitive(aCx,
SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::toPrimitive)));
if (!JS_DefinePropertyById(aCx, unforgeableHolder, toPrimitive,
if (!JS_DefinePropertyById(aCx, ${holderName}, toPrimitive,
JS::UndefinedHandleValue,
JSPROP_READONLY | JSPROP_PERMANENT) ||
!JS_DefineProperty(aCx, unforgeableHolder, "toJSON",
!JS_DefineProperty(aCx, ${holderName}, "toJSON",
JS::UndefinedHandleValue,
JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_PERMANENT)) {
$*{failureCode}
}
""",
failureCode=failureCode)))
failureCode=failureCode,
holderName=holderName)))
return CGWrapper(CGList(unforgeables), pre="\n")
def CopyUnforgeablePropertiesToInstance(descriptor, wrapperCache):
def CopyUnforgeablePropertiesToInstance(descriptor, failureCode):
"""
Copy the unforgeable properties from the unforgeable holder for
this interface to the instance object we have.
"""
assert not descriptor.isGlobal();
if not descriptor.hasUnforgeableMembers:
return ""
@ -3416,15 +3422,6 @@ def CopyUnforgeablePropertiesToInstance(descriptor, wrapperCache):
"""))
]
if wrapperCache:
cleanup = dedent(
"""
aCache->ReleaseWrapper(aObject);
aCache->ClearWrapper();
""")
else:
cleanup = ""
# For proxies, we want to define on the expando object, not directly on the
# reflector, so we can make sure we don't get confused by named getters.
if descriptor.proxy:
@ -3433,34 +3430,24 @@ def CopyUnforgeablePropertiesToInstance(descriptor, wrapperCache):
JS::Rooted<JSObject*> expando(aCx,
DOMProxyHandler::EnsureExpandoObject(aCx, aReflector));
if (!expando) {
$*{cleanup}
return false;
$*{failureCode}
}
""",
cleanup=cleanup)))
failureCode=failureCode)))
obj = "expando"
else:
obj = "aReflector"
# We can't do the fast copy for globals, because we can't allocate the
# unforgeable holder for those with the right JSClass. Luckily, there
# aren't too many globals being created.
if descriptor.isGlobal():
copyFunc = "JS_CopyPropertiesFrom"
else:
copyFunc = "JS_InitializePropertiesFromCompatibleNativeObject"
copyCode.append(CGGeneric(fill(
"""
JS::Rooted<JSObject*> unforgeableHolder(aCx,
&js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
if (!${copyFunc}(aCx, ${obj}, unforgeableHolder)) {
$*{cleanup}
return false;
if (!JS_InitializePropertiesFromCompatibleNativeObject(aCx, ${obj}, unforgeableHolder)) {
$*{failureCode}
}
""",
copyFunc=copyFunc,
obj=obj,
cleanup=cleanup)))
failureCode=failureCode)))
return CGWrapper(CGList(copyCode), pre="\n").define()
@ -3480,7 +3467,7 @@ def AssertInheritanceChain(descriptor):
return asserts
def InitMemberSlots(descriptor, wrapperCache):
def InitMemberSlots(descriptor, failureCode):
"""
Initialize member slots on our JS object if we're supposed to have some.
@ -3491,22 +3478,31 @@ def InitMemberSlots(descriptor, wrapperCache):
"""
if not descriptor.interface.hasMembersInSlots():
return ""
if wrapperCache:
clearWrapper = dedent(
"""
aCache->ReleaseWrapper(aObject);
aCache->ClearWrapper();
""")
else:
clearWrapper = ""
return fill(
"""
if (!UpdateMemberSlots(aCx, aReflector, aObject)) {
$*{clearWrapper}
return false;
$*{failureCode}
}
""",
clearWrapper=clearWrapper)
failureCode=failureCode)
def SetImmutablePrototype(descriptor, failureCode):
if not descriptor.hasNonOrdinaryGetPrototypeOf():
return ""
return fill(
"""
bool succeeded;
if (!JS_SetImmutablePrototype(aCx, aReflector, &succeeded)) {
${failureCode}
}
MOZ_ASSERT(succeeded,
"Making a fresh reflector instance have an immutable "
"prototype can internally fail, but it should never be "
"unsuccessful");
""",
failureCode=failureCode)
def DeclareProto():
@ -3563,6 +3559,14 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
""")
else:
preserveWrapper = "PreserveWrapper(aObject);\n"
failureCode = dedent(
"""
aCache->ReleaseWrapper(aObject);
aCache->ClearWrapper();
return false;
""")
return fill(
"""
$*{assertInheritance}
@ -3598,6 +3602,7 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
aCache->SetWrapper(aReflector);
$*{unforgeable}
$*{slots}
$*{setImmutablePrototype}
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
@ -3617,8 +3622,11 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
assertInheritance=AssertInheritanceChain(self.descriptor),
declareProto=DeclareProto(),
createObject=CreateBindingJSObject(self.descriptor, self.properties),
unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor, True),
slots=InitMemberSlots(self.descriptor, True),
unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor,
failureCode),
slots=InitMemberSlots(self.descriptor, failureCode),
setImmutablePrototype=SetImmutablePrototype(self.descriptor,
failureCode),
preserveWrapper=preserveWrapper)
@ -3657,6 +3665,8 @@ class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
self.properties = properties
def definition_body(self):
failureCode = "return false;\n"
return fill(
"""
$*{assertions}
@ -3669,14 +3679,19 @@ class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
$*{unforgeable}
$*{slots}
$*{setImmutablePrototype}
creator.InitializationSucceeded();
return true;
""",
assertions=AssertInheritanceChain(self.descriptor),
declareProto=DeclareProto(),
createObject=CreateBindingJSObject(self.descriptor, self.properties),
unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor, False),
slots=InitMemberSlots(self.descriptor, False))
unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor,
failureCode),
slots=InitMemberSlots(self.descriptor, failureCode),
setImmutablePrototype=SetImmutablePrototype(self.descriptor,
failureCode))
class CGWrapGlobalMethod(CGAbstractMethod):
@ -3709,14 +3724,19 @@ class CGWrapGlobalMethod(CGAbstractMethod):
else:
chromeProperties = "nullptr"
failureCode = dedent(
"""
aCache->ReleaseWrapper(aObject);
aCache->ClearWrapper();
return false;
""");
if self.descriptor.hasUnforgeableMembers:
declareProto = "JS::Handle<JSObject*> canonicalProto =\n"
assertProto = (
"MOZ_ASSERT(canonicalProto &&\n"
" IsDOMIfaceAndProtoClass(js::GetObjectClass(canonicalProto)));\n")
unforgeable = InitUnforgeablePropertiesOnHolder(
self.descriptor, self.properties, failureCode,
"aReflector").define();
else:
declareProto = ""
assertProto = ""
unforgeable = ""
return fill(
"""
@ -3724,26 +3744,23 @@ class CGWrapGlobalMethod(CGAbstractMethod):
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
$*{declareProto}
CreateGlobal<${nativeType}, GetProtoObjectHandle>(aCx,
if (!CreateGlobal<${nativeType}, GetProtoObjectHandle>(aCx,
aObject,
aCache,
sClass.ToJSClass(),
aOptions,
aPrincipal,
aInitStandardClasses,
aReflector);
if (!aReflector) {
return false;
aReflector)) {
$*{failureCode}
}
$*{assertProto}
// aReflector is a new global, so has a new compartment. Enter it
// before doing anything with it.
JSAutoCompartment ac(aCx, aReflector);
if (!DefineProperties(aCx, aReflector, ${properties}, ${chromeProperties})) {
return false;
$*{failureCode}
}
$*{unforgeable}
@ -3753,12 +3770,11 @@ class CGWrapGlobalMethod(CGAbstractMethod):
""",
assertions=AssertInheritanceChain(self.descriptor),
nativeType=self.descriptor.nativeType,
declareProto=declareProto,
assertProto=assertProto,
properties=properties,
chromeProperties=chromeProperties,
unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor, True),
slots=InitMemberSlots(self.descriptor, True))
failureCode=failureCode,
unforgeable=unforgeable,
slots=InitMemberSlots(self.descriptor, failureCode))
class CGUpdateMemberSlotsMethod(CGAbstractStaticMethod):

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

@ -45,6 +45,7 @@ skip-if = (toolkit == 'gonk' && !debug)
[test_browserElement_oop_Close.html]
[test_browserElement_oop_CookiesNotThirdParty.html]
[test_browserElement_oop_CopyPaste.html]
subsuite = clipboard
[test_browserElement_oop_DOMRequestError.html]
disabled = Disabling some OOP tests for WebIDL scope changes
[test_browserElement_oop_DataURI.html]

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

@ -51,7 +51,6 @@ OffscreenCanvas::OffscreenCanvas(nsIGlobalObject* aGlobal,
, mWidth(aWidth)
, mHeight(aHeight)
, mCompositorBackendType(aCompositorBackend)
, mCanvasClient(nullptr)
, mCanvasRenderer(aRenderer)
{}
@ -85,8 +84,6 @@ OffscreenCanvas::ClearResources()
{
if (mCanvasClient) {
mCanvasClient->Clear();
ImageBridgeChild::DispatchReleaseCanvasClient(mCanvasClient);
mCanvasClient = nullptr;
if (mCanvasRenderer) {
nsCOMPtr<nsIThread> activeThread = mCanvasRenderer->GetActiveThread();
@ -99,6 +96,8 @@ OffscreenCanvas::ClearResources()
mCanvasRenderer->mGLContext = nullptr;
mCanvasRenderer->ResetActiveThread();
}
mCanvasClient = nullptr;
}
}
@ -151,7 +150,7 @@ OffscreenCanvas::GetContext(JSContext* aCx,
if (ImageBridgeChild::IsCreated()) {
TextureFlags flags = TextureFlags::ORIGIN_BOTTOM_LEFT;
mCanvasClient = ImageBridgeChild::GetSingleton()->
CreateCanvasClient(CanvasClient::CanvasClientTypeShSurf, flags).take();
CreateCanvasClient(CanvasClient::CanvasClientTypeShSurf, flags);
mCanvasRenderer->SetCanvasClient(mCanvasClient);
gl::GLScreenBuffer* screen = gl->Screen();

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

@ -204,7 +204,7 @@ private:
layers::LayersBackend mCompositorBackendType;
layers::CanvasClient* mCanvasClient;
RefPtr<layers::CanvasClient> mCanvasClient;
RefPtr<layers::AsyncCanvasRenderer> mCanvasRenderer;
};

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

@ -1544,9 +1544,9 @@ EventListenerManager::GetListenerInfo(nsCOMArray<nsIEventListenerInfo>* aList)
nsCOMPtr<EventTarget> target = do_QueryInterface(mTarget);
NS_ENSURE_STATE(target);
aList->Clear();
uint32_t count = mListeners.Length();
for (uint32_t i = 0; i < count; ++i) {
const Listener& listener = mListeners.ElementAt(i);
nsAutoTObserverArray<Listener, 2>::ForwardIterator iter(mListeners);
while (iter.HasMore()) {
const Listener& listener = iter.GetNext();
// If this is a script handler and we haven't yet
// compiled the event handler itself go ahead and compile it
if (listener.mListenerType == Listener::eJSEventListener &&

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

@ -85,7 +85,7 @@ class nsGeolocationRequest final
nsGeolocationRequest(Geolocation* aLocator,
GeoPositionCallback aCallback,
GeoPositionErrorCallback aErrorCallback,
PositionOptions* aOptions,
nsAutoPtr<PositionOptions>&& aOptions,
uint8_t aProtocolType,
bool aWatchPositionRequest = false,
int32_t aWatchId = 0);
@ -138,7 +138,7 @@ class nsGeolocationRequest final
uint8_t mProtocolType;
};
static PositionOptions*
static nsAutoPtr<PositionOptions>
CreatePositionOptionsCopy(const PositionOptions& aOptions)
{
nsAutoPtr<PositionOptions> geoOptions(new PositionOptions());
@ -147,7 +147,7 @@ CreatePositionOptionsCopy(const PositionOptions& aOptions)
geoOptions->mMaximumAge = aOptions.mMaximumAge;
geoOptions->mTimeout = aOptions.mTimeout;
return geoOptions.forget();
return geoOptions;
}
class GeolocationSettingsCallback : public nsISettingsServiceCallback
@ -349,14 +349,14 @@ PositionError::NotifyCallback(const GeoPositionErrorCallback& aCallback)
nsGeolocationRequest::nsGeolocationRequest(Geolocation* aLocator,
GeoPositionCallback aCallback,
GeoPositionErrorCallback aErrorCallback,
PositionOptions* aOptions,
nsAutoPtr<PositionOptions>&& aOptions,
uint8_t aProtocolType,
bool aWatchPositionRequest,
int32_t aWatchId)
: mIsWatchPositionRequest(aWatchPositionRequest),
mCallback(Move(aCallback)),
mErrorCallback(Move(aErrorCallback)),
mOptions(aOptions),
mOptions(Move(aOptions)),
mLocator(aLocator),
mWatchId(aWatchId),
mShutdown(false),
@ -1392,7 +1392,7 @@ Geolocation::GetCurrentPosition(PositionCallback& aCallback,
{
nsresult rv = GetCurrentPosition(GeoPositionCallback(&aCallback),
GeoPositionErrorCallback(aErrorCallback),
CreatePositionOptionsCopy(aOptions));
Move(CreatePositionOptionsCopy(aOptions)));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
@ -1404,30 +1404,34 @@ Geolocation::GetCurrentPosition(PositionCallback& aCallback,
NS_IMETHODIMP
Geolocation::GetCurrentPosition(nsIDOMGeoPositionCallback* aCallback,
nsIDOMGeoPositionErrorCallback* aErrorCallback,
PositionOptions* aOptions)
nsAutoPtr<PositionOptions>&& aOptions)
{
NS_ENSURE_ARG_POINTER(aCallback);
return GetCurrentPosition(GeoPositionCallback(aCallback),
GeoPositionErrorCallback(aErrorCallback), aOptions);
GeoPositionErrorCallback(aErrorCallback),
Move(aOptions));
}
nsresult
Geolocation::GetCurrentPosition(GeoPositionCallback callback,
GeoPositionErrorCallback errorCallback,
PositionOptions *options)
nsAutoPtr<PositionOptions>&& options)
{
if (mPendingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW) {
return NS_ERROR_NOT_AVAILABLE;
}
// After this we hand over ownership of options to our nsGeolocationRequest.
// Count the number of requests per protocol/scheme.
Telemetry::Accumulate(Telemetry::GEOLOCATION_GETCURRENTPOSITION_SECURE_ORIGIN,
static_cast<uint8_t>(mProtocolType));
RefPtr<nsGeolocationRequest> request =
new nsGeolocationRequest(this, Move(callback), Move(errorCallback), options,
static_cast<uint8_t>(mProtocolType), false);
new nsGeolocationRequest(this, Move(callback), Move(errorCallback),
Move(options), static_cast<uint8_t>(mProtocolType),
false);
if (!sGeoEnabled) {
nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(false, request);
@ -1477,7 +1481,7 @@ Geolocation::WatchPosition(PositionCallback& aCallback,
int32_t ret = 0;
nsresult rv = WatchPosition(GeoPositionCallback(&aCallback),
GeoPositionErrorCallback(aErrorCallback),
CreatePositionOptionsCopy(aOptions), &ret);
Move(CreatePositionOptionsCopy(aOptions)), &ret);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
@ -1489,20 +1493,20 @@ Geolocation::WatchPosition(PositionCallback& aCallback,
NS_IMETHODIMP
Geolocation::WatchPosition(nsIDOMGeoPositionCallback *aCallback,
nsIDOMGeoPositionErrorCallback *aErrorCallback,
PositionOptions *aOptions,
nsAutoPtr<PositionOptions>&& aOptions,
int32_t* aRv)
{
NS_ENSURE_ARG_POINTER(aCallback);
return WatchPosition(GeoPositionCallback(aCallback),
GeoPositionErrorCallback(aErrorCallback),
aOptions, aRv);
Move(aOptions), aRv);
}
nsresult
Geolocation::WatchPosition(GeoPositionCallback aCallback,
GeoPositionErrorCallback aErrorCallback,
PositionOptions* aOptions,
nsAutoPtr<PositionOptions>&& aOptions,
int32_t* aRv)
{
if (mWatchingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW) {
@ -1518,8 +1522,8 @@ Geolocation::WatchPosition(GeoPositionCallback aCallback,
RefPtr<nsGeolocationRequest> request =
new nsGeolocationRequest(this, Move(aCallback), Move(aErrorCallback),
aOptions, static_cast<uint8_t>(mProtocolType),
true, *aRv);
Move(aOptions),
static_cast<uint8_t>(mProtocolType), true, *aRv);
if (!sGeoEnabled) {
nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(false, request);

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

@ -191,10 +191,10 @@ private:
nsresult GetCurrentPosition(GeoPositionCallback aCallback,
GeoPositionErrorCallback aErrorCallback,
PositionOptions* aOptions);
nsAutoPtr<PositionOptions>&& aOptions);
nsresult WatchPosition(GeoPositionCallback aCallback,
GeoPositionErrorCallback aErrorCallback,
PositionOptions* aOptions, int32_t* aRv);
nsAutoPtr<PositionOptions>&& aOptions, int32_t* aRv);
bool RegisterRequestWithPrompt(nsGeolocationRequest* request);

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

@ -13,18 +13,20 @@ namespace dom {
struct PositionOptions;
}
}
template<class T> class nsAutoPtr;
%}
[ptr] native NamespacedPositionOptions(mozilla::dom::PositionOptions);
native PositionOptionsRef(nsAutoPtr<mozilla::dom::PositionOptions>&&);
[builtinclass, uuid(9142ab45-0ab5-418c-9bab-338a6d271d4f)]
interface nsIDOMGeoGeolocation : nsISupports
{
int32_t watchPosition(in nsIDOMGeoPositionCallback callback,
in nsIDOMGeoPositionErrorCallback errorCallback,
in NamespacedPositionOptions options);
in PositionOptionsRef options);
void getCurrentPosition(in nsIDOMGeoPositionCallback callback,
in nsIDOMGeoPositionErrorCallback errorCallback,
in NamespacedPositionOptions options);
in PositionOptionsRef options);
void clearWatch(in long watchId);
};

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

@ -4061,12 +4061,12 @@ AddGeolocationListener(nsIDOMGeoPositionCallback* watcher,
return -1;
}
PositionOptions* options = new PositionOptions();
nsAutoPtr<PositionOptions> options(new PositionOptions());
options->mTimeout = 0;
options->mMaximumAge = 0;
options->mEnableHighAccuracy = highAccuracy;
int32_t retval = 1;
geo->WatchPosition(watcher, errorCallBack, options, &retval);
geo->WatchPosition(watcher, errorCallBack, Move(options), &retval);
return retval;
}

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

@ -288,6 +288,15 @@ function testCatch1() {
).then(nextTest);
}
function testToStringTag1() {
is(win.Promise.prototype[Symbol.toStringTag], "Promise", "@@toStringTag was incorrect");
var p = win.Promise.resolve();
is(String(p), "[object Promise]", "String() result was incorrect");
is(p.toString(), "[object Promise]", "toString result was incorrect");
is(Object.prototype.toString.call(p), "[object Promise]", "second toString result was incorrect");
nextTest();
}
var tests = [
testLoadComplete,
testHaveXray,
@ -309,6 +318,7 @@ var tests = [
testThen1,
testThen2,
testCatch1,
testToStringTag1,
];
function nextTest() {

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

@ -108,6 +108,8 @@ interface Node : EventTarget {
[ChromeOnly]
sequence<MutationObserver> getBoundMutationObservers();
#ifdef ACCESSIBILITY
[Pref="accessibility.AOM.enabled"]
readonly attribute AccessibleNode? accessibleNode;
#endif
};

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

@ -11,6 +11,7 @@ GENERATED_WEBIDL_FILES = [
PREPROCESSED_WEBIDL_FILES = [
'HTMLMediaElement.webidl',
'Navigator.webidl',
'Node.webidl',
'Promise.webidl',
'PromiseDebugging.webidl',
'Window.webidl',
@ -18,7 +19,6 @@ PREPROCESSED_WEBIDL_FILES = [
WEBIDL_FILES = [
'AbstractWorker.webidl',
'AccessibleNode.webidl',
'AddonManager.webidl',
'AnalyserNode.webidl',
'Animatable.webidl',
@ -350,7 +350,6 @@ WEBIDL_FILES = [
'NetDashboard.webidl',
'NetworkInformation.webidl',
'NetworkOptions.webidl',
'Node.webidl',
'NodeFilter.webidl',
'NodeIterator.webidl',
'NodeList.webidl',
@ -925,3 +924,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
WEBIDL_FILES += [
'AlarmsManager.webidl',
]
if CONFIG['ACCESSIBILITY']:
WEBIDL_FILES += [
'AccessibleNode.webidl',
]

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

@ -672,6 +672,7 @@ public:
typedef void (*FontDescriptorOutput)(const uint8_t *aData, uint32_t aLength, Float aFontSize, void *aBaton);
virtual FontType GetType() const = 0;
virtual AntialiasMode GetDefaultAAMode() { return AntialiasMode::DEFAULT; }
/** This allows getting a path that describes the outline of a set of glyphs.
* A target is passed in so that the guarantee is made the returned path

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

@ -1183,12 +1183,8 @@ ShouldUseCGToFillGlyphs(const GlyphRenderingOptions* aOptions, const Pattern& aP
#endif
void
DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
const GlyphBuffer &aBuffer,
const Pattern &aPattern,
const DrawOptions &aOptions,
const GlyphRenderingOptions *aRenderingOptions)
static bool
CanDrawFont(ScaledFont* aFont)
{
switch (aFont->GetType()) {
case FontType::SKIA:
@ -1197,8 +1193,20 @@ DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
case FontType::MAC:
case FontType::GDI:
case FontType::DWRITE:
break;
return true;
default:
return false;
}
}
void
DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
const GlyphBuffer &aBuffer,
const Pattern &aPattern,
const DrawOptions &aOptions,
const GlyphRenderingOptions *aRenderingOptions)
{
if (!CanDrawFont(aFont)) {
return;
}
@ -1219,11 +1227,18 @@ DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
}
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
AntialiasMode aaMode = aFont->GetDefaultAAMode();
if (aOptions.mAntialiasMode != AntialiasMode::DEFAULT) {
aaMode = aOptions.mAntialiasMode;
}
bool aaEnabled = aaMode != AntialiasMode::NONE;
paint.mPaint.setAntiAlias(aaEnabled);
paint.mPaint.setTypeface(typeface);
paint.mPaint.setTextSize(SkFloatToScalar(skiaFont->mSize));
paint.mPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
bool shouldLCDRenderText = ShouldLCDRenderText(aFont->GetType(), aOptions.mAntialiasMode);
bool shouldLCDRenderText = ShouldLCDRenderText(aFont->GetType(), aaMode);
paint.mPaint.setLCDRenderText(shouldLCDRenderText);
bool useSubpixelText = true;
@ -1237,7 +1252,7 @@ DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
useSubpixelText = false;
break;
case FontType::MAC:
if (aOptions.mAntialiasMode == AntialiasMode::GRAY) {
if (aaMode == AntialiasMode::GRAY) {
// Normally, Skia enables LCD FontSmoothing which creates thicker fonts
// and also enables subpixel AA. CoreGraphics without font smoothing
// explicitly creates thinner fonts and grayscale AA.
@ -1257,14 +1272,15 @@ DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
}
break;
case FontType::GDI:
{
if (!shouldLCDRenderText) {
// If we have non LCD GDI text, Cairo currently always uses cleartype fonts and
// converts them to grayscale. Force Skia to do the same, otherwise we use
// GDI fonts with the ANTIALIASED_QUALITY which is generally bolder than
// Cleartype fonts.
// If we have non LCD GDI text, render the fonts as cleartype and convert them
// to grayscale. This seems to be what Chrome and IE are doing on Windows 7.
// This also applies if cleartype is disabled system wide.
paint.mPaint.setFlags(paint.mPaint.getFlags() | SkPaint::kGenA8FromLCD_Flag);
}
break;
}
default:
break;
}

58
gfx/2d/HelpersWinFonts.h Normal file
Просмотреть файл

@ -0,0 +1,58 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
namespace mozilla {
namespace gfx {
// Cleartype can be dynamically enabled/disabled, so we have to check it
// everytime we want to render some text.
static BYTE
GetSystemTextQuality()
{
BOOL font_smoothing;
UINT smoothing_type;
if (!SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &font_smoothing, 0)) {
return DEFAULT_QUALITY;
}
if (font_smoothing) {
if (!SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE,
0, &smoothing_type, 0)) {
return DEFAULT_QUALITY;
}
if (smoothing_type == FE_FONTSMOOTHINGCLEARTYPE) {
return CLEARTYPE_QUALITY;
}
return ANTIALIASED_QUALITY;
}
return DEFAULT_QUALITY;
}
static AntialiasMode
GetSystemDefaultAAMode()
{
AntialiasMode defaultMode = AntialiasMode::SUBPIXEL;
switch (GetSystemTextQuality()) {
case CLEARTYPE_QUALITY:
defaultMode = AntialiasMode::SUBPIXEL;
break;
case ANTIALIASED_QUALITY:
defaultMode = AntialiasMode::GRAY;
break;
case DEFAULT_QUALITY:
defaultMode = AntialiasMode::NONE;
break;
}
return defaultMode;
}
} // namespace gfx
} // namespace mozilla

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

@ -22,35 +22,11 @@ using namespace std;
#include "cairo-win32.h"
#endif
#include "HelpersWinFonts.h"
namespace mozilla {
namespace gfx {
static BYTE
GetSystemTextQuality()
{
BOOL font_smoothing;
UINT smoothing_type;
if (!SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &font_smoothing, 0)) {
return DEFAULT_QUALITY;
}
if (font_smoothing) {
if (!SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE,
0, &smoothing_type, 0)) {
return DEFAULT_QUALITY;
}
if (smoothing_type == FE_FONTSMOOTHINGCLEARTYPE) {
return CLEARTYPE_QUALITY;
}
return ANTIALIASED_QUALITY;
}
return DEFAULT_QUALITY;
}
#define GASP_TAG 0x70736167
#define GASP_DOGRAY 0x2
@ -315,19 +291,7 @@ ScaledFontDWrite::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton
AntialiasMode
ScaledFontDWrite::GetDefaultAAMode()
{
AntialiasMode defaultMode = AntialiasMode::SUBPIXEL;
switch (GetSystemTextQuality()) {
case CLEARTYPE_QUALITY:
defaultMode = AntialiasMode::SUBPIXEL;
break;
case ANTIALIASED_QUALITY:
defaultMode = AntialiasMode::GRAY;
break;
case DEFAULT_QUALITY:
defaultMode = AntialiasMode::NONE;
break;
}
AntialiasMode defaultMode = GetSystemDefaultAAMode();
if (defaultMode == AntialiasMode::GRAY) {
if (!DoGrayscale(mFontFace, mSize)) {

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

@ -44,7 +44,7 @@ public:
virtual bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton);
virtual AntialiasMode GetDefaultAAMode();
virtual AntialiasMode GetDefaultAAMode() override;
#ifdef USE_SKIA
virtual SkTypeface* GetSkTypeface();

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

@ -18,6 +18,8 @@
#include "cairo-win32.h"
#endif
#include "HelpersWinFonts.h"
namespace mozilla {
namespace gfx {
@ -86,6 +88,12 @@ ScaledFontWin::GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton)
return true;
}
AntialiasMode
ScaledFontWin::GetDefaultAAMode()
{
return GetSystemDefaultAAMode();
}
#ifdef USE_SKIA
SkTypeface* ScaledFontWin::GetSkTypeface()
{

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

@ -22,6 +22,7 @@ public:
bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton) override;
virtual bool GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) override;
virtual AntialiasMode GetDefaultAAMode() override;
#ifdef USE_SKIA
virtual SkTypeface* GetSkTypeface();

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

@ -9,6 +9,7 @@
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/Unused.h"
#include "gfxPlatform.h"
namespace mozilla {
namespace layers {

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

@ -188,7 +188,6 @@ ImageContainer::ImageContainer(Mode flag)
mDroppedImageCount(0),
mImageFactory(new ImageFactory()),
mRecycleBin(new BufferRecycleBin()),
mImageClient(nullptr),
mCurrentProducerID(-1),
mIPDLChild(nullptr)
{
@ -200,7 +199,7 @@ ImageContainer::ImageContainer(Mode flag)
break;
case ASYNCHRONOUS:
mIPDLChild = new ImageContainerChild(this);
mImageClient = ImageBridgeChild::GetSingleton()->CreateImageClient(CompositableType::IMAGE, this).take();
mImageClient = ImageBridgeChild::GetSingleton()->CreateImageClient(CompositableType::IMAGE, this);
MOZ_ASSERT(mImageClient);
break;
default:
@ -219,7 +218,6 @@ ImageContainer::ImageContainer(uint64_t aAsyncContainerID)
mDroppedImageCount(0),
mImageFactory(nullptr),
mRecycleBin(nullptr),
mImageClient(nullptr),
mAsyncContainerID(aAsyncContainerID),
mCurrentProducerID(-1),
mIPDLChild(nullptr)
@ -231,7 +229,7 @@ ImageContainer::~ImageContainer()
{
if (mIPDLChild) {
mIPDLChild->ForgetImageContainer();
ImageBridgeChild::DispatchReleaseImageClient(mImageClient, mIPDLChild);
ImageBridgeChild::DispatchReleaseImageContainer(mIPDLChild);
}
}

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

@ -636,7 +636,7 @@ private:
// In this case the ImageContainer is perfectly usable, but it will forward
// frames to the compositor through transactions in the main thread rather than
// asynchronusly using the ImageBridge IPDL protocol.
ImageClient* mImageClient;
RefPtr<ImageClient> mImageClient;
uint64_t mAsyncContainerID;

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

@ -649,10 +649,10 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap();
CompositableClient* compositable =
RefPtr<CompositableClient> compositable =
CompositableClient::FromIPDLActor(obs.compositableChild());
ContentClientRemote* contentClient =
static_cast<ContentClientRemote*>(compositable);
static_cast<ContentClientRemote*>(compositable.get());
MOZ_ASSERT(contentClient);
contentClient->SwapBuffers(obs.frontUpdatedRegion());

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

@ -0,0 +1,119 @@
/* -*- Mode: C++; tab-width: 20; 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 "CompositableChild.h"
#include "CompositableClient.h"
namespace mozilla {
namespace layers {
/* static */ PCompositableChild*
CompositableChild::CreateActor()
{
CompositableChild* child = new CompositableChild();
child->AddRef();
return child;
}
/* static */ void
CompositableChild::DestroyActor(PCompositableChild* aChild)
{
static_cast<CompositableChild*>(aChild)->Release();
}
CompositableChild::CompositableChild()
: mCompositableClient(nullptr),
mAsyncID(0),
mCanSend(true)
{
MOZ_COUNT_CTOR(CompositableChild);
}
CompositableChild::~CompositableChild()
{
MOZ_COUNT_DTOR(CompositableChild);
}
bool
CompositableChild::IsConnected() const
{
return mCompositableClient && mCanSend;
}
void
CompositableChild::Init(CompositableClient* aCompositable, uint64_t aAsyncID)
{
mCompositableClient = aCompositable;
mAsyncID = aAsyncID;
}
void
CompositableChild::RevokeCompositableClient()
{
mCompositableClient = nullptr;
}
RefPtr<CompositableClient>
CompositableChild::GetCompositableClient()
{
return mCompositableClient;
}
void
CompositableChild::ActorDestroy(ActorDestroyReason)
{
MOZ_ASSERT(NS_IsMainThread());
mCanSend = false;
if (mCompositableClient) {
mCompositableClient->mCompositableChild = nullptr;
mCompositableClient = nullptr;
}
}
/* static */ PCompositableChild*
AsyncCompositableChild::CreateActor()
{
AsyncCompositableChild* child = new AsyncCompositableChild();
child->AddRef();
return child;
}
AsyncCompositableChild::AsyncCompositableChild()
: mLock("AsyncCompositableChild.mLock")
{
}
AsyncCompositableChild::~AsyncCompositableChild()
{
}
void
AsyncCompositableChild::ActorDestroy(ActorDestroyReason)
{
mCanSend = false;
// We do not revoke CompositableClient::mCompositableChild here, since that
// could race with the main thread.
RevokeCompositableClient();
}
void
AsyncCompositableChild::RevokeCompositableClient()
{
MutexAutoLock lock(mLock);
mCompositableClient = nullptr;
}
RefPtr<CompositableClient>
AsyncCompositableChild::GetCompositableClient()
{
MutexAutoLock lock(mLock);
return CompositableChild::GetCompositableClient();
}
} // namespace layers
} // namespace mozilla

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

@ -0,0 +1,91 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
#ifndef mozilla_gfx_layers_client_CompositableChild_h
#define mozilla_gfx_layers_client_CompositableChild_h
#include <stdint.h>
#include "IPDLActor.h"
#include "mozilla/Mutex.h"
#include "mozilla/layers/PCompositableChild.h"
namespace mozilla {
namespace layers {
class CompositableClient;
class AsyncCompositableChild;
/**
* IPDL actor used by CompositableClient to match with its corresponding
* CompositableHost on the compositor side.
*
* CompositableChild is owned by a CompositableClient.
*/
class CompositableChild : public PCompositableChild
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositableChild)
static PCompositableChild* CreateActor();
static void DestroyActor(PCompositableChild* aChild);
void Init(CompositableClient* aCompositable, uint64_t aAsyncID);
virtual void RevokeCompositableClient();
virtual void ActorDestroy(ActorDestroyReason) override;
virtual RefPtr<CompositableClient> GetCompositableClient();
virtual AsyncCompositableChild* AsAsyncCompositableChild() {
return nullptr;
}
uint64_t GetAsyncID() const {
return mAsyncID;
}
// These should only be called on the IPDL thread.
bool IsConnected() const;
bool CanSend() const {
return mCanSend;
}
protected:
CompositableChild();
virtual ~CompositableChild();
protected:
CompositableClient* mCompositableClient;
uint64_t mAsyncID;
bool mCanSend;
};
// This CompositableChild can be used off the main thread.
class AsyncCompositableChild final : public CompositableChild
{
public:
static PCompositableChild* CreateActor();
void RevokeCompositableClient() override;
RefPtr<CompositableClient> GetCompositableClient() override;
void ActorDestroy(ActorDestroyReason) override;
AsyncCompositableChild* AsAsyncCompositableChild() override {
return this;
}
protected:
AsyncCompositableChild();
~AsyncCompositableChild() override;
private:
Mutex mLock;
};
} // namespace layers
} // namespace mozilla
#endif // mozilla_gfx_layers_client_CompositableChild_h

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

@ -6,6 +6,7 @@
#include "mozilla/layers/CompositableClient.h"
#include <stdint.h> // for uint64_t, uint32_t
#include "gfxPlatform.h" // for gfxPlatform
#include "mozilla/layers/CompositableChild.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/TextureClient.h" // for TextureClient, etc
@ -26,37 +27,6 @@ namespace layers {
using namespace mozilla::gfx;
/**
* IPDL actor used by CompositableClient to match with its corresponding
* CompositableHost on the compositor side.
*
* CompositableChild is owned by a CompositableClient.
*/
class CompositableChild : public ChildActor<PCompositableChild>
{
public:
CompositableChild()
: mCompositableClient(nullptr), mAsyncID(0)
{
MOZ_COUNT_CTOR(CompositableChild);
}
virtual ~CompositableChild()
{
MOZ_COUNT_DTOR(CompositableChild);
}
virtual void ActorDestroy(ActorDestroyReason) override {
if (mCompositableClient) {
mCompositableClient->mCompositableChild = nullptr;
}
}
CompositableClient* mCompositableClient;
uint64_t mAsyncID;
};
void
RemoveTextureFromCompositableTracker::ReleaseTextureClient()
{
@ -73,40 +43,34 @@ RemoveTextureFromCompositableTracker::ReleaseTextureClient()
}
}
/* static */ PCompositableChild*
CompositableClient::CreateIPDLActor()
{
return new CompositableChild();
}
/* static */ bool
CompositableClient::DestroyIPDLActor(PCompositableChild* actor)
{
delete actor;
return true;
}
void
CompositableClient::InitIPDLActor(PCompositableChild* aActor, uint64_t aAsyncID)
{
MOZ_ASSERT(aActor);
CompositableChild* child = static_cast<CompositableChild*>(aActor);
mCompositableChild = child;
child->mCompositableClient = this;
child->mAsyncID = aAsyncID;
mForwarder->AssertInForwarderThread();
mCompositableChild = static_cast<CompositableChild*>(aActor);
mCompositableChild->Init(this, aAsyncID);
}
/* static */ CompositableClient*
/* static */ RefPtr<CompositableClient>
CompositableClient::FromIPDLActor(PCompositableChild* aActor)
{
MOZ_ASSERT(aActor);
return static_cast<CompositableChild*>(aActor)->mCompositableClient;
RefPtr<CompositableClient> client = static_cast<CompositableChild*>(aActor)->GetCompositableClient();
if (!client) {
return nullptr;
}
client->mForwarder->AssertInForwarderThread();
return client;
}
CompositableClient::CompositableClient(CompositableForwarder* aForwarder,
TextureFlags aTextureFlags)
: mCompositableChild(nullptr)
, mForwarder(aForwarder)
: mForwarder(aForwarder)
, mTextureFlags(aTextureFlags)
{
MOZ_COUNT_CTOR(CompositableClient);
@ -124,12 +88,6 @@ CompositableClient::GetCompositorBackendType() const
return mForwarder->GetCompositorBackendType();
}
void
CompositableClient::SetIPDLActor(CompositableChild* aChild)
{
mCompositableChild = aChild;
}
PCompositableChild*
CompositableClient::GetIPDLActor() const
{
@ -143,6 +101,8 @@ CompositableClient::Connect(ImageContainer* aImageContainer)
if (!GetForwarder() || GetIPDLActor()) {
return false;
}
GetForwarder()->AssertInForwarderThread();
GetForwarder()->Connect(this, aImageContainer);
return true;
}
@ -150,35 +110,35 @@ CompositableClient::Connect(ImageContainer* aImageContainer)
bool
CompositableClient::IsConnected() const
{
return mCompositableChild && mCompositableChild->CanSend();
// CanSend() is only reliable in the same thread as the IPDL channel.
mForwarder->AssertInForwarderThread();
return mCompositableChild && mCompositableChild->IsConnected();
}
void
CompositableClient::Destroy()
{
if (!IsConnected()) {
if (!mCompositableChild) {
return;
}
if (mTextureClientRecycler) {
mTextureClientRecycler->Destroy();
}
mCompositableChild->mCompositableClient = nullptr;
mCompositableChild->Destroy(mForwarder);
mCompositableChild = nullptr;
}
bool
CompositableClient::DestroyFallback(PCompositableChild* aActor)
{
return aActor->SendDestroySync();
// Take away our IPDL's actor reference back to us.
mCompositableChild->RevokeCompositableClient();
// Schedule the IPDL actor to be destroyed on the forwarder's thread.
mForwarder->Destroy(mCompositableChild);
mCompositableChild = nullptr;
}
uint64_t
CompositableClient::GetAsyncID() const
{
if (mCompositableChild) {
return mCompositableChild->mAsyncID;
return mCompositableChild->GetAsyncID();
}
return 0; // zero is always an invalid async ID
}

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

@ -161,15 +161,10 @@ public:
void Destroy();
static bool DestroyFallback(PCompositableChild* aActor);
bool IsConnected() const;
PCompositableChild* GetIPDLActor() const;
// should only be called by a CompositableForwarder
virtual void SetIPDLActor(CompositableChild* aChild);
CompositableForwarder* GetForwarder() const
{
return mForwarder;
@ -216,19 +211,7 @@ public:
*/
virtual void RemoveTexture(TextureClient* aTexture);
static CompositableClient* FromIPDLActor(PCompositableChild* aActor);
/**
* Allocate and deallocate a CompositableChild actor.
*
* CompositableChild is an implementation detail of CompositableClient that is not
* exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor
* are for use with the managing IPDL protocols only (so that they can
* implement AllocCompositableChild and DeallocPCompositableChild).
*/
static PCompositableChild* CreateIPDLActor();
static bool DestroyIPDLActor(PCompositableChild* actor);
static RefPtr<CompositableClient> FromIPDLActor(PCompositableChild* aActor);
void InitIPDLActor(PCompositableChild* aActor, uint64_t aAsyncID = 0);
@ -242,7 +225,7 @@ public:
TextureClient* aTexture,
TextureDumpMode aCompress);
protected:
CompositableChild* mCompositableChild;
RefPtr<CompositableChild> mCompositableChild;
RefPtr<CompositableForwarder> mForwarder;
// Some layers may want to enforce some flags to all their textures
// (like disallowing tiling)

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

@ -131,11 +131,6 @@ public:
return TextureInfo(mType);
}
virtual void SetIPDLActor(CompositableChild* aChild) override
{
MOZ_ASSERT(!aChild, "ImageClientBridge should not have IPDL actor");
}
protected:
uint64_t mAsyncContainerID;
};

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

@ -883,7 +883,7 @@ TextureClient::InitIPDLActor(CompositableForwarder* aForwarder)
// It's Ok for a texture to move from a ShadowLayerForwarder to another, but
// not form a CompositorBridgeChild to another (they use different channels).
if (currentTexFwd && currentTexFwd != aForwarder->AsTextureForwarder()) {
gfxCriticalError() << "Attempt to move a texture to a different channel.";
gfxCriticalError() << "Attempt to move a texture to a different channel CF.";
return false;
}
if (currentFwd && currentFwd->GetCompositorBackendType() != aForwarder->GetCompositorBackendType()) {
@ -940,7 +940,7 @@ TextureClient::InitIPDLActor(TextureForwarder* aForwarder, LayersBackend aBacken
}
if (currentTexFwd && currentTexFwd != aForwarder) {
gfxCriticalError() << "Attempt to move a texture to a different channel.";
gfxCriticalError() << "Attempt to move a texture to a different channel TF.";
return false;
}
mActor->mTextureForwarder = aForwarder;

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

@ -0,0 +1,28 @@
/* -*- 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/. */
#include "CompositableForwarder.h"
#include "mozilla/layers/CompositableChild.h"
namespace mozilla {
namespace layers {
void
CompositableForwarder::Destroy(CompositableChild* aCompositable)
{
AssertInForwarderThread();
if (!aCompositable->CanSend()) {
return;
}
if (!DestroyInTransaction(aCompositable, false)) {
aCompositable->SendDestroy();
}
}
} // namespace layers
} // namespace mozilla

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

@ -111,6 +111,8 @@ public:
const gfx::IntRect& aPictureRect) = 0;
#endif
virtual void Destroy(CompositableChild* aCompositable);
virtual bool DestroyInTransaction(PTextureChild* aTexture, bool synchronously) = 0;
virtual bool DestroyInTransaction(PCompositableChild* aCompositable, bool synchronously) = 0;
@ -174,6 +176,12 @@ public:
return mTextureFactoryIdentifier.mMaxTextureSize;
}
virtual bool InForwarderThread() = 0;
void AssertInForwarderThread() {
MOZ_ASSERT(InForwarderThread());
}
/**
* Returns the type of backend that is used off the main thread.
* We only don't allow changing the backend type at runtime so this value can

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

@ -23,6 +23,7 @@
#include "mozilla/layers/AsyncCanvasRenderer.h"
#include "mozilla/media/MediaSystemResourceManager.h" // for MediaSystemResourceManager
#include "mozilla/media/MediaSystemResourceManagerChild.h" // for MediaSystemResourceManagerChild
#include "mozilla/layers/CompositableChild.h"
#include "mozilla/layers/CompositableClient.h" // for CompositableChild, etc
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator
@ -142,7 +143,7 @@ struct CompositableTransaction
break;
}
case OpDestroy::TPCompositableChild: {
DebugOnly<bool> ok = CompositableClient::DestroyFallback(actor.get_PCompositableChild());
DebugOnly<bool> ok = actor.get_PCompositableChild()->SendDestroySync();
MOZ_ASSERT(ok);
break;
}
@ -521,6 +522,8 @@ ImageBridgeChild::Connect(CompositableClient* aCompositable,
{
MOZ_ASSERT(aCompositable);
MOZ_ASSERT(!mShuttingDown);
MOZ_ASSERT(InImageBridgeChildThread());
uint64_t id = 0;
PImageContainerChild* imageContainerChild = nullptr;
@ -539,13 +542,14 @@ ImageBridgeChild::AllocPCompositableChild(const TextureInfo& aInfo,
PImageContainerChild* aChild, uint64_t* aID)
{
MOZ_ASSERT(!mShuttingDown);
return CompositableClient::CreateIPDLActor();
return AsyncCompositableChild::CreateActor();
}
bool
ImageBridgeChild::DeallocPCompositableChild(PCompositableChild* aActor)
{
return CompositableClient::DestroyIPDLActor(aActor);
AsyncCompositableChild::DestroyActor(aActor);
return true;
}
@ -564,13 +568,9 @@ bool ImageBridgeChild::IsCreated()
return GetSingleton() != nullptr;
}
static void ReleaseImageClientNow(ImageClient* aClient,
PImageContainerChild* aChild)
static void ReleaseImageContainerNow(PImageContainerChild* aChild)
{
MOZ_ASSERT(InImageBridgeChildThread());
if (aClient) {
aClient->Release();
}
if (aChild) {
ImageContainer::AsyncDestroyActor(aChild);
@ -578,57 +578,19 @@ static void ReleaseImageClientNow(ImageClient* aClient,
}
// static
void ImageBridgeChild::DispatchReleaseImageClient(ImageClient* aClient,
PImageContainerChild* aChild)
void ImageBridgeChild::DispatchReleaseImageContainer(PImageContainerChild* aChild)
{
if (!aClient && !aChild) {
if (!aChild) {
return;
}
if (!IsCreated()) {
if (aClient) {
// CompositableClient::Release should normally happen in the ImageBridgeChild
// thread because it usually generate some IPDL messages.
// However, if we take this branch it means that the ImageBridgeChild
// has already shut down, along with the CompositableChild, which means no
// message will be sent and it is safe to run this code from any thread.
MOZ_ASSERT(aClient->GetIPDLActor() == nullptr);
aClient->Release();
}
delete aChild;
return;
}
sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
NewRunnableFunction(&ReleaseImageClientNow, aClient, aChild));
}
static void ReleaseCanvasClientNow(CanvasClient* aClient)
{
MOZ_ASSERT(InImageBridgeChildThread());
aClient->Release();
}
// static
void ImageBridgeChild::DispatchReleaseCanvasClient(CanvasClient* aClient)
{
if (!aClient) {
return;
}
if (!IsCreated()) {
// CompositableClient::Release should normally happen in the ImageBridgeChild
// thread because it usually generate some IPDL messages.
// However, if we take this branch it means that the ImageBridgeChild
// has already shut down, along with the CompositableChild, which means no
// message will be sent and it is safe to run this code from any thread.
MOZ_ASSERT(aClient->GetIPDLActor() == nullptr);
aClient->Release();
return;
}
sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
NewRunnableFunction(&ReleaseCanvasClientNow, aClient));
NewRunnableFunction(&ReleaseImageContainerNow, aChild));
}
static void ReleaseTextureClientNow(TextureClient* aClient)
@ -659,7 +621,8 @@ void ImageBridgeChild::DispatchReleaseTextureClient(TextureClient* aClient)
NewRunnableFunction(&ReleaseTextureClientNow, aClient));
}
static void UpdateImageClientNow(ImageClient* aClient, RefPtr<ImageContainer>&& aContainer)
static void
UpdateImageClientNow(RefPtr<ImageClient> aClient, RefPtr<ImageContainer>&& aContainer)
{
if (!ImageBridgeChild::IsCreated() || ImageBridgeChild::IsShutDown()) {
NS_WARNING("Something is holding on to graphics resources after the shutdown"
@ -668,6 +631,13 @@ static void UpdateImageClientNow(ImageClient* aClient, RefPtr<ImageContainer>&&
}
MOZ_ASSERT(aClient);
MOZ_ASSERT(aContainer);
// If the client has become disconnected before this event was dispatched,
// early return now.
if (!aClient->IsConnected()) {
return;
}
sImageBridgeChildSingleton->BeginTransaction();
aClient->UpdateImage(aContainer, Layer::CONTENT_OPAQUE);
sImageBridgeChildSingleton->EndTransaction();
@ -690,8 +660,10 @@ void ImageBridgeChild::DispatchImageClientUpdate(ImageClient* aClient,
UpdateImageClientNow(aClient, aContainer);
return;
}
sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
NewRunnableFunction(&UpdateImageClientNow, aClient, RefPtr<ImageContainer>(aContainer)));
NewRunnableFunction(&UpdateImageClientNow,
RefPtr<ImageClient>(aClient), RefPtr<ImageContainer>(aContainer)));
}
static void UpdateAsyncCanvasRendererSync(AsyncCanvasRenderer* aWrapper,
@ -1424,5 +1396,25 @@ bool ImageBridgeChild::IsSameProcess() const
return OtherPid() == base::GetCurrentProcId();
}
static void
DestroyCompositableNow(RefPtr<ImageBridgeChild> aImageBridge,
RefPtr<CompositableChild> aCompositable)
{
aImageBridge->Destroy(aCompositable);
}
void
ImageBridgeChild::Destroy(CompositableChild* aCompositable)
{
if (!InImageBridgeChildThread()) {
RefPtr<ImageBridgeChild> self = this;
RefPtr<CompositableChild> compositable = aCompositable;
GetMessageLoop()->PostTask(
NewRunnableFunction(&DestroyCompositableNow, self, compositable));
return;
}
CompositableForwarder::Destroy(aCompositable);
}
} // namespace layers
} // namespace mozilla

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

@ -227,9 +227,7 @@ public:
already_AddRefed<CanvasClient> CreateCanvasClientNow(CanvasClient::CanvasClientType aType,
TextureFlags aFlag);
static void DispatchReleaseImageClient(ImageClient* aClient,
PImageContainerChild* aChild = nullptr);
static void DispatchReleaseCanvasClient(CanvasClient* aClient);
static void DispatchReleaseImageContainer(PImageContainerChild* aChild = nullptr);
static void DispatchReleaseTextureClient(TextureClient* aClient);
static void DispatchImageClientUpdate(ImageClient* aClient, ImageContainer* aContainer);
@ -262,6 +260,8 @@ public:
const nsIntRect& aPictureRect) override;
#endif
void Destroy(CompositableChild* aCompositable) override;
/**
* Hold TextureClient ref until end of usage on host side if TextureFlags::RECYCLE is set.
* Host side's usage is checked via CompositableRef.
@ -341,6 +341,11 @@ public:
virtual void UpdateFwdTransactionId() override { ++mFwdTransactionId; }
virtual uint64_t GetFwdTransactionId() override { return mFwdTransactionId; }
bool InForwarderThread() override {
return InImageBridgeChildThread();
}
void MarkShutDown();
void FallbackDestroyActors();

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

@ -7,7 +7,7 @@
#include "LayerTransactionChild.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/layers/CompositableClient.h" // for CompositableChild
#include "mozilla/layers/CompositableChild.h"
#include "mozilla/layers/PCompositableChild.h" // for PCompositableChild
#include "mozilla/layers/PLayerChild.h" // for PLayerChild
#include "mozilla/layers/PImageContainerChild.h"
@ -60,13 +60,14 @@ PCompositableChild*
LayerTransactionChild::AllocPCompositableChild(const TextureInfo& aInfo)
{
MOZ_ASSERT(!mDestroyed);
return CompositableClient::CreateIPDLActor();
return CompositableChild::CreateActor();
}
bool
LayerTransactionChild::DeallocPCompositableChild(PCompositableChild* actor)
{
return CompositableClient::DestroyIPDLActor(actor);
CompositableChild::DestroyActor(actor);
return true;
}
void

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

@ -30,6 +30,7 @@
#include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG
#include "mozilla/layers/LayerTransactionChild.h"
#include "mozilla/layers/SharedBufferManagerChild.h"
#include "mozilla/layers/PCompositableChild.h"
#include "mozilla/layers/PTextureChild.h"
#include "ShadowLayerUtils.h"
#include "mozilla/layers/TextureClient.h" // for TextureClient
@ -169,7 +170,7 @@ public:
break;
}
case OpDestroy::TPCompositableChild: {
DebugOnly<bool> ok = CompositableClient::DestroyFallback(actor.get_PCompositableChild());
DebugOnly<bool> ok = actor.get_PCompositableChild()->SendDestroySync();
MOZ_ASSERT(ok);
break;
}

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

@ -392,6 +392,10 @@ public:
virtual void UpdateFwdTransactionId() override;
virtual uint64_t GetFwdTransactionId() override;
bool InForwarderThread() override {
return NS_IsMainThread();
}
// Returns true if aSurface wraps a Shmem.
static bool IsShmem(SurfaceDescriptor* aSurface);

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

@ -43,8 +43,6 @@ SharedPlanarYCbCrImage::~SharedPlanarYCbCrImage() {
ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient);
mTextureClient = nullptr;
}
ImageBridgeChild::DispatchReleaseImageClient(mCompositable.forget().take());
}
}

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

@ -68,8 +68,6 @@ SharedRGBImage::~SharedRGBImage()
ADDREF_MANUALLY(mTextureClient);
ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient);
mTextureClient = nullptr;
ImageBridgeChild::DispatchReleaseImageClient(mCompositable.forget().take());
}
}

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

@ -128,6 +128,7 @@ EXPORTS.mozilla.layers += [
'BSPTree.h',
'BufferTexture.h',
'client/CanvasClient.h',
'client/CompositableChild.h',
'client/CompositableClient.h',
'client/ContentClient.h',
'client/ImageClient.h',
@ -316,6 +317,7 @@ UNIFIED_SOURCES += [
'client/ClientLayerManager.cpp',
'client/ClientPaintedLayer.cpp',
'client/ClientTiledPaintedLayer.cpp',
'client/CompositableChild.cpp',
'client/CompositableClient.cpp',
'client/ContentClient.cpp',
'client/ImageClient.cpp',
@ -352,6 +354,7 @@ UNIFIED_SOURCES += [
'ipc/APZCTreeManagerChild.cpp',
'ipc/APZCTreeManagerParent.cpp',
'ipc/AsyncTransactionTracker.cpp',
'ipc/CompositableForwarder.cpp',
'ipc/CompositableTransactionParent.cpp',
'ipc/CompositorBench.cpp',
'ipc/CompositorBridgeChild.cpp',

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

@ -758,6 +758,17 @@ VRDisplayOculus::SubmitFrame(TextureSourceD3D11* aSource,
if (!mIsPresenting) {
return;
}
if (mRenderTargets.IsEmpty()) {
/**
* XXX - We should resolve fail the promise returned by
* VRDisplay.requestPresent() when the DX11 resources fail allocation
* in VRDisplayOculus::StartPresentation().
* Bailing out here prevents the crash but content should be aware
* that frames are not being presented.
* See Bug 1299309.
**/
return;
}
MOZ_ASSERT(mDevice);
MOZ_ASSERT(mContext);

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

@ -31,6 +31,8 @@ class Latin1Chars : public mozilla::Range<Latin1Char>
typedef mozilla::Range<Latin1Char> Base;
public:
using CharT = Latin1Char;
Latin1Chars() : Base() {}
Latin1Chars(char* aBytes, size_t aLength) : Base(reinterpret_cast<Latin1Char*>(aBytes), aLength) {}
Latin1Chars(const Latin1Char* aBytes, size_t aLength)
@ -49,6 +51,8 @@ class Latin1CharsZ : public mozilla::RangedPtr<Latin1Char>
typedef mozilla::RangedPtr<Latin1Char> Base;
public:
using CharT = Latin1Char;
Latin1CharsZ() : Base(nullptr, 0) {}
Latin1CharsZ(char* aBytes, size_t aLength)
@ -73,6 +77,8 @@ class UTF8Chars : public mozilla::Range<unsigned char>
typedef mozilla::Range<unsigned char> Base;
public:
using CharT = unsigned char;
UTF8Chars() : Base() {}
UTF8Chars(char* aBytes, size_t aLength)
: Base(reinterpret_cast<unsigned char*>(aBytes), aLength)
@ -90,6 +96,8 @@ class UTF8CharsZ : public mozilla::RangedPtr<unsigned char>
typedef mozilla::RangedPtr<unsigned char> Base;
public:
using CharT = unsigned char;
UTF8CharsZ() : Base(nullptr, 0) {}
UTF8CharsZ(char* aBytes, size_t aLength)
@ -120,6 +128,8 @@ class ConstUTF8CharsZ
const char* data_;
public:
using CharT = unsigned char;
ConstUTF8CharsZ() : data_(nullptr)
{}
@ -157,6 +167,8 @@ class TwoByteChars : public mozilla::Range<char16_t>
typedef mozilla::Range<char16_t> Base;
public:
using CharT = char16_t;
TwoByteChars() : Base() {}
TwoByteChars(char16_t* aChars, size_t aLength) : Base(aChars, aLength) {}
TwoByteChars(const char16_t* aChars, size_t aLength) : Base(const_cast<char16_t*>(aChars), aLength) {}
@ -170,6 +182,8 @@ class TwoByteCharsZ : public mozilla::RangedPtr<char16_t>
typedef mozilla::RangedPtr<char16_t> Base;
public:
using CharT = char16_t;
TwoByteCharsZ() : Base(nullptr, 0) {}
TwoByteCharsZ(char16_t* chars, size_t length)
@ -191,6 +205,8 @@ class ConstTwoByteChars : public mozilla::Range<const char16_t>
typedef mozilla::Range<const char16_t> Base;
public:
using CharT = char16_t;
ConstTwoByteChars() : Base() {}
ConstTwoByteChars(const char16_t* aChars, size_t aLength) : Base(aChars, aLength) {}
};
@ -272,6 +288,41 @@ JS_PUBLIC_API(void)
DeflateStringToUTF8Buffer(JSFlatString* src, mozilla::RangedPtr<char> dst,
size_t* dstlenp = nullptr, size_t* numcharsp = nullptr);
/*
* The smallest character encoding capable of fully representing a particular
* string.
*/
enum class SmallestEncoding {
ASCII,
Latin1,
UTF16
};
/*
* Returns the smallest encoding possible for the given string: if all
* codepoints are <128 then ASCII, otherwise if all codepoints are <256
* Latin-1, else UTF16.
*/
JS_PUBLIC_API(SmallestEncoding)
FindSmallestEncoding(UTF8Chars utf8);
/*
* Return a null-terminated Latin-1 string copied from the input string,
* storing its length (excluding null terminator) in |*outlen|. Fail and
* report an error if the string contains non-Latin-1 codepoints. Returns
* Latin1CharsZ() on failure.
*/
extern Latin1CharsZ
UTF8CharsToNewLatin1CharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen);
/*
* Return a null-terminated Latin-1 string copied from the input string,
* storing its length (excluding null terminator) in |*outlen|. Non-Latin-1
* codepoints are replaced by '?'. Returns Latin1CharsZ() on failure.
*/
extern Latin1CharsZ
LossyUTF8CharsToNewLatin1CharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen);
} // namespace JS
inline void JS_free(JS::Latin1CharsZ& ptr) { js_free((void*)ptr.get()); }

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

@ -8504,6 +8504,9 @@ BuildConsoleMessage(ExclusiveContext* cx, unsigned time, JS::AsmJSCacheResult ca
case JS::AsmJSCache_InternalError:
cacheString = "unable to store in cache due to internal error (consider filing a bug)";
break;
case JS::AsmJSCache_Disabled_PrivateBrowsing:
cacheString = "caching disabled by private browsing mode";
break;
case JS::AsmJSCache_LIMIT:
MOZ_CRASH("bad AsmJSCacheResult");
break;

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

@ -1397,6 +1397,11 @@ static const JSFunctionSpec promise_methods[] = {
JS_FS_END
};
static const JSPropertySpec promise_properties[] = {
JS_STRING_SYM_PS(toStringTag, "Promise", JSPROP_READONLY),
JS_PS_END
};
static const JSFunctionSpec promise_static_methods[] = {
JS_SELF_HOSTED_FN("all", "Promise_static_all", 1, 0),
JS_SELF_HOSTED_FN("race", "Promise_static_race", 1, 0),
@ -1415,7 +1420,8 @@ static const ClassSpec PromiseObjectClassSpec = {
CreatePromisePrototype,
promise_static_methods,
promise_static_properties,
promise_methods
promise_methods,
promise_properties
};
const Class PromiseObject::class_ = {

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

@ -3112,15 +3112,6 @@ ByteSizeOfScript(JSContext*cx, unsigned argc, Value* vp)
return true;
}
static bool
ImmutablePrototypesEnabled(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().setBoolean(JS_ImmutablePrototypesEnabled());
return true;
}
static bool
SetImmutablePrototype(JSContext* cx, unsigned argc, Value* vp)
{
@ -3991,11 +3982,6 @@ gc::ZealModeHelpText),
"byteSizeOfScript(f)",
" Return the size in bytes occupied by the function |f|'s JSScript.\n"),
JS_FN_HELP("immutablePrototypesEnabled", ImmutablePrototypesEnabled, 0, 0,
"immutablePrototypesEnabled()",
" Returns true if immutable-prototype behavior (triggered by setImmutablePrototype)\n"
" is enabled, such that modifying an immutable prototype will fail."),
JS_FN_HELP("setImmutablePrototype", SetImmutablePrototype, 1, 0,
"setImmutablePrototype(obj)",
" Try to make obj's [[Prototype]] immutable, such that subsequent attempts to\n"

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

@ -1170,22 +1170,15 @@ BytecodeEmitter::EmitterScope::enterFunctionExtraBodyVar(BytecodeEmitter* bce, F
class DynamicBindingIter : public BindingIter
{
uint32_t functionEnd_;
public:
explicit DynamicBindingIter(GlobalSharedContext* sc)
: BindingIter(*sc->bindings),
functionEnd_(sc->functionBindingEnd)
{
MOZ_ASSERT(functionEnd_ >= varStart_ && functionEnd_ <= letStart_);
}
: BindingIter(*sc->bindings)
{ }
explicit DynamicBindingIter(EvalSharedContext* sc)
: BindingIter(*sc->bindings, /* strict = */ false),
functionEnd_(sc->functionBindingEnd)
: BindingIter(*sc->bindings, /* strict = */ false)
{
MOZ_ASSERT(!sc->strict());
MOZ_ASSERT(functionEnd_ >= varStart_ && functionEnd_ <= letStart_);
}
JSOp bindingOp() const {
@ -1200,10 +1193,6 @@ class DynamicBindingIter : public BindingIter
MOZ_CRASH("Bad BindingKind");
}
}
bool isBodyLevelFunction() const {
return index_ < functionEnd_;
}
};
bool
@ -1243,7 +1232,7 @@ BytecodeEmitter::EmitterScope::enterGlobal(BytecodeEmitter* bce, GlobalSharedCon
// Define the name in the prologue. Do not emit DEFVAR for
// functions that we'll emit DEFFUN for.
if (bi.isBodyLevelFunction())
if (bi.isTopLevelFunction())
continue;
if (!bce->emitAtomOp(name, bi.bindingOp()))
@ -1303,7 +1292,7 @@ BytecodeEmitter::EmitterScope::enterEval(BytecodeEmitter* bce, EvalSharedContext
for (DynamicBindingIter bi(evalsc); bi; bi++) {
MOZ_ASSERT(bi.bindingOp() == JSOP_DEFVAR);
if (bi.isBodyLevelFunction())
if (bi.isTopLevelFunction())
continue;
if (!bce->emitAtomOp(bi.name(), JSOP_DEFVAR))

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

@ -275,7 +275,6 @@ EvalSharedContext::EvalSharedContext(ExclusiveContext* cx, JSObject* enclosingEn
bool extraWarnings)
: SharedContext(cx, Kind::Eval, directives, extraWarnings),
enclosingScope_(cx, enclosingScope),
functionBindingEnd(0),
bindings(cx)
{
computeAllowSyntax(enclosingScope);
@ -1374,8 +1373,7 @@ NewEmptyBindingData(ExclusiveContext* cx, LifoAlloc& alloc, uint32_t numBindings
template <>
Maybe<GlobalScope::Data*>
Parser<FullParseHandler>::newGlobalScopeData(ParseContext::Scope& scope,
uint32_t* functionBindingEnd)
Parser<FullParseHandler>::newGlobalScopeData(ParseContext::Scope& scope)
{
Vector<BindingName> funs(context);
Vector<BindingName> vars(context);
@ -1420,12 +1418,10 @@ Parser<FullParseHandler>::newGlobalScopeData(ParseContext::Scope& scope,
BindingName* start = bindings->names;
BindingName* cursor = start;
// Keep track of what vars are functions. This is only used in BCE to omit
// superfluous DEFVARs.
PodCopy(cursor, funs.begin(), funs.length());
cursor += funs.length();
*functionBindingEnd = cursor - start;
bindings->varStart = cursor - start;
PodCopy(cursor, vars.begin(), vars.length());
cursor += vars.length();
@ -1510,8 +1506,7 @@ Parser<FullParseHandler>::newModuleScopeData(ParseContext::Scope& scope)
template <>
Maybe<EvalScope::Data*>
Parser<FullParseHandler>::newEvalScopeData(ParseContext::Scope& scope,
uint32_t* functionBindingEnd)
Parser<FullParseHandler>::newEvalScopeData(ParseContext::Scope& scope)
{
Vector<BindingName> funs(context);
Vector<BindingName> vars(context);
@ -1545,8 +1540,8 @@ Parser<FullParseHandler>::newEvalScopeData(ParseContext::Scope& scope,
// superfluous DEFVARs.
PodCopy(cursor, funs.begin(), funs.length());
cursor += funs.length();
*functionBindingEnd = cursor - start;
bindings->varStart = cursor - start;
PodCopy(cursor, vars.begin(), vars.length());
bindings->length = numBindings;
}
@ -1830,14 +1825,10 @@ Parser<FullParseHandler>::evalBody(EvalSharedContext* evalsc)
if (!FoldConstants(context, &body, this))
return nullptr;
uint32_t functionBindingEnd = 0;
Maybe<EvalScope::Data*> bindings =
newEvalScopeData(pc->varScope(), &functionBindingEnd);
Maybe<EvalScope::Data*> bindings = newEvalScopeData(pc->varScope());
if (!bindings)
return nullptr;
evalsc->bindings = *bindings;
evalsc->functionBindingEnd = functionBindingEnd;
return body;
}
@ -1864,13 +1855,10 @@ Parser<FullParseHandler>::globalBody(GlobalSharedContext* globalsc)
if (!FoldConstants(context, &body, this))
return nullptr;
uint32_t functionBindingEnd = 0;
Maybe<GlobalScope::Data*> bindings = newGlobalScopeData(pc->varScope(), &functionBindingEnd);
Maybe<GlobalScope::Data*> bindings = newGlobalScopeData(pc->varScope());
if (!bindings)
return nullptr;
globalsc->bindings = *bindings;
globalsc->functionBindingEnd = functionBindingEnd;
return body;
}

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

@ -1290,11 +1290,9 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter
// Required on Scope exit.
bool propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope);
mozilla::Maybe<GlobalScope::Data*> newGlobalScopeData(ParseContext::Scope& scope,
uint32_t* functionBindingEnd);
mozilla::Maybe<GlobalScope::Data*> newGlobalScopeData(ParseContext::Scope& scope);
mozilla::Maybe<ModuleScope::Data*> newModuleScopeData(ParseContext::Scope& scope);
mozilla::Maybe<EvalScope::Data*> newEvalScopeData(ParseContext::Scope& scope,
uint32_t* functionBindingEnd);
mozilla::Maybe<EvalScope::Data*> newEvalScopeData(ParseContext::Scope& scope);
mozilla::Maybe<FunctionScope::Data*> newFunctionScopeData(ParseContext::Scope& scope,
bool hasParameterExprs);
mozilla::Maybe<VarScope::Data*> newVarScopeData(ParseContext::Scope& scope);

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

@ -380,22 +380,12 @@ class MOZ_STACK_CLASS GlobalSharedContext : public SharedContext
ScopeKind scopeKind_;
public:
// We omit DEFFVAR in the prologue for global functions since we emit
// DEFFUN for them. In order to distinguish function vars, functions are
// ordered before vars. See Parser::newGlobalScopeData and
// EmitterScope::enterGlobal.
//
// This is only used in BytecodeEmitter, and is thus not kept in
// GlobalScope::Data.
uint32_t functionBindingEnd;
Rooted<GlobalScope::Data*> bindings;
GlobalSharedContext(ExclusiveContext* cx, ScopeKind scopeKind, Directives directives,
bool extraWarnings)
: SharedContext(cx, Kind::Global, directives, extraWarnings),
scopeKind_(scopeKind),
functionBindingEnd(0),
bindings(cx)
{
MOZ_ASSERT(scopeKind == ScopeKind::Global || scopeKind == ScopeKind::NonSyntactic);
@ -423,15 +413,6 @@ class MOZ_STACK_CLASS EvalSharedContext : public SharedContext
RootedScope enclosingScope_;
public:
// We omit DEFFVAR in the prologue for body-level functions since we emit
// DEFFUN for them. In order to distinguish function vars, functions are
// ordered before vars. See Parser::newEvalScopeData and
// EmitterScope::enterEval.
//
// This is only used in BytecodeEmitter, and is thus not kept in
// EvalScope::Data.
uint32_t functionBindingEnd;
Rooted<EvalScope::Data*> bindings;
EvalSharedContext(ExclusiveContext* cx, JSObject* enclosingEnv, Scope* enclosingScope,

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

@ -1,7 +1,4 @@
function globalPrototypeChainIsMutable()
{
if (typeof immutablePrototypesEnabled !== "function")
return true;
return !immutablePrototypesEnabled();
return false;
}

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

@ -0,0 +1,10 @@
var g = newGlobal();
g.parent = this;
g.eval("(" + function() {
var dbg = new Debugger(parent);
dbg.onExceptionUnwind = function(frame) {
frame.eval("h = 3");
};
} + ")()");
g = function h() { }
g();

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

@ -0,0 +1,41 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
// Flags: -e "version(170)"
//-----------------------------------------------------------------------------
version(170)
//-----------------------------------------------------------------------------
var du = new Debugger();
if (typeof du.drainTraceLoggerScriptCalls == "function") {
du.setupTraceLoggerScriptCalls();
du.startTraceLogger();
test();
du.endTraceLogger();
var objs = du.drainTraceLoggerScriptCalls();
var scripts = 0;
var stops = 0;
for (var i = 0; i < objs.length; i++) {
if (objs[i].logType == "Script") {
scripts++;
} else if (objs[i].logType == "Stop") {
stops++;
} else {
throw "We shouldn't receive non-script events.";
}
}
assertEq(scripts, stops + 1);
// "+ 1" because we get a start for bug1298541.js:1, but not the stop.
}
function test()
{
for (var i in (function(){ for (var j=0;j<4;++j) { yield ""; } })());
}

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

@ -2,7 +2,7 @@ function TestDrainTraceLoggerInvariants(obj) {
var scripts = 0;
var stops = 0;
for (var i = 0; i < objs.length; i++) {
if (objs[i].logType == "Scripts") {
if (objs[i].logType == "Script") {
scripts++;
assertEq("fileName" in objs[i], true);
assertEq("lineNumber" in objs[i], true);
@ -13,11 +13,13 @@ function TestDrainTraceLoggerInvariants(obj) {
assertEq(true, false);
}
}
assertEq(scripts, stops);
assertEq(scripts, stops + 1);
// "+ 1" because we get a start for drainTraceLogger.js:1, but not the stop.
}
function GetMaxScriptDepth(obj) {
var max_depth = 0;
var depth = 0;
for (var i = 0; i < objs.length; i++) {
if (objs[i].logType == "Stop")
depth--;
@ -38,42 +40,39 @@ function foo2() {
}
var du = new Debugger();
if (typeof du.drainTraceLoggerTraces == "function") {
print(1);
if (typeof du.drainTraceLoggerScriptCalls == "function") {
// Test normal setup.
du = new Debugger();
du.setupTraceLoggerForTraces();
du.setupTraceLoggerScriptCalls();
du.startTraceLogger();
du.endTraceLogger();
var objs = du.drainTraceLoggerTraces();
var objs = du.drainTraceLoggerScriptCalls();
TestDrainTraceLoggerInvariants(objs);
var empty_depth = GetMaxScriptDepth(objs);
var empty_length = objs.length;
// Test basic script.
for (var i=0; i<20; i++)
foo1();
du = new Debugger();
du.setupTraceLoggerTraces();
du.setupTraceLoggerScriptCalls();
du.startTraceLogger();
foo1();
du.endTraceLogger();
var objs = du.drainTraceLoggerTraces();
var objs = du.drainTraceLoggerScriptCalls();
TestDrainTraceLoggerInvariants(objs);
assertEq(empty_depth + 2 == GetMaxScriptDepth(objs));
assertEq(empty_length + 4 == GetMaxScriptDepth(objs));
assertEq(3, GetMaxScriptDepth(objs), "drainTraceLogger.js:0 + foo1 + foo2");
assertEq(5, objs.length, "drainTraceLogger.js:0 + foo1 + foo2 + stop + stop");
// Test basic script.
for (var i=0; i<20; i++)
foo1();
du = new Debugger();
du.setupTraceLoggerForTraces();
du.setupTraceLoggerScriptCalls();
du.startTraceLogger();
for (var i=0; i<100; i++) {
@ -81,8 +80,9 @@ print(1);
}
du.endTraceLogger();
var objs = du.drainTraceLoggerTraces();
var objs = du.drainTraceLoggerScriptCalls();
TestDrainTraceLoggerInvariants(objs);
assertEq(empty_depth + 2 == GetMaxScriptDepth(objs));
assertEq(empty_length + 4*100 == GetMaxScriptDepth(objs));
assertEq(3, GetMaxScriptDepth(objs), "drainTraceLogger.js:0 + foo1 + foo2");
assertEq(4*100 + 1, objs.length);
assertEq(1 + 4*100, objs.length, "drainTraceLogger.js:0 + 4 * ( foo1 + foo2 + stop + stop )");
}

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

@ -196,20 +196,18 @@ BaselineCompiler::compile()
// Note: There is an extra entry in the bytecode type map for the search hint, see below.
size_t bytecodeTypeMapEntries = script->nTypeSets() + 1;
UniquePtr<BaselineScript> baselineScript(
BaselineScript::New(script, prologueOffset_.offset(),
epilogueOffset_.offset(),
profilerEnterFrameToggleOffset_.offset(),
profilerExitFrameToggleOffset_.offset(),
traceLoggerEnterToggleOffset_.offset(),
traceLoggerExitToggleOffset_.offset(),
postDebugPrologueOffset_.offset(),
icEntries_.length(),
pcMappingIndexEntries.length(),
pcEntries.length(),
bytecodeTypeMapEntries,
yieldOffsets_.length()),
yieldOffsets_.length(),
traceLoggerToggleOffsets_.length()),
JS::DeletePolicy<BaselineScript>(cx->runtime()));
if (!baselineScript) {
ReportOutOfMemory(cx);
@ -263,7 +261,7 @@ BaselineCompiler::compile()
#ifdef JS_TRACE_LOGGING
// Initialize the tracelogger instrumentation.
baselineScript->initTraceLogger(cx->runtime(), script);
baselineScript->initTraceLogger(cx->runtime(), script, traceLoggerToggleOffsets_);
#endif
uint32_t* bytecodeMap = baselineScript->bytecodeTypeMap();
@ -842,7 +840,8 @@ BaselineCompiler::emitTraceLoggerEnter()
Register scriptReg = regs.takeAnyGeneral();
Label noTraceLogger;
traceLoggerEnterToggleOffset_ = masm.toggledJump(&noTraceLogger);
if (!traceLoggerToggleOffsets_.append(masm.toggledJump(&noTraceLogger)))
return false;
masm.Push(loggerReg);
masm.Push(scriptReg);
@ -875,7 +874,8 @@ BaselineCompiler::emitTraceLoggerExit()
Register loggerReg = regs.takeAnyGeneral();
Label noTraceLogger;
traceLoggerExitToggleOffset_ = masm.toggledJump(&noTraceLogger);
if (!traceLoggerToggleOffsets_.append(masm.toggledJump(&noTraceLogger)))
return false;
masm.Push(loggerReg);
masm.movePtr(ImmPtr(logger), loggerReg);
@ -889,6 +889,32 @@ BaselineCompiler::emitTraceLoggerExit()
return true;
}
bool
BaselineCompiler::emitTraceLoggerResume(Register baselineScript, AllocatableGeneralRegisterSet& regs)
{
Register scriptId = regs.takeAny();
Register loggerReg = regs.takeAny();
Label noTraceLogger;
if (!traceLoggerToggleOffsets_.append(masm.toggledJump(&noTraceLogger)))
return false;
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
masm.movePtr(ImmPtr(logger), loggerReg);
Address scriptEvent(baselineScript, BaselineScript::offsetOfTraceLoggerScriptEvent());
masm.computeEffectiveAddress(scriptEvent, scriptId);
masm.tracelogStartEvent(loggerReg, scriptId);
masm.tracelogStartId(loggerReg, TraceLogger_Baseline, /* force = */ true);
regs.add(loggerReg);
regs.add(scriptId);
masm.bind(&noTraceLogger);
return true;
}
#endif
void
@ -4223,6 +4249,11 @@ BaselineCompiler::emit_JSOP_RESUME()
masm.loadPtr(Address(scratch1, JSScript::offsetOfBaselineScript()), scratch1);
masm.branchPtr(Assembler::BelowOrEqual, scratch1, ImmPtr(BASELINE_DISABLED_SCRIPT), &interpret);
#ifdef JS_TRACE_LOGGING
if (!emitTraceLoggerResume(scratch1, regs))
return false;
#endif
Register constructing = regs.takeAny();
ValueOperand newTarget = regs.takeAnyValue();
masm.loadValue(Address(genObj, GeneratorObject::offsetOfNewTargetSlot()), newTarget);

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

@ -300,6 +300,7 @@ class BaselineCompiler : public BaselineCompilerSpecific
MOZ_MUST_USE bool emitDebugTrap();
MOZ_MUST_USE bool emitTraceLoggerEnter();
MOZ_MUST_USE bool emitTraceLoggerExit();
MOZ_MUST_USE bool emitTraceLoggerResume(Register script, AllocatableGeneralRegisterSet& regs);
void emitProfilerEnterFrame();
void emitProfilerExitFrame();

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

@ -7,6 +7,7 @@
#include "jit/BaselineJIT.h"
#include "mozilla/BinarySearch.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/MemoryReporting.h"
#include "asmjs/WasmInstance.h"
@ -28,6 +29,7 @@
#include "vm/Stack-inl.h"
using mozilla::BinarySearchIf;
using mozilla::DebugOnly;
using namespace js;
using namespace js::jit;
@ -54,8 +56,6 @@ ICStubSpace::freeAllAfterMinorGC(JSRuntime* rt)
BaselineScript::BaselineScript(uint32_t prologueOffset, uint32_t epilogueOffset,
uint32_t profilerEnterToggleOffset,
uint32_t profilerExitToggleOffset,
uint32_t traceLoggerEnterToggleOffset,
uint32_t traceLoggerExitToggleOffset,
uint32_t postDebugPrologueOffset)
: method_(nullptr),
templateEnv_(nullptr),
@ -70,8 +70,6 @@ BaselineScript::BaselineScript(uint32_t prologueOffset, uint32_t epilogueOffset,
traceLoggerScriptsEnabled_(false),
traceLoggerEngineEnabled_(false),
# endif
traceLoggerEnterToggleOffset_(traceLoggerEnterToggleOffset),
traceLoggerExitToggleOffset_(traceLoggerExitToggleOffset),
traceLoggerScriptEvent_(),
#endif
postDebugPrologueOffset_(postDebugPrologueOffset),
@ -404,13 +402,12 @@ BaselineScript::New(JSScript* jsscript,
uint32_t prologueOffset, uint32_t epilogueOffset,
uint32_t profilerEnterToggleOffset,
uint32_t profilerExitToggleOffset,
uint32_t traceLoggerEnterToggleOffset,
uint32_t traceLoggerExitToggleOffset,
uint32_t postDebugPrologueOffset,
size_t icEntries,
size_t pcMappingIndexEntries, size_t pcMappingSize,
size_t bytecodeTypeMapEntries,
size_t yieldEntries)
size_t yieldEntries,
size_t traceLoggerToggleOffsetEntries)
{
static const unsigned DataAlignment = sizeof(uintptr_t);
@ -418,25 +415,27 @@ BaselineScript::New(JSScript* jsscript,
size_t pcMappingIndexEntriesSize = pcMappingIndexEntries * sizeof(PCMappingIndexEntry);
size_t bytecodeTypeMapSize = bytecodeTypeMapEntries * sizeof(uint32_t);
size_t yieldEntriesSize = yieldEntries * sizeof(uintptr_t);
size_t tlEntriesSize = traceLoggerToggleOffsetEntries * sizeof(uint32_t);
size_t paddedICEntriesSize = AlignBytes(icEntriesSize, DataAlignment);
size_t paddedPCMappingIndexEntriesSize = AlignBytes(pcMappingIndexEntriesSize, DataAlignment);
size_t paddedPCMappingSize = AlignBytes(pcMappingSize, DataAlignment);
size_t paddedBytecodeTypesMapSize = AlignBytes(bytecodeTypeMapSize, DataAlignment);
size_t paddedYieldEntriesSize = AlignBytes(yieldEntriesSize, DataAlignment);
size_t paddedTLEntriesSize = AlignBytes(tlEntriesSize, DataAlignment);
size_t allocBytes = paddedICEntriesSize +
paddedPCMappingIndexEntriesSize +
paddedPCMappingSize +
paddedBytecodeTypesMapSize +
paddedYieldEntriesSize;
paddedYieldEntriesSize +
paddedTLEntriesSize;
BaselineScript* script = jsscript->zone()->pod_malloc_with_extra<BaselineScript, uint8_t>(allocBytes);
if (!script)
return nullptr;
new (script) BaselineScript(prologueOffset, epilogueOffset,
profilerEnterToggleOffset, profilerExitToggleOffset,
traceLoggerEnterToggleOffset, traceLoggerExitToggleOffset,
postDebugPrologueOffset);
size_t offsetCursor = sizeof(BaselineScript);
@ -460,6 +459,10 @@ BaselineScript::New(JSScript* jsscript,
script->yieldEntriesOffset_ = yieldEntries ? offsetCursor : 0;
offsetCursor += paddedYieldEntriesSize;
script->traceLoggerToggleOffsetsOffset_ = tlEntriesSize ? offsetCursor : 0;
script->numTraceLoggerToggleOffsets_ = traceLoggerToggleOffsetEntries;
offsetCursor += paddedTLEntriesSize;
MOZ_ASSERT(offsetCursor == sizeof(BaselineScript) + allocBytes);
return script;
}
@ -968,7 +971,8 @@ BaselineScript::toggleDebugTraps(JSScript* script, jsbytecode* pc)
#ifdef JS_TRACE_LOGGING
void
BaselineScript::initTraceLogger(JSRuntime* runtime, JSScript* script)
BaselineScript::initTraceLogger(JSRuntime* runtime, JSScript* script,
const Vector<CodeOffset>& offsets)
{
#ifdef DEBUG
traceLoggerScriptsEnabled_ = TraceLogTextIdEnabled(TraceLogger_Scripts);
@ -976,45 +980,42 @@ BaselineScript::initTraceLogger(JSRuntime* runtime, JSScript* script)
#endif
TraceLoggerThread* logger = TraceLoggerForMainThread(runtime);
traceLoggerScriptEvent_ = TraceLoggerEvent(logger, TraceLogger_Scripts, script);
MOZ_ASSERT(offsets.length() == numTraceLoggerToggleOffsets_);
for (size_t i = 0; i < offsets.length(); i++)
traceLoggerToggleOffsets()[i] = offsets[i].offset();
if (TraceLogTextIdEnabled(TraceLogger_Engine) || TraceLogTextIdEnabled(TraceLogger_Scripts)) {
CodeLocationLabel enter(method_, CodeOffset(traceLoggerEnterToggleOffset_));
CodeLocationLabel exit(method_, CodeOffset(traceLoggerExitToggleOffset_));
Assembler::ToggleToCmp(enter);
Assembler::ToggleToCmp(exit);
traceLoggerScriptEvent_ = TraceLoggerEvent(logger, TraceLogger_Scripts, script);
for (size_t i = 0; i < numTraceLoggerToggleOffsets_; i++) {
CodeLocationLabel label(method_, CodeOffset(traceLoggerToggleOffsets()[i]));
Assembler::ToggleToCmp(label);
}
}
}
void
BaselineScript::toggleTraceLoggerScripts(JSRuntime* runtime, JSScript* script, bool enable)
{
bool engineEnabled = TraceLogTextIdEnabled(TraceLogger_Engine);
DebugOnly<bool> engineEnabled = TraceLogTextIdEnabled(TraceLogger_Engine);
MOZ_ASSERT(enable == !traceLoggerScriptsEnabled_);
MOZ_ASSERT(engineEnabled == traceLoggerEngineEnabled_);
// Patch the logging script textId to be correct.
// When logging log the specific textId else the global Scripts textId.
TraceLoggerThread* logger = TraceLoggerForMainThread(runtime);
if (enable)
if (enable && !traceLoggerScriptEvent_.hasPayload())
traceLoggerScriptEvent_ = TraceLoggerEvent(logger, TraceLogger_Scripts, script);
else
traceLoggerScriptEvent_ = TraceLoggerEvent(logger, TraceLogger_Scripts);
AutoWritableJitCode awjc(method());
// Enable/Disable the traceLogger prologue and epilogue.
CodeLocationLabel enter(method_, CodeOffset(traceLoggerEnterToggleOffset_));
CodeLocationLabel exit(method_, CodeOffset(traceLoggerExitToggleOffset_));
if (!engineEnabled) {
if (enable) {
Assembler::ToggleToCmp(enter);
Assembler::ToggleToCmp(exit);
} else {
Assembler::ToggleToJmp(enter);
Assembler::ToggleToJmp(exit);
}
// Enable/Disable the traceLogger.
for (size_t i = 0; i < numTraceLoggerToggleOffsets_; i++) {
CodeLocationLabel label(method_, CodeOffset(traceLoggerToggleOffsets()[i]));
if (enable)
Assembler::ToggleToCmp(label);
else
Assembler::ToggleToJmp(label);
}
#if DEBUG
@ -1025,24 +1026,19 @@ BaselineScript::toggleTraceLoggerScripts(JSRuntime* runtime, JSScript* script, b
void
BaselineScript::toggleTraceLoggerEngine(bool enable)
{
bool scriptsEnabled = TraceLogTextIdEnabled(TraceLogger_Scripts);
DebugOnly<bool> scriptsEnabled = TraceLogTextIdEnabled(TraceLogger_Scripts);
MOZ_ASSERT(enable == !traceLoggerEngineEnabled_);
MOZ_ASSERT(scriptsEnabled == traceLoggerScriptsEnabled_);
AutoWritableJitCode awjc(method());
// Enable/Disable the traceLogger prologue and epilogue.
CodeLocationLabel enter(method_, CodeOffset(traceLoggerEnterToggleOffset_));
CodeLocationLabel exit(method_, CodeOffset(traceLoggerExitToggleOffset_));
if (!scriptsEnabled) {
if (enable) {
Assembler::ToggleToCmp(enter);
Assembler::ToggleToCmp(exit);
} else {
Assembler::ToggleToJmp(enter);
Assembler::ToggleToJmp(exit);
}
for (size_t i = 0; i < numTraceLoggerToggleOffsets_; i++) {
CodeLocationLabel label(method_, CodeOffset(traceLoggerToggleOffsets()[i]));
if (enable)
Assembler::ToggleToCmp(label);
else
Assembler::ToggleToJmp(label);
}
#if DEBUG

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

@ -158,8 +158,6 @@ struct BaselineScript
bool traceLoggerScriptsEnabled_;
bool traceLoggerEngineEnabled_;
# endif
uint32_t traceLoggerEnterToggleOffset_;
uint32_t traceLoggerExitToggleOffset_;
TraceLoggerEvent traceLoggerScriptEvent_;
#endif
@ -221,6 +219,11 @@ struct BaselineScript
// instruction.
uint32_t yieldEntriesOffset_;
// By default tracelogger is disabled. Therefore we disable the logging code
// by default. We store the offsets we must patch to enable the logging.
uint32_t traceLoggerToggleOffsetsOffset_;
uint32_t numTraceLoggerToggleOffsets_;
// The total bytecode length of all scripts we inlined when we Ion-compiled
// this script. 0 if Ion did not compile this script or if we didn't inline
// anything.
@ -241,8 +244,6 @@ struct BaselineScript
BaselineScript(uint32_t prologueOffset, uint32_t epilogueOffset,
uint32_t profilerEnterToggleOffset,
uint32_t profilerExitToggleOffset,
uint32_t traceLoggerEnterToggleOffset,
uint32_t traceLoggerExitToggleOffset,
uint32_t postDebugPrologueOffset);
~BaselineScript() {
@ -255,13 +256,12 @@ struct BaselineScript
uint32_t prologueOffset, uint32_t epilogueOffset,
uint32_t profilerEnterToggleOffset,
uint32_t profilerExitToggleOffset,
uint32_t traceLoggerEnterToggleOffset,
uint32_t traceLoggerExitToggleOffset,
uint32_t postDebugPrologueOffset,
size_t icEntries,
size_t pcMappingIndexEntries, size_t pcMappingSize,
size_t bytecodeTypeMapEntries,
size_t yieldEntries);
size_t yieldEntries,
size_t traceLoggerToggleOffsetEntries);
static void Trace(JSTracer* trc, BaselineScript* script);
static void Destroy(FreeOp* fop, BaselineScript* script);
@ -433,13 +433,19 @@ struct BaselineScript
}
#ifdef JS_TRACE_LOGGING
void initTraceLogger(JSRuntime* runtime, JSScript* script);
void initTraceLogger(JSRuntime* runtime, JSScript* script, const Vector<CodeOffset>& offsets);
void toggleTraceLoggerScripts(JSRuntime* runtime, JSScript* script, bool enable);
void toggleTraceLoggerEngine(bool enable);
static size_t offsetOfTraceLoggerScriptEvent() {
return offsetof(BaselineScript, traceLoggerScriptEvent_);
}
uint32_t* traceLoggerToggleOffsets() {
MOZ_ASSERT(traceLoggerToggleOffsetsOffset_);
return reinterpret_cast<uint32_t*>(reinterpret_cast<uint8_t*>(this) +
traceLoggerToggleOffsetsOffset_);
}
#endif
void noteAccessedGetter(uint32_t pcOffset);

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

@ -787,6 +787,15 @@ HandleException(ResumeFromException* rfe)
IonScript* ionScript = nullptr;
bool invalidated = iter.checkInvalidation(&ionScript);
#ifdef JS_TRACE_LOGGING
if (logger && cx->compartment()->isDebuggee() && logger->enabled()) {
logger->disable(/* force = */ true,
"Forcefully disabled tracelogger, due to "
"throwing an exception with an active Debugger "
"in IonMonkey.");
}
#endif
for (;;) {
HandleExceptionIon(cx, frames, rfe, &overrecursed);

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

@ -770,6 +770,11 @@ FinalSuspend(JSContext* cx, HandleObject obj, BaselineFrame* frame, jsbytecode*
MOZ_ASSERT(*pc == JSOP_FINALYIELDRVAL);
if (!GeneratorObject::finalSuspend(cx, obj)) {
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
TraceLogStopEvent(logger, TraceLogger_Engine);
TraceLogStopEvent(logger, TraceLogger_Scripts);
// Leave this frame and propagate the exception to the caller.
return DebugEpilogue(cx, frame, pc, /* ok = */ false);
}

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

@ -36,8 +36,7 @@ BaselineCompilerShared::BaselineCompilerShared(JSContext* cx, TempAllocator& all
spsPushToggleOffset_(),
profilerEnterFrameToggleOffset_(),
profilerExitFrameToggleOffset_(),
traceLoggerEnterToggleOffset_(),
traceLoggerExitToggleOffset_(),
traceLoggerToggleOffsets_(cx),
traceLoggerScriptTextIdOffset_()
{ }

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

@ -65,8 +65,8 @@ class BaselineCompilerShared
CodeOffset spsPushToggleOffset_;
CodeOffset profilerEnterFrameToggleOffset_;
CodeOffset profilerExitFrameToggleOffset_;
CodeOffset traceLoggerEnterToggleOffset_;
CodeOffset traceLoggerExitToggleOffset_;
Vector<CodeOffset> traceLoggerToggleOffsets_;
CodeOffset traceLoggerScriptTextIdOffset_;
BaselineCompilerShared(JSContext* cx, TempAllocator& alloc, JSScript* script);

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

@ -118,6 +118,7 @@ MSG_DEF(JSMSG_TOO_MANY_CON_SPREADARGS, 0, JSEXN_RANGEERR, "too many constructor
MSG_DEF(JSMSG_TOO_MANY_FUN_SPREADARGS, 0, JSEXN_RANGEERR, "too many function arguments")
MSG_DEF(JSMSG_UNINITIALIZED_LEXICAL, 1, JSEXN_REFERENCEERR, "can't access lexical declaration `{0}' before initialization")
MSG_DEF(JSMSG_BAD_CONST_ASSIGN, 1, JSEXN_TYPEERR, "invalid assignment to const `{0}'")
MSG_DEF(JSMSG_CANT_DECLARE_GLOBAL_BINDING, 2, JSEXN_TYPEERR, "cannot declare global binding `{0}': {1}")
// Date
MSG_DEF(JSMSG_INVALID_DATE, 0, JSEXN_RANGEERR, "invalid date")

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

@ -81,6 +81,7 @@
#include "vm/SelfHosting.h"
#include "vm/Shape.h"
#include "vm/StopIterationObject.h"
#include "vm/String.h"
#include "vm/StringBuffer.h"
#include "vm/Symbol.h"
#include "vm/TypedArrayCommon.h"
@ -3138,17 +3139,31 @@ JS_DefineProperties(JSContext* cx, HandleObject obj, const JSPropertySpec* ps)
if (!PropertySpecNameToId(cx, ps->name, &id))
return false;
if (ps->isAccessor()) {
if (ps->isSelfHosted()) {
if (!DefineSelfHostedProperty(cx, obj, id,
ps->getter.selfHosted.funname,
ps->setter.selfHosted.funname,
ps->accessors.getter.selfHosted.funname,
ps->accessors.setter.selfHosted.funname,
ps->flags, 0))
{
return false;
}
} else {
if (!DefinePropertyById(cx, obj, id, JS::UndefinedHandleValue,
ps->getter.native, ps->setter.native, ps->flags, 0))
ps->accessors.getter.native, ps->accessors.setter.native,
ps->flags, 0))
{
return false;
}
}
} else {
RootedAtom atom(cx, Atomize(cx, ps->string.value, strlen(ps->string.value)));
if (!atom)
return false;
RootedValue v(cx, StringValue(atom));
if (!DefinePropertyById(cx, obj, id, v, NativeOpWrapper(nullptr),
NativeOpWrapper(nullptr), ps->flags & ~JSPROP_INTERNAL_USE_BIT, 0))
{
return false;
}
@ -4938,6 +4953,22 @@ JS_NewStringCopyZ(JSContext* cx, const char* s)
return NewStringCopyZ<CanGC>(cx, s);
}
JS_PUBLIC_API(JSString*)
JS_NewStringCopyUTF8Z(JSContext* cx, const JS::ConstUTF8CharsZ s)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
return NewStringCopyUTF8Z<CanGC>(cx, s);
}
JS_PUBLIC_API(JSString*)
JS_NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars s)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
return NewStringCopyUTF8N<CanGC>(cx, s);
}
JS_PUBLIC_API(bool)
JS_StringHasBeenPinned(JSContext* cx, JSString* str)
{

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

@ -27,6 +27,7 @@
#include "jspubtd.h"
#include "js/CallArgs.h"
#include "js/CharacterEncoding.h"
#include "js/Class.h"
#include "js/GCVector.h"
#include "js/HashTable.h"
@ -843,7 +844,6 @@ class MOZ_STACK_CLASS SourceBufferHolder final
object that delegates to a prototype
containing this property */
#define JSPROP_INTERNAL_USE_BIT 0x80 /* internal JS engine use only */
// 0x100 /* Unused */
#define JSFUN_STUB_GSOPS 0x200 /* use JS_PropertyStub getter/setter
instead of defaulting to class gsops
for property holding function */
@ -1874,8 +1874,15 @@ struct JSPropertySpec {
const char* funname;
};
struct StringValueWrapper {
void* unused;
const char* value;
};
const char* name;
uint8_t flags;
union {
struct {
union {
JSNativeWrapper native;
SelfHostedWrapper selfHosted;
@ -1884,8 +1891,17 @@ struct JSPropertySpec {
JSNativeWrapper native;
SelfHostedWrapper selfHosted;
} setter;
} accessors;
StringValueWrapper string;
};
bool isAccessor() const {
return !(flags & JSPROP_INTERNAL_USE_BIT);
}
bool isSelfHosted() const {
MOZ_ASSERT(isAccessor());
#ifdef DEBUG
// Verify that our accessors match our JSPROP_GETTER flag.
if (flags & JSPROP_GETTER)
@ -1904,17 +1920,17 @@ struct JSPropertySpec {
"JSNativeWrapper::info");
private:
void checkAccessorsAreNative() const {
MOZ_ASSERT(getter.native.op);
MOZ_ASSERT(accessors.getter.native.op);
// We may not have a setter at all. So all we can assert here, for the
// native case is that if we have a jitinfo for the setter then we have
// a setter op too. This is good enough to make sure we don't have a
// SelfHostedWrapper for the setter.
MOZ_ASSERT_IF(setter.native.info, setter.native.op);
MOZ_ASSERT_IF(accessors.setter.native.info, accessors.setter.native.op);
}
void checkAccessorsAreSelfHosted() const {
MOZ_ASSERT(!getter.selfHosted.unused);
MOZ_ASSERT(!setter.selfHosted.unused);
MOZ_ASSERT(!accessors.getter.selfHosted.unused);
MOZ_ASSERT(!accessors.setter.selfHosted.unused);
}
};
@ -1963,37 +1979,46 @@ inline int CheckIsSetterOp(JSSetterOp op);
#define JS_STUBSETTER JS_PROPERTYOP_SETTER(JS_StrictPropertyStub)
#define JS_PS_ACCESSOR_SPEC(name, getter, setter, flags, extraFlags) \
{ name, uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | extraFlags), \
{ { getter, setter } } }
#define JS_PS_STRINGVALUE_SPEC(name, value, flags) \
{ name, uint8_t(flags | JSPROP_INTERNAL_USE_BIT), \
{ { STRINGVALUE_WRAPPER(value), JSNATIVE_WRAPPER(nullptr) } } }
#define SELFHOSTED_WRAPPER(name) \
{ { nullptr, JS_CAST_STRING_TO(name, const JSJitInfo*) } }
#define STRINGVALUE_WRAPPER(value) \
{ { nullptr, JS_CAST_STRING_TO(value, const JSJitInfo*) } }
/*
* JSPropertySpec uses JSNativeWrapper. These macros encapsulate the definition
* of JSNative-backed JSPropertySpecs, by defining the JSNativeWrappers for
* them.
*/
#define JS_PSG(name, getter, flags) \
{name, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED), \
JSNATIVE_WRAPPER(getter), \
JSNATIVE_WRAPPER(nullptr)}
JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(nullptr), flags, \
JSPROP_SHARED)
#define JS_PSGS(name, getter, setter, flags) \
{name, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED), \
JSNATIVE_WRAPPER(getter), \
JSNATIVE_WRAPPER(setter)}
JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(setter), flags, \
JSPROP_SHARED)
#define JS_SELF_HOSTED_GET(name, getterName, flags) \
{name, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER), \
{ { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo*) } }, \
JSNATIVE_WRAPPER(nullptr) }
JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \
JSPROP_SHARED | JSPROP_GETTER)
#define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \
{name, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER), \
{ nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo*) }, \
{ nullptr, JS_CAST_STRING_TO(setterName, const JSJitInfo*) } }
#define JS_PS_END { nullptr, 0, JSNATIVE_WRAPPER(nullptr), JSNATIVE_WRAPPER(nullptr) }
JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), SELFHOSTED_WRAPPER(setterName), \
flags, JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER)
#define JS_SELF_HOSTED_SYM_GET(symbol, getterName, flags) \
{reinterpret_cast<const char*>(uint32_t(::JS::SymbolCode::symbol) + 1), \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER), \
{ { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo*) } }, \
JSNATIVE_WRAPPER(nullptr) }
JS_PS_ACCESSOR_SPEC(reinterpret_cast<const char*>(uint32_t(::JS::SymbolCode::symbol) + 1), \
SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \
JSPROP_SHARED | JSPROP_GETTER)
#define JS_STRING_PS(name, string, flags) \
JS_PS_STRINGVALUE_SPEC(name, string, flags)
#define JS_STRING_SYM_PS(symbol, string, flags) \
JS_PS_STRINGVALUE_SPEC(reinterpret_cast<const char*>(uint32_t(::JS::SymbolCode::symbol) + 1), \
string, flags)
#define JS_PS_END \
JS_PS_ACCESSOR_SPEC(nullptr, JSNATIVE_WRAPPER(nullptr), JSNATIVE_WRAPPER(nullptr), 0, 0)
/**
* To define a native function, set call to a JSNativeWrapper. To define a
@ -4615,6 +4640,12 @@ JS_NewStringCopyN(JSContext* cx, const char* s, size_t n);
extern JS_PUBLIC_API(JSString*)
JS_NewStringCopyZ(JSContext* cx, const char* s);
extern JS_PUBLIC_API(JSString*)
JS_NewStringCopyUTF8Z(JSContext* cx, const JS::ConstUTF8CharsZ s);
extern JS_PUBLIC_API(JSString*)
JS_NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars s);
extern JS_PUBLIC_API(JSString*)
JS_AtomizeAndPinJSString(JSContext* cx, JS::HandleString str);
@ -5803,6 +5834,7 @@ enum AsmJSCacheResult
AsmJSCache_Disabled_ShellFlags,
AsmJSCache_Disabled_JitInspector,
AsmJSCache_InternalError,
AsmJSCache_Disabled_PrivateBrowsing,
AsmJSCache_LIMIT
};

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

@ -74,9 +74,6 @@ JS_ObjectCountDynamicSlots(JS::HandleObject obj);
extern JS_FRIEND_API(size_t)
JS_SetProtoCalled(JSContext* cx);
extern JS_FRIEND_API(bool)
JS_ImmutablePrototypesEnabled();
extern JS_FRIEND_API(size_t)
JS_GetCustomIteratorCount(JSContext* cx);

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

@ -2493,20 +2493,6 @@ js::GetPrototypeIfOrdinary(JSContext* cx, HandleObject obj, bool* isOrdinary,
return true;
}
// Our immutable-prototype behavior is non-standard, and it's unclear whether
// it's shippable. (Or at least it's unclear whether it's shippable with any
// provided-by-default uses exposed to script.) If this bool is true,
// immutable-prototype behavior is enforced; if it's false, behavior is not
// enforced, and immutable-prototype bits stored on objects are completely
// ignored.
static const bool ImmutablePrototypesEnabled = true;
JS_FRIEND_API(bool)
JS_ImmutablePrototypesEnabled()
{
return ImmutablePrototypesEnabled;
}
/*** ES6 standard internal methods ***************************************************************/
bool
@ -2527,7 +2513,7 @@ js::SetPrototype(JSContext* cx, HandleObject obj, HandleObject proto, JS::Object
return result.succeed();
/* Disallow mutation of immutable [[Prototype]]s. */
if (obj->staticPrototypeIsImmutable() && ImmutablePrototypesEnabled)
if (obj->staticPrototypeIsImmutable())
return result.fail(JSMSG_CANT_SET_PROTO);
/*
@ -2550,16 +2536,6 @@ js::SetPrototype(JSContext* cx, HandleObject obj, HandleObject proto, JS::Object
return false;
}
/*
* Explicitly disallow mutating the [[Prototype]] of Location objects
* for flash-related security reasons.
*/
if (!strcmp(obj->getClass()->name, "Location")) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_SET_PROTO_OF,
"incompatible Location object");
return false;
}
/* ES6 9.1.2 step 5 forbids changing [[Prototype]] if not [[Extensible]]. */
bool extensible;
if (!IsExtensible(cx, obj, &extensible))

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

@ -1179,6 +1179,8 @@ ExpressionDecompiler::decompilePC(jsbytecode* pc)
case JSOP_GETARG: {
unsigned slot = GET_ARGNO(pc);
JSAtom* atom = getArg(slot);
if (!atom)
return false;
return write(atom);
}
case JSOP_GETLOCAL: {

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

@ -6360,8 +6360,10 @@ static const JSJitInfo doFoo_methodinfo = {
static const JSPropertySpec dom_props[] = {
{"x",
JSPROP_SHARED | JSPROP_ENUMERATE,
{ {
{ { dom_genericGetter, &dom_x_getterinfo } },
{ { dom_genericSetter, &dom_x_setterinfo } }
} },
},
JS_PS_END
};

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

@ -0,0 +1,10 @@
try {
eval("var shouldNotBeDefined1; function NaN(){}; var shouldNotBeDefined2;");
} catch (e) {
}
assertEq(Object.getOwnPropertyDescriptor(this, 'shouldNotBeDefined2'), undefined);
assertEq(Object.getOwnPropertyDescriptor(this, 'shouldNotBeDefined1'), undefined);
if (typeof reportCompare === "function")
reportCompare(true, true);

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

@ -147,7 +147,6 @@ testDefault(function* () {}.constructor.prototype, "GeneratorFunction");
testDefault(function* () {}().__proto__.__proto__, "Generator");
// ES6 25.4.5.4 Promise.prototype [ @@toStringTag ]
// testDefault(Promise.prototype, "Promise");
// Promise is not yet implemented.
testDefault(Promise.prototype, "Promise");
reportCompare(true, true);

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

@ -36,13 +36,6 @@ if (typeof setImmutablePrototype !== "function")
}
}
if (typeof immutablePrototypesEnabled !== "function" &&
typeof SpecialPowers !== "undefined")
{
immutablePrototypesEnabled =
SpecialPowers.Cu.getJSTestingFunctions().immutablePrototypesEnabled;
}
if (typeof wrap !== "function")
{
// good enough
@ -93,9 +86,7 @@ function checkPrototypeMutationFailure(obj, desc)
function runNormalTests(global)
{
if (typeof setImmutablePrototype !== "function" ||
typeof immutablePrototypesEnabled !== "function" ||
!immutablePrototypesEnabled())
if (typeof setImmutablePrototype !== "function")
{
print("no testable setImmutablePrototype function available, skipping tests");
return;

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

@ -8,6 +8,9 @@
#include "mozilla/Range.h"
#include <algorithm>
#include <type_traits>
#include "jscntxt.h"
#include "jsprf.h"
@ -250,22 +253,30 @@ enum InflateUTF8Action {
CountAndReportInvalids,
CountAndIgnoreInvalids,
AssertNoInvalids,
Copy
Copy,
FindEncoding
};
static const uint32_t REPLACE_UTF8 = 0xFFFD;
static const char16_t REPLACE_UTF8 = 0xFFFD;
static const Latin1Char REPLACE_UTF8_LATIN1 = '?';
// If making changes to this algorithm, make sure to also update
// LossyConvertUTF8toUTF16() in dom/wifi/WifiUtils.cpp
template <InflateUTF8Action Action>
template <InflateUTF8Action Action, typename CharT>
static bool
InflateUTF8StringToBuffer(JSContext* cx, const UTF8Chars src, char16_t* dst, size_t* dstlenp,
bool* isAsciip)
InflateUTF8StringToBuffer(JSContext* cx, const UTF8Chars src, CharT* dst, size_t* dstlenp,
JS::SmallestEncoding *smallestEncoding)
{
if (Action != AssertNoInvalids)
*isAsciip = true;
*smallestEncoding = JS::SmallestEncoding::ASCII;
auto RequireLatin1 = [&smallestEncoding]{
*smallestEncoding = std::max(JS::SmallestEncoding::Latin1, *smallestEncoding);
};
auto RequireUTF16 = [&smallestEncoding]{
*smallestEncoding = JS::SmallestEncoding::UTF16;
};
// Count how many char16_t characters need to be in the inflated string.
// Count how many code units need to be in the inflated string.
// |i| is the index into |src|, and |j| is the the index into |dst|.
size_t srclen = src.length();
uint32_t j = 0;
@ -274,12 +285,10 @@ InflateUTF8StringToBuffer(JSContext* cx, const UTF8Chars src, char16_t* dst, siz
if (!(v & 0x80)) {
// ASCII code unit. Simple copy.
if (Action == Copy)
dst[j] = char16_t(v);
dst[j] = CharT(v);
} else {
// Non-ASCII code unit. Determine its length in bytes (n).
if (Action != AssertNoInvalids)
*isAsciip = false;
uint32_t n = 1;
while (v & (0x80 >> n))
n++;
@ -292,10 +301,15 @@ InflateUTF8StringToBuffer(JSContext* cx, const UTF8Chars src, char16_t* dst, siz
} else if (Action == AssertNoInvalids) { \
MOZ_CRASH("invalid UTF-8 string: " # report); \
} else { \
if (Action == Copy) \
dst[j] = char16_t(REPLACE_UTF8); \
if (Action == Copy) { \
if (std::is_same<decltype(dst[0]), Latin1Char>::value) \
dst[j] = CharT(REPLACE_UTF8_LATIN1); \
else \
MOZ_ASSERT(Action == CountAndIgnoreInvalids); \
dst[j] = CharT(REPLACE_UTF8); \
} else { \
MOZ_ASSERT(Action == CountAndIgnoreInvalids || \
Action == FindEncoding); \
} \
n = n2; \
goto invalidMultiByteCodeUnit; \
} \
@ -320,29 +334,40 @@ InflateUTF8StringToBuffer(JSContext* cx, const UTF8Chars src, char16_t* dst, siz
}
// Check the continuation bytes.
for (uint32_t m = 1; m < n; m++)
for (uint32_t m = 1; m < n; m++) {
if ((src[i + m] & 0xC0) != 0x80)
INVALID(ReportInvalidCharacter, i, m);
}
// Determine the code unit's length in char16_t and act accordingly.
// Determine the code unit's length in CharT and act accordingly.
v = JS::Utf8ToOneUcs4Char((uint8_t*)&src[i], n);
if (Action != AssertNoInvalids) {
if (v > 0xff) {
RequireUTF16();
if (Action == FindEncoding) {
MOZ_ASSERT(dst == nullptr);
return true;
}
} else {
RequireLatin1();
}
}
if (v < 0x10000) {
// The n-byte UTF8 code unit will fit in a single char16_t.
// The n-byte UTF8 code unit will fit in a single CharT.
if (Action == Copy)
dst[j] = char16_t(v);
dst[j] = CharT(v);
} else {
v -= 0x10000;
if (v <= 0xFFFFF) {
// The n-byte UTF8 code unit will fit in two char16_t units.
// The n-byte UTF8 code unit will fit in two CharT units.
if (Action == Copy)
dst[j] = char16_t((v >> 10) + 0xD800);
dst[j] = CharT((v >> 10) + 0xD800);
j++;
if (Action == Copy)
dst[j] = char16_t((v & 0x3FF) + 0xDC00);
dst[j] = CharT((v & 0x3FF) + 0xDC00);
} else {
// The n-byte UTF8 code unit won't fit in two char16_t units.
// The n-byte UTF8 code unit won't fit in two CharT units.
INVALID(ReportTooBigCharacter, v, 1);
}
}
@ -352,70 +377,97 @@ InflateUTF8StringToBuffer(JSContext* cx, const UTF8Chars src, char16_t* dst, siz
// header will do the final i++ to move to the start of the next
// code unit.
i += n - 1;
if (Action != AssertNoInvalids)
RequireUTF16();
}
}
if (Action != AssertNoInvalids)
if (Action != AssertNoInvalids || Action != FindEncoding)
*dstlenp = j;
return true;
}
template <InflateUTF8Action Action>
static TwoByteCharsZ
template <InflateUTF8Action Action, typename CharsT>
static CharsT
InflateUTF8StringHelper(JSContext* cx, const UTF8Chars src, size_t* outlen)
{
using CharT = typename CharsT::CharT;
*outlen = 0;
bool isAscii;
if (!InflateUTF8StringToBuffer<Action>(cx, src, /* dst = */ nullptr, outlen, &isAscii))
return TwoByteCharsZ();
JS::SmallestEncoding encoding;
if (!InflateUTF8StringToBuffer<Action, CharT>(cx, src, /* dst = */ nullptr, outlen, &encoding))
return CharsT();
char16_t* dst = cx->pod_malloc<char16_t>(*outlen + 1); // +1 for NUL
CharT* dst = cx->pod_malloc<CharT>(*outlen + 1); // +1 for NUL
if (!dst) {
ReportOutOfMemory(cx);
return TwoByteCharsZ();
return CharsT();
}
if (isAscii) {
if (encoding == JS::SmallestEncoding::ASCII) {
size_t srclen = src.length();
MOZ_ASSERT(*outlen == srclen);
for (uint32_t i = 0; i < srclen; i++)
dst[i] = char16_t(src[i]);
dst[i] = CharT(src[i]);
} else {
JS_ALWAYS_TRUE(InflateUTF8StringToBuffer<Copy>(cx, src, dst, outlen, &isAscii));
MOZ_ALWAYS_TRUE((InflateUTF8StringToBuffer<Copy, CharT>(cx, src, dst, outlen, &encoding)));
}
dst[*outlen] = 0; // NUL char
return TwoByteCharsZ(dst, *outlen);
return CharsT(dst, *outlen);
}
TwoByteCharsZ
JS::UTF8CharsToNewTwoByteCharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen)
{
return InflateUTF8StringHelper<CountAndReportInvalids>(cx, utf8, outlen);
return InflateUTF8StringHelper<CountAndReportInvalids, TwoByteCharsZ>(cx, utf8, outlen);
}
TwoByteCharsZ
JS::UTF8CharsToNewTwoByteCharsZ(JSContext* cx, const ConstUTF8CharsZ& utf8, size_t* outlen)
{
UTF8Chars chars(utf8.c_str(), strlen(utf8.c_str()));
return InflateUTF8StringHelper<CountAndReportInvalids>(cx, chars, outlen);
return InflateUTF8StringHelper<CountAndReportInvalids, TwoByteCharsZ>(cx, chars, outlen);
}
TwoByteCharsZ
JS::LossyUTF8CharsToNewTwoByteCharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen)
{
return InflateUTF8StringHelper<CountAndIgnoreInvalids>(cx, utf8, outlen);
return InflateUTF8StringHelper<CountAndIgnoreInvalids, TwoByteCharsZ>(cx, utf8, outlen);
}
TwoByteCharsZ
JS::LossyUTF8CharsToNewTwoByteCharsZ(JSContext* cx, const ConstUTF8CharsZ& utf8, size_t* outlen)
{
UTF8Chars chars(utf8.c_str(), strlen(utf8.c_str()));
return InflateUTF8StringHelper<CountAndIgnoreInvalids>(cx, chars, outlen);
return InflateUTF8StringHelper<CountAndIgnoreInvalids, TwoByteCharsZ>(cx, chars, outlen);
}
JS::SmallestEncoding
JS::FindSmallestEncoding(UTF8Chars utf8)
{
JS::SmallestEncoding encoding;
MOZ_ALWAYS_TRUE((InflateUTF8StringToBuffer<FindEncoding, char16_t>(
/* cx = */ nullptr,
utf8,
/* dst = */ nullptr,
/* dstlen = */ nullptr,
&encoding)));
return encoding;
}
Latin1CharsZ
JS::UTF8CharsToNewLatin1CharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen)
{
return InflateUTF8StringHelper<CountAndReportInvalids, Latin1CharsZ>(cx, utf8, outlen);
}
Latin1CharsZ
JS::LossyUTF8CharsToNewLatin1CharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen)
{
return InflateUTF8StringHelper<CountAndIgnoreInvalids, Latin1CharsZ>(cx, utf8, outlen);
}
#ifdef DEBUG
@ -424,6 +476,7 @@ JS::ConstUTF8CharsZ::validate(size_t aLength)
{
MOZ_ASSERT(data_);
UTF8Chars chars(data_, aLength);
InflateUTF8StringToBuffer<AssertNoInvalids>(nullptr, chars, nullptr, nullptr, nullptr);
InflateUTF8StringToBuffer<AssertNoInvalids, char16_t>(nullptr, chars, nullptr, nullptr,
nullptr);
}
#endif

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

@ -650,6 +650,17 @@ Debugger::Debugger(JSContext* cx, NativeObject* dbg)
JS_INIT_CLIST(&breakpoints);
JS_INIT_CLIST(&onNewGlobalObjectWatchersLink);
#ifdef JS_TRACE_LOGGING
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
if (logger) {
#ifdef NIGHTLY_BUILD
logger->getIterationAndSize(&traceLoggerLastDrainedIteration, &traceLoggerLastDrainedSize);
#endif
logger->getIterationAndSize(&traceLoggerScriptedCallsLastDrainedIteration,
&traceLoggerScriptedCallsLastDrainedSize);
}
#endif
}
Debugger::~Debugger()
@ -5056,7 +5067,14 @@ Debugger::drainTraceLoggerScriptCalls(JSContext* cx, unsigned argc, Value* vp)
if (!item)
return false;
// Filter out internal time.
uint32_t textId = eventItem->textId;
if (textId == TraceLogger_Internal) {
eventItem++;
MOZ_ASSERT(eventItem->textId == TraceLogger_Stop);
continue;
}
if (textId != TraceLogger_Stop && !logger->textIdIsScriptEvent(textId))
continue;

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

@ -1375,28 +1375,27 @@ class DebugEnvironmentProxyHandler : public BaseProxyHandler
};
/*
* This function handles access to unaliased locals/formals. Since they are
* unaliased, the values of these variables are not stored in the slots of
* the normal Call/ClonedBlockObject scope objects and thus must be
* recovered from somewhere else:
* + if the invocation for which the scope was created is still executing,
* This function handles access to unaliased locals/formals. Since they
* are unaliased, the values of these variables are not stored in the
* slots of the normal CallObject and LexicalEnvironmentObject
* environments and thus must be recovered from somewhere else:
* + if the invocation for which the env was created is still executing,
* there is a JS frame live on the stack holding the values;
* + if the invocation for which the scope was created finished executing:
* - and there was a DebugEnvironmentProxy associated with scope, then the
* DebugEnvironments::onPop(Call|Block) handler copied out the unaliased
* variables:
* . for block scopes, the unaliased values were copied directly
* into the block object, since there is a slot allocated for every
* block binding, regardless of whether it is aliased;
* . for function scopes, a dense array is created in onPopCall to hold
* the unaliased values and attached to the DebugEnvironmentProxy;
* + if the invocation for which the env was created finished executing:
* - and there was a DebugEnvironmentProxy associated with env, then
* the DebugEnvironments::onPop(Call|Lexical) handler copied out the
* unaliased variables. In both cases, a dense array is created in
* onPop(Call|Lexical) to hold the unaliased values and attached to
* the DebugEnvironmentProxy;
* - and there was not a DebugEnvironmentProxy yet associated with the
* scope, then the unaliased values are lost and not recoverable.
*
* Callers should check accessResult for non-failure results:
* - ACCESS_UNALIASED if the access was unaliased and completed
* - ACCESS_GENERIC if the access was aliased or the property not found
* - ACCESS_LOST if the value has been lost to the debugger
* - ACCESS_LOST if the value has been lost to the debugger and the
* action is GET; if the action is SET, we assign to the
* name of the variable on the environment object
*/
bool handleUnaliasedAccess(JSContext* cx, Handle<DebugEnvironmentProxy*> debugEnv,
Handle<EnvironmentObject*> env, HandleId id, Action action,
@ -1532,6 +1531,7 @@ class DebugEnvironmentProxyHandler : public BaseProxyHandler
// Named lambdas that are not closed over are lost.
if (loc.kind() == BindingLocation::Kind::NamedLambdaCallee) {
if (action == GET)
*accessResult = ACCESS_LOST;
return true;
}
@ -2031,8 +2031,7 @@ class DebugEnvironmentProxyHandler : public BaseProxyHandler
switch (access) {
case ACCESS_UNALIASED:
return result.succeed();
case ACCESS_GENERIC:
{
case ACCESS_GENERIC: {
RootedValue envVal(cx, ObjectValue(*env));
return SetProperty(cx, env, id, v, envVal, result);
}
@ -3182,6 +3181,59 @@ js::CheckVarNameConflict(JSContext* cx, Handle<LexicalEnvironmentObject*> lexica
return true;
}
static void
ReportCannotDeclareGlobalBinding(JSContext* cx, HandlePropertyName name, const char* reason)
{
JSAutoByteString printable;
if (AtomToPrintableString(cx, name, &printable)) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
JSMSG_CANT_DECLARE_GLOBAL_BINDING,
printable.ptr(), reason);
}
}
bool
js::CheckCanDeclareGlobalBinding(JSContext* cx, Handle<GlobalObject*> global,
HandlePropertyName name, bool isFunction)
{
RootedId id(cx, NameToId(name));
Rooted<PropertyDescriptor> desc(cx);
if (!GetOwnPropertyDescriptor(cx, global, id, &desc))
return false;
// ES 8.1.14.15 CanDeclareGlobalVar
// ES 8.1.14.16 CanDeclareGlobalFunction
// Step 4.
if (!desc.object()) {
// 8.1.14.15 step 6.
// 8.1.14.16 step 5.
if (global->nonProxyIsExtensible())
return true;
ReportCannotDeclareGlobalBinding(cx, name, "global is non-extensible");
return false;
}
// Global functions have additional restrictions.
if (isFunction) {
// 8.1.14.16 step 6.
if (desc.configurable())
return true;
// 8.1.14.16 step 7.
if (desc.isDataDescriptor() && desc.writable() && desc.enumerable())
return true;
ReportCannotDeclareGlobalBinding(cx, name,
"property must be configurable or "
"both writable and enumerable");
return false;
}
return true;
}
bool
js::CheckGlobalDeclarationConflicts(JSContext* cx, HandleScript script,
Handle<LexicalEnvironmentObject*> lexicalEnv,
@ -3196,14 +3248,32 @@ js::CheckGlobalDeclarationConflicts(JSContext* cx, HandleScript script,
RootedPropertyName name(cx);
Rooted<BindingIter> bi(cx, BindingIter(script));
// ES 15.1.11 GlobalDeclarationInstantiation
// Step 6.
//
// Check 'var' declarations do not conflict with existing bindings in the
// global lexical environment.
for (; bi; bi++) {
if (bi.kind() != BindingKind::Var)
break;
name = bi.name()->asPropertyName();
if (!CheckVarNameConflict(cx, lexicalEnv, name))
return false;
// Step 10 and 12.
//
// Check that global functions and vars may be declared.
if (varObj->is<GlobalObject>()) {
Handle<GlobalObject*> global = varObj.as<GlobalObject>();
if (!CheckCanDeclareGlobalBinding(cx, global, name, bi.isTopLevelFunction()))
return false;
}
}
// Step 5.
//
// Check that lexical bindings do not conflict.
for (; bi; bi++) {
name = bi.name()->asPropertyName();
if (!CheckLexicalNameConflict(cx, lexicalEnv, varObj, name))
@ -3256,7 +3326,9 @@ js::CheckEvalDeclarationConflicts(JSContext* cx, HandleScript script,
RootedObject obj(cx, scopeChain);
// ES6 18.2.1.2 step d
// ES 18.2.1.3.
// Step 5.
//
// Check that a direct eval will not hoist 'var' bindings over lexical
// bindings with the same name.
@ -3266,6 +3338,19 @@ js::CheckEvalDeclarationConflicts(JSContext* cx, HandleScript script,
obj = obj->enclosingEnvironment();
}
// Step 8.
//
// Check that global functions may be declared.
if (varObj->is<GlobalObject>()) {
Handle<GlobalObject*> global = varObj.as<GlobalObject>();
RootedPropertyName name(cx);
for (Rooted<BindingIter> bi(cx, BindingIter(script)); bi; bi++) {
name = bi.name()->asPropertyName();
if (!CheckCanDeclareGlobalBinding(cx, global, name, bi.isTopLevelFunction()))
return false;
}
}
return true;
}

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