зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-i to m-c, a=merge
This commit is contained in:
Коммит
400813c30b
2
CLOBBER
2
CLOBBER
|
@ -22,4 +22,4 @@
|
|||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Merge day clobber
|
||||
Bug 1280590 - xpcshell failure in windows7
|
||||
|
|
|
@ -484,6 +484,59 @@ EventTree::Mutated(AccMutationEvent* aEv)
|
|||
Accessible* cntr = (*node)->mContainer;
|
||||
while (cntr != mContainer) {
|
||||
if (cntr == aEv->mAccessible) {
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eEventTree)) {
|
||||
logging::MsgBegin("EVENTS_TREE", "Trim subtree");
|
||||
logging::AccessibleInfo("Show/hide container", aEv->mAccessible);
|
||||
logging::AccessibleInfo("Trimmed subtree root", (*node)->mContainer);
|
||||
logging::MsgEnd();
|
||||
}
|
||||
#endif
|
||||
|
||||
// If the new hide is part of a move and it contains existing child
|
||||
// shows, then move preceding events from the child shows to the buffer,
|
||||
// so the ongoing show event will pick them up.
|
||||
if (aEv->IsHide()) {
|
||||
AccHideEvent* hideEv = downcast_accEvent(aEv);
|
||||
if (!hideEv->mNeedsShutdown) {
|
||||
for (uint32_t i = 0; i < (*node)->mDependentEvents.Length(); i++) {
|
||||
AccMutationEvent* childEv = (*node)->mDependentEvents[i];
|
||||
if (childEv->IsShow()) {
|
||||
AccShowEvent* childShowEv = downcast_accEvent(childEv);
|
||||
if (childShowEv->mPrecedingEvents.Length() > 0) {
|
||||
Controller(mContainer)->StorePrecedingEvents(
|
||||
mozilla::Move(childShowEv->mPrecedingEvents));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the new show contains existing child shows, then move preceding
|
||||
// events from the child shows to the new show.
|
||||
else if (aEv->IsShow()) {
|
||||
AccShowEvent* showEv = downcast_accEvent(aEv);
|
||||
for (uint32_t i = 0; (*node)->mDependentEvents.Length(); i++) {
|
||||
AccMutationEvent* childEv = (*node)->mDependentEvents[i];
|
||||
if (childEv->IsShow()) {
|
||||
AccShowEvent* showChildEv = downcast_accEvent(childEv);
|
||||
if (showChildEv->mPrecedingEvents.Length() > 0) {
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eEventTree)) {
|
||||
logging::MsgBegin("EVENTS_TREE", "Adopt preceding events");
|
||||
logging::AccessibleInfo("Parent", aEv->mAccessible);
|
||||
for (uint32_t j = 0; j < showChildEv->mPrecedingEvents.Length(); j++) {
|
||||
logging::AccessibleInfo("Adoptee",
|
||||
showChildEv->mPrecedingEvents[i]->mAccessible);
|
||||
}
|
||||
logging::MsgEnd();
|
||||
}
|
||||
#endif
|
||||
showEv->mPrecedingEvents.AppendElements(showChildEv->mPrecedingEvents);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*node = Move((*node)->mNext);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -558,6 +558,52 @@
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Move 't9_c2_moved' node by aria-owns, and then move 't9_c3_moved' node
|
||||
* under 't9_c2_moved' (same as test9 but has different aria-owns
|
||||
* ordering), the eventing looks same way as in test9:
|
||||
* reorder for 't9_c1'
|
||||
* hide for 't9_c1_child'
|
||||
* show for 't9_c2_moved'
|
||||
* reorder for 't9_c2'
|
||||
* hide for 't9_c2_moved'
|
||||
* reorder for 't9_c3'
|
||||
* hide for 't9_c3_moved'
|
||||
*
|
||||
* The hide events for 't9_c2_moved' and 't9_c3_moved' should be delivered
|
||||
* before the show event for 't9_c2_moved'.
|
||||
*/
|
||||
function test9()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getNode('t9_c1_child')),
|
||||
new invokerChecker(EVENT_HIDE, 't9_c3_moved'),
|
||||
new invokerChecker(EVENT_HIDE, 't9_c2_moved'),
|
||||
new invokerChecker(EVENT_SHOW, 't9_c2_moved'),
|
||||
new invokerChecker(EVENT_REORDER, 't9_c1'),
|
||||
new invokerChecker(EVENT_HIDE, getNode('t9_c2_child')),
|
||||
new invokerChecker(EVENT_REORDER, 't9_c2'),
|
||||
new invokerChecker(EVENT_REORDER, 't9_c3'),
|
||||
new unexpectedInvokerChecker(EVENT_SHOW, 't9_c3_moved')
|
||||
];
|
||||
|
||||
this.invoke = function test9_invoke()
|
||||
{
|
||||
// Remove child nodes from 't9_c1' and 't9_c2' containers to give
|
||||
// the event tree a needed structure ('t9_c1' and 't9_c2' nodes go
|
||||
// first in the event tree),
|
||||
getNode('t9_c1_child').remove();
|
||||
getNode('t9_c2_child').remove();
|
||||
// then do aria-owns magic.
|
||||
getNode('t9_c2_moved').setAttribute('aria-owns', 't9_c3_moved');
|
||||
getNode('t9_c1').setAttribute('aria-owns', 't9_c2_moved');
|
||||
};
|
||||
|
||||
this.getID = function test9_getID() {
|
||||
return "Move node #1 by aria-owns and then move node #2 into node #1";
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests.
|
||||
|
||||
|
@ -592,6 +638,7 @@
|
|||
gQueue.push(new test6());
|
||||
gQueue.push(new test7());
|
||||
gQueue.push(new test8());
|
||||
gQueue.push(new test9());
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
@ -699,5 +746,16 @@
|
|||
<div id="t8_c2_moved"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="t9">
|
||||
<div id="t9_c1"><div id="t9_c1_child"></div></div>
|
||||
<div id="t9_c2">
|
||||
<div id="t9_c2_child"></div>
|
||||
<div id="t9_c2_moved"></div>
|
||||
</div>
|
||||
<div id="t9_c3">
|
||||
<div id="t9_c3_moved"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -106,8 +106,10 @@ exports.close = close
|
|||
function resize(panel, width, height) {
|
||||
// Resize the iframe instead of using panel.sizeTo
|
||||
// because sizeTo doesn't work with arrow panels
|
||||
panel.firstChild.style.width = width + "px";
|
||||
panel.firstChild.style.height = height + "px";
|
||||
if (panel.firstChild) {
|
||||
panel.firstChild.style.width = width + "px";
|
||||
panel.firstChild.style.height = height + "px";
|
||||
}
|
||||
}
|
||||
exports.resize = resize
|
||||
|
||||
|
@ -187,12 +189,14 @@ function display(panel, options, anchor) {
|
|||
panel.setAttribute("flip", "both");
|
||||
}
|
||||
|
||||
panel.viewFrame = document.importNode(panel.backgroundFrame, false);
|
||||
panel.appendChild(panel.viewFrame);
|
||||
if (!panel.viewFrame) {
|
||||
panel.viewFrame = document.importNode(panel.backgroundFrame, false);
|
||||
panel.appendChild(panel.viewFrame);
|
||||
|
||||
let {privateBrowsingId} = getDocShell(panel.viewFrame).getOriginAttributes();
|
||||
let principal = Services.scriptSecurityManager.createNullPrincipal({privateBrowsingId});
|
||||
getDocShell(panel.viewFrame).createAboutBlankContentViewer(principal);
|
||||
let {privateBrowsingId} = getDocShell(panel.viewFrame).getOriginAttributes();
|
||||
let principal = Services.scriptSecurityManager.createNullPrincipal({privateBrowsingId});
|
||||
getDocShell(panel.viewFrame).createAboutBlankContentViewer(principal);
|
||||
}
|
||||
|
||||
// Resize the iframe instead of using panel.sizeTo
|
||||
// because sizeTo doesn't work with arrow panels
|
||||
|
|
|
@ -254,6 +254,10 @@ exports["test Resize Panel"] = function(assert, done) {
|
|||
height: 10,
|
||||
width: 10,
|
||||
onMessage: function (message) {
|
||||
// Make sure that attempting to resize a panel while it isn't
|
||||
// visible doesn't cause an error.
|
||||
panel.resize(1, 1);
|
||||
|
||||
panel.show();
|
||||
},
|
||||
onShow: function () {
|
||||
|
@ -335,7 +339,7 @@ exports["test Several Show Hides"] = function(assert, done) {
|
|||
panel.show();
|
||||
};
|
||||
|
||||
exports["test Anchor And Arrow"] = function(assert, done) {
|
||||
exports["test Anchor And Arrow"] = function*(assert, done) {
|
||||
let { loader } = LoaderWithHookedConsole(module, ignorePassingDOMNodeWarning);
|
||||
let { Panel } = loader.require('sdk/panel');
|
||||
|
||||
|
|
|
@ -153,10 +153,8 @@ CustomizeMode.prototype = {
|
|||
let lwthemeButton = aDocument.getElementById("customization-lwtheme-button");
|
||||
let lwthemeIcon = aDocument.getAnonymousElementByAttribute(lwthemeButton,
|
||||
"class", "button-icon");
|
||||
let imageURL = LightweightThemeManager.currentTheme === null ?
|
||||
"chrome://browser/skin/theme-switcher-icon.png" :
|
||||
LightweightThemeManager.currentTheme.iconURL;
|
||||
lwthemeIcon.style.backgroundImage = "url(" + imageURL + ")";
|
||||
lwthemeIcon.style.backgroundImage = LightweightThemeManager.currentTheme ?
|
||||
"url(" + LightweightThemeManager.currentTheme.iconURL + ")" : "";
|
||||
},
|
||||
|
||||
setTab: function(aTab) {
|
||||
|
|
|
@ -115,6 +115,7 @@ var SessionCookiesInternal = {
|
|||
* Restores a given list of session cookies.
|
||||
*/
|
||||
restore(cookies) {
|
||||
|
||||
for (let cookie of cookies) {
|
||||
let expiry = "expiry" in cookie ? cookie.expiry : MAX_EXPIRY;
|
||||
let cookieObj = {
|
||||
|
@ -122,7 +123,7 @@ var SessionCookiesInternal = {
|
|||
path: cookie.path || "",
|
||||
name: cookie.name || ""
|
||||
};
|
||||
if (!Services.cookies.cookieExists(cookieObj)) {
|
||||
if (!Services.cookies.cookieExists(cookieObj, cookie.originAttributes || {})) {
|
||||
Services.cookies.add(cookie.host, cookie.path || "", cookie.name || "",
|
||||
cookie.value, !!cookie.secure, !!cookie.httponly,
|
||||
/* isSession = */ true, expiry, cookie.originAttributes || {});
|
||||
|
|
|
@ -9,6 +9,9 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
|||
Cu.import("resource://gre/modules/Preferences.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/UpdateUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/TelemetryArchive.jsm");
|
||||
Cu.import("resource://gre/modules/TelemetryController.jsm");
|
||||
|
||||
// The amount of people to be part of e10s
|
||||
const TEST_THRESHOLD = {
|
||||
|
@ -30,6 +33,9 @@ const PREF_TOGGLE_E10S = "browser.tabs.remote.autostart.2";
|
|||
const PREF_E10S_ADDON_POLICY = "extensions.e10s.rollout.policy";
|
||||
const PREF_E10S_ADDON_BLOCKLIST = "extensions.e10s.rollout.blocklist";
|
||||
const PREF_E10S_HAS_NONEXEMPT_ADDON = "extensions.e10s.rollout.hasAddon";
|
||||
const PREF_DISABLED_FOR_SPINNERS = "e10s.rollout.disabledByLongSpinners";
|
||||
|
||||
const LONG_SPINNER_HISTOGRAM = "FX_TAB_SWITCH_SPINNER_VISIBLE_LONG_MS";
|
||||
|
||||
function startup() {
|
||||
// In theory we only need to run this once (on install()), but
|
||||
|
@ -41,6 +47,8 @@ function startup() {
|
|||
// to take effect, so we keep the data based on how it was when
|
||||
// the session started.
|
||||
defineCohort();
|
||||
|
||||
setUpSpinnerCheck();
|
||||
}
|
||||
|
||||
function install() {
|
||||
|
@ -170,6 +178,10 @@ function optedOut() {
|
|||
* string must be returned.
|
||||
*/
|
||||
function getTemporaryDisqualification() {
|
||||
if (Preferences.isSet(PREF_DISABLED_FOR_SPINNERS)) {
|
||||
return "longspinner";
|
||||
}
|
||||
|
||||
let applicationLanguage =
|
||||
Cc["@mozilla.org/chrome/chrome-registry;1"]
|
||||
.getService(Ci.nsIXULChromeRegistry)
|
||||
|
@ -182,3 +194,84 @@ function getTemporaryDisqualification() {
|
|||
|
||||
return "";
|
||||
}
|
||||
|
||||
let performLongSpinnerCheck = Task.async(function*() {
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
return;
|
||||
}
|
||||
|
||||
const DAYS_OLD = 3;
|
||||
let thresholdDate = new Date(Date.now() - (1000 * 60 * 60 * 24 * DAYS_OLD));
|
||||
|
||||
let allPingsInfo = yield TelemetryArchive.promiseArchivedPingList();
|
||||
|
||||
let recentPingsInfo = allPingsInfo.filter(ping => {
|
||||
let pingDate = new Date(ping.timestampCreated);
|
||||
return pingDate > thresholdDate;
|
||||
});
|
||||
|
||||
let pingList = [];
|
||||
|
||||
for (let pingInfo of recentPingsInfo) {
|
||||
pingList.push(yield TelemetryArchive.promiseArchivedPingById(pingInfo.id));
|
||||
}
|
||||
|
||||
pingList.push(TelemetryController.getCurrentPingData(/* subsession = */ true));
|
||||
|
||||
let totalSessionTime = 0;
|
||||
let totalSpinnerTime = 0;
|
||||
|
||||
for (let ping of pingList) {
|
||||
try {
|
||||
if (ping.type != "main") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ping.environment.settings.e10sEnabled) {
|
||||
continue;
|
||||
}
|
||||
|
||||
totalSessionTime = ping.payload.info.subsessionLength;
|
||||
|
||||
if (!(LONG_SPINNER_HISTOGRAM in ping.payload.histograms)) {
|
||||
// The Histogram might not be defined in this ping if no data was recorded for it.
|
||||
// In this case, we still add the session length because that was a valid session
|
||||
// without a long spinner.
|
||||
continue;
|
||||
}
|
||||
|
||||
let histogram = ping.payload.histograms[LONG_SPINNER_HISTOGRAM];
|
||||
|
||||
for (spinnerTime of Object.keys(histogram.values)) {
|
||||
// Only consider spinners that took more than 2 seconds.
|
||||
// Note: the first bucket size that fits this criteria is
|
||||
// 2297ms. And the largest bucket is 64000ms, meaning that
|
||||
// any pause larger than that is only counted as a 64s pause.
|
||||
// For reference, the bucket sizes are:
|
||||
// 0, 1000, 2297, 5277, 12124, 27856, 64000
|
||||
if (spinnerTime >= 2000) {
|
||||
totalSpinnerTime += spinnerTime * histogram.values[spinnerTime];
|
||||
}
|
||||
}
|
||||
} catch (e) { /* just in case there's a malformed ping, ignore it silently */ }
|
||||
}
|
||||
|
||||
totalSpinnerTime /= 1000; // session time is in seconds, but spinner time in ms
|
||||
|
||||
const ACCEPTABLE_THRESHOLD = 20 / 3600; // 20 seconds per hour, per bug 1301131
|
||||
|
||||
if ((totalSpinnerTime / totalSessionTime) > ACCEPTABLE_THRESHOLD) {
|
||||
Preferences.set(PREF_DISABLED_FOR_SPINNERS, true);
|
||||
} else {
|
||||
Preferences.reset(PREF_DISABLED_FOR_SPINNERS);
|
||||
}
|
||||
});
|
||||
|
||||
function setUpSpinnerCheck() {
|
||||
let {setTimeout, setInterval} = Cu.import("resource://gre/modules/Timer.jsm");
|
||||
|
||||
// Perform an initial check after 5min (which should give good clearance from
|
||||
// the startup process), and then a subsequent check every hour.
|
||||
setTimeout(performLongSpinnerCheck, 1000 * 60 * 5);
|
||||
setInterval(performLongSpinnerCheck, 1000 * 60 * 60);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>e10srollout@mozilla.org</em:id>
|
||||
<em:version>1.3</em:version>
|
||||
<em:version>1.4</em:version>
|
||||
<em:type>2</em:type>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
<em:multiprocessCompatible>true</em:multiprocessCompatible>
|
||||
|
|
|
@ -194,6 +194,7 @@
|
|||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 2px;
|
||||
background-image: url("chrome://browser/skin/theme-switcher-icon.png");
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
|
|
Двоичные данные
dom/apps/tests/addons/application.zip
Двоичные данные
dom/apps/tests/addons/application.zip
Двоичный файл не отображается.
|
@ -1,26 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>This page will be modified by the add-on</title>
|
||||
<script>
|
||||
function sendAlertsForNode(node) {
|
||||
alert(node.textContent);
|
||||
var color = window.getComputedStyle(node).getPropertyValue("color");
|
||||
alert(color);
|
||||
}
|
||||
|
||||
function run() {
|
||||
// We need to wait for the next tick because add-ons are injected in the
|
||||
// onload event too.
|
||||
window.setTimeout(function() {
|
||||
sendAlertsForNode(document.getElementById("header"));
|
||||
sendAlertsForNode(document.getElementById("header2"));
|
||||
}, 0);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="run()">
|
||||
<h1 id="header">Lorem ipsum</h1>
|
||||
<h2 id="header2">Uncustomized content</h2>
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"name": "Addon app with an invalid name",
|
||||
"description": "Let me inject script and css!",
|
||||
"developer": { "name": "The Mozilla Community" },
|
||||
"package_path" : "application.zip"
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
Content-Type: application/manifest+json
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"name": "Addon app",
|
||||
"version": "1.0",
|
||||
"manifest_version": 2,
|
||||
"permissions": ["tabs"],
|
||||
"description": "Let me inject script and css!",
|
||||
"author": "The Mozilla Community",
|
||||
"content_scripts": [
|
||||
{"matches": ["http://mochi.test/tests/dom/apps/tests/addons/index.html"],
|
||||
"js": ["script.js", "script2.js", "invalid.js", "script.js"],
|
||||
"css": ["style.css", "style2.css"]}
|
||||
]
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
// Simple script that changes an element's content.
|
||||
|
||||
var head = document.getElementById("header");
|
||||
head.innerHTML = "Hello World!";
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
// Simple script that changes an element's content.
|
||||
|
||||
var head = document.getElementById("header2");
|
||||
head.innerHTML = "Customized content";
|
||||
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#header {
|
||||
color: red;
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
#header2 {
|
||||
color: blue;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"name": "Addon app",
|
||||
"description": "Let me inject script and css!",
|
||||
"developer": { "name": "The Mozilla Community" },
|
||||
"package_path" : "application.zip",
|
||||
"id": "webextension@mochitest"
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
Content-Type: application/manifest+json
|
|
@ -1,12 +1,6 @@
|
|||
[DEFAULT]
|
||||
skip-if = true ### Bug 1255339: blacklist because no more mozApps
|
||||
support-files =
|
||||
addons/application.zip
|
||||
addons/invalid.webapp
|
||||
addons/invalid.webapp^headers^
|
||||
addons/update.webapp
|
||||
addons/update.webapp^headers^
|
||||
addons/index.html
|
||||
chromeAddCert.js
|
||||
common.js
|
||||
file_app.sjs
|
||||
|
@ -39,10 +33,6 @@ support-files =
|
|||
icon15alternate.png
|
||||
icon48.png
|
||||
|
||||
[test_app_addons.html]
|
||||
skip-if = os == "android" || toolkit == "gonk" || e10s # embed-apps doesn't work in mochitest app
|
||||
[test_app_blocklist.html]
|
||||
skip-if = buildapp != 'mulet' # we need MOZ_B2G defined and the test to run in the parent process.
|
||||
[test_app_enabled.html]
|
||||
[test_app_update.html]
|
||||
skip-if = os == "android" || toolkit == "gonk" || e10s # embed-apps doesn't work in mochitest app
|
||||
|
|
|
@ -1,216 +0,0 @@
|
|||
<!DOCTYPE HTML><!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1042881
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 923897 - Test apps as addons</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="common.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="application/javascript;version=1.7">
|
||||
/**
|
||||
* Test for Bug 923897
|
||||
* This file covers testing addons.
|
||||
*
|
||||
* The setup is as follows:
|
||||
* - app is installed and offers both script and css to inject in
|
||||
* http://mochi.test:8888/tests/dom/apps/tests/addons/index.html
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const baseURL = "http://mochi.test:8888/tests/dom/apps/tests/addons/";
|
||||
|
||||
const appManifestURL = baseURL + "update.webapp";
|
||||
const invalidAppManifestURL = baseURL + "invalid.webapp";
|
||||
|
||||
let gGenerator = runTest();
|
||||
|
||||
function go() {
|
||||
gGenerator.next();
|
||||
}
|
||||
|
||||
function continueTest() {
|
||||
try {
|
||||
gGenerator.next();
|
||||
} catch (e if e instanceof StopIteration) {
|
||||
SpecialPowers.debugUserCustomizations(false);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function mozAppsError() {
|
||||
ok(false, "mozApps error: " + this.error.name);
|
||||
SpecialPowers.debugUserCustomizations(false);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
// Triggers one navigation test to the given page.
|
||||
// Waits for alert() messages before tearing down the iframe.
|
||||
function openPage(pageURL, messages) {
|
||||
info("Navigating to " + pageURL);
|
||||
let ifr = document.createElement("iframe");
|
||||
let listener = function(event) {
|
||||
let message = messages.shift();
|
||||
is(event.detail.message, message, "Checking alert message for " + pageURL);
|
||||
if (messages.length == 0) {
|
||||
ifr.removeEventListener("mozbrowsershowmodalprompt", listener);
|
||||
ifr.parentNode.removeChild(ifr);
|
||||
continueTest();
|
||||
}
|
||||
}
|
||||
|
||||
ifr.addEventListener("mozbrowsershowmodalprompt", listener, false);
|
||||
|
||||
// Open an the app url in an iframe.
|
||||
ifr.setAttribute("mozbrowser", "true");
|
||||
ifr.setAttribute("src", pageURL);
|
||||
document.getElementById("container").appendChild(ifr);
|
||||
}
|
||||
|
||||
let apps = [];
|
||||
|
||||
function installApp(manifestURL, expectedError) {
|
||||
info("About to install app at " + manifestURL);
|
||||
let req = navigator.mozApps.installPackage(manifestURL);
|
||||
req.onsuccess = function() {
|
||||
apps.push(req.result);
|
||||
is(req.result.manifestURL, manifestURL, "app installed");
|
||||
if (req.result.installState == "installed") {
|
||||
is(req.result.manifest.version, "1.0", "correct version");
|
||||
is(req.result.installState, "installed", "app downloaded");
|
||||
continueTest();
|
||||
} else {
|
||||
req.result.ondownloadapplied = function() {
|
||||
is(req.result.manifest.version, "1.0", "correct version");
|
||||
is(req.result.installState, "installed", "app downloaded");
|
||||
continueTest();
|
||||
}
|
||||
|
||||
req.result.ondownloaderror = function() {
|
||||
if (expectedError) {
|
||||
is(req.result.downloadError.name, "MANIFEST_MISMATCH");
|
||||
} else {
|
||||
ok(false, "unexpected installation error: " + req.result.downloadError.name);
|
||||
}
|
||||
continueTest();
|
||||
}
|
||||
}
|
||||
}
|
||||
req.onerror = mozAppsError;
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
// Set up.
|
||||
SpecialPowers.allowUnsignedAddons();
|
||||
SpecialPowers.debugUserCustomizations(true);
|
||||
SpecialPowers.pushPrefEnv({'set': [
|
||||
["dom.mozBrowserFramesEnabled", true],
|
||||
["dom.apps.customization.enabled", true],
|
||||
]},continueTest);
|
||||
yield undefined;
|
||||
|
||||
SpecialPowers.pushPermissions(
|
||||
[{ "type": "webapps-manage", "allow": 1, "context": document },
|
||||
{ "type": "browser", "allow": 1, "context": document } ],
|
||||
continueTest);
|
||||
yield undefined;
|
||||
|
||||
SpecialPowers.autoConfirmAppInstall(continueTest);
|
||||
yield undefined;
|
||||
|
||||
SpecialPowers.autoConfirmAppUninstall(continueTest);
|
||||
yield undefined;
|
||||
|
||||
// Install addon app with an invalid manifest.
|
||||
installApp(invalidAppManifestURL, true);
|
||||
yield undefined;
|
||||
|
||||
// Uninstall the invalid app.
|
||||
while (apps.length) {
|
||||
let app = apps.pop();
|
||||
req = navigator.mozApps.mgmt.uninstall(app);
|
||||
req.onsuccess = continueTest;
|
||||
req.onerror = mozAppsError;
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
// Opens the iframe to the test page, initial state.
|
||||
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
|
||||
["Lorem ipsum", "rgb(0, 0, 0)",
|
||||
"Uncustomized content", "rgb(0, 0, 0)"]);
|
||||
yield undefined;
|
||||
|
||||
// Install valid addon app.
|
||||
installApp(appManifestURL, false);
|
||||
yield undefined;
|
||||
|
||||
// Opens the iframe to the test page, customized.
|
||||
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
|
||||
["Hello World!", "rgb(255, 0, 0)",
|
||||
"Customized content", "rgb(0, 0, 255)"]);
|
||||
yield undefined;
|
||||
|
||||
// Disable the app.
|
||||
navigator.mozApps.mgmt.onenabledstatechange = function(event) {
|
||||
ok(true, "onenabledstatechange received");
|
||||
is(event.application.enabled, false, "Application is disabled");
|
||||
is(apps[0].enabled, false, "Application is disabled");
|
||||
continueTest();
|
||||
}
|
||||
|
||||
navigator.mozApps.mgmt.setEnabled(apps[0], false);
|
||||
yield undefined;
|
||||
|
||||
// Opens the iframe to the test page, back to initial state.
|
||||
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
|
||||
["Lorem ipsum", "rgb(0, 0, 0)",
|
||||
"Uncustomized content", "rgb(0, 0, 0)"]);
|
||||
yield undefined;
|
||||
|
||||
// Re-enable the app.
|
||||
navigator.mozApps.mgmt.onenabledstatechange = function(event) {
|
||||
ok(true, "onenabledstatechange received");
|
||||
is(event.application.enabled, true, "Application is enabled");
|
||||
is(apps[0].enabled, true, "Application is enabled");
|
||||
continueTest();
|
||||
}
|
||||
|
||||
navigator.mozApps.mgmt.setEnabled(apps[0], true);
|
||||
yield undefined;
|
||||
|
||||
// Opens the iframe to the test page, customized.
|
||||
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
|
||||
["Hello World!", "rgb(255, 0, 0)",
|
||||
"Customized content", "rgb(0, 0, 255)"]);
|
||||
yield undefined;
|
||||
|
||||
// Clean up after ourselves by uninstalling apps.
|
||||
while (apps.length) {
|
||||
let app = apps.pop();
|
||||
req = navigator.mozApps.mgmt.uninstall(app);
|
||||
req.onsuccess = continueTest;
|
||||
req.onerror = mozAppsError;
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
// Opens the iframe to the test page, back to initial state.
|
||||
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
|
||||
["Lorem ipsum", "rgb(0, 0, 0)",
|
||||
"Uncustomized content", "rgb(0, 0, 0)"]);
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="prepareEnv(go)">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<div id="container"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,191 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id={1208242}
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug {1208242}</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="common.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={1208242}">Mozilla Bug {1208242}</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript;version=1.7">
|
||||
|
||||
var baseURL = "http://mochi.test:8888/tests/dom/apps/tests/addons/";
|
||||
var appManifestURL = baseURL + "update.webapp";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var gGenerator = runTest();
|
||||
|
||||
// Utilities to turn off auto update of the blocklist.
|
||||
// Copied from toolkit/mozapps/extensions/test/browser/head.js
|
||||
var gCatMan = SpecialPowers.Cc["@mozilla.org/categorymanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsICategoryManager);
|
||||
|
||||
var UTIMER = "update-timer";
|
||||
var BLOCKLIST = "nsBlocklistService";
|
||||
|
||||
var blocklistUpdateConfig = "@mozilla.org/extensions/blocklist;1,getService,blocklist-background-update-timer,extensions.blocklist.interval,86400";
|
||||
|
||||
function disableBlocklistUpdateTimer() {
|
||||
info("Disabling " + UTIMER + " " + BLOCKLIST);
|
||||
blocklistUpdateConfig = gCatMan.getCategoryEntry(UTIMER, BLOCKLIST);
|
||||
gCatMan.deleteCategoryEntry(UTIMER, BLOCKLIST, true);
|
||||
}
|
||||
|
||||
function enableBlocklistUpdateTimer() {
|
||||
info("Enabling " + UTIMER + " " + BLOCKLIST);
|
||||
gCatMan.addCategoryEntry(UTIMER, BLOCKLIST, blocklistUpdateConfig, false, true);
|
||||
}
|
||||
|
||||
// End of utilities
|
||||
|
||||
function go() {
|
||||
disableBlocklistUpdateTimer();
|
||||
SpecialPowers.allowUnsignedAddons();
|
||||
SpecialPowers.pushPermissions(
|
||||
[{ "type": "webapps-manage", "allow": 1, "context": document }],
|
||||
function() { gGenerator.next() });
|
||||
}
|
||||
|
||||
function continueTest() {
|
||||
try {
|
||||
gGenerator.next();
|
||||
} catch (e if e instanceof StopIteration) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
function finish() {
|
||||
enableBlocklistUpdateTimer();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function cbError(aEvent) {
|
||||
ok(false, "Error callback invoked " +
|
||||
aEvent.target.error.name + " " + aEvent.target.error.message);
|
||||
finish();
|
||||
}
|
||||
|
||||
function mozAppsError() {
|
||||
ok(false, "mozApps error: " + this.error.name);
|
||||
SpecialPowers.debugUserCustomizations(false);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function installApp(manifestURL) {
|
||||
info("About to install app at " + manifestURL);
|
||||
let req = navigator.mozApps.installPackage(manifestURL);
|
||||
req.onsuccess = function() {
|
||||
is(req.result.manifestURL, manifestURL, "app installed");
|
||||
if (req.result.installState == "installed") {
|
||||
is(req.result.manifest.version, "1.0", "correct version");
|
||||
is(req.result.installState, "installed", "app downloaded");
|
||||
continueTest();
|
||||
} else {
|
||||
req.result.ondownloadapplied = function() {
|
||||
is(req.result.manifest.version, "1.0", "correct version");
|
||||
is(req.result.installState, "installed", "app downloaded");
|
||||
continueTest();
|
||||
}
|
||||
|
||||
req.result.ondownloaderror = function() {
|
||||
ok(false, "unexpected installation error: " + req.result.downloadError.name);
|
||||
continueTest();
|
||||
}
|
||||
}
|
||||
}
|
||||
req.onerror = mozAppsError;
|
||||
return req;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test blocking of an add-on.
|
||||
*/
|
||||
function runTest() {
|
||||
SpecialPowers.autoConfirmAppInstall(continueTest);
|
||||
yield undefined;
|
||||
|
||||
SpecialPowers.autoConfirmAppUninstall(continueTest);
|
||||
yield undefined;
|
||||
|
||||
request = navigator.mozApps.mgmt.getAll();
|
||||
request.onerror = cbError;
|
||||
request.onsuccess = continueTest;
|
||||
yield undefined;
|
||||
var initialAppsCount = request.result.length;
|
||||
info("Starting with " + initialAppsCount + " apps installed.");
|
||||
|
||||
// Install valid addon app.
|
||||
var req = installApp(appManifestURL, false);
|
||||
yield undefined;
|
||||
|
||||
var app = req.result;
|
||||
|
||||
ok(app, "App is non-null");
|
||||
is(app.manifestURL, appManifestURL, "App manifest url is correct.");
|
||||
is(app.enabled, true, "App is enabled by default after install.");
|
||||
|
||||
// Check that the app is disabled
|
||||
navigator.mozApps.mgmt.onenabledstatechange = function(event) {
|
||||
ok(true, "onenabledstatechange received");
|
||||
is(event.application.enabled, false, "Application is disabled");
|
||||
continueTest();
|
||||
}
|
||||
|
||||
// Trigger the blocklist by passing an XML blocklist string.
|
||||
var blocklist =
|
||||
`<?xml version="1.0"?>
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1443544016000">
|
||||
<emItems>
|
||||
<emItem blockID="i00" id="webextension@mochitest">
|
||||
<versionRange minVersion="0" maxVersion="*" severity="1"> </versionRange>
|
||||
</emItem>
|
||||
</emItems>
|
||||
</blocklist>`;
|
||||
|
||||
var bls = SpecialPowers.Cc["@mozilla.org/extensions/blocklist;1"]
|
||||
.getService(SpecialPowers.Ci.nsIBlocklistService).wrappedJSObject;
|
||||
bls._loadBlocklistFromString(blocklist);
|
||||
|
||||
//navigator.mozApps.mgmt.setEnabled(app, true);
|
||||
yield undefined;
|
||||
|
||||
// Cleaning up after ourselves.
|
||||
navigator.mozApps.mgmt.onuninstall = function(event) {
|
||||
var app = event.application;
|
||||
is(app.manifestURL, appManifestURL, "App uninstall event ok.");
|
||||
is(app.manifest.name, "Addon app", "App uninstall manifest ok.");
|
||||
continueTest();
|
||||
}
|
||||
request = navigator.mozApps.mgmt.uninstall(app);
|
||||
request.onerror = cbError;
|
||||
request.onsuccess = continueTest;
|
||||
yield undefined;
|
||||
yield undefined;
|
||||
is(request.result, appManifestURL, "App uninstalled.");
|
||||
navigator.mozApps.mgmt.onuninstall = null;
|
||||
|
||||
request = navigator.mozApps.mgmt.getAll();
|
||||
request.onerror = cbError;
|
||||
request.onsuccess = continueTest;
|
||||
yield undefined;
|
||||
is(request.result.length, initialAppsCount, "All apps are uninstalled.");
|
||||
}
|
||||
|
||||
addLoadEvent(() => prepareEnv(go));
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -667,7 +667,7 @@ class nsOuterWindowProxy : public js::Wrapper
|
|||
public:
|
||||
constexpr nsOuterWindowProxy() : js::Wrapper(0) { }
|
||||
|
||||
virtual bool finalizeInBackground(JS::Value priv) const override {
|
||||
virtual bool finalizeInBackground(const JS::Value& priv) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -102,8 +102,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSScriptTimeoutHandler)
|
|||
if (MOZ_UNLIKELY(cb.WantDebugInfo())) {
|
||||
nsAutoCString name("nsJSScriptTimeoutHandler");
|
||||
if (tmp->mFunction) {
|
||||
JSFunction* fun =
|
||||
JS_GetObjectFunction(js::UncheckedUnwrap(tmp->mFunction->Callable()));
|
||||
JSObject* obj = tmp->mFunction->CallablePreserveColor();
|
||||
JSFunction* fun = JS_GetObjectFunction(js::UncheckedUnwrap(obj));
|
||||
if (fun && JS_GetFunctionId(fun)) {
|
||||
JSFlatString *funId = JS_ASSERT_STRING_IS_FLAT(JS_GetFunctionId(fun));
|
||||
size_t size = 1 + JS_PutEscapedFlatString(nullptr, 0, funId, 0);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "nsStringGlue.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsIPrincipal;
|
||||
class nsWrapperCache;
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -108,6 +109,10 @@ public:
|
|||
return !Get();
|
||||
}
|
||||
|
||||
// It returns the subjectPrincipal if called on the main-thread, otherwise
|
||||
// a nullptr is returned.
|
||||
nsIPrincipal* GetSubjectPrincipal() const;
|
||||
|
||||
protected:
|
||||
JS::Rooted<JSObject*> mGlobalJSObject;
|
||||
JSContext* mCx;
|
||||
|
@ -274,7 +279,7 @@ class Optional<JS::Value>
|
|||
private:
|
||||
Optional() = delete;
|
||||
|
||||
explicit Optional(JS::Value aValue) = delete;
|
||||
explicit Optional(const JS::Value& aValue) = delete;
|
||||
};
|
||||
|
||||
// A specialization of Optional for NonNull that lets us get a T& from Value()
|
||||
|
|
|
@ -2254,6 +2254,19 @@ GlobalObject::GetAsSupports() const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
GlobalObject::GetSubjectPrincipal() const
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JSCompartment* compartment = js::GetContextCompartment(mCx);
|
||||
MOZ_ASSERT(compartment);
|
||||
JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
|
||||
return nsJSPrincipals::get(principals);
|
||||
}
|
||||
|
||||
static bool
|
||||
CallOrdinaryHasInstance(JSContext* cx, JS::CallArgs& args)
|
||||
{
|
||||
|
|
|
@ -45,6 +45,11 @@ public:
|
|||
return Callback();
|
||||
}
|
||||
|
||||
JS::Handle<JSObject*> CallablePreserveColor() const
|
||||
{
|
||||
return CallbackPreserveColor();
|
||||
}
|
||||
|
||||
bool HasGrayCallable() const
|
||||
{
|
||||
// Play it safe in case this gets called after unlink.
|
||||
|
|
|
@ -10453,7 +10453,7 @@ class CGClass(CGThing):
|
|||
def declare(self, cgClass):
|
||||
name = cgClass.getNameString()
|
||||
return ("%s(const %s&) = delete;\n"
|
||||
"void operator=(const %s) = delete;\n" % (name, name, name))
|
||||
"void operator=(const %s&) = delete;\n" % (name, name, name))
|
||||
|
||||
disallowedCopyConstructors = [DisallowedCopyConstructor()]
|
||||
else:
|
||||
|
@ -11633,7 +11633,7 @@ class CGDOMJSProxyHandler_className(ClassMethod):
|
|||
|
||||
class CGDOMJSProxyHandler_finalizeInBackground(ClassMethod):
|
||||
def __init__(self, descriptor):
|
||||
args = [Argument('JS::Value', 'priv')]
|
||||
args = [Argument('const JS::Value&', 'priv')]
|
||||
ClassMethod.__init__(self, "finalizeInBackground", "bool", args,
|
||||
virtual=True, override=True, const=True)
|
||||
self.descriptor = descriptor
|
||||
|
@ -13843,7 +13843,7 @@ class CGNativeMember(ClassMethod):
|
|||
if self.member.isMethod() and self.member.isLegacycaller():
|
||||
# If it has an identifier, we can't deal with it yet
|
||||
assert self.member.isIdentifierLess()
|
||||
args.insert(0, Argument("JS::Value", "aThisVal"))
|
||||
args.insert(0, Argument("const JS::Value&", "aThisVal"))
|
||||
# And jscontext bits.
|
||||
if needCx(returnType, argList, self.extendedAttrs,
|
||||
self.passJSBitsAsNeeded, self.member.isStatic()):
|
||||
|
|
|
@ -244,7 +244,7 @@ FillPropertyDescriptor(JS::MutableHandle<JS::PropertyDescriptor> desc,
|
|||
|
||||
inline void
|
||||
FillPropertyDescriptor(JS::MutableHandle<JS::PropertyDescriptor> desc,
|
||||
JSObject* obj, JS::Value v,
|
||||
JSObject* obj, const JS::Value& v,
|
||||
bool readonly, bool enumerable = true)
|
||||
{
|
||||
desc.value().set(v);
|
||||
|
@ -253,7 +253,7 @@ FillPropertyDescriptor(JS::MutableHandle<JS::PropertyDescriptor> desc,
|
|||
|
||||
inline void
|
||||
FillPropertyDescriptor(JS::MutableHandle<JS::PropertyDescriptor> desc,
|
||||
JSObject* obj, unsigned attributes, JS::Value v)
|
||||
JSObject* obj, unsigned attributes, const JS::Value& v)
|
||||
{
|
||||
desc.object().set(obj);
|
||||
desc.value().set(v);
|
||||
|
|
|
@ -805,11 +805,11 @@ public:
|
|||
int8_t DeprecatedAttribute();
|
||||
int8_t SetDeprecatedAttribute(int8_t);
|
||||
int8_t DeprecatedMethod();
|
||||
int8_t DeprecatedMethodWithContext(JSContext*, JS::Value);
|
||||
int8_t DeprecatedMethodWithContext(JSContext*, const JS::Value&);
|
||||
|
||||
// Static methods and attributes
|
||||
static void StaticMethod(const GlobalObject&, bool);
|
||||
static void StaticMethodWithContext(const GlobalObject&, JS::Value);
|
||||
static void StaticMethodWithContext(const GlobalObject&, const JS::Value&);
|
||||
static bool StaticAttribute(const GlobalObject&);
|
||||
static void SetStaticAttribute(const GlobalObject&, bool);
|
||||
static void Assert(const GlobalObject&, bool);
|
||||
|
@ -818,7 +818,7 @@ public:
|
|||
static int8_t StaticDeprecatedAttribute(const GlobalObject&);
|
||||
static int8_t SetStaticDeprecatedAttribute(const GlobalObject&, int8_t);
|
||||
static int8_t StaticDeprecatedMethod(const GlobalObject&);
|
||||
static int8_t StaticDeprecatedMethodWithContext(const GlobalObject&, JS::Value);
|
||||
static int8_t StaticDeprecatedMethodWithContext(const GlobalObject&, const JS::Value&);
|
||||
|
||||
// Overload resolution tests
|
||||
bool Overload1(TestInterface&);
|
||||
|
@ -933,7 +933,7 @@ public:
|
|||
void SetThrowingGetterAttr(bool arg);
|
||||
bool ThrowingSetterAttr() const;
|
||||
void SetThrowingSetterAttr(bool arg, ErrorResult& aRv);
|
||||
int16_t LegacyCall(JS::Value, uint32_t, TestInterface&);
|
||||
int16_t LegacyCall(const JS::Value&, uint32_t, TestInterface&);
|
||||
void PassArgsWithDefaults(JSContext*, const Optional<int32_t>&,
|
||||
TestInterface*, const Dict&, double,
|
||||
const Optional<float>&);
|
||||
|
|
|
@ -112,7 +112,7 @@ DoDrawImageSecurityCheck(dom::HTMLCanvasElement *aCanvasElement,
|
|||
}
|
||||
|
||||
bool
|
||||
CoerceDouble(JS::Value v, double* d)
|
||||
CoerceDouble(const JS::Value& v, double* d)
|
||||
{
|
||||
if (v.isDouble()) {
|
||||
*d = v.toDouble();
|
||||
|
|
|
@ -49,7 +49,7 @@ void DoDrawImageSecurityCheck(dom::HTMLCanvasElement *aCanvasElement,
|
|||
// Make a double out of |v|, treating undefined values as 0.0 (for
|
||||
// the sake of sparse arrays). Return true iff coercion
|
||||
// succeeded.
|
||||
bool CoerceDouble(JS::Value v, double* d);
|
||||
bool CoerceDouble(const JS::Value& v, double* d);
|
||||
|
||||
/* Float validation stuff */
|
||||
#define VALIDATE(_f) if (!IsFinite(_f)) return false
|
||||
|
|
|
@ -828,8 +828,11 @@ void
|
|||
WebGLContext::ThrowEvent_WebGLContextCreationError(const nsACString& text)
|
||||
{
|
||||
RefPtr<EventTarget> target = mCanvasElement;
|
||||
if (!target) {
|
||||
if (!target && mOffscreenCanvas) {
|
||||
target = mOffscreenCanvas;
|
||||
} else if (!target) {
|
||||
GenerateWarning("Failed to create WebGL context: %s", text.BeginReading());
|
||||
return;
|
||||
}
|
||||
|
||||
const auto kEventName = NS_LITERAL_STRING("webglcontextcreationerror");
|
||||
|
|
|
@ -870,21 +870,13 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
|
|||
}
|
||||
|
||||
if (gl->IsCompatibilityProfile()) {
|
||||
// gl_PointSize is always available in ES2 GLSL, but has to be
|
||||
// specifically enabled on desktop GLSL.
|
||||
gl->fEnable(LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
|
||||
/* gl_PointCoord is always available in ES2 GLSL and in newer desktop
|
||||
* GLSL versions, but apparently not in OpenGL 2 and apparently not (due
|
||||
* to a driver bug) on certain NVIDIA setups. See:
|
||||
* http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=261472
|
||||
*
|
||||
* Note that this used to cause crashes on old ATI drivers... Hopefully
|
||||
* not a significant anymore. See bug 602183.
|
||||
*/
|
||||
gl->fEnable(LOCAL_GL_POINT_SPRITE);
|
||||
}
|
||||
|
||||
if (!gl->IsGLES()) {
|
||||
gl->fEnable(LOCAL_GL_PROGRAM_POINT_SIZE);
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (gl->WorkAroundDriverBugs() &&
|
||||
gl->Vendor() == gl::GLVendor::ATI &&
|
||||
|
|
|
@ -5275,7 +5275,6 @@ skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.
|
|||
[generated/test_2_conformance__glsl__variables__gl-frontfacing.html]
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
|
||||
[generated/test_2_conformance__glsl__variables__gl-pointcoord.html]
|
||||
fail-if = (os == 'mac')
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
|
||||
[generated/test_2_conformance__glsl__variables__glsl-built-ins.html]
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
|
||||
|
@ -5781,12 +5780,10 @@ skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.
|
|||
[generated/test_2_conformance__rendering__point-no-attributes.html]
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
|
||||
[generated/test_2_conformance__rendering__point-size.html]
|
||||
fail-if = (os == 'mac')
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
|
||||
[generated/test_2_conformance__rendering__point-specific-shader-variables.html]
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
|
||||
[generated/test_2_conformance__rendering__point-with-gl-pointcoord-in-fragment-shader.html]
|
||||
fail-if = (os == 'mac')
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
|
||||
[generated/test_2_conformance__rendering__polygon-offset.html]
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
|
||||
|
|
|
@ -534,16 +534,10 @@ fail-if = (os == 'mac' && os_version == '10.8')
|
|||
|
||||
####################
|
||||
# failure on OSX
|
||||
[generated/test_2_conformance__rendering__point-with-gl-pointcoord-in-fragment-shader.html]
|
||||
fail-if = (os == 'mac')
|
||||
[generated/test_2_conformance__glsl__variables__gl-pointcoord.html]
|
||||
fail-if = (os == 'mac')
|
||||
[generated/test_2_conformance2__state__gl-get-calls.html]
|
||||
fail-if = (os == 'mac')
|
||||
[generated/test_conformance__extensions__angle-instanced-arrays.html]
|
||||
fail-if = (os == 'mac')
|
||||
[generated/test_2_conformance__rendering__point-size.html]
|
||||
fail-if = (os == 'mac')
|
||||
[generated/test_conformance__glsl__misc__shaders-with-invariance.html]
|
||||
fail-if = (os == 'mac')
|
||||
|
||||
|
|
|
@ -75,7 +75,8 @@ ClipboardEvent::Constructor(const GlobalObject& aGlobal,
|
|||
// support other types of events, make sure that read/write privileges are
|
||||
// checked properly within DataTransfer.
|
||||
clipboardData = new DataTransfer(ToSupports(e), eCopy, false, -1);
|
||||
clipboardData->SetData(aParam.mDataType, aParam.mData, aRv);
|
||||
clipboardData->SetData(aParam.mDataType, aParam.mData,
|
||||
Some(aGlobal.GetSubjectPrincipal()), aRv);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -284,9 +284,11 @@ DataTransfer::GetMozUserCancelled(bool* aUserCancelled)
|
|||
}
|
||||
|
||||
already_AddRefed<FileList>
|
||||
DataTransfer::GetFiles(ErrorResult& aRv)
|
||||
DataTransfer::GetFiles(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
return mItems->Files(nsContentUtils::SubjectPrincipal());
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
return mItems->Files(aSubjectPrincipal.value());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -374,14 +376,17 @@ DataTransfer::GetTypes(nsISupports** aTypes)
|
|||
|
||||
void
|
||||
DataTransfer::GetData(const nsAString& aFormat, nsAString& aData,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
// return an empty string if data for the format was not found
|
||||
aData.Truncate();
|
||||
|
||||
nsCOMPtr<nsIVariant> data;
|
||||
nsresult rv =
|
||||
GetDataAtInternal(aFormat, 0, nsContentUtils::SubjectPrincipal(),
|
||||
GetDataAtInternal(aFormat, 0, aSubjectPrincipal.value(),
|
||||
getter_AddRefs(data));
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv != NS_ERROR_DOM_INDEX_SIZE_ERR) {
|
||||
|
@ -433,19 +438,21 @@ NS_IMETHODIMP
|
|||
DataTransfer::GetData(const nsAString& aFormat, nsAString& aData)
|
||||
{
|
||||
ErrorResult rv;
|
||||
GetData(aFormat, aData, rv);
|
||||
GetData(aFormat, aData, Some(nsContentUtils::SubjectPrincipal()), rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
void
|
||||
DataTransfer::SetData(const nsAString& aFormat, const nsAString& aData,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
RefPtr<nsVariantCC> variant = new nsVariantCC();
|
||||
variant->SetAsAString(aData);
|
||||
|
||||
aRv = SetDataAtInternal(aFormat, variant, 0,
|
||||
nsContentUtils::SubjectPrincipal());
|
||||
aRv = SetDataAtInternal(aFormat, variant, 0, aSubjectPrincipal.value());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -641,10 +648,13 @@ void
|
|||
DataTransfer::MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
|
||||
uint32_t aIndex,
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
nsCOMPtr<nsIVariant> data;
|
||||
aRv = GetDataAtInternal(aFormat, aIndex, nsContentUtils::SubjectPrincipal(),
|
||||
aRv = GetDataAtInternal(aFormat, aIndex, aSubjectPrincipal.value(),
|
||||
getter_AddRefs(data));
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
|
@ -723,15 +733,17 @@ DataTransfer::SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData,
|
|||
|
||||
void
|
||||
DataTransfer::MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
|
||||
JS::Handle<JS::Value> aData,
|
||||
uint32_t aIndex, ErrorResult& aRv)
|
||||
JS::Handle<JS::Value> aData, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
nsCOMPtr<nsIVariant> data;
|
||||
aRv = nsContentUtils::XPConnect()->JSValToVariant(aCx, aData,
|
||||
getter_AddRefs(data));
|
||||
if (!aRv.Failed()) {
|
||||
aRv = SetDataAtInternal(aFormat, data, aIndex,
|
||||
nsContentUtils::SubjectPrincipal());
|
||||
aRv = SetDataAtInternal(aFormat, data, aIndex, aSubjectPrincipal.value());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -818,8 +830,11 @@ DataTransfer::SetDragImage(nsIDOMElement* aImage, int32_t aX, int32_t aY)
|
|||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
DataTransfer::GetFilesAndDirectories(ErrorResult& aRv)
|
||||
DataTransfer::GetFilesAndDirectories(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
nsCOMPtr<nsINode> parentNode = do_QueryInterface(mParent);
|
||||
if (!parentNode) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
|
@ -838,7 +853,7 @@ DataTransfer::GetFilesAndDirectories(ErrorResult& aRv)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<FileList> files = mItems->Files(nsContentUtils::SubjectPrincipal());
|
||||
RefPtr<FileList> files = mItems->Files(aSubjectPrincipal.value());
|
||||
if (NS_WARN_IF(!files)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -855,10 +870,12 @@ DataTransfer::GetFilesAndDirectories(ErrorResult& aRv)
|
|||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
DataTransfer::GetFiles(bool aRecursiveFlag, ErrorResult& aRv)
|
||||
DataTransfer::GetFiles(bool aRecursiveFlag,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// Currently we don't support directories.
|
||||
return GetFilesAndDirectories(aRv);
|
||||
return GetFilesAndDirectories(aSubjectPrincipal, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -138,20 +138,30 @@ public:
|
|||
|
||||
already_AddRefed<DOMStringList> GetTypes(ErrorResult& rv) const;
|
||||
|
||||
void GetData(const nsAString& aFormat, nsAString& aData, ErrorResult& aRv);
|
||||
void GetData(const nsAString& aFormat, nsAString& aData,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void SetData(const nsAString& aFormat, const nsAString& aData,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void ClearData(const mozilla::dom::Optional<nsAString>& aFormat,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<FileList> GetFiles(mozilla::ErrorResult& aRv);
|
||||
already_AddRefed<FileList>
|
||||
GetFiles(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise> GetFilesAndDirectories(ErrorResult& aRv);
|
||||
already_AddRefed<Promise>
|
||||
GetFilesAndDirectories(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise> GetFiles(bool aRecursiveFlag, ErrorResult& aRv);
|
||||
already_AddRefed<Promise>
|
||||
GetFiles(bool aRecursiveFlag,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
|
||||
void AddElement(Element& aElement, mozilla::ErrorResult& aRv);
|
||||
|
@ -176,10 +186,12 @@ public:
|
|||
|
||||
void MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
|
||||
JS::Handle<JS::Value> aData, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
void MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
|
||||
uint32_t aIndex, JS::MutableHandle<JS::Value> aRetval,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
bool MozUserCancelled() const
|
||||
|
@ -363,4 +375,3 @@ NS_DEFINE_STATIC_IID_ACCESSOR(DataTransfer, NS_DATATRANSFER_IID)
|
|||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_dom_DataTransfer_h */
|
||||
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Pointer Events properties tests</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<!--script src="/resources/testharnessreport.js"></script-->
|
||||
<!-- Additional helper script for common checks across event types -->
|
||||
<script type="text/javascript" src="pointerevent_support.js"></script>
|
||||
<script type="text/javascript" src="mochitest_support_internal.js"></script>
|
||||
<script>
|
||||
var detected_pointertypes = {};
|
||||
var test_pointerEvent = async_test("implicit pointer capture for touch");
|
||||
// showPointerTypes is defined in pointerevent_support.js
|
||||
// Requirements: the callback function will reference the test_pointerEvent object and
|
||||
// will fail unless the async_test is created with the var name "test_pointerEvent".
|
||||
add_completion_callback(showPointerTypes);
|
||||
|
||||
function run() {
|
||||
let target0 = window.document.getElementById("target0");
|
||||
let target1 = window.document.getElementById("target1");
|
||||
|
||||
on_event(target0, "pointerdown", function (event) {
|
||||
pointerdown_event = event;
|
||||
detected_pointertypes[event.pointerType] = true;
|
||||
assert_true(true, "target0 receives pointerdown");
|
||||
});
|
||||
|
||||
on_event(target0, "pointermove", function (event) {
|
||||
assert_true(true, "target0 receives pointermove");
|
||||
assert_true(target0.hasPointerCapture(event.pointerId), "target0.hasPointerCapture should be true");
|
||||
});
|
||||
|
||||
on_event(target0, "gotpointercapture", function (event) {
|
||||
assert_true(true, "target0 should receive gotpointercapture");
|
||||
});
|
||||
|
||||
on_event(target0, "lostpointercapture", function (event) {
|
||||
assert_true(true, "target0 should receive lostpointercapture");
|
||||
});
|
||||
|
||||
on_event(target1, "pointermove", function (event) {
|
||||
assert_true(false, "target1 should not receive pointermove");
|
||||
});
|
||||
|
||||
on_event(target0, "pointerup", function (event) {
|
||||
assert_true(true, "target0 receives pointerup");
|
||||
test_pointerEvent.done();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="run()">
|
||||
<h1>Pointer Events tests</h1>
|
||||
<div id="target0" style="width: 200px; height: 200px; background: green" touch-action:none></div>
|
||||
<div id="target1" style="width: 200px; height: 200px; background: green" touch-action:none></div>
|
||||
<div id="complete-notice">
|
||||
<p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
|
||||
<p>Refresh the page to run the tests again with a different pointer type.</p>
|
||||
</div>
|
||||
<div id="log"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,65 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Pointer Events properties tests</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<!--script src="/resources/testharnessreport.js"></script-->
|
||||
<!-- Additional helper script for common checks across event types -->
|
||||
<script type="text/javascript" src="pointerevent_support.js"></script>
|
||||
<script type="text/javascript" src="mochitest_support_internal.js"></script>
|
||||
<script>
|
||||
var detected_pointertypes = {};
|
||||
var test_pointerEvent = async_test("implicit pointer capture for touch");
|
||||
// showPointerTypes is defined in pointerevent_support.js
|
||||
// Requirements: the callback function will reference the test_pointerEvent object and
|
||||
// will fail unless the async_test is created with the var name "test_pointerEvent".
|
||||
add_completion_callback(showPointerTypes);
|
||||
|
||||
function run() {
|
||||
let target0 = window.document.getElementById("target0");
|
||||
let target1 = window.document.getElementById("target1");
|
||||
|
||||
on_event(target0, "pointerdown", function (event) {
|
||||
pointerdown_event = event;
|
||||
detected_pointertypes[event.pointerType] = true;
|
||||
assert_true(true, "target0 receives pointerdown");
|
||||
});
|
||||
|
||||
on_event(target0, "pointermove", function (event) {
|
||||
assert_true(true, "target0 receives pointermove");
|
||||
assert_false(target0.hasPointerCapture(event.pointerId), "target0.hasPointerCapture should be false");
|
||||
});
|
||||
|
||||
on_event(target0, "gotpointercapture", function (event) {
|
||||
assert_unreached("target0 should not receive gotpointercapture");
|
||||
});
|
||||
|
||||
on_event(target0, "lostpointercapture", function (event) {
|
||||
assert_unreached("target0 should not receive lostpointercapture");
|
||||
});
|
||||
|
||||
on_event(target1, "pointermove", function (event) {
|
||||
assert_true(true, "target1 receives pointermove");
|
||||
assert_false(target1.hasPointerCapture(), "target1.hasPointerCapture should be false");
|
||||
});
|
||||
|
||||
on_event(target0, "pointerup", function (event) {
|
||||
assert_true(true, "target0 receives pointerup");
|
||||
test_pointerEvent.done();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="run()">
|
||||
<h1>Pointer Events tests</h1>
|
||||
<div id="target0" style="width: 200px; height: 200px; background: green" touch-action:none></div>
|
||||
<div id="target1" style="width: 200px; height: 200px; background: green" touch-action:none></div>
|
||||
<div id="complete-notice">
|
||||
<p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
|
||||
<p>Refresh the page to run the tests again with a different pointer type.</p>
|
||||
</div>
|
||||
<div id="log"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -149,5 +149,9 @@ support-files =
|
|||
pointerevent_touch-action-svg-test_touch-manual.html
|
||||
pointerevent_touch-action-table-test_touch-manual.html
|
||||
[test_bug1285128.html]
|
||||
[test_bug1293174_implicit_pointer_capture_for_touch_1.html]
|
||||
support-files = bug1293174_implicit_pointer_capture_for_touch_1.html
|
||||
[test_bug1293174_implicit_pointer_capture_for_touch_2.html]
|
||||
support-files = bug1293174_implicit_pointer_capture_for_touch_2.html
|
||||
[test_empty_file.html]
|
||||
disabled = disabled # Bug 1150091 - Issue with support-files
|
||||
|
|
|
@ -15,6 +15,15 @@ function prepareTest() {
|
|||
turnOnPointerEvents(startTest);
|
||||
}
|
||||
|
||||
function setImplicitPointerCapture(capture, callback) {
|
||||
console.log("SET dom.w3c_pointer_events.implicit_capture as " + capture);
|
||||
SpecialPowers.pushPrefEnv({
|
||||
"set": [
|
||||
["dom.w3c_pointer_events.implicit_capture", capture]
|
||||
]
|
||||
}, callback);
|
||||
}
|
||||
|
||||
function turnOnPointerEvents(callback) {
|
||||
console.log("SET dom.w3c_pointer_events.enabled as TRUE");
|
||||
console.log("SET layout.css.touch_action.enabled as TRUE");
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1293174</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="text/javascript" src="mochitest_support_external.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
function startTest() {
|
||||
setImplicitPointerCapture(true, loadSubFrame);
|
||||
}
|
||||
function loadSubFrame() {
|
||||
var iframe = document.getElementById("testFrame");
|
||||
iframe.src = "bug1293174_implicit_pointer_capture_for_touch_1.html";
|
||||
}
|
||||
function executeTest(int_win) {
|
||||
sendTouchEvent(int_win, "target0", "touchstart");
|
||||
sendTouchEvent(int_win, "target0", "touchmove");
|
||||
sendTouchEvent(int_win, "target1", "touchmove");
|
||||
sendTouchEvent(int_win, "target0", "touchmove");
|
||||
sendTouchEvent(int_win, "target0", "touchend");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="testFrame" height="800" width="1000"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1293174</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="text/javascript" src="mochitest_support_external.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
function startTest() {
|
||||
setImplicitPointerCapture(false, loadSubFrame);
|
||||
}
|
||||
function loadSubFrame() {
|
||||
var iframe = document.getElementById("testFrame");
|
||||
iframe.src = "bug1293174_implicit_pointer_capture_for_touch_2.html";
|
||||
}
|
||||
function executeTest(int_win) {
|
||||
sendTouchEvent(int_win, "target0", "touchstart");
|
||||
sendTouchEvent(int_win, "target0", "touchmove");
|
||||
sendTouchEvent(int_win, "target1", "touchmove");
|
||||
sendTouchEvent(int_win, "target0", "touchmove");
|
||||
sendTouchEvent(int_win, "target0", "touchend");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="testFrame" height="800" width="1000"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1778,9 +1778,6 @@ TabChild::RecvHandleTap(const GeckoContentController::TapType& aType,
|
|||
|
||||
switch (aType) {
|
||||
case GeckoContentController::TapType::eSingleTap:
|
||||
if (mRemoteFrame) {
|
||||
mRemoteFrame->SendTakeFocusForClickFromTap();
|
||||
}
|
||||
if (mGlobal && mTabChildGlobal) {
|
||||
mAPZEventState->ProcessSingleTap(point, scale, aModifiers, aGuid, 1);
|
||||
}
|
||||
|
@ -1789,9 +1786,6 @@ TabChild::RecvHandleTap(const GeckoContentController::TapType& aType,
|
|||
HandleDoubleTap(point, aModifiers, aGuid);
|
||||
break;
|
||||
case GeckoContentController::TapType::eSecondTap:
|
||||
if (mRemoteFrame) {
|
||||
mRemoteFrame->SendTakeFocusForClickFromTap();
|
||||
}
|
||||
if (mGlobal && mTabChildGlobal) {
|
||||
mAPZEventState->ProcessSingleTap(point, scale, aModifiers, aGuid, 2);
|
||||
}
|
||||
|
|
|
@ -1696,6 +1696,10 @@ TabParent::SendHandleTap(TapType aType,
|
|||
if (mIsDestroyed) {
|
||||
return false;
|
||||
}
|
||||
if ((aType == TapType::eSingleTap || aType == TapType::eSecondTap) &&
|
||||
GetRenderFrame()) {
|
||||
GetRenderFrame()->TakeFocusForClickFromTap();
|
||||
}
|
||||
LayoutDeviceIntPoint offset = GetChildProcessOffset();
|
||||
return PBrowserParent::SendHandleTap(aType, aPoint + offset, aModifiers, aGuid,
|
||||
aInputBlockId);
|
||||
|
|
|
@ -34,7 +34,8 @@ namespace camera {
|
|||
CamerasSingleton::CamerasSingleton()
|
||||
: mCamerasMutex("CamerasSingleton::mCamerasMutex"),
|
||||
mCameras(nullptr),
|
||||
mCamerasChildThread(nullptr) {
|
||||
mCamerasChildThread(nullptr),
|
||||
mFakeDeviceChangeEventThread(nullptr) {
|
||||
LOG(("CamerasSingleton: %p", this));
|
||||
}
|
||||
|
||||
|
@ -58,7 +59,7 @@ public:
|
|||
|
||||
if (mCounter++ < FAKE_ONDEVICECHANGE_EVENT_REPEAT_COUNT) {
|
||||
RefPtr<FakeOnDeviceChangeEventRunnable> evt = new FakeOnDeviceChangeEventRunnable(mCounter);
|
||||
CamerasSingleton::Thread()->DelayedDispatch(evt.forget(),
|
||||
CamerasSingleton::FakeDeviceChangeEventThread()->DelayedDispatch(evt.forget(),
|
||||
FAKE_ONDEVICECHANGE_EVENT_PERIOD_IN_MS);
|
||||
}
|
||||
}
|
||||
|
@ -590,6 +591,14 @@ CamerasChild::ShutdownChild()
|
|||
LOG(("Erasing sCameras & thread refs (original thread)"));
|
||||
CamerasSingleton::Child() = nullptr;
|
||||
CamerasSingleton::Thread() = nullptr;
|
||||
|
||||
if (CamerasSingleton::FakeDeviceChangeEventThread()) {
|
||||
RefPtr<ShutdownRunnable> runnable =
|
||||
new ShutdownRunnable(NewRunnableMethod(CamerasSingleton::FakeDeviceChangeEventThread(),
|
||||
&nsIThread::Shutdown));
|
||||
CamerasSingleton::FakeDeviceChangeEventThread()->Dispatch(runnable.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
CamerasSingleton::FakeDeviceChangeEventThread() = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -627,10 +636,19 @@ CamerasChild::SetFakeDeviceChangeEvents()
|
|||
{
|
||||
CamerasSingleton::Mutex().AssertCurrentThreadOwns();
|
||||
|
||||
if(!CamerasSingleton::FakeDeviceChangeEventThread()) {
|
||||
nsresult rv = NS_NewNamedThread("Fake DC Event",
|
||||
getter_AddRefs(CamerasSingleton::FakeDeviceChangeEventThread()));
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("Error launching Fake OnDeviceChange Event Thread"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// To simulate the devicechange event in mochitest,
|
||||
// we fire a fake devicechange event in Camera IPC thread periodically
|
||||
RefPtr<FakeOnDeviceChangeEventRunnable> evt = new FakeOnDeviceChangeEventRunnable(0);
|
||||
CamerasSingleton::Thread()->Dispatch(evt.forget(), NS_DISPATCH_NORMAL);
|
||||
CamerasSingleton::FakeDeviceChangeEventThread()->Dispatch(evt.forget(), NS_DISPATCH_NORMAL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -84,6 +84,11 @@ public:
|
|||
return gTheInstance.get()->mCamerasChildThread;
|
||||
}
|
||||
|
||||
static nsCOMPtr<nsIThread>& FakeDeviceChangeEventThread() {
|
||||
Mutex().AssertCurrentThreadOwns();
|
||||
return gTheInstance.get()->mFakeDeviceChangeEventThread;
|
||||
}
|
||||
|
||||
private:
|
||||
static Singleton<CamerasSingleton> gTheInstance;
|
||||
|
||||
|
@ -100,6 +105,7 @@ private:
|
|||
// will be before actual destruction.
|
||||
CamerasChild* mCameras;
|
||||
nsCOMPtr<nsIThread> mCamerasChildThread;
|
||||
nsCOMPtr<nsIThread> mFakeDeviceChangeEventThread;
|
||||
};
|
||||
|
||||
// Get a pointer to a CamerasChild object we can use to do IPC with.
|
||||
|
|
|
@ -539,7 +539,7 @@ NPVariantToJSVal(NPP npp, JSContext *cx, const NPVariant *variant)
|
|||
}
|
||||
|
||||
bool
|
||||
JSValToNPVariant(NPP npp, JSContext *cx, JS::Value val, NPVariant *variant)
|
||||
JSValToNPVariant(NPP npp, JSContext *cx, const JS::Value& val, NPVariant *variant)
|
||||
{
|
||||
NS_ASSERTION(npp, "Must have an NPP to wrap a jsval!");
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ public:
|
|||
};
|
||||
|
||||
bool
|
||||
JSValToNPVariant(NPP npp, JSContext *cx, JS::Value val, NPVariant *variant);
|
||||
JSValToNPVariant(NPP npp, JSContext *cx, const JS::Value& val, NPVariant *variant);
|
||||
|
||||
|
||||
#endif // nsJSNPRuntime_h_
|
||||
|
|
|
@ -19,21 +19,21 @@ interface DataTransfer {
|
|||
|
||||
[Throws]
|
||||
readonly attribute DOMStringList types;
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
DOMString getData(DOMString format);
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
void setData(DOMString format, DOMString data);
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
void clearData(optional DOMString format);
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
readonly attribute FileList? files;
|
||||
};
|
||||
|
||||
partial interface DataTransfer {
|
||||
[Throws, Pref="dom.input.dirpicker"]
|
||||
[Throws, Pref="dom.input.dirpicker", NeedsSubjectPrincipal]
|
||||
Promise<sequence<(File or Directory)>> getFilesAndDirectories();
|
||||
|
||||
[Throws, Pref="dom.input.dirpicker"]
|
||||
[Throws, Pref="dom.input.dirpicker", NeedsSubjectPrincipal]
|
||||
Promise<sequence<File>> getFiles(optional boolean recursiveFlag = false);
|
||||
};
|
||||
|
||||
|
@ -115,7 +115,7 @@ partial interface DataTransfer {
|
|||
* @throws NS_ERROR_DOM_INDEX_SIZE_ERR if index is greater than itemCount
|
||||
* @throws NO_MODIFICATION_ALLOWED_ERR if the item cannot be modified
|
||||
*/
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
void mozSetDataAt(DOMString format, any data, unsigned long index);
|
||||
|
||||
/**
|
||||
|
@ -127,7 +127,7 @@ partial interface DataTransfer {
|
|||
* @returns the data of the given format, or null if it doesn't exist.
|
||||
* @throws NS_ERROR_DOM_INDEX_SIZE_ERR if index is greater or equal than itemCount
|
||||
*/
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
any mozGetDataAt(DOMString format, unsigned long index);
|
||||
|
||||
/**
|
||||
|
|
|
@ -6655,7 +6655,7 @@ EventTarget::IsOnCurrentThread(bool* aIsOnCurrentThread)
|
|||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
WorkerCrossThreadDispatcher*
|
||||
GetWorkerCrossThreadDispatcher(JSContext* aCx, JS::Value aWorker)
|
||||
GetWorkerCrossThreadDispatcher(JSContext* aCx, const JS::Value& aWorker)
|
||||
{
|
||||
if (!aWorker.isObject()) {
|
||||
return nullptr;
|
||||
|
|
|
@ -348,7 +348,7 @@ public:
|
|||
};
|
||||
|
||||
WorkerCrossThreadDispatcher*
|
||||
GetWorkerCrossThreadDispatcher(JSContext* aCx, JS::Value aWorker);
|
||||
GetWorkerCrossThreadDispatcher(JSContext* aCx, const JS::Value& aWorker);
|
||||
|
||||
// Random unique constant to facilitate JSPrincipal debugging
|
||||
const uint32_t kJSPrincipalsDebugToken = 0x7e2df9d2;
|
||||
|
|
|
@ -114,6 +114,11 @@ struct BarrierMethods<nsXBLMaybeCompiled<UncompiledT>>
|
|||
nullptr);
|
||||
}
|
||||
}
|
||||
static void exposeToJS(nsXBLMaybeCompiled<UncompiledT> fun) {
|
||||
if (fun.IsCompiled()) {
|
||||
JS::ExposeObjectToActiveJS(fun.UnsafeGetJSFunction());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
|
|
@ -87,7 +87,7 @@ public:
|
|||
void AddParameter(const nsAString& aName);
|
||||
|
||||
void SetLineNumber(uint32_t aLineNumber);
|
||||
|
||||
|
||||
virtual nsresult InstallMember(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aTargetClassObject) override;
|
||||
virtual nsresult CompileMember(mozilla::dom::AutoJSAPI& jsapi, const nsString& aClassStr,
|
||||
|
@ -137,7 +137,7 @@ public:
|
|||
explicit nsXBLProtoImplAnonymousMethod(const char16_t* aName) :
|
||||
nsXBLProtoImplMethod(aName)
|
||||
{}
|
||||
|
||||
|
||||
nsresult Execute(nsIContent* aBoundElement, JSAddonId* aAddonId);
|
||||
|
||||
// Override InstallMember; these methods never get installed as members on
|
||||
|
|
|
@ -1420,6 +1420,7 @@ DrawTargetD2D1::GetDeviceSpaceClipRect(D2D1_RECT_F& aClipRect, bool& aIsPixelAli
|
|||
return false;
|
||||
}
|
||||
|
||||
aIsPixelAligned = true;
|
||||
aClipRect = D2D1::RectF(0, 0, mSize.width, mSize.height);
|
||||
for (auto iter = CurrentLayer().mPushedClips.begin();iter != CurrentLayer().mPushedClips.end(); iter++) {
|
||||
if (iter->mGeometry) {
|
||||
|
|
|
@ -33,6 +33,25 @@
|
|||
|
||||
static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
|
||||
|
||||
/**
|
||||
** bug 1293598 - clean up every pointer after free to avoid
|
||||
** "dereferencing freed memory" problem
|
||||
**/
|
||||
#define PIXMAN_POSION
|
||||
|
||||
static void
|
||||
free_memory (void** p)
|
||||
{
|
||||
#ifdef PIXMAN_POISON
|
||||
if (*p) {
|
||||
#endif
|
||||
free (*p);
|
||||
#ifdef PIXMAN_POISON
|
||||
*p = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
gradient_property_changed (pixman_image_t *image)
|
||||
{
|
||||
|
@ -145,8 +164,8 @@ _pixman_image_fini (pixman_image_t *image)
|
|||
|
||||
pixman_region32_fini (&common->clip_region);
|
||||
|
||||
free (common->transform);
|
||||
free (common->filter_params);
|
||||
free_memory (&common->transform);
|
||||
free_memory (&common->filter_params);
|
||||
|
||||
if (common->alpha_map)
|
||||
pixman_image_unref ((pixman_image_t *)common->alpha_map);
|
||||
|
@ -158,7 +177,8 @@ _pixman_image_fini (pixman_image_t *image)
|
|||
if (image->gradient.stops)
|
||||
{
|
||||
/* See _pixman_init_gradient() for an explanation of the - 1 */
|
||||
free (image->gradient.stops - 1);
|
||||
void *addr = image->gradient.stops - 1;
|
||||
free_memory (&addr);
|
||||
}
|
||||
|
||||
/* This will trigger if someone adds a property_changed
|
||||
|
@ -169,8 +189,11 @@ _pixman_image_fini (pixman_image_t *image)
|
|||
image->common.property_changed == gradient_property_changed);
|
||||
}
|
||||
|
||||
if (image->type == BITS && image->bits.free_me)
|
||||
free (image->bits.free_me);
|
||||
if (image->type == BITS && image->bits.free_me) {
|
||||
free_memory (&image->bits.free_me);
|
||||
image->bits.bits = NULL;
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -210,7 +233,7 @@ pixman_image_unref (pixman_image_t *image)
|
|||
{
|
||||
if (_pixman_image_fini (image))
|
||||
{
|
||||
free (image);
|
||||
free_memory (&image);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ GPUProcessManager::Shutdown()
|
|||
GPUProcessManager::GPUProcessManager()
|
||||
: mTaskFactory(this),
|
||||
mNextLayerTreeId(0),
|
||||
mNumProcessAttempts(0),
|
||||
mProcess(nullptr),
|
||||
mGPUChild(nullptr)
|
||||
{
|
||||
|
@ -107,7 +108,7 @@ GPUProcessManager::OnXPCOMShutdown()
|
|||
}
|
||||
|
||||
void
|
||||
GPUProcessManager::EnableGPUProcess()
|
||||
GPUProcessManager::LaunchGPUProcess()
|
||||
{
|
||||
if (mProcess) {
|
||||
return;
|
||||
|
@ -116,6 +117,8 @@ GPUProcessManager::EnableGPUProcess()
|
|||
// Start the Vsync I/O thread so can use it as soon as the process launches.
|
||||
EnsureVsyncIOThread();
|
||||
|
||||
mNumProcessAttempts++;
|
||||
|
||||
// The subprocess is launched asynchronously, so we wait for a callback to
|
||||
// acquire the IPDL actor.
|
||||
mProcess = new GPUProcessHost(this);
|
||||
|
@ -127,6 +130,10 @@ GPUProcessManager::EnableGPUProcess()
|
|||
void
|
||||
GPUProcessManager::DisableGPUProcess(const char* aMessage)
|
||||
{
|
||||
if (!gfxConfig::IsEnabled(Feature::GPU_PROCESS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gfxConfig::SetFailed(Feature::GPU_PROCESS, FeatureStatus::Failed, aMessage);
|
||||
gfxCriticalNote << aMessage;
|
||||
|
||||
|
@ -247,6 +254,13 @@ GPUProcessManager::OnProcessUnexpectedShutdown(GPUProcessHost* aHost)
|
|||
|
||||
DestroyProcess();
|
||||
|
||||
if (mNumProcessAttempts > uint32_t(gfxPrefs::GPUProcessDevMaxRestarts())) {
|
||||
DisableGPUProcess("GPU processed crashed too many times");
|
||||
}
|
||||
if (gfxConfig::IsEnabled(Feature::GPU_PROCESS)) {
|
||||
LaunchGPUProcess();
|
||||
}
|
||||
|
||||
// The shutdown and restart sequence for the GPU process is as follows:
|
||||
//
|
||||
// (1) The GPU process dies. IPDL will enqueue an ActorDestroy message on
|
||||
|
|
|
@ -73,7 +73,7 @@ public:
|
|||
~GPUProcessManager();
|
||||
|
||||
// If not using a GPU process, launch a new GPU process asynchronously.
|
||||
void EnableGPUProcess();
|
||||
void LaunchGPUProcess();
|
||||
|
||||
// Ensure that GPU-bound methods can be used. If no GPU process is being
|
||||
// used, or one is launched and ready, this function returns immediately.
|
||||
|
@ -194,6 +194,7 @@ private:
|
|||
ipc::TaskFactory<GPUProcessManager> mTaskFactory;
|
||||
RefPtr<VsyncIOThreadHolder> mVsyncIOThread;
|
||||
uint64_t mNextLayerTreeId;
|
||||
uint32_t mNumProcessAttempts;
|
||||
|
||||
nsTArray<RefPtr<RemoteCompositorSession>> mRemoteSessions;
|
||||
nsTArray<GPUProcessListener*> mListeners;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "RemoteCompositorSession.h"
|
||||
#include "mozilla/VsyncDispatcher.h"
|
||||
#include "mozilla/layers/APZChild.h"
|
||||
#include "mozilla/layers/APZCTreeManagerChild.h"
|
||||
#include "nsBaseWidget.h"
|
||||
|
|
|
@ -843,6 +843,15 @@ CompositorBridgeChild::SendNotifyApproximatelyVisibleRegion(const ScrollableLaye
|
|||
return PCompositorBridgeChild::SendNotifyApproximatelyVisibleRegion(aGuid, aRegion);
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeChild::SendAllPluginsCaptured()
|
||||
{
|
||||
if (!mCanSend) {
|
||||
return false;
|
||||
}
|
||||
return PCompositorBridgeChild::SendAllPluginsCaptured();
|
||||
}
|
||||
|
||||
PTextureChild*
|
||||
CompositorBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
|
||||
const LayersBackend&,
|
||||
|
|
|
@ -165,6 +165,7 @@ public:
|
|||
bool SendClearApproximatelyVisibleRegions(uint64_t aLayersId, uint32_t aPresShellId);
|
||||
bool SendNotifyApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid,
|
||||
const mozilla::CSSIntRegion& aRegion);
|
||||
bool SendAllPluginsCaptured();
|
||||
bool IsSameProcess() const override;
|
||||
|
||||
virtual bool IPCOpen() const override { return mCanSend; }
|
||||
|
|
|
@ -2178,7 +2178,7 @@ gfxPlatform::InitAcceleration()
|
|||
|
||||
if (gpuProc.IsEnabled()) {
|
||||
GPUProcessManager* gpu = GPUProcessManager::Get();
|
||||
gpu->EnableGPUProcess();
|
||||
gpu->LaunchGPUProcess();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -479,6 +479,7 @@ private:
|
|||
DECL_GFX_PREF(Live, "layers.frame-counter", DrawFrameCounter, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.gpu-process.dev.enabled", GPUProcessDevEnabled, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.gpu-process.dev.timeout_ms", GPUProcessDevTimeoutMs, int32_t, 5000);
|
||||
DECL_GFX_PREF(Live, "layers.gpu-process.dev.max_restarts", GPUProcessDevMaxRestarts, int32_t, 0);
|
||||
DECL_GFX_PREF(Once, "layers.gralloc.disable", DisableGralloc, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.low-precision-buffer", UseLowPrecisionBuffer, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.low-precision-opacity", LowPrecisionOpacity, float, 1.0f);
|
||||
|
|
|
@ -501,7 +501,7 @@ imgFrame::SurfaceForDrawing(bool aDoPartialDecode,
|
|||
|
||||
if (!aDoPartialDecode) {
|
||||
return SurfaceWithFormat(new gfxSurfaceDrawable(aSurface, mImageSize),
|
||||
mFormat);
|
||||
mFormat);
|
||||
}
|
||||
|
||||
gfxRect available = gfxRect(mDecoded.x, mDecoded.y, mDecoded.width,
|
||||
|
|
|
@ -51,7 +51,7 @@ TestShellParent::CommandDone(TestShellCommandParent* command,
|
|||
|
||||
bool
|
||||
TestShellCommandParent::SetCallback(JSContext* aCx,
|
||||
JS::Value aCallback)
|
||||
const JS::Value& aCallback)
|
||||
{
|
||||
if (!mCallback.initialized()) {
|
||||
mCallback.init(aCx, aCallback);
|
||||
|
|
|
@ -42,7 +42,7 @@ class TestShellCommandParent : public PTestShellCommandParent
|
|||
public:
|
||||
TestShellCommandParent() {}
|
||||
|
||||
bool SetCallback(JSContext* aCx, JS::Value aCallback);
|
||||
bool SetCallback(JSContext* aCx, const JS::Value& aCallback);
|
||||
|
||||
bool RunCallback(const nsString& aResponse);
|
||||
|
||||
|
|
|
@ -83,6 +83,17 @@ IdToObjectMap::empty() const
|
|||
return table_.empty();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
IdToObjectMap::has(const ObjectId& id, const JSObject* obj) const
|
||||
{
|
||||
auto p = table_.lookup(id);
|
||||
if (!p)
|
||||
return false;
|
||||
return p->value().unbarrieredGet() == obj;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
ObjectToIdMap::init()
|
||||
{
|
||||
|
|
|
@ -101,6 +101,10 @@ class IdToObjectMap
|
|||
void clear();
|
||||
bool empty() const;
|
||||
|
||||
#ifdef DEBUG
|
||||
bool has(const ObjectId& id, const JSObject* obj) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
Table table_;
|
||||
};
|
||||
|
@ -173,6 +177,12 @@ class JavaScriptShared : public CPOWManager
|
|||
}
|
||||
JSObject* findObjectById(JSContext* cx, const ObjectId& objId);
|
||||
|
||||
#ifdef DEBUG
|
||||
bool hasCPOW(const ObjectId& objId, const JSObject* obj) {
|
||||
return cpows_.has(objId, obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool LoggingEnabled() { return sLoggingEnabled; }
|
||||
static bool StackLoggingEnabled() { return sStackLoggingEnabled; }
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ ObjectId
|
|||
WrapperOwner::idOf(JSObject* obj)
|
||||
{
|
||||
ObjectId objId = idOfUnchecked(obj);
|
||||
MOZ_ASSERT(findCPOWById(objId) == obj);
|
||||
MOZ_ASSERT(hasCPOW(objId, obj));
|
||||
return objId;
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ class CPOWProxyHandler : public BaseProxyHandler
|
|||
constexpr CPOWProxyHandler()
|
||||
: BaseProxyHandler(&family) {}
|
||||
|
||||
virtual bool finalizeInBackground(Value priv) const override {
|
||||
virtual bool finalizeInBackground(const Value& priv) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -930,7 +930,7 @@ void
|
|||
WrapperOwner::updatePointer(JSObject* obj, const JSObject* old)
|
||||
{
|
||||
ObjectId objId = idOfUnchecked(obj);
|
||||
MOZ_ASSERT(findCPOWById(objId) == old);
|
||||
MOZ_ASSERT(hasCPOW(objId, old));
|
||||
cpows_.add(objId, obj);
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ ComputeThis(JSContext* cx, JS::Value* vp);
|
|||
|
||||
#ifdef JS_DEBUG
|
||||
extern JS_PUBLIC_API(void)
|
||||
CheckIsValidConstructible(Value v);
|
||||
CheckIsValidConstructible(const Value& v);
|
||||
#endif
|
||||
|
||||
class MOZ_STACK_CLASS IncludeUsedRval
|
||||
|
@ -241,12 +241,12 @@ class MOZ_STACK_CLASS CallArgsBase : public WantUsedRval
|
|||
// implementing a JSNative method and encapsulating access to |vp| within
|
||||
// it. You probably don't want to use these!
|
||||
|
||||
void setCallee(Value aCalleev) const {
|
||||
void setCallee(const Value& aCalleev) const {
|
||||
this->clearUsedRval();
|
||||
argv_[-2] = aCalleev;
|
||||
}
|
||||
|
||||
void setThis(Value aThisv) const {
|
||||
void setThis(const Value& aThisv) const {
|
||||
argv_[-1] = aThisv;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ ToBooleanSlow(JS::HandleValue v);
|
|||
|
||||
/* DO NOT CALL THIS. Use JS::ToNumber. */
|
||||
extern JS_PUBLIC_API(bool)
|
||||
ToNumberSlow(JSContext* cx, JS::Value v, double* dp);
|
||||
ToNumberSlow(JSContext* cx, const JS::Value& v, double* dp);
|
||||
|
||||
/* DO NOT CALL THIS. Use JS::ToInt8. */
|
||||
extern JS_PUBLIC_API(bool)
|
||||
|
|
|
@ -361,31 +361,6 @@ GetStringZone(JSString* str)
|
|||
extern JS_PUBLIC_API(Zone*)
|
||||
GetObjectZone(JSObject* obj);
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
ObjectIsTenured(JSObject* obj)
|
||||
{
|
||||
return !js::gc::IsInsideNursery(reinterpret_cast<js::gc::Cell*>(obj));
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
ObjectIsMarkedGray(JSObject* obj)
|
||||
{
|
||||
/*
|
||||
* GC things residing in the nursery cannot be gray: they have no mark bits.
|
||||
* All live objects in the nursery are moved to tenured at the beginning of
|
||||
* each GC slice, so the gray marker never sees nursery things.
|
||||
*/
|
||||
if (js::gc::IsInsideNursery(reinterpret_cast<js::gc::Cell*>(obj)))
|
||||
return false;
|
||||
return js::gc::detail::CellIsMarkedGray(reinterpret_cast<js::gc::Cell*>(obj));
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
ScriptIsMarkedGray(JSScript* script)
|
||||
{
|
||||
return js::gc::detail::CellIsMarkedGray(reinterpret_cast<js::gc::Cell*>(script));
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
GCThingIsMarkedGray(GCCellPtr thing)
|
||||
{
|
||||
|
|
|
@ -191,13 +191,17 @@ template <>
|
|||
struct BarrierMethods<jsid>
|
||||
{
|
||||
static void postBarrier(jsid* idp, jsid prev, jsid next) {}
|
||||
static void exposeToJS(jsid id) {
|
||||
if (JSID_IS_GCTHING(id))
|
||||
js::gc::ExposeGCThingToActiveJS(JSID_TO_GCTHING(id));
|
||||
}
|
||||
};
|
||||
|
||||
// If the jsid is a GC pointer type, convert to that type and call |f| with
|
||||
// the pointer. If the jsid is not a GC type, calls F::defaultValue.
|
||||
template <typename F, typename... Args>
|
||||
auto
|
||||
DispatchTyped(F f, jsid& id, Args&&... args)
|
||||
DispatchTyped(F f, const jsid& id, Args&&... args)
|
||||
-> decltype(f(static_cast<JSString*>(nullptr), mozilla::Forward<Args>(args)...))
|
||||
{
|
||||
if (JSID_IS_STRING(id))
|
||||
|
|
|
@ -211,7 +211,7 @@ class JS_FRIEND_API(BaseProxyHandler)
|
|||
return offsetof(BaseProxyHandler, mFamily);
|
||||
}
|
||||
|
||||
virtual bool finalizeInBackground(Value priv) const {
|
||||
virtual bool finalizeInBackground(const Value& priv) const {
|
||||
/*
|
||||
* Called on creation of a proxy to determine whether its finalize
|
||||
* method can be finalized on the background thread.
|
||||
|
@ -534,7 +534,7 @@ NewProxyObject(JSContext* cx, const BaseProxyHandler* handler, HandleValue priv,
|
|||
JSObject* proto, const ProxyOptions& options = ProxyOptions());
|
||||
|
||||
JSObject*
|
||||
RenewProxyObject(JSContext* cx, JSObject* obj, BaseProxyHandler* handler, Value priv);
|
||||
RenewProxyObject(JSContext* cx, JSObject* obj, BaseProxyHandler* handler, const Value& priv);
|
||||
|
||||
class JS_FRIEND_API(AutoEnterPolicy)
|
||||
{
|
||||
|
|
|
@ -238,7 +238,7 @@ class Heap : public js::HeapBase<T>
|
|||
"Heap<T> must be binary compatible with T.");
|
||||
init(GCPolicy<T>::initial());
|
||||
}
|
||||
explicit Heap(T p) { init(p); }
|
||||
explicit Heap(const T& p) { init(p); }
|
||||
|
||||
/*
|
||||
* For Heap, move semantics are equivalent to copy semantics. In C++, a
|
||||
|
@ -254,10 +254,25 @@ class Heap : public js::HeapBase<T>
|
|||
|
||||
DECLARE_POINTER_CONSTREF_OPS(T);
|
||||
DECLARE_POINTER_ASSIGN_OPS(Heap, T);
|
||||
DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr);
|
||||
|
||||
const T* address() const { return &ptr; }
|
||||
const T& get() const {
|
||||
js::BarrierMethods<T>::exposeToJS(ptr);
|
||||
return ptr;
|
||||
}
|
||||
const T& unbarrieredGet() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
T* unsafeGet() { return &ptr; }
|
||||
|
||||
explicit operator bool() const {
|
||||
return bool(js::BarrierMethods<T>::asGCThingOrNull(ptr));
|
||||
}
|
||||
explicit operator bool() {
|
||||
return bool(js::BarrierMethods<T>::asGCThingOrNull(ptr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the pointer to a value which will cause a crash if it is
|
||||
* dereferenced.
|
||||
|
@ -271,12 +286,12 @@ class Heap : public js::HeapBase<T>
|
|||
}
|
||||
|
||||
private:
|
||||
void init(T newPtr) {
|
||||
void init(const T& newPtr) {
|
||||
ptr = newPtr;
|
||||
post(GCPolicy<T>::initial(), ptr);
|
||||
}
|
||||
|
||||
void set(T newPtr) {
|
||||
void set(const T& newPtr) {
|
||||
T tmp = ptr;
|
||||
ptr = newPtr;
|
||||
post(tmp, ptr);
|
||||
|
@ -293,6 +308,49 @@ class Heap : public js::HeapBase<T>
|
|||
T ptr;
|
||||
};
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
ObjectIsTenured(JSObject* obj)
|
||||
{
|
||||
return !js::gc::IsInsideNursery(reinterpret_cast<js::gc::Cell*>(obj));
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
ObjectIsTenured(const Heap<JSObject*>& obj)
|
||||
{
|
||||
return ObjectIsTenured(obj.unbarrieredGet());
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
ObjectIsMarkedGray(JSObject* obj)
|
||||
{
|
||||
/*
|
||||
* GC things residing in the nursery cannot be gray: they have no mark bits.
|
||||
* All live objects in the nursery are moved to tenured at the beginning of
|
||||
* each GC slice, so the gray marker never sees nursery things.
|
||||
*/
|
||||
if (js::gc::IsInsideNursery(reinterpret_cast<js::gc::Cell*>(obj)))
|
||||
return false;
|
||||
return js::gc::detail::CellIsMarkedGray(reinterpret_cast<js::gc::Cell*>(obj));
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
ObjectIsMarkedGray(const JS::Heap<JSObject*>& obj)
|
||||
{
|
||||
return ObjectIsMarkedGray(obj.unbarrieredGet());
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
ScriptIsMarkedGray(JSScript* script)
|
||||
{
|
||||
return js::gc::detail::CellIsMarkedGray(reinterpret_cast<js::gc::Cell*>(script));
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
ScriptIsMarkedGray(const Heap<JSScript*>& script)
|
||||
{
|
||||
return ScriptIsMarkedGray(script.unbarrieredGet());
|
||||
}
|
||||
|
||||
/**
|
||||
* The TenuredHeap<T> class is similar to the Heap<T> class above in that it
|
||||
* encapsulates the GC concerns of an on-heap reference to a JS object. However,
|
||||
|
@ -492,7 +550,7 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase<T>
|
|||
MutableHandle(decltype(nullptr)) = delete;
|
||||
|
||||
public:
|
||||
void set(T v) {
|
||||
void set(const T& v) {
|
||||
*ptr = v;
|
||||
}
|
||||
|
||||
|
@ -528,11 +586,20 @@ template <typename T>
|
|||
struct BarrierMethods<T*>
|
||||
{
|
||||
static T* initial() { return nullptr; }
|
||||
static gc::Cell* asGCThingOrNull(T* v) {
|
||||
if (!v)
|
||||
return nullptr;
|
||||
MOZ_ASSERT(uintptr_t(v) > 32);
|
||||
return reinterpret_cast<gc::Cell*>(v);
|
||||
}
|
||||
static void postBarrier(T** vp, T* prev, T* next) {
|
||||
if (next)
|
||||
JS::AssertGCThingIsNotAnObjectSubclass(reinterpret_cast<js::gc::Cell*>(next));
|
||||
}
|
||||
static void relocate(T** vp) {}
|
||||
static void exposeToJS(T* t) {
|
||||
if (t)
|
||||
js::gc::ExposeGCThingToActiveJS(JS::GCCellPtr(t));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
|
@ -548,17 +615,31 @@ struct BarrierMethods<JSObject*>
|
|||
static void postBarrier(JSObject** vp, JSObject* prev, JSObject* next) {
|
||||
JS::HeapObjectPostBarrier(vp, prev, next);
|
||||
}
|
||||
static void exposeToJS(JSObject* obj) {
|
||||
if (obj)
|
||||
JS::ExposeObjectToActiveJS(obj);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct BarrierMethods<JSFunction*>
|
||||
{
|
||||
static JSFunction* initial() { return nullptr; }
|
||||
static gc::Cell* asGCThingOrNull(JSFunction* v) {
|
||||
if (!v)
|
||||
return nullptr;
|
||||
MOZ_ASSERT(uintptr_t(v) > 32);
|
||||
return reinterpret_cast<gc::Cell*>(v);
|
||||
}
|
||||
static void postBarrier(JSFunction** vp, JSFunction* prev, JSFunction* next) {
|
||||
JS::HeapObjectPostBarrier(reinterpret_cast<JSObject**>(vp),
|
||||
reinterpret_cast<JSObject*>(prev),
|
||||
reinterpret_cast<JSObject*>(next));
|
||||
}
|
||||
static void exposeToJS(JSFunction* fun) {
|
||||
if (fun)
|
||||
JS::ExposeObjectToActiveJS(reinterpret_cast<JSObject*>(fun));
|
||||
}
|
||||
};
|
||||
|
||||
// Provide hash codes for Cell kinds that may be relocated and, thus, not have
|
||||
|
@ -594,7 +675,9 @@ struct JS_PUBLIC_API(MovableCellHasher<JS::Heap<T>>)
|
|||
static bool hasHash(const Lookup& l) { return MovableCellHasher<T>::hasHash(l); }
|
||||
static bool ensureHash(const Lookup& l) { return MovableCellHasher<T>::ensureHash(l); }
|
||||
static HashNumber hash(const Lookup& l) { return MovableCellHasher<T>::hash(l); }
|
||||
static bool match(const Key& k, const Lookup& l) { return MovableCellHasher<T>::match(k, l); }
|
||||
static bool match(const Key& k, const Lookup& l) {
|
||||
return MovableCellHasher<T>::match(k.unbarrieredGet(), l);
|
||||
}
|
||||
static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); }
|
||||
};
|
||||
|
||||
|
@ -713,7 +796,7 @@ class MOZ_RAII Rooted : public js::RootedBase<T>
|
|||
* This method is public for Rooted so that Codegen.py can use a Rooted
|
||||
* interchangeably with a MutableHandleValue.
|
||||
*/
|
||||
void set(T value) {
|
||||
void set(const T& value) {
|
||||
ptr = value;
|
||||
}
|
||||
|
||||
|
@ -829,7 +912,7 @@ class FakeMutableHandle : public js::MutableHandleBase<T>
|
|||
ptr = root->address();
|
||||
}
|
||||
|
||||
void set(T v) {
|
||||
void set(const T& v) {
|
||||
*ptr = v;
|
||||
}
|
||||
|
||||
|
@ -886,7 +969,7 @@ template <typename T> class MaybeRooted<T, CanGC>
|
|||
template <typename T> class MaybeRooted<T, NoGC>
|
||||
{
|
||||
public:
|
||||
typedef T HandleType;
|
||||
typedef const T& HandleType;
|
||||
typedef FakeRooted<T> RootType;
|
||||
typedef FakeMutableHandle<T> MutableHandleType;
|
||||
|
||||
|
@ -1114,6 +1197,7 @@ class JS_PUBLIC_API(ObjectPtr)
|
|||
void init(JSObject* obj) { value = obj; }
|
||||
|
||||
JSObject* get() const { return value; }
|
||||
JSObject* unbarrieredGet() const { return value.unbarrieredGet(); }
|
||||
|
||||
void writeBarrierPre(JSContext* cx) {
|
||||
IncrementalObjectBarrier(value);
|
||||
|
@ -1132,6 +1216,9 @@ class JS_PUBLIC_API(ObjectPtr)
|
|||
JSObject& operator*() const { return *value; }
|
||||
JSObject* operator->() const { return value; }
|
||||
operator JSObject*() const { return value; }
|
||||
|
||||
explicit operator bool() const { return value.unbarrieredGet(); }
|
||||
explicit operator bool() { return value.unbarrieredGet(); }
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
|
|
|
@ -393,7 +393,7 @@ BUILD_JSVAL(JSValueTag tag, uint32_t payload)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_DOUBLE_IMPL(jsval_layout l)
|
||||
JSVAL_IS_DOUBLE_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return (uint32_t)l.s.tag <= (uint32_t)JSVAL_TAG_CLEAR;
|
||||
}
|
||||
|
@ -408,13 +408,13 @@ DOUBLE_TO_JSVAL_IMPL(double d)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_INT32_IMPL(jsval_layout l)
|
||||
JSVAL_IS_INT32_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.tag == JSVAL_TAG_INT32;
|
||||
}
|
||||
|
||||
static inline int32_t
|
||||
JSVAL_TO_INT32_IMPL(jsval_layout l)
|
||||
JSVAL_TO_INT32_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.payload.i32;
|
||||
}
|
||||
|
@ -433,7 +433,7 @@ INT32_TO_JSVAL_IMPL(int32_t i)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_NUMBER_IMPL(jsval_layout l)
|
||||
JSVAL_IS_NUMBER_IMPL(const jsval_layout& l)
|
||||
{
|
||||
JSValueTag tag = l.s.tag;
|
||||
MOZ_ASSERT(tag != JSVAL_TAG_CLEAR);
|
||||
|
@ -441,13 +441,13 @@ JSVAL_IS_NUMBER_IMPL(jsval_layout l)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_UNDEFINED_IMPL(jsval_layout l)
|
||||
JSVAL_IS_UNDEFINED_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.tag == JSVAL_TAG_UNDEFINED;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_STRING_IMPL(jsval_layout l)
|
||||
JSVAL_IS_STRING_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.tag == JSVAL_TAG_STRING;
|
||||
}
|
||||
|
@ -463,13 +463,13 @@ STRING_TO_JSVAL_IMPL(JSString* str)
|
|||
}
|
||||
|
||||
static inline JSString*
|
||||
JSVAL_TO_STRING_IMPL(jsval_layout l)
|
||||
JSVAL_TO_STRING_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.payload.str;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_SYMBOL_IMPL(jsval_layout l)
|
||||
JSVAL_IS_SYMBOL_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.tag == JSVAL_TAG_SYMBOL;
|
||||
}
|
||||
|
@ -485,19 +485,19 @@ SYMBOL_TO_JSVAL_IMPL(JS::Symbol* sym)
|
|||
}
|
||||
|
||||
static inline JS::Symbol*
|
||||
JSVAL_TO_SYMBOL_IMPL(jsval_layout l)
|
||||
JSVAL_TO_SYMBOL_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.payload.sym;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_BOOLEAN_IMPL(jsval_layout l)
|
||||
JSVAL_IS_BOOLEAN_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.tag == JSVAL_TAG_BOOLEAN;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_TO_BOOLEAN_IMPL(jsval_layout l)
|
||||
JSVAL_TO_BOOLEAN_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return bool(l.s.payload.boo);
|
||||
}
|
||||
|
@ -512,32 +512,32 @@ BOOLEAN_TO_JSVAL_IMPL(bool b)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_MAGIC_IMPL(jsval_layout l)
|
||||
JSVAL_IS_MAGIC_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.tag == JSVAL_TAG_MAGIC;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_OBJECT_IMPL(jsval_layout l)
|
||||
JSVAL_IS_OBJECT_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.tag == JSVAL_TAG_OBJECT;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l)
|
||||
JSVAL_IS_PRIMITIVE_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return (uint32_t)l.s.tag < (uint32_t)JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l)
|
||||
JSVAL_IS_OBJECT_OR_NULL_IMPL(const jsval_layout& l)
|
||||
{
|
||||
MOZ_ASSERT((uint32_t)l.s.tag <= (uint32_t)JSVAL_TAG_OBJECT);
|
||||
return (uint32_t)l.s.tag >= (uint32_t)JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET;
|
||||
}
|
||||
|
||||
static inline JSObject*
|
||||
JSVAL_TO_OBJECT_IMPL(jsval_layout l)
|
||||
JSVAL_TO_OBJECT_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.payload.obj;
|
||||
}
|
||||
|
@ -553,7 +553,7 @@ OBJECT_TO_JSVAL_IMPL(JSObject* obj)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_NULL_IMPL(jsval_layout l)
|
||||
JSVAL_IS_NULL_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.tag == JSVAL_TAG_NULL;
|
||||
}
|
||||
|
@ -570,7 +570,7 @@ PRIVATE_PTR_TO_JSVAL_IMPL(void* ptr)
|
|||
}
|
||||
|
||||
static inline void*
|
||||
JSVAL_TO_PRIVATE_PTR_IMPL(jsval_layout l)
|
||||
JSVAL_TO_PRIVATE_PTR_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.payload.ptr;
|
||||
}
|
||||
|
@ -593,26 +593,26 @@ PRIVATE_GCTHING_TO_JSVAL_IMPL(js::gc::Cell* cell)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_PRIVATE_GCTHING_IMPL(jsval_layout l)
|
||||
JSVAL_IS_PRIVATE_GCTHING_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.tag == JSVAL_TAG_PRIVATE_GCTHING;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_GCTHING_IMPL(jsval_layout l)
|
||||
JSVAL_IS_GCTHING_IMPL(const jsval_layout& l)
|
||||
{
|
||||
/* gcc sometimes generates signed < without explicit casts. */
|
||||
return (uint32_t)l.s.tag >= (uint32_t)JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET;
|
||||
}
|
||||
|
||||
static inline js::gc::Cell*
|
||||
JSVAL_TO_GCTHING_IMPL(jsval_layout l)
|
||||
JSVAL_TO_GCTHING_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.s.payload.cell;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
JSVAL_TRACE_KIND_IMPL(jsval_layout l)
|
||||
JSVAL_TRACE_KIND_IMPL(const jsval_layout& l)
|
||||
{
|
||||
static_assert((JSVAL_TAG_STRING & 0x03) == size_t(JS::TraceKind::String),
|
||||
"Value type tags must correspond with JS::TraceKinds.");
|
||||
|
@ -626,13 +626,13 @@ JSVAL_TRACE_KIND_IMPL(jsval_layout l)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32_t i32)
|
||||
JSVAL_IS_SPECIFIC_INT32_IMPL(const jsval_layout& l, int32_t i32)
|
||||
{
|
||||
return l.s.tag == JSVAL_TAG_INT32 && l.s.payload.i32 == i32;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_SPECIFIC_BOOLEAN_IMPL(jsval_layout l, bool b)
|
||||
JSVAL_IS_SPECIFIC_BOOLEAN_IMPL(const jsval_layout& l, bool b)
|
||||
{
|
||||
return (l.s.tag == JSVAL_TAG_BOOLEAN) && (l.s.payload.boo == uint32_t(b));
|
||||
}
|
||||
|
@ -656,14 +656,14 @@ MAGIC_UINT32_TO_JSVAL_IMPL(uint32_t payload)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs)
|
||||
JSVAL_SAME_TYPE_IMPL(const jsval_layout& lhs, const jsval_layout& rhs)
|
||||
{
|
||||
JSValueTag ltag = lhs.s.tag, rtag = rhs.s.tag;
|
||||
return ltag == rtag || (ltag < JSVAL_TAG_CLEAR && rtag < JSVAL_TAG_CLEAR);
|
||||
}
|
||||
|
||||
static inline JSValueType
|
||||
JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l)
|
||||
JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(const jsval_layout& l)
|
||||
{
|
||||
uint32_t type = l.s.tag & 0xF;
|
||||
MOZ_ASSERT(type > JSVAL_TYPE_DOUBLE);
|
||||
|
@ -679,7 +679,7 @@ BUILD_JSVAL(JSValueTag tag, uint64_t payload)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_DOUBLE_IMPL(jsval_layout l)
|
||||
JSVAL_IS_DOUBLE_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return (l.asBits | mozilla::DoubleTypeTraits::kSignBit) <= JSVAL_SHIFTED_TAG_MAX_DOUBLE;
|
||||
}
|
||||
|
@ -694,13 +694,13 @@ DOUBLE_TO_JSVAL_IMPL(double d)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_INT32_IMPL(jsval_layout l)
|
||||
JSVAL_IS_INT32_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_INT32;
|
||||
}
|
||||
|
||||
static inline int32_t
|
||||
JSVAL_TO_INT32_IMPL(jsval_layout l)
|
||||
JSVAL_TO_INT32_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return (int32_t)l.asBits;
|
||||
}
|
||||
|
@ -712,19 +712,19 @@ INT32_TO_JSVAL_IMPL(int32_t i32)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_NUMBER_IMPL(jsval_layout l)
|
||||
JSVAL_IS_NUMBER_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_UNDEFINED_IMPL(jsval_layout l)
|
||||
JSVAL_IS_UNDEFINED_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.asBits == JSVAL_SHIFTED_TAG_UNDEFINED;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_STRING_IMPL(jsval_layout l)
|
||||
JSVAL_IS_STRING_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_STRING;
|
||||
}
|
||||
|
@ -741,13 +741,13 @@ STRING_TO_JSVAL_IMPL(JSString* str)
|
|||
}
|
||||
|
||||
static inline JSString*
|
||||
JSVAL_TO_STRING_IMPL(jsval_layout l)
|
||||
JSVAL_TO_STRING_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return (JSString*)(l.asBits & JSVAL_PAYLOAD_MASK);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_SYMBOL_IMPL(jsval_layout l)
|
||||
JSVAL_IS_SYMBOL_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_SYMBOL;
|
||||
}
|
||||
|
@ -764,19 +764,19 @@ SYMBOL_TO_JSVAL_IMPL(JS::Symbol* sym)
|
|||
}
|
||||
|
||||
static inline JS::Symbol*
|
||||
JSVAL_TO_SYMBOL_IMPL(jsval_layout l)
|
||||
JSVAL_TO_SYMBOL_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return (JS::Symbol*)(l.asBits & JSVAL_PAYLOAD_MASK);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_BOOLEAN_IMPL(jsval_layout l)
|
||||
JSVAL_IS_BOOLEAN_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_BOOLEAN;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_TO_BOOLEAN_IMPL(jsval_layout l)
|
||||
JSVAL_TO_BOOLEAN_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return (bool)(l.asBits & JSVAL_PAYLOAD_MASK);
|
||||
}
|
||||
|
@ -790,33 +790,33 @@ BOOLEAN_TO_JSVAL_IMPL(bool b)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_MAGIC_IMPL(jsval_layout l)
|
||||
JSVAL_IS_MAGIC_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return (l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_MAGIC;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l)
|
||||
JSVAL_IS_PRIMITIVE_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_OBJECT_IMPL(jsval_layout l)
|
||||
JSVAL_IS_OBJECT_IMPL(const jsval_layout& l)
|
||||
{
|
||||
MOZ_ASSERT((l.asBits >> JSVAL_TAG_SHIFT) <= JSVAL_TAG_OBJECT);
|
||||
return l.asBits >= JSVAL_SHIFTED_TAG_OBJECT;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l)
|
||||
JSVAL_IS_OBJECT_OR_NULL_IMPL(const jsval_layout& l)
|
||||
{
|
||||
MOZ_ASSERT((l.asBits >> JSVAL_TAG_SHIFT) <= JSVAL_TAG_OBJECT);
|
||||
return l.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET;
|
||||
}
|
||||
|
||||
static inline JSObject*
|
||||
JSVAL_TO_OBJECT_IMPL(jsval_layout l)
|
||||
JSVAL_TO_OBJECT_IMPL(const jsval_layout& l)
|
||||
{
|
||||
uint64_t ptrBits = l.asBits & JSVAL_PAYLOAD_MASK;
|
||||
MOZ_ASSERT((ptrBits & 0x7) == 0);
|
||||
|
@ -835,25 +835,25 @@ OBJECT_TO_JSVAL_IMPL(JSObject* obj)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_NULL_IMPL(jsval_layout l)
|
||||
JSVAL_IS_NULL_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.asBits == JSVAL_SHIFTED_TAG_NULL;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_PRIVATE_GCTHING_IMPL(jsval_layout l)
|
||||
JSVAL_IS_PRIVATE_GCTHING_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return (l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_PRIVATE_GCTHING;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_GCTHING_IMPL(jsval_layout l)
|
||||
JSVAL_IS_GCTHING_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return l.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET;
|
||||
}
|
||||
|
||||
static inline js::gc::Cell*
|
||||
JSVAL_TO_GCTHING_IMPL(jsval_layout l)
|
||||
JSVAL_TO_GCTHING_IMPL(const jsval_layout& l)
|
||||
{
|
||||
uint64_t ptrBits = l.asBits & JSVAL_PAYLOAD_MASK;
|
||||
MOZ_ASSERT((ptrBits & 0x7) == 0);
|
||||
|
@ -861,7 +861,7 @@ JSVAL_TO_GCTHING_IMPL(jsval_layout l)
|
|||
}
|
||||
|
||||
static inline uint32_t
|
||||
JSVAL_TRACE_KIND_IMPL(jsval_layout l)
|
||||
JSVAL_TRACE_KIND_IMPL(const jsval_layout& l)
|
||||
{
|
||||
static_assert((JSVAL_TAG_STRING & 0x03) == size_t(JS::TraceKind::String),
|
||||
"Value type tags must correspond with JS::TraceKinds.");
|
||||
|
@ -886,7 +886,7 @@ PRIVATE_PTR_TO_JSVAL_IMPL(void* ptr)
|
|||
}
|
||||
|
||||
static inline void*
|
||||
JSVAL_TO_PRIVATE_PTR_IMPL(jsval_layout l)
|
||||
JSVAL_TO_PRIVATE_PTR_IMPL(const jsval_layout& l)
|
||||
{
|
||||
MOZ_ASSERT((l.asBits & 0x8000000000000000LL) == 0);
|
||||
return (void*)(l.asBits << 1);
|
||||
|
@ -911,13 +911,13 @@ PRIVATE_GCTHING_TO_JSVAL_IMPL(js::gc::Cell* cell)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32_t i32)
|
||||
JSVAL_IS_SPECIFIC_INT32_IMPL(const jsval_layout& l, int32_t i32)
|
||||
{
|
||||
return l.asBits == (((uint64_t)(uint32_t)i32) | JSVAL_SHIFTED_TAG_INT32);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_SPECIFIC_BOOLEAN_IMPL(jsval_layout l, bool b)
|
||||
JSVAL_IS_SPECIFIC_BOOLEAN_IMPL(const jsval_layout& l, bool b)
|
||||
{
|
||||
return l.asBits == (((uint64_t)(uint32_t)b) | JSVAL_SHIFTED_TAG_BOOLEAN);
|
||||
}
|
||||
|
@ -939,14 +939,14 @@ MAGIC_UINT32_TO_JSVAL_IMPL(uint32_t payload)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs)
|
||||
JSVAL_SAME_TYPE_IMPL(const jsval_layout& lhs, const jsval_layout& rhs)
|
||||
{
|
||||
return (JSVAL_IS_DOUBLE_IMPL(lhs) && JSVAL_IS_DOUBLE_IMPL(rhs)) ||
|
||||
(((lhs.asBits ^ rhs.asBits) & 0xFFFF800000000000LL) == 0);
|
||||
}
|
||||
|
||||
static inline JSValueType
|
||||
JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l)
|
||||
JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(const jsval_layout& l)
|
||||
{
|
||||
uint64_t type = (l.asBits >> JSVAL_TAG_SHIFT) & 0xF;
|
||||
MOZ_ASSERT(type > JSVAL_TYPE_DOUBLE);
|
||||
|
@ -956,13 +956,13 @@ JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l)
|
|||
#endif /* JS_PUNBOX64 */
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_TRACEABLE_IMPL(jsval_layout l)
|
||||
JSVAL_IS_TRACEABLE_IMPL(const jsval_layout& l)
|
||||
{
|
||||
return JSVAL_IS_GCTHING_IMPL(l) && !JSVAL_IS_NULL_IMPL(l);
|
||||
}
|
||||
|
||||
static inline jsval_layout JSVAL_TO_IMPL(JS::Value v);
|
||||
static inline JS_VALUE_CONSTEXPR JS::Value IMPL_TO_JSVAL(jsval_layout l);
|
||||
static inline jsval_layout JSVAL_TO_IMPL(const JS::Value& v);
|
||||
static inline JS_VALUE_CONSTEXPR JS::Value IMPL_TO_JSVAL(const jsval_layout& l);
|
||||
|
||||
namespace JS {
|
||||
|
||||
|
@ -1392,7 +1392,7 @@ class Value
|
|||
|
||||
private:
|
||||
#if defined(JS_VALUE_IS_CONSTEXPR)
|
||||
MOZ_IMPLICIT JS_VALUE_CONSTEXPR Value(jsval_layout layout) : data(layout) {}
|
||||
MOZ_IMPLICIT JS_VALUE_CONSTEXPR Value(const jsval_layout& layout) : data(layout) {}
|
||||
#endif
|
||||
|
||||
void staticAssertions() {
|
||||
|
@ -1402,8 +1402,8 @@ class Value
|
|||
JS_STATIC_ASSERT(sizeof(Value) == 8);
|
||||
}
|
||||
|
||||
friend jsval_layout (::JSVAL_TO_IMPL)(Value);
|
||||
friend Value JS_VALUE_CONSTEXPR (::IMPL_TO_JSVAL)(jsval_layout l);
|
||||
friend jsval_layout (::JSVAL_TO_IMPL)(const Value&);
|
||||
friend Value JS_VALUE_CONSTEXPR (::IMPL_TO_JSVAL)(const jsval_layout& l);
|
||||
friend Value JS_VALUE_CONSTEXPR (JS::UndefinedValue)();
|
||||
} JS_HAZ_GC_POINTER;
|
||||
|
||||
|
@ -1739,6 +1739,9 @@ struct BarrierMethods<JS::Value>
|
|||
static void postBarrier(JS::Value* v, const JS::Value& prev, const JS::Value& next) {
|
||||
JS::HeapValuePostBarrier(v, prev, next);
|
||||
}
|
||||
static void exposeToJS(JS::Value v) {
|
||||
JS::ExposeValueToActiveJS(v);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Outer> class MutableValueOperations;
|
||||
|
@ -1922,20 +1925,20 @@ DispatchTyped(F f, const JS::Value& val, Args&&... args)
|
|||
return F::defaultValue(val);
|
||||
}
|
||||
|
||||
template <class S> struct VoidDefaultAdaptor { static void defaultValue(S) {} };
|
||||
template <class S> struct VoidDefaultAdaptor { static void defaultValue(const S&) {} };
|
||||
template <class S> struct IdentityDefaultAdaptor { static S defaultValue(const S& v) {return v;} };
|
||||
template <class S, bool v> struct BoolDefaultAdaptor { static bool defaultValue(S) { return v; } };
|
||||
template <class S, bool v> struct BoolDefaultAdaptor { static bool defaultValue(const S&) { return v; } };
|
||||
|
||||
} // namespace js
|
||||
|
||||
inline jsval_layout
|
||||
JSVAL_TO_IMPL(JS::Value v)
|
||||
JSVAL_TO_IMPL(const JS::Value& v)
|
||||
{
|
||||
return v.data;
|
||||
}
|
||||
|
||||
inline JS_VALUE_CONSTEXPR JS::Value
|
||||
IMPL_TO_JSVAL(jsval_layout l)
|
||||
IMPL_TO_JSVAL(const jsval_layout& l)
|
||||
{
|
||||
#if defined(JS_VALUE_IS_CONSTEXPR)
|
||||
return JS::Value(l);
|
||||
|
|
|
@ -858,7 +858,7 @@ class NumLit
|
|||
public:
|
||||
NumLit() = default;
|
||||
|
||||
NumLit(Which w, Value v) : which_(w) {
|
||||
NumLit(Which w, const Value& v) : which_(w) {
|
||||
u.scalar_ = v;
|
||||
MOZ_ASSERT(!isSimd());
|
||||
}
|
||||
|
@ -1296,6 +1296,46 @@ class Type
|
|||
return NonVoidToValType(canonicalToExprType());
|
||||
}
|
||||
|
||||
// Convert this type to a wasm::ExprType for use in a wasm
|
||||
// block signature. This works for all types, including non-canonical
|
||||
// ones. Consequently, the type isn't valid for subsequent asm.js
|
||||
// validation; it's only valid for use in producing wasm.
|
||||
ExprType toWasmBlockSignatureType() const {
|
||||
switch (which()) {
|
||||
case Fixnum:
|
||||
case Signed:
|
||||
case Unsigned:
|
||||
case Int:
|
||||
case Intish:
|
||||
return ExprType::I32;
|
||||
|
||||
case Float:
|
||||
case MaybeFloat:
|
||||
case Floatish:
|
||||
return ExprType::F32;
|
||||
|
||||
case DoubleLit:
|
||||
case Double:
|
||||
case MaybeDouble:
|
||||
return ExprType::F64;
|
||||
|
||||
case Void:
|
||||
return ExprType::Void;
|
||||
|
||||
case Uint8x16:
|
||||
case Int8x16: return ExprType::I8x16;
|
||||
case Uint16x8:
|
||||
case Int16x8: return ExprType::I16x8;
|
||||
case Uint32x4:
|
||||
case Int32x4: return ExprType::I32x4;
|
||||
case Float32x4: return ExprType::F32x4;
|
||||
case Bool8x16: return ExprType::B8x16;
|
||||
case Bool16x8: return ExprType::B16x8;
|
||||
case Bool32x4: return ExprType::B32x4;
|
||||
}
|
||||
MOZ_CRASH("Invalid Type");
|
||||
}
|
||||
|
||||
const char* toChars() const {
|
||||
switch (which_) {
|
||||
case Double: return "double";
|
||||
|
@ -2648,7 +2688,7 @@ ExtractNumericLiteral(ModuleValidator& m, ParseNode* pn)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
IsLiteralInt(NumLit lit, uint32_t* u32)
|
||||
IsLiteralInt(const NumLit& lit, uint32_t* u32)
|
||||
{
|
||||
switch (lit.which()) {
|
||||
case NumLit::Fixnum:
|
||||
|
@ -3107,7 +3147,7 @@ class MOZ_STACK_CLASS FunctionValidator
|
|||
return encoder().writeExpr(Expr::I32Const) &&
|
||||
encoder().writeVarS32(i32);
|
||||
}
|
||||
MOZ_MUST_USE bool writeConstExpr(NumLit lit) {
|
||||
MOZ_MUST_USE bool writeConstExpr(const NumLit& lit) {
|
||||
switch (lit.which()) {
|
||||
case NumLit::Fixnum:
|
||||
case NumLit::NegativeInt:
|
||||
|
@ -5949,7 +5989,7 @@ CheckComma(FunctionValidator& f, ParseNode* comma, Type* type)
|
|||
if (!CheckExpr(f, pn, type))
|
||||
return false;
|
||||
|
||||
f.encoder().patchFixedU7(typeAt, uint8_t(Type::canonicalize(*type).canonicalToExprType()));
|
||||
f.encoder().patchFixedU7(typeAt, uint8_t(type->toWasmBlockSignatureType()));
|
||||
|
||||
return f.encoder().writeExpr(Expr::End);
|
||||
}
|
||||
|
@ -5999,7 +6039,7 @@ CheckConditional(FunctionValidator& f, ParseNode* ternary, Type* type)
|
|||
thenType.toChars(), elseType.toChars());
|
||||
}
|
||||
|
||||
if (!f.popIf(typeAt, Type::canonicalize(*type).canonicalToExprType()))
|
||||
if (!f.popIf(typeAt, type->toWasmBlockSignatureType()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -1112,6 +1112,8 @@ ExprIter<Policy>::readBrTableEntry(ExprType* type, Value* value, uint32_t* depth
|
|||
if (!readVarU32(depth))
|
||||
return false;
|
||||
|
||||
ExprType knownType = *type;
|
||||
|
||||
if (MOZ_LIKELY(reachable_)) {
|
||||
ControlStackEntry<ControlItem>* controlItem = nullptr;
|
||||
if (!getControl(*depth, &controlItem))
|
||||
|
@ -1122,7 +1124,6 @@ ExprIter<Policy>::readBrTableEntry(ExprType* type, Value* value, uint32_t* depth
|
|||
|
||||
// If we've already seen one label, we know the type and can check
|
||||
// that the type for the current label matches it.
|
||||
ExprType knownType = *type;
|
||||
if (knownType != ExprType::Limit)
|
||||
return checkType(knownType, controlItem->type());
|
||||
|
||||
|
@ -1133,6 +1134,9 @@ ExprIter<Policy>::readBrTableEntry(ExprType* type, Value* value, uint32_t* depth
|
|||
return popWithType(NonVoidToValType(expectedType), value);
|
||||
}
|
||||
}
|
||||
|
||||
if (knownType != ExprType::Limit && knownType != ExprType::Void)
|
||||
return typeMismatch(knownType, ExprType::Void);
|
||||
}
|
||||
|
||||
*type = ExprType::Void;
|
||||
|
|
|
@ -312,7 +312,7 @@ class FunctionCompiler
|
|||
return constant;
|
||||
}
|
||||
|
||||
MDefinition* constant(Value v, MIRType type)
|
||||
MDefinition* constant(const Value& v, MIRType type)
|
||||
{
|
||||
if (inDeadCode())
|
||||
return nullptr;
|
||||
|
@ -1665,7 +1665,7 @@ EmitLoop(FunctionCompiler& f)
|
|||
if (!f.iter().readLoop())
|
||||
return false;
|
||||
|
||||
MBasicBlock *loopHeader;
|
||||
MBasicBlock* loopHeader;
|
||||
if (!f.startLoop(&loopHeader))
|
||||
return false;
|
||||
|
||||
|
@ -1678,7 +1678,7 @@ EmitLoop(FunctionCompiler& f)
|
|||
static bool
|
||||
EmitIf(FunctionCompiler& f)
|
||||
{
|
||||
MDefinition* condition;
|
||||
MDefinition* condition = nullptr;
|
||||
if (!f.iter().readIf(&condition))
|
||||
return false;
|
||||
|
||||
|
@ -1693,7 +1693,7 @@ EmitIf(FunctionCompiler& f)
|
|||
static bool
|
||||
EmitElse(FunctionCompiler& f)
|
||||
{
|
||||
MBasicBlock *block = f.iter().controlItem();
|
||||
MBasicBlock* block = f.iter().controlItem();
|
||||
|
||||
ExprType thenType;
|
||||
MDefinition* thenValue;
|
||||
|
@ -1712,7 +1712,7 @@ EmitElse(FunctionCompiler& f)
|
|||
static bool
|
||||
EmitEnd(FunctionCompiler& f)
|
||||
{
|
||||
MBasicBlock *block = f.iter().controlItem();
|
||||
MBasicBlock* block = f.iter().controlItem();
|
||||
|
||||
LabelKind kind;
|
||||
ExprType type;
|
||||
|
@ -1723,7 +1723,7 @@ EmitEnd(FunctionCompiler& f)
|
|||
if (!IsVoid(type))
|
||||
f.pushDef(value);
|
||||
|
||||
MDefinition* def;
|
||||
MDefinition* def = nullptr;
|
||||
switch (kind) {
|
||||
case LabelKind::Block:
|
||||
if (!f.finishBlock(&def))
|
||||
|
@ -1749,8 +1749,10 @@ EmitEnd(FunctionCompiler& f)
|
|||
break;
|
||||
}
|
||||
|
||||
if (!IsVoid(type))
|
||||
if (!IsVoid(type)) {
|
||||
MOZ_ASSERT_IF(!f.inDeadCode(), def);
|
||||
f.iter().setResult(def);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2353,7 +2353,7 @@ ParseBranchTable(WasmParseContext& c, WasmToken brTable, bool inParens)
|
|||
}
|
||||
|
||||
if (table.empty()) {
|
||||
c.ts.generateError(brTable, c.error);
|
||||
c.ts.generateError(c.ts.get(), c.error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -830,7 +830,7 @@ ModuleObject::hostDefinedField() const
|
|||
}
|
||||
|
||||
void
|
||||
ModuleObject::setHostDefinedField(JS::Value value)
|
||||
ModuleObject::setHostDefinedField(const JS::Value& value)
|
||||
{
|
||||
setReservedSlot(HostDefinedSlot, value);
|
||||
}
|
||||
|
|
|
@ -265,7 +265,7 @@ class ModuleObject : public NativeObject
|
|||
static bool DeclarationInstantiation(JSContext* cx, HandleModuleObject self);
|
||||
static bool Evaluation(JSContext* cx, HandleModuleObject self);
|
||||
|
||||
void setHostDefinedField(JS::Value value);
|
||||
void setHostDefinedField(const JS::Value& value);
|
||||
|
||||
// For intrinsic_CreateModuleEnvironment.
|
||||
void createEnvironment();
|
||||
|
|
|
@ -477,7 +477,7 @@ obj_setPrototypeOf(JSContext* cx, unsigned argc, Value* vp)
|
|||
#if JS_HAS_OBJ_WATCHPOINT
|
||||
|
||||
bool
|
||||
js::WatchHandler(JSContext* cx, JSObject* obj_, jsid id_, JS::Value old,
|
||||
js::WatchHandler(JSContext* cx, JSObject* obj_, jsid id_, const JS::Value& old,
|
||||
JS::Value* nvp, void* closure)
|
||||
{
|
||||
RootedObject obj(cx, obj_);
|
||||
|
|
|
@ -79,7 +79,7 @@ ObjectToSource(JSContext* cx, JS::HandleObject obj);
|
|||
#endif // JS_HAS_TOSOURCE
|
||||
|
||||
extern MOZ_MUST_USE bool
|
||||
WatchHandler(JSContext* cx, JSObject* obj, jsid id, JS::Value old,
|
||||
WatchHandler(JSContext* cx, JSObject* obj, jsid id, const JS::Value& old,
|
||||
JS::Value* nvp, void* closure);
|
||||
|
||||
} /* namespace js */
|
||||
|
|
|
@ -1179,7 +1179,7 @@ js::regexp_test_no_statics(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
|
||||
static void
|
||||
GetParen(JSLinearString* matched, JS::Value capture, JSSubString* out)
|
||||
GetParen(JSLinearString* matched, const JS::Value& capture, JSSubString* out)
|
||||
{
|
||||
if (capture.isUndefined()) {
|
||||
out->initEmpty(matched);
|
||||
|
|
|
@ -960,9 +960,6 @@ ReplaceLane(JSContext* cx, unsigned argc, Value* vp)
|
|||
if (args.length() < 2 || !IsVectorObject<V>(args[0]))
|
||||
return ErrorBadArgs(cx);
|
||||
|
||||
Elem* vec = TypedObjectMemory<Elem*>(args[0]);
|
||||
Elem result[V::lanes];
|
||||
|
||||
unsigned lane;
|
||||
if (!ArgumentToLaneIndex(cx, args[1], V::lanes, &lane))
|
||||
return false;
|
||||
|
@ -971,8 +968,11 @@ ReplaceLane(JSContext* cx, unsigned argc, Value* vp)
|
|||
if (!V::Cast(cx, args.get(2), &value))
|
||||
return false;
|
||||
|
||||
Elem* vec = TypedObjectMemory<Elem*>(args[0]);
|
||||
Elem result[V::lanes];
|
||||
for (unsigned i = 0; i < V::lanes; i++)
|
||||
result[i] = i == lane ? value : vec[i];
|
||||
|
||||
return StoreResult<V>(cx, args, result);
|
||||
}
|
||||
|
||||
|
@ -1039,17 +1039,18 @@ BinaryScalar(JSContext* cx, unsigned argc, Value* vp)
|
|||
if (args.length() != 2)
|
||||
return ErrorBadArgs(cx);
|
||||
|
||||
Elem result[V::lanes];
|
||||
if (!IsVectorObject<V>(args[0]))
|
||||
return ErrorBadArgs(cx);
|
||||
|
||||
Elem* val = TypedObjectMemory<Elem*>(args[0]);
|
||||
int32_t bits;
|
||||
if (!ToInt32(cx, args[1], &bits))
|
||||
return false;
|
||||
|
||||
Elem result[V::lanes];
|
||||
Elem* val = TypedObjectMemory<Elem*>(args[0]);
|
||||
for (unsigned i = 0; i < V::lanes; i++)
|
||||
result[i] = Op<Elem>::apply(val[i], bits);
|
||||
|
||||
return StoreResult<V>(cx, args, result);
|
||||
}
|
||||
|
||||
|
|
|
@ -323,7 +323,7 @@ namespace StructType {
|
|||
namespace FunctionType {
|
||||
static bool Create(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool ConstructData(JSContext* cx, HandleObject typeObj,
|
||||
HandleObject dataObj, HandleObject fnObj, HandleObject thisObj, Value errVal);
|
||||
HandleObject dataObj, HandleObject fnObj, HandleObject thisObj, HandleValue errVal);
|
||||
|
||||
static bool Call(JSContext* cx, unsigned argc, Value* vp);
|
||||
|
||||
|
@ -1460,9 +1460,8 @@ FieldCountMismatch(JSContext* cx,
|
|||
}
|
||||
|
||||
static bool
|
||||
FieldDescriptorCountError(JSContext* cx, Value val, size_t length)
|
||||
FieldDescriptorCountError(JSContext* cx, HandleValue typeVal, size_t length)
|
||||
{
|
||||
RootedValue typeVal(cx, val);
|
||||
JSAutoByteString valBytes;
|
||||
const char* valStr = CTypesToSourceForError(cx, typeVal, valBytes);
|
||||
if (!valStr)
|
||||
|
@ -1511,9 +1510,8 @@ FieldDescriptorSizeError(JSContext* cx, HandleObject typeObj, HandleId id)
|
|||
}
|
||||
|
||||
static bool
|
||||
FieldDescriptorNameTypeError(JSContext* cx, Value val)
|
||||
FieldDescriptorNameTypeError(JSContext* cx, HandleValue typeVal)
|
||||
{
|
||||
RootedValue typeVal(cx, val);
|
||||
JSAutoByteString valBytes;
|
||||
const char* valStr = CTypesToSourceForError(cx, typeVal, valBytes);
|
||||
if (!valStr)
|
||||
|
@ -1619,11 +1617,10 @@ FunctionArgumentLengthMismatch(JSContext* cx,
|
|||
|
||||
static bool
|
||||
FunctionArgumentTypeError(JSContext* cx,
|
||||
uint32_t index, Value type, const char* reason)
|
||||
uint32_t index, HandleValue typeVal, const char* reason)
|
||||
{
|
||||
RootedValue val(cx, type);
|
||||
JSAutoByteString valBytes;
|
||||
const char* valStr = CTypesToSourceForError(cx, val, valBytes);
|
||||
const char* valStr = CTypesToSourceForError(cx, typeVal, valBytes);
|
||||
if (!valStr)
|
||||
return false;
|
||||
|
||||
|
@ -1637,11 +1634,10 @@ FunctionArgumentTypeError(JSContext* cx,
|
|||
}
|
||||
|
||||
static bool
|
||||
FunctionReturnTypeError(JSContext* cx, Value type, const char* reason)
|
||||
FunctionReturnTypeError(JSContext* cx, HandleValue type, const char* reason)
|
||||
{
|
||||
RootedValue val(cx, type);
|
||||
JSAutoByteString valBytes;
|
||||
const char* valStr = CTypesToSourceForError(cx, val, valBytes);
|
||||
const char* valStr = CTypesToSourceForError(cx, type, valBytes);
|
||||
if (!valStr)
|
||||
return false;
|
||||
|
||||
|
@ -2318,12 +2314,16 @@ InitTypeClasses(JSContext* cx, HandleObject ctypesObj)
|
|||
// * __proto__ === ctypes.CData.prototype
|
||||
// * 'constructor' property === 't'
|
||||
#define DEFINE_TYPE(name, type, ffiType) \
|
||||
RootedObject typeObj_##name(cx, \
|
||||
CType::DefineBuiltin(cx, ctypesObj, #name, CTypeProto, CDataProto, #name, \
|
||||
TYPE_##name, Int32Value(sizeof(type)), \
|
||||
Int32Value(ffiType.alignment), &ffiType)); \
|
||||
if (!typeObj_##name) \
|
||||
return false;
|
||||
RootedObject typeObj_##name(cx); \
|
||||
{ \
|
||||
RootedValue typeVal(cx, Int32Value(sizeof(type))); \
|
||||
RootedValue alignVal(cx, Int32Value(ffiType.alignment)); \
|
||||
typeObj_##name = CType::DefineBuiltin(cx, ctypesObj, #name, CTypeProto, \
|
||||
CDataProto, #name, TYPE_##name, \
|
||||
typeVal, alignVal, &ffiType); \
|
||||
if (!typeObj_##name) \
|
||||
return false; \
|
||||
}
|
||||
CTYPES_FOR_EACH_TYPE(DEFINE_TYPE)
|
||||
#undef DEFINE_TYPE
|
||||
|
||||
|
@ -2342,7 +2342,7 @@ InitTypeClasses(JSContext* cx, HandleObject ctypesObj)
|
|||
// Create objects representing the special types void_t and voidptr_t.
|
||||
RootedObject typeObj(cx,
|
||||
CType::DefineBuiltin(cx, ctypesObj, "void_t", CTypeProto, CDataProto, "void",
|
||||
TYPE_void_t, JS::UndefinedValue(), JS::UndefinedValue(),
|
||||
TYPE_void_t, JS::UndefinedHandleValue, JS::UndefinedHandleValue,
|
||||
&ffi_type_void));
|
||||
if (!typeObj)
|
||||
return false;
|
||||
|
@ -2665,7 +2665,7 @@ static MOZ_ALWAYS_INLINE bool IsNegative(Type i)
|
|||
// Implicitly convert val to bool, allowing bool, int, and double
|
||||
// arguments numerically equal to 0 or 1.
|
||||
static bool
|
||||
jsvalToBool(JSContext* cx, Value val, bool* result)
|
||||
jsvalToBool(JSContext* cx, HandleValue val, bool* result)
|
||||
{
|
||||
if (val.isBoolean()) {
|
||||
*result = val.toBoolean();
|
||||
|
@ -2691,7 +2691,7 @@ jsvalToBool(JSContext* cx, Value val, bool* result)
|
|||
// representable by IntegerType.
|
||||
template<class IntegerType>
|
||||
static bool
|
||||
jsvalToInteger(JSContext* cx, Value val, IntegerType* result)
|
||||
jsvalToInteger(JSContext* cx, HandleValue val, IntegerType* result)
|
||||
{
|
||||
JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
|
||||
|
||||
|
@ -2781,7 +2781,7 @@ jsvalToInteger(JSContext* cx, Value val, IntegerType* result)
|
|||
// representable by FloatType.
|
||||
template<class FloatType>
|
||||
static bool
|
||||
jsvalToFloat(JSContext* cx, Value val, FloatType* result)
|
||||
jsvalToFloat(JSContext* cx, HandleValue val, FloatType* result)
|
||||
{
|
||||
JS_STATIC_ASSERT(!numeric_limits<FloatType>::is_exact);
|
||||
|
||||
|
@ -2913,7 +2913,7 @@ StringToInteger(JSContext* cx, JSString* string, IntegerType* result,
|
|||
template<class IntegerType>
|
||||
static bool
|
||||
jsvalToBigInteger(JSContext* cx,
|
||||
Value val,
|
||||
HandleValue val,
|
||||
bool allowString,
|
||||
IntegerType* result,
|
||||
bool* overflow)
|
||||
|
@ -2970,7 +2970,7 @@ jsvalToBigInteger(JSContext* cx,
|
|||
// Implicitly convert val to a size value, where the size value is represented
|
||||
// by size_t but must also fit in a double.
|
||||
static bool
|
||||
jsvalToSize(JSContext* cx, Value val, bool allowString, size_t* result)
|
||||
jsvalToSize(JSContext* cx, HandleValue val, bool allowString, size_t* result)
|
||||
{
|
||||
bool dummy;
|
||||
if (!jsvalToBigInteger(cx, val, allowString, result, &dummy))
|
||||
|
@ -3037,7 +3037,7 @@ SizeTojsval(JSContext* cx, size_t size, MutableHandleValue result)
|
|||
// Forcefully convert val to IntegerType when explicitly requested.
|
||||
template<class IntegerType>
|
||||
static bool
|
||||
jsvalToIntegerExplicit(Value val, IntegerType* result)
|
||||
jsvalToIntegerExplicit(HandleValue val, IntegerType* result)
|
||||
{
|
||||
JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
|
||||
|
||||
|
@ -3066,7 +3066,7 @@ jsvalToIntegerExplicit(Value val, IntegerType* result)
|
|||
|
||||
// Forcefully convert val to a pointer value when explicitly requested.
|
||||
static bool
|
||||
jsvalToPtrExplicit(JSContext* cx, Value val, uintptr_t* result)
|
||||
jsvalToPtrExplicit(JSContext* cx, HandleValue val, uintptr_t* result)
|
||||
{
|
||||
if (val.isInt32()) {
|
||||
// int32_t always fits in intptr_t. If the integer is negative, cast through
|
||||
|
@ -4399,13 +4399,11 @@ CType::Create(JSContext* cx,
|
|||
HandleObject dataProto,
|
||||
TypeCode type,
|
||||
JSString* name_,
|
||||
Value size_,
|
||||
Value align_,
|
||||
HandleValue size,
|
||||
HandleValue align,
|
||||
ffi_type* ffiType)
|
||||
{
|
||||
RootedString name(cx, name_);
|
||||
RootedValue size(cx, size_);
|
||||
RootedValue align(cx, align_);
|
||||
|
||||
// Create a CType object with the properties and slots common to all CTypes.
|
||||
// Each type object 't' has:
|
||||
|
@ -4471,14 +4469,12 @@ CType::DefineBuiltin(JSContext* cx,
|
|||
JSObject* dataProto_,
|
||||
const char* name,
|
||||
TypeCode type,
|
||||
Value size_,
|
||||
Value align_,
|
||||
HandleValue size,
|
||||
HandleValue align,
|
||||
ffi_type* ffiType)
|
||||
{
|
||||
RootedObject typeProto(cx, typeProto_);
|
||||
RootedObject dataProto(cx, dataProto_);
|
||||
RootedValue size(cx, size_);
|
||||
RootedValue align(cx, align_);
|
||||
|
||||
RootedString nameStr(cx, JS_NewStringCopyZ(cx, name));
|
||||
if (!nameStr)
|
||||
|
@ -5113,10 +5109,11 @@ PointerType::CreateInternal(JSContext* cx, HandleObject baseType)
|
|||
return nullptr;
|
||||
|
||||
// Create a new CType object with the common properties and slots.
|
||||
RootedValue sizeVal(cx, Int32Value(sizeof(void*)));
|
||||
RootedValue alignVal(cx, Int32Value(ffi_type_pointer.alignment));
|
||||
JSObject* typeObj = CType::Create(cx, typeProto, dataProto, TYPE_pointer,
|
||||
nullptr, Int32Value(sizeof(void*)),
|
||||
Int32Value(ffi_type_pointer.alignment),
|
||||
&ffi_type_pointer);
|
||||
nullptr, sizeVal, alignVal,
|
||||
&ffi_type_pointer);
|
||||
if (!typeObj)
|
||||
return nullptr;
|
||||
|
||||
|
@ -5201,7 +5198,7 @@ PointerType::ConstructData(JSContext* cx,
|
|||
// The third argument is an optional error sentinel that js-ctypes will return
|
||||
// if an exception is raised while executing the closure. The type must match
|
||||
// the return type of the callback.
|
||||
Value errVal = JS::UndefinedValue();
|
||||
RootedValue errVal(cx);
|
||||
if (args.length() == 3)
|
||||
errVal = args[2];
|
||||
|
||||
|
@ -5425,8 +5422,8 @@ ArrayType::CreateInternal(JSContext* cx,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
RootedValue sizeVal(cx, JS::UndefinedValue());
|
||||
RootedValue lengthVal(cx, JS::UndefinedValue());
|
||||
RootedValue sizeVal(cx);
|
||||
RootedValue lengthVal(cx);
|
||||
if (lengthDefined) {
|
||||
// Check for overflow, and convert to an int or double as required.
|
||||
size_t size = length * baseSize;
|
||||
|
@ -5444,11 +5441,11 @@ ArrayType::CreateInternal(JSContext* cx,
|
|||
}
|
||||
}
|
||||
|
||||
size_t align = CType::GetAlignment(baseType);
|
||||
RootedValue alignVal(cx, Int32Value(CType::GetAlignment(baseType)));
|
||||
|
||||
// Create a new CType object with the common properties and slots.
|
||||
JSObject* typeObj = CType::Create(cx, typeProto, dataProto, TYPE_array, nullptr,
|
||||
sizeVal, Int32Value(align), nullptr);
|
||||
sizeVal, alignVal, nullptr);
|
||||
if (!typeObj)
|
||||
return nullptr;
|
||||
|
||||
|
@ -5952,8 +5949,9 @@ StructType::Create(JSContext* cx, unsigned argc, Value* vp)
|
|||
// non-instantiable as CData, will have no 'prototype' property, and will
|
||||
// have undefined size and alignment and no ffi_type.
|
||||
RootedObject result(cx, CType::Create(cx, typeProto, nullptr, TYPE_struct,
|
||||
name.toString(), JS::UndefinedValue(),
|
||||
JS::UndefinedValue(), nullptr));
|
||||
name.toString(),
|
||||
JS::UndefinedHandleValue,
|
||||
JS::UndefinedHandleValue, nullptr));
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
|
@ -6572,7 +6570,7 @@ struct AutoValue
|
|||
};
|
||||
|
||||
static bool
|
||||
GetABI(JSContext* cx, Value abiType, ffi_abi* result)
|
||||
GetABI(JSContext* cx, HandleValue abiType, ffi_abi* result)
|
||||
{
|
||||
if (abiType.isPrimitive())
|
||||
return false;
|
||||
|
@ -6650,7 +6648,7 @@ PrepareType(JSContext* cx, uint32_t index, HandleValue type)
|
|||
}
|
||||
|
||||
static JSObject*
|
||||
PrepareReturnType(JSContext* cx, Value type)
|
||||
PrepareReturnType(JSContext* cx, HandleValue type)
|
||||
{
|
||||
if (type.isPrimitive() || !CType::IsCType(type.toObjectOrNull())) {
|
||||
FunctionReturnTypeError(cx, type, "is not a ctypes type");
|
||||
|
@ -6678,7 +6676,7 @@ PrepareReturnType(JSContext* cx, Value type)
|
|||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
IsEllipsis(JSContext* cx, Value v, bool* isEllipsis)
|
||||
IsEllipsis(JSContext* cx, HandleValue v, bool* isEllipsis)
|
||||
{
|
||||
*isEllipsis = false;
|
||||
if (!v.isString())
|
||||
|
@ -6701,7 +6699,8 @@ PrepareCIF(JSContext* cx,
|
|||
FunctionInfo* fninfo)
|
||||
{
|
||||
ffi_abi abi;
|
||||
if (!GetABI(cx, ObjectOrNullValue(fninfo->mABI), &abi)) {
|
||||
RootedValue abiType(cx, ObjectOrNullValue(fninfo->mABI));
|
||||
if (!GetABI(cx, abiType, &abi)) {
|
||||
JS_ReportErrorASCII(cx, "Invalid ABI specification");
|
||||
return false;
|
||||
}
|
||||
|
@ -6932,8 +6931,8 @@ FunctionType::CreateInternal(JSContext* cx,
|
|||
|
||||
// Create a new CType object with the common properties and slots.
|
||||
RootedObject typeObj(cx, CType::Create(cx, typeProto, dataProto, TYPE_function,
|
||||
nullptr, JS::UndefinedValue(),
|
||||
JS::UndefinedValue(), nullptr));
|
||||
nullptr, JS::UndefinedHandleValue,
|
||||
JS::UndefinedHandleValue, nullptr));
|
||||
if (!typeObj)
|
||||
return nullptr;
|
||||
|
||||
|
@ -6953,7 +6952,7 @@ FunctionType::ConstructData(JSContext* cx,
|
|||
HandleObject dataObj,
|
||||
HandleObject fnObj,
|
||||
HandleObject thisObj,
|
||||
Value errVal)
|
||||
HandleValue errVal)
|
||||
{
|
||||
MOZ_ASSERT(CType::GetTypeCode(typeObj) == TYPE_function);
|
||||
|
||||
|
@ -7284,10 +7283,9 @@ CClosure::Create(JSContext* cx,
|
|||
HandleObject typeObj,
|
||||
HandleObject fnObj,
|
||||
HandleObject thisObj,
|
||||
Value errVal_,
|
||||
HandleValue errVal,
|
||||
PRFuncPtr* fnptr)
|
||||
{
|
||||
RootedValue errVal(cx, errVal_);
|
||||
MOZ_ASSERT(fnObj);
|
||||
|
||||
RootedObject result(cx, JS_NewObject(cx, &sCClosureClass));
|
||||
|
@ -8309,8 +8307,9 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, Value* vp)
|
|||
SLOT_DATAFINALIZER_CODETYPE,
|
||||
ObjectValue(*objCodePtrType));
|
||||
|
||||
RootedValue abiType(cx, ObjectOrNullValue(funInfoFinalizer->mABI));
|
||||
ffi_abi abi;
|
||||
if (!GetABI(cx, ObjectOrNullValue(funInfoFinalizer->mABI), &abi)) {
|
||||
if (!GetABI(cx, abiType, &abi)) {
|
||||
JS_ReportErrorASCII(cx, "Internal Error: "
|
||||
"Invalid ABI specification in CDataFinalizer");
|
||||
return false;
|
||||
|
@ -8479,7 +8478,7 @@ CDataFinalizer::Methods::Dispose(JSContext* cx, unsigned argc, Value* vp)
|
|||
MOZ_ASSERT(CType::GetTypeCode(objCodeType) == TYPE_function);
|
||||
|
||||
RootedObject resultType(cx, FunctionType::GetFunctionInfo(objCodeType)->mReturnType);
|
||||
RootedValue result(cx, JS::UndefinedValue());
|
||||
RootedValue result(cx);
|
||||
|
||||
int errnoStatus;
|
||||
#if defined(XP_WIN)
|
||||
|
|
|
@ -444,11 +444,12 @@ enum Int64FunctionSlot {
|
|||
|
||||
namespace CType {
|
||||
JSObject* Create(JSContext* cx, HandleObject typeProto, HandleObject dataProto,
|
||||
TypeCode type, JSString* name, Value size, Value align, ffi_type* ffiType);
|
||||
TypeCode type, JSString* name, HandleValue size, HandleValue align,
|
||||
ffi_type* ffiType);
|
||||
|
||||
JSObject* DefineBuiltin(JSContext* cx, HandleObject ctypesObj, const char* propName,
|
||||
JSObject* typeProto, JSObject* dataProto, const char* name, TypeCode type,
|
||||
Value size, Value align, ffi_type* ffiType);
|
||||
HandleValue size, HandleValue align, ffi_type* ffiType);
|
||||
|
||||
bool IsCType(JSObject* obj);
|
||||
bool IsCTypeProto(JSObject* obj);
|
||||
|
@ -506,7 +507,7 @@ namespace FunctionType {
|
|||
|
||||
namespace CClosure {
|
||||
JSObject* Create(JSContext* cx, HandleObject typeObj, HandleObject fnObj,
|
||||
HandleObject thisObj, Value errVal, PRFuncPtr* fnptr);
|
||||
HandleObject thisObj, HandleValue errVal, PRFuncPtr* fnptr);
|
||||
} // namespace CClosure
|
||||
|
||||
namespace CData {
|
||||
|
|
|
@ -86,9 +86,8 @@ Library::Name(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
|
||||
JSObject*
|
||||
Library::Create(JSContext* cx, Value path_, const JSCTypesCallbacks* callbacks)
|
||||
Library::Create(JSContext* cx, HandleValue path, const JSCTypesCallbacks* callbacks)
|
||||
{
|
||||
RootedValue path(cx, path_);
|
||||
RootedObject libraryObj(cx, JS_NewObject(cx, &sLibraryClass));
|
||||
if (!libraryObj)
|
||||
return nullptr;
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace Library
|
|||
{
|
||||
MOZ_MUST_USE bool Name(JSContext* cx, unsigned argc, JS::Value* vp);
|
||||
|
||||
JSObject* Create(JSContext* cx, JS::Value path, const JSCTypesCallbacks* callbacks);
|
||||
JSObject* Create(JSContext* cx, JS::HandleValue path, const JSCTypesCallbacks* callbacks);
|
||||
|
||||
bool IsLibrary(JSObject* obj);
|
||||
PRLibrary* GetLibrary(JSObject* obj);
|
||||
|
|
|
@ -27,7 +27,7 @@ struct IdValuePair
|
|||
explicit IdValuePair(jsid idArg)
|
||||
: value(UndefinedValue()), id(idArg)
|
||||
{}
|
||||
IdValuePair(jsid idArg, Value valueArg)
|
||||
IdValuePair(jsid idArg, const Value& valueArg)
|
||||
: value(valueArg), id(idArg)
|
||||
{}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ class CGConstList {
|
|||
Vector<Value> list;
|
||||
public:
|
||||
explicit CGConstList(ExclusiveContext* cx) : list(cx) {}
|
||||
MOZ_MUST_USE bool append(Value v) {
|
||||
MOZ_MUST_USE bool append(const Value& v) {
|
||||
MOZ_ASSERT_IF(v.isString(), v.toString()->isAtom());
|
||||
return list.append(v);
|
||||
}
|
||||
|
|
|
@ -5546,17 +5546,21 @@ Parser<ParseHandler>::continueStatement(YieldHandling yieldHandling)
|
|||
};
|
||||
|
||||
if (label) {
|
||||
bool foundTarget = false;
|
||||
ParseContext::Statement* stmt = pc->innermostStatement();
|
||||
bool foundLoop = false;
|
||||
|
||||
for (;;) {
|
||||
stmt = ParseContext::Statement::findNearest(stmt, isLoop);
|
||||
if (!stmt) {
|
||||
report(ParseError, false, null(), JSMSG_BAD_CONTINUE);
|
||||
report(ParseError, false, null(),
|
||||
foundLoop ? JSMSG_LABEL_NOT_FOUND : JSMSG_BAD_CONTINUE);
|
||||
return null();
|
||||
}
|
||||
|
||||
foundLoop = true;
|
||||
|
||||
// Is it labeled by our label?
|
||||
bool foundTarget = false;
|
||||
stmt = stmt->enclosing();
|
||||
while (stmt && stmt->is<ParseContext::LabelStatement>()) {
|
||||
if (stmt->as<ParseContext::LabelStatement>().label() == label) {
|
||||
|
@ -5568,11 +5572,6 @@ Parser<ParseHandler>::continueStatement(YieldHandling yieldHandling)
|
|||
if (foundTarget)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!foundTarget) {
|
||||
report(ParseError, false, null(), JSMSG_LABEL_NOT_FOUND);
|
||||
return null();
|
||||
}
|
||||
} else if (!pc->findInnermostStatement(isLoop)) {
|
||||
report(ParseError, false, null(), JSMSG_BAD_CONTINUE);
|
||||
return null();
|
||||
|
|
|
@ -310,7 +310,7 @@ GCRuntime::refillFreeListOffMainThread(ExclusiveContext* cx, AllocKind thingKind
|
|||
// whatever value we get. We need to first ensure the main thread is not in
|
||||
// a GC session.
|
||||
AutoLockHelperThreadState lock;
|
||||
while (rt->isHeapBusy()) {
|
||||
while (rt->isHeapCollecting()) {
|
||||
HelperThreadState().wait(lock, GlobalHelperThreadState::PRODUCER);
|
||||
HelperThreadState().notifyOne(GlobalHelperThreadState::PRODUCER, lock);
|
||||
}
|
||||
|
|
|
@ -279,10 +279,10 @@ template <typename S> struct ReadBarrierFunctor : public VoidDefaultAdaptor<S> {
|
|||
template <>
|
||||
struct InternalBarrierMethods<Value>
|
||||
{
|
||||
static bool isMarkable(Value v) { return v.isMarkable(); }
|
||||
static bool isMarkableTaggedPointer(Value v) { return isMarkable(v); }
|
||||
static bool isMarkable(const Value& v) { return v.isMarkable(); }
|
||||
static bool isMarkableTaggedPointer(const Value& v) { return isMarkable(v); }
|
||||
|
||||
static void preBarrier(Value v) {
|
||||
static void preBarrier(const Value& v) {
|
||||
DispatchTyped(PreBarrierFunctor<Value>(), v);
|
||||
}
|
||||
|
||||
|
@ -334,7 +334,7 @@ class BarrieredBase : public BarrieredBaseMixins<T>
|
|||
{
|
||||
protected:
|
||||
// BarrieredBase is not directly instantiable.
|
||||
explicit BarrieredBase(T v) : value(v) {}
|
||||
explicit BarrieredBase(const T& v) : value(v) {}
|
||||
|
||||
// Storage for all barrier classes. |value| must be a GC thing reference
|
||||
// type: either a direct pointer to a GC thing or a supported tagged
|
||||
|
@ -355,7 +355,7 @@ class WriteBarrieredBase : public BarrieredBase<T>
|
|||
{
|
||||
protected:
|
||||
// WriteBarrieredBase is not directly instantiable.
|
||||
explicit WriteBarrieredBase(T v) : BarrieredBase<T>(v) {}
|
||||
explicit WriteBarrieredBase(const T& v) : BarrieredBase<T>(v) {}
|
||||
|
||||
public:
|
||||
DECLARE_POINTER_COMPARISON_OPS(T);
|
||||
|
@ -366,14 +366,16 @@ class WriteBarrieredBase : public BarrieredBase<T>
|
|||
|
||||
// Use this if you want to change the value without invoking barriers.
|
||||
// Obviously this is dangerous unless you know the barrier is not needed.
|
||||
void unsafeSet(T v) { this->value = v; }
|
||||
void unsafeSet(const T& v) { this->value = v; }
|
||||
|
||||
// For users who need to manually barrier the raw types.
|
||||
static void writeBarrierPre(const T& v) { InternalBarrierMethods<T>::preBarrier(v); }
|
||||
|
||||
protected:
|
||||
void pre() { InternalBarrierMethods<T>::preBarrier(this->value); }
|
||||
void post(T prev, T next) { InternalBarrierMethods<T>::postBarrier(&this->value, prev, next); }
|
||||
void post(const T& prev, const T& next) {
|
||||
InternalBarrierMethods<T>::postBarrier(&this->value, prev, next);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -391,11 +393,11 @@ class PreBarriered : public WriteBarrieredBase<T>
|
|||
* Allow implicit construction for use in generic contexts, such as
|
||||
* DebuggerWeakMap::markKeys.
|
||||
*/
|
||||
MOZ_IMPLICIT PreBarriered(T v) : WriteBarrieredBase<T>(v) {}
|
||||
MOZ_IMPLICIT PreBarriered(const T& v) : WriteBarrieredBase<T>(v) {}
|
||||
explicit PreBarriered(const PreBarriered<T>& v) : WriteBarrieredBase<T>(v.value) {}
|
||||
~PreBarriered() { this->pre(); }
|
||||
|
||||
void init(T v) {
|
||||
void init(const T& v) {
|
||||
this->value = v;
|
||||
}
|
||||
|
||||
|
@ -430,7 +432,7 @@ class GCPtr : public WriteBarrieredBase<T>
|
|||
{
|
||||
public:
|
||||
GCPtr() : WriteBarrieredBase<T>(JS::GCPolicy<T>::initial()) {}
|
||||
explicit GCPtr(T v) : WriteBarrieredBase<T>(v) {
|
||||
explicit GCPtr(const T& v) : WriteBarrieredBase<T>(v) {
|
||||
this->post(JS::GCPolicy<T>::initial(), v);
|
||||
}
|
||||
explicit GCPtr(const GCPtr<T>& v) : WriteBarrieredBase<T>(v) {
|
||||
|
@ -446,7 +448,7 @@ class GCPtr : public WriteBarrieredBase<T>
|
|||
}
|
||||
#endif
|
||||
|
||||
void init(T v) {
|
||||
void init(const T& v) {
|
||||
this->value = v;
|
||||
this->post(JS::GCPolicy<T>::initial(), v);
|
||||
}
|
||||
|
@ -523,7 +525,7 @@ class HeapPtr : public WriteBarrieredBase<T>
|
|||
this->post(this->value, JS::GCPolicy<T>::initial());
|
||||
}
|
||||
|
||||
void init(T v) {
|
||||
void init(const T& v) {
|
||||
this->value = v;
|
||||
this->post(JS::GCPolicy<T>::initial(), this->value);
|
||||
}
|
||||
|
@ -556,11 +558,13 @@ class ReadBarrieredBase : public BarrieredBase<T>
|
|||
{
|
||||
protected:
|
||||
// ReadBarrieredBase is not directly instantiable.
|
||||
explicit ReadBarrieredBase(T v) : BarrieredBase<T>(v) {}
|
||||
explicit ReadBarrieredBase(const T& v) : BarrieredBase<T>(v) {}
|
||||
|
||||
protected:
|
||||
void read() const { InternalBarrierMethods<T>::readBarrier(this->value); }
|
||||
void post(T prev, T next) { InternalBarrierMethods<T>::postBarrier(&this->value, prev, next); }
|
||||
void post(const T& prev, const T& next) {
|
||||
InternalBarrierMethods<T>::postBarrier(&this->value, prev, next);
|
||||
}
|
||||
};
|
||||
|
||||
// Incremental GC requires that weak pointers have read barriers. See the block
|
||||
|
|
|
@ -315,7 +315,7 @@ ShouldMarkCrossCompartment(JSTracer* trc, JSObject* src, Cell* cell)
|
|||
}
|
||||
|
||||
static bool
|
||||
ShouldMarkCrossCompartment(JSTracer* trc, JSObject* src, Value val)
|
||||
ShouldMarkCrossCompartment(JSTracer* trc, JSObject* src, const Value& val)
|
||||
{
|
||||
return val.isMarkable() && ShouldMarkCrossCompartment(trc, src, (Cell*)val.toGCThing());
|
||||
}
|
||||
|
@ -400,7 +400,7 @@ ConvertToBase(T* thingp)
|
|||
template <typename T> void DispatchToTracer(JSTracer* trc, T* thingp, const char* name);
|
||||
template <typename T> T DoCallback(JS::CallbackTracer* trc, T* thingp, const char* name);
|
||||
template <typename T> void DoMarking(GCMarker* gcmarker, T* thing);
|
||||
template <typename T> void DoMarking(GCMarker* gcmarker, T thing);
|
||||
template <typename T> void DoMarking(GCMarker* gcmarker, const T& thing);
|
||||
template <typename T> void NoteWeakEdge(GCMarker* gcmarker, T** thingp);
|
||||
template <typename T> void NoteWeakEdge(GCMarker* gcmarker, T* thingp);
|
||||
|
||||
|
@ -431,7 +431,7 @@ JS_PUBLIC_API(void)
|
|||
JS::TraceEdge(JSTracer* trc, JS::Heap<T>* thingp, const char* name)
|
||||
{
|
||||
MOZ_ASSERT(thingp);
|
||||
if (InternalBarrierMethods<T>::isMarkable(thingp->get()))
|
||||
if (InternalBarrierMethods<T>::isMarkable(*thingp->unsafeGet()))
|
||||
DispatchToTracer(trc, ConvertToBase(thingp->unsafeGet()), name);
|
||||
}
|
||||
|
||||
|
@ -807,7 +807,7 @@ struct DoMarkingFunctor : public VoidDefaultAdaptor<S> {
|
|||
|
||||
template <typename T>
|
||||
void
|
||||
DoMarking(GCMarker* gcmarker, T thing)
|
||||
DoMarking(GCMarker* gcmarker, const T& thing)
|
||||
{
|
||||
DispatchTyped(DoMarkingFunctor<T>(), thing, gcmarker);
|
||||
}
|
||||
|
@ -956,7 +956,7 @@ template <typename V, typename S> struct TraverseEdgeFunctor : public VoidDefaul
|
|||
|
||||
template <typename S, typename T>
|
||||
void
|
||||
js::GCMarker::traverseEdge(S source, T thing)
|
||||
js::GCMarker::traverseEdge(S source, const T& thing)
|
||||
{
|
||||
DispatchTyped(TraverseEdgeFunctor<T, S>(), thing, this, source);
|
||||
}
|
||||
|
@ -2949,6 +2949,7 @@ TypedUnmarkGrayCellRecursively(T* t)
|
|||
|
||||
JSRuntime* rt = t->runtimeFromMainThread();
|
||||
MOZ_ASSERT(!rt->isHeapCollecting());
|
||||
MOZ_ASSERT(!rt->isCycleCollecting());
|
||||
|
||||
bool unmarkedArg = false;
|
||||
if (t->isTenured()) {
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче