mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge inbound to central, a=merge
This commit is contained in:
commit
86142733ec
@ -254,8 +254,26 @@ def bootstrap(topsrcdir, mozilla_dir=None):
|
||||
raise
|
||||
|
||||
# Add common metadata to help submit sorted data later on.
|
||||
# For now, we'll just record the mach command that was invoked.
|
||||
data['argv'] = sys.argv
|
||||
data.setdefault('system', {}).update(dict(
|
||||
architecture=list(platform.architecture()),
|
||||
machine=platform.machine(),
|
||||
python_version=platform.python_version(),
|
||||
release=platform.release(),
|
||||
system=platform.system(),
|
||||
version=platform.version(),
|
||||
))
|
||||
|
||||
if platform.system() == 'Linux':
|
||||
dist = list(platform.linux_distribution())
|
||||
data['system']['linux_distribution'] = dist
|
||||
elif platform.system() == 'Windows':
|
||||
win32_ver=list((platform.win32_ver())),
|
||||
data['system']['win32_ver'] = win32_ver
|
||||
elif platform.system() == 'Darwin':
|
||||
# mac version is a special Cupertino snowflake
|
||||
r, v, m = platform.mac_ver()
|
||||
data['system']['mac_ver'] = [r, list(v), m]
|
||||
|
||||
with open(os.path.join(outgoing_dir, str(uuid.uuid4()) + '.json'),
|
||||
'w') as f:
|
||||
|
24
build/telemetry-schema.json
Normal file
24
build/telemetry-schema.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"argv": {"type": "array"},
|
||||
"system": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"architecture": {"type": "array"},
|
||||
"linux_distribution": {"type": "array"},
|
||||
"mac_ver": {"type": "array"},
|
||||
"machine": {"type": "string"},
|
||||
"python_version": {"type": "string"},
|
||||
"release": {"type": "string"},
|
||||
"system": {"type": "string"},
|
||||
"version": {"type": "string"},
|
||||
"win_ver": {"type": "array"}
|
||||
},
|
||||
"required": ["architecture", "machine", "python_version",
|
||||
"release", "system", "version"]
|
||||
}
|
||||
},
|
||||
"required": ["argv", "system"]
|
||||
}
|
20
configure.in
20
configure.in
@ -3851,18 +3851,6 @@ MOZ_ARG_WITH_STRING(gcm-senderid-keyfile,
|
||||
MOZ_ANDROID_GCM_SENDERID=`cat $withval`)
|
||||
AC_SUBST(MOZ_ANDROID_GCM_SENDERID)
|
||||
|
||||
# Whether to include optional-but-large font files in the final APK.
|
||||
# We want this in mobile/android/confvars.sh, so it goes early.
|
||||
MOZ_ARG_DISABLE_BOOL(android-include-fonts,
|
||||
[ --disable-android-include-fonts
|
||||
Disable the inclusion of fonts into the final APK],
|
||||
MOZ_ANDROID_EXCLUDE_FONTS=1)
|
||||
|
||||
if test -n "$MOZ_ANDROID_EXCLUDE_FONTS"; then
|
||||
AC_DEFINE(MOZ_ANDROID_EXCLUDE_FONTS)
|
||||
fi
|
||||
AC_SUBST(MOZ_ANDROID_EXCLUDE_FONTS)
|
||||
|
||||
# Whether this APK is destined for resource constrained devices.
|
||||
# We want this in mobile/android/confvars.sh, so it goes early.
|
||||
MOZ_ARG_ENABLE_BOOL(android-resource-constrained,
|
||||
@ -4775,6 +4763,13 @@ if test -n "$MOZ_ANDROID_MLS_STUMBLER"; then
|
||||
AC_DEFINE(MOZ_ANDROID_MLS_STUMBLER)
|
||||
fi
|
||||
|
||||
dnl =========================================================
|
||||
dnl = Whether to exclude font files in the build
|
||||
dnl =========================================================
|
||||
if test -n "$MOZ_ANDROID_EXCLUDE_FONTS"; then
|
||||
AC_DEFINE(MOZ_ANDROID_EXCLUDE_FONTS)
|
||||
fi
|
||||
|
||||
dnl =========================================================
|
||||
dnl = Whether to exclude hyphenations files in the build
|
||||
dnl =========================================================
|
||||
@ -8457,6 +8452,7 @@ AC_SUBST(MOZ_ANDROID_APPLICATION_CLASS)
|
||||
AC_SUBST(MOZ_ANDROID_BROWSER_INTENT_CLASS)
|
||||
AC_SUBST(MOZ_ANDROID_SEARCH_INTENT_CLASS)
|
||||
AC_SUBST(MOZ_ANDROID_DOWNLOAD_CONTENT_SERVICE)
|
||||
AC_SUBST(MOZ_ANDROID_EXCLUDE_FONTS)
|
||||
AC_SUBST(MOZ_EXCLUDE_HYPHENATION_DICTIONARIES)
|
||||
AC_SUBST(MOZ_INSTALL_TRACKING)
|
||||
AC_SUBST(MOZ_SWITCHBOARD)
|
||||
|
@ -1,8 +1,8 @@
|
||||
load 1239889-1.html
|
||||
load 1244595-1.html
|
||||
load 1216842-1.html
|
||||
load 1216842-2.html
|
||||
load 1216842-3.html
|
||||
load 1216842-4.html
|
||||
load 1216842-5.html
|
||||
load 1216842-6.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1239889-1.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1244595-1.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1216842-1.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1216842-2.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1216842-3.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1216842-4.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1216842-5.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1216842-6.html
|
||||
|
@ -486,7 +486,7 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' # b2g
|
||||
[test_iframe_sandbox_popups.html]
|
||||
skip-if = buildapp == 'b2g' # b2g(multiple concurrent window.open()s fail on B2G) b2g-debug(multiple concurrent window.open()s fail on B2G) b2g-desktop(Bug 931116, b2g desktop specific, initial triage)
|
||||
[test_iframe_sandbox_popups_inheritance.html]
|
||||
skip-if = buildapp == 'b2g' || e10s || toolkit == 'android' # b2g(multiple concurrent window.open()s fail on B2G) b2g-debug(multiple concurrent window.open()s fail on B2G) b2g-desktop(Bug 931116, b2g desktop specific, initial triage) android(bug 939642)
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' # b2g(multiple concurrent window.open()s fail on B2G) b2g-debug(multiple concurrent window.open()s fail on B2G) b2g-desktop(Bug 931116, b2g desktop specific, initial triage) android(bug 939642)
|
||||
[test_iframe_sandbox_redirect.html]
|
||||
[test_iframe_sandbox_refresh.html]
|
||||
[test_iframe_sandbox_same_origin.html]
|
||||
@ -582,7 +582,7 @@ skip-if = toolkit == 'android'
|
||||
[test_bug677495.html]
|
||||
[test_bug677495-1.html]
|
||||
[test_bug741266.html]
|
||||
skip-if = buildapp == "mulet" || buildapp == "b2g" || toolkit == "android" || toolkit == "windows" || e10s # b2g(needs control of popup window size) b2g-debug(needs control of popup window size) b2g-desktop(needs control of popup window size) windows(bug 1234520)
|
||||
skip-if = buildapp == "mulet" || buildapp == "b2g" || toolkit == "android" || toolkit == "windows" # b2g(needs control of popup window size) b2g-debug(needs control of popup window size) b2g-desktop(needs control of popup window size) windows(bug 1234520)
|
||||
[test_non-ascii-cookie.html]
|
||||
skip-if = buildapp == 'b2g'
|
||||
support-files = file_cookiemanager.js
|
||||
|
@ -2052,6 +2052,17 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
|
||||
RemoveFromWindowList(windowID, listener);
|
||||
return NS_OK;
|
||||
}
|
||||
} else if (loop) {
|
||||
// Record that we gave Loop permission to use camera access.
|
||||
nsCOMPtr<nsIPermissionManager> permManager =
|
||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = permManager->Add(docURI, "camera",
|
||||
nsIPermissionManager::ALLOW_ACTION,
|
||||
nsIPermissionManager::EXPIRE_SESSION,
|
||||
0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
#if defined(MOZ_B2G_CAMERA) && defined(MOZ_WIDGET_GONK)
|
||||
|
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for B2G PresentationReceiver on a non-receiver inner iframe of the receiver page at receiver side (OOP)</title>
|
||||
</head>
|
||||
<body onload="testConnectionAvailable()">
|
||||
<div id="content"></div>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
"use strict";
|
||||
|
||||
function ok(a, msg) {
|
||||
alert((a ? 'OK ' : 'KO ') + msg);
|
||||
}
|
||||
|
||||
function testConnectionAvailable() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
ok(!navigator.presentation, "navigator.presentation shouldn't be available in inner iframes with different origins from receiving OOP pages.");
|
||||
aResolve();
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for B2G PresentationReceiver in an inner iframe of the receiver page at receiver side (OOP)</title>
|
||||
</head>
|
||||
<body onload="testConnectionAvailable()">
|
||||
<div id="content"></div>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
"use strict";
|
||||
|
||||
function ok(a, msg) {
|
||||
alert((a ? 'OK ' : 'KO ') + msg);
|
||||
}
|
||||
|
||||
function testConnectionAvailable() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
ok(navigator.presentation, "navigator.presentation should be available in same-origin inner iframes of receiving OOP pages.");
|
||||
aResolve();
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -54,7 +54,7 @@ function testConnectionAvailable() {
|
||||
});
|
||||
}
|
||||
|
||||
function testConnectionAvailableInnerIframe() {
|
||||
function testConnectionAvailableSameOriginInnerIframe() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('src', './file_presentation_receiver_inner_iframe_oop.html');
|
||||
@ -64,6 +64,16 @@ function testConnectionAvailableInnerIframe() {
|
||||
});
|
||||
}
|
||||
|
||||
function testConnectionUnavailableDiffOriginInnerIframe() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('src', 'http://example.com/tests/dom/presentation/tests/mochitest/file_presentation_non_receiver_inner_iframe_oop.html');
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
aResolve();
|
||||
});
|
||||
}
|
||||
|
||||
function testConnectionReady() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
connection.onstatechange = function() {
|
||||
@ -104,7 +114,11 @@ function testTerminateConnection() {
|
||||
}
|
||||
|
||||
testConnectionAvailable().
|
||||
then(testConnectionAvailableInnerIframe).
|
||||
// TODO Bug 1234128 - Fix the timing issue for navigator.presentation.receiver.
|
||||
// This test fails intermittently under some edge cases. Disable it for now until
|
||||
// the issue gets fixed.
|
||||
// then(testConnectionAvailableSameOriginInnerIframe).
|
||||
then(testConnectionUnavailableDiffOriginInnerIframe).
|
||||
then(testConnectionReady).
|
||||
then(testIncomingMessage).
|
||||
then(testTerminateConnection).
|
||||
|
@ -6,6 +6,8 @@ support-files =
|
||||
file_presentation_receiver_oop.html
|
||||
file_presentation_non_receiver_oop.html
|
||||
file_presentation_receiver_establish_connection_error.html
|
||||
file_presentation_receiver_inner_iframe_oop.html
|
||||
file_presentation_non_receiver_inner_iframe_oop.html
|
||||
|
||||
[test_presentation_device_info.html]
|
||||
[test_presentation_device_info_permission.html]
|
||||
|
@ -40,6 +40,7 @@ namespace {
|
||||
|
||||
static const char* gSupportedRegistrarVersions[] = {
|
||||
SERVICEWORKERREGISTRAR_VERSION,
|
||||
"3",
|
||||
"2"
|
||||
};
|
||||
|
||||
@ -330,6 +331,7 @@ ServiceWorkerRegistrar::ReadData()
|
||||
nsTArray<ServiceWorkerRegistrationData> tmpData;
|
||||
|
||||
bool overwrite = false;
|
||||
bool dedupe = false;
|
||||
while (hasMoreLines) {
|
||||
ServiceWorkerRegistrationData* entry = tmpData.AppendElement();
|
||||
|
||||
@ -343,6 +345,7 @@ ServiceWorkerRegistrar::ReadData()
|
||||
}
|
||||
|
||||
nsAutoCString line;
|
||||
nsAutoCString unused;
|
||||
if (version.EqualsLiteral(SERVICEWORKERREGISTRAR_VERSION)) {
|
||||
nsAutoCString suffix;
|
||||
GET_LINE(suffix);
|
||||
@ -352,18 +355,19 @@ ServiceWorkerRegistrar::ReadData()
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
GET_LINE(line);
|
||||
entry->principal() =
|
||||
mozilla::ipc::ContentPrincipalInfo(attrs, line);
|
||||
|
||||
GET_LINE(entry->scope());
|
||||
|
||||
entry->principal() =
|
||||
mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
|
||||
|
||||
GET_LINE(entry->currentWorkerURL());
|
||||
|
||||
nsAutoCString cacheName;
|
||||
GET_LINE(cacheName);
|
||||
CopyUTF8toUTF16(cacheName, entry->cacheName());
|
||||
} else if (version.EqualsLiteral("2")) {
|
||||
} else if (version.EqualsLiteral("3")) {
|
||||
overwrite = true;
|
||||
dedupe = true;
|
||||
|
||||
nsAutoCString suffix;
|
||||
GET_LINE(suffix);
|
||||
@ -373,14 +377,40 @@ ServiceWorkerRegistrar::ReadData()
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
GET_LINE(line);
|
||||
entry->principal() =
|
||||
mozilla::ipc::ContentPrincipalInfo(attrs, line);
|
||||
// principal spec is no longer used; we use scope directly instead
|
||||
GET_LINE(unused);
|
||||
|
||||
GET_LINE(entry->scope());
|
||||
|
||||
entry->principal() =
|
||||
mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
|
||||
|
||||
GET_LINE(entry->currentWorkerURL());
|
||||
|
||||
nsAutoCString cacheName;
|
||||
GET_LINE(cacheName);
|
||||
CopyUTF8toUTF16(cacheName, entry->cacheName());
|
||||
} else if (version.EqualsLiteral("2")) {
|
||||
overwrite = true;
|
||||
dedupe = true;
|
||||
|
||||
nsAutoCString suffix;
|
||||
GET_LINE(suffix);
|
||||
|
||||
PrincipalOriginAttributes attrs;
|
||||
if (!attrs.PopulateFromSuffix(suffix)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// principal spec is no longer used; we use scope directly instead
|
||||
GET_LINE(unused);
|
||||
|
||||
GET_LINE(entry->scope());
|
||||
|
||||
entry->principal() =
|
||||
mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
|
||||
|
||||
// scriptSpec is no more used in latest version.
|
||||
nsAutoCString unused;
|
||||
GET_LINE(unused);
|
||||
|
||||
GET_LINE(entry->currentWorkerURL());
|
||||
@ -409,22 +439,32 @@ ServiceWorkerRegistrar::ReadData()
|
||||
|
||||
stream->Close();
|
||||
|
||||
// Dedupe data in file. Old profiles had many duplicates. In theory
|
||||
// we can remove this in the future. (Bug 1248449)
|
||||
// Copy data over to mData.
|
||||
for (uint32_t i = 0; i < tmpData.Length(); ++i) {
|
||||
bool match = false;
|
||||
for (uint32_t j = 0; j < mData.Length(); ++j) {
|
||||
// Use same comparison as RegisterServiceWorker. Scope contains
|
||||
// basic origin information. Combine with any principal attributes.
|
||||
if (Equivalent(tmpData[i], mData[j])) {
|
||||
// Last match wins, just like legacy loading used to do in
|
||||
// the ServiceWorkerManager.
|
||||
mData[j] = tmpData[i];
|
||||
// Dupe found, so overwrite file with reduced list.
|
||||
overwrite = true;
|
||||
match = true;
|
||||
break;
|
||||
if (dedupe) {
|
||||
MOZ_ASSERT(overwrite);
|
||||
// If this is an old profile, then we might need to deduplicate. In
|
||||
// theory this can be removed in the future (Bug 1248449)
|
||||
for (uint32_t j = 0; j < mData.Length(); ++j) {
|
||||
// Use same comparison as RegisterServiceWorker. Scope contains
|
||||
// basic origin information. Combine with any principal attributes.
|
||||
if (Equivalent(tmpData[i], mData[j])) {
|
||||
// Last match wins, just like legacy loading used to do in
|
||||
// the ServiceWorkerManager.
|
||||
mData[j] = tmpData[i];
|
||||
// Dupe found, so overwrite file with reduced list.
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
// Otherwise assert no duplications in debug builds.
|
||||
for (uint32_t j = 0; j < mData.Length(); ++j) {
|
||||
MOZ_ASSERT(!Equivalent(tmpData[i], mData[j]));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (!match) {
|
||||
mData.AppendElement(tmpData[i]);
|
||||
@ -647,9 +687,6 @@ ServiceWorkerRegistrar::WriteData()
|
||||
buffer.Append(suffix.get());
|
||||
buffer.Append('\n');
|
||||
|
||||
buffer.Append(cInfo.spec());
|
||||
buffer.Append('\n');
|
||||
|
||||
buffer.Append(data[i].scope());
|
||||
buffer.Append('\n');
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "nsTArray.h"
|
||||
|
||||
#define SERVICEWORKERREGISTRAR_FILE "serviceworker.txt"
|
||||
#define SERVICEWORKERREGISTRAR_VERSION "3"
|
||||
#define SERVICEWORKERREGISTRAR_VERSION "4"
|
||||
#define SERVICEWORKERREGISTRAR_TERMINATOR "#"
|
||||
#define SERVICEWORKERREGISTRAR_TRUE "true"
|
||||
#define SERVICEWORKERREGISTRAR_FALSE "false"
|
||||
|
@ -142,11 +142,11 @@ TEST(ServiceWorkerRegistrar, TestReadData)
|
||||
nsAutoCString buffer(SERVICEWORKERREGISTRAR_VERSION "\n");
|
||||
|
||||
buffer.Append("^appId=123&inBrowser=1\n");
|
||||
buffer.Append("spec 0\nscope 0\ncurrentWorkerURL 0\ncacheName 0\n");
|
||||
buffer.Append("scope 0\ncurrentWorkerURL 0\ncacheName 0\n");
|
||||
buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
|
||||
|
||||
buffer.Append("\n");
|
||||
buffer.Append("spec 1\nscope 1\ncurrentWorkerURL 1\ncacheName 1\n");
|
||||
buffer.Append("scope 1\ncurrentWorkerURL 1\ncacheName 1\n");
|
||||
buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
|
||||
|
||||
ASSERT_TRUE(CreateFile(buffer)) << "CreateFile should not fail";
|
||||
@ -167,7 +167,7 @@ TEST(ServiceWorkerRegistrar, TestReadData)
|
||||
cInfo0.attrs().CreateSuffix(suffix0);
|
||||
|
||||
ASSERT_STREQ("^appId=123&inBrowser=1", suffix0.get());
|
||||
ASSERT_STREQ("spec 0", cInfo0.spec().get());
|
||||
ASSERT_STREQ("scope 0", cInfo0.spec().get());
|
||||
ASSERT_STREQ("scope 0", data[0].scope().get());
|
||||
ASSERT_STREQ("currentWorkerURL 0", data[0].currentWorkerURL().get());
|
||||
ASSERT_STREQ("cacheName 0", NS_ConvertUTF16toUTF8(data[0].cacheName()).get());
|
||||
@ -180,7 +180,7 @@ TEST(ServiceWorkerRegistrar, TestReadData)
|
||||
cInfo1.attrs().CreateSuffix(suffix1);
|
||||
|
||||
ASSERT_STREQ("", suffix1.get());
|
||||
ASSERT_STREQ("spec 1", cInfo1.spec().get());
|
||||
ASSERT_STREQ("scope 1", cInfo1.spec().get());
|
||||
ASSERT_STREQ("scope 1", data[1].scope().get());
|
||||
ASSERT_STREQ("currentWorkerURL 1", data[1].currentWorkerURL().get());
|
||||
ASSERT_STREQ("cacheName 1", NS_ConvertUTF16toUTF8(data[1].cacheName()).get());
|
||||
@ -246,7 +246,7 @@ TEST(ServiceWorkerRegistrar, TestWriteData)
|
||||
|
||||
ASSERT_STREQ(expectSuffix.get(), suffix.get());
|
||||
|
||||
test.AppendPrintf("spec write %d", i);
|
||||
test.AppendPrintf("scope write %d", i);
|
||||
ASSERT_STREQ(test.get(), cInfo.spec().get());
|
||||
|
||||
test.Truncate();
|
||||
@ -283,7 +283,7 @@ TEST(ServiceWorkerRegistrar, TestVersion2Migration)
|
||||
ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail";
|
||||
|
||||
const nsTArray<ServiceWorkerRegistrationData>& data = swr->TestGetData();
|
||||
ASSERT_EQ((uint32_t)2, data.Length()) << "4 entries should be found";
|
||||
ASSERT_EQ((uint32_t)2, data.Length()) << "2 entries should be found";
|
||||
|
||||
const mozilla::ipc::PrincipalInfo& info0 = data[0].principal();
|
||||
ASSERT_EQ(info0.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) << "First principal must be content";
|
||||
@ -293,7 +293,7 @@ TEST(ServiceWorkerRegistrar, TestVersion2Migration)
|
||||
cInfo0.attrs().CreateSuffix(suffix0);
|
||||
|
||||
ASSERT_STREQ("^appId=123&inBrowser=1", suffix0.get());
|
||||
ASSERT_STREQ("spec 0", cInfo0.spec().get());
|
||||
ASSERT_STREQ("scope 0", cInfo0.spec().get());
|
||||
ASSERT_STREQ("scope 0", data[0].scope().get());
|
||||
ASSERT_STREQ("currentWorkerURL 0", data[0].currentWorkerURL().get());
|
||||
ASSERT_STREQ("activeCache 0", NS_ConvertUTF16toUTF8(data[0].cacheName()).get());
|
||||
@ -306,15 +306,64 @@ TEST(ServiceWorkerRegistrar, TestVersion2Migration)
|
||||
cInfo1.attrs().CreateSuffix(suffix1);
|
||||
|
||||
ASSERT_STREQ("", suffix1.get());
|
||||
ASSERT_STREQ("spec 1", cInfo1.spec().get());
|
||||
ASSERT_STREQ("scope 1", cInfo1.spec().get());
|
||||
ASSERT_STREQ("scope 1", data[1].scope().get());
|
||||
ASSERT_STREQ("currentWorkerURL 1", data[1].currentWorkerURL().get());
|
||||
ASSERT_STREQ("activeCache 1", NS_ConvertUTF16toUTF8(data[1].cacheName()).get());
|
||||
}
|
||||
|
||||
TEST(ServiceWorkerRegistrar, TestVersion3Migration)
|
||||
{
|
||||
nsAutoCString buffer("3" "\n");
|
||||
|
||||
buffer.Append("^appId=123&inBrowser=1\n");
|
||||
buffer.Append("spec 0\nscope 0\ncurrentWorkerURL 0\ncacheName 0\n");
|
||||
buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
|
||||
|
||||
buffer.Append("\n");
|
||||
buffer.Append("spec 1\nscope 1\ncurrentWorkerURL 1\ncacheName 1\n");
|
||||
buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
|
||||
|
||||
ASSERT_TRUE(CreateFile(buffer)) << "CreateFile should not fail";
|
||||
|
||||
RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest;
|
||||
|
||||
nsresult rv = swr->TestReadData();
|
||||
ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail";
|
||||
|
||||
const nsTArray<ServiceWorkerRegistrationData>& data = swr->TestGetData();
|
||||
ASSERT_EQ((uint32_t)2, data.Length()) << "2 entries should be found";
|
||||
|
||||
const mozilla::ipc::PrincipalInfo& info0 = data[0].principal();
|
||||
ASSERT_EQ(info0.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) << "First principal must be content";
|
||||
const mozilla::ipc::ContentPrincipalInfo& cInfo0 = data[0].principal();
|
||||
|
||||
nsAutoCString suffix0;
|
||||
cInfo0.attrs().CreateSuffix(suffix0);
|
||||
|
||||
ASSERT_STREQ("^appId=123&inBrowser=1", suffix0.get());
|
||||
ASSERT_STREQ("scope 0", cInfo0.spec().get());
|
||||
ASSERT_STREQ("scope 0", data[0].scope().get());
|
||||
ASSERT_STREQ("currentWorkerURL 0", data[0].currentWorkerURL().get());
|
||||
ASSERT_STREQ("cacheName 0", NS_ConvertUTF16toUTF8(data[0].cacheName()).get());
|
||||
|
||||
const mozilla::ipc::PrincipalInfo& info1 = data[1].principal();
|
||||
ASSERT_EQ(info1.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) << "First principal must be content";
|
||||
const mozilla::ipc::ContentPrincipalInfo& cInfo1 = data[1].principal();
|
||||
|
||||
nsAutoCString suffix1;
|
||||
cInfo1.attrs().CreateSuffix(suffix1);
|
||||
|
||||
ASSERT_STREQ("", suffix1.get());
|
||||
ASSERT_STREQ("scope 1", cInfo1.spec().get());
|
||||
ASSERT_STREQ("scope 1", data[1].scope().get());
|
||||
ASSERT_STREQ("currentWorkerURL 1", data[1].currentWorkerURL().get());
|
||||
ASSERT_STREQ("cacheName 1", NS_ConvertUTF16toUTF8(data[1].cacheName()).get());
|
||||
}
|
||||
|
||||
TEST(ServiceWorkerRegistrar, TestDedupe)
|
||||
{
|
||||
nsAutoCString buffer(SERVICEWORKERREGISTRAR_VERSION "\n");
|
||||
nsAutoCString buffer("3" "\n");
|
||||
|
||||
// unique entries
|
||||
buffer.Append("^appId=123&inBrowser=1\n");
|
||||
@ -356,7 +405,7 @@ TEST(ServiceWorkerRegistrar, TestDedupe)
|
||||
cInfo0.attrs().CreateSuffix(suffix0);
|
||||
|
||||
ASSERT_STREQ("^appId=123&inBrowser=1", suffix0.get());
|
||||
ASSERT_STREQ("spec 2", cInfo0.spec().get());
|
||||
ASSERT_STREQ("scope 0", cInfo0.spec().get());
|
||||
ASSERT_STREQ("scope 0", data[0].scope().get());
|
||||
ASSERT_STREQ("currentWorkerURL 0", data[0].currentWorkerURL().get());
|
||||
ASSERT_STREQ("cacheName 0", NS_ConvertUTF16toUTF8(data[0].cacheName()).get());
|
||||
@ -369,7 +418,7 @@ TEST(ServiceWorkerRegistrar, TestDedupe)
|
||||
cInfo1.attrs().CreateSuffix(suffix1);
|
||||
|
||||
ASSERT_STREQ("", suffix1.get());
|
||||
ASSERT_STREQ("spec 3", cInfo1.spec().get());
|
||||
ASSERT_STREQ("scope 1", cInfo1.spec().get());
|
||||
ASSERT_STREQ("scope 1", data[1].scope().get());
|
||||
ASSERT_STREQ("currentWorkerURL 1", data[1].currentWorkerURL().get());
|
||||
ASSERT_STREQ("cacheName 1", NS_ConvertUTF16toUTF8(data[1].cacheName()).get());
|
||||
|
@ -170,3 +170,10 @@ function synthesizeNativeDrag(aElement, aX, aY, aDeltaX, aDeltaY, aObserver = nu
|
||||
synthesizeNativeTouch(aElement, aX + aDeltaX, aY + aDeltaY, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, aTouchId);
|
||||
return synthesizeNativeTouch(aElement, aX + aDeltaX, aY + aDeltaY, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, aObserver, aTouchId);
|
||||
}
|
||||
|
||||
function synthesizeNativeTap(aElement, aX, aY, aObserver = null) {
|
||||
var pt = coordinatesRelativeToWindow(aX, aY, aElement);
|
||||
var utils = SpecialPowers.getDOMWindowUtils(aElement.ownerDocument.defaultView);
|
||||
utils.sendNativeTouchTap(pt.x, pt.y, false, aObserver);
|
||||
return true;
|
||||
}
|
||||
|
42
gfx/layers/apz/test/mochitest/helper_tap.html
Normal file
42
gfx/layers/apz/test/mochitest/helper_tap.html
Normal file
@ -0,0 +1,42 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width; initial-scale=1.0">
|
||||
<title>Sanity touch-tapping test</title>
|
||||
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
|
||||
<script type="application/javascript" src="apz_test_utils.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
|
||||
<script type="application/javascript">
|
||||
|
||||
function clickButton() {
|
||||
if (!window.TouchEvent) {
|
||||
window.opener.ok(true, "Touch events are not supported on this platform, sorry!\n");
|
||||
window.opener.testDone();
|
||||
return;
|
||||
}
|
||||
|
||||
document.addEventListener('click', clicked, false);
|
||||
|
||||
synthesizeNativeTap(document.getElementById('b'), 5, 5, function() {
|
||||
dump("Finished synthesizing tap, waiting for button to be clicked...\n");
|
||||
});
|
||||
}
|
||||
|
||||
function clicked(e) {
|
||||
window.opener.is(e.target, document.getElementById('b'), "Clicked on button, yay! (at " + e.clientX + "," + e.clientY + ")");
|
||||
window.opener.testDone();
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
waitForAllPaints(function() {
|
||||
flushApzRepaints(clickButton);
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<button id="b" style="width: 10px; height: 10px"></button>
|
||||
</body>
|
||||
</html>
|
@ -10,6 +10,7 @@ support-files =
|
||||
helper_basic_pan.html
|
||||
helper_div_pan.html
|
||||
helper_iframe_pan.html
|
||||
helper_tap.html
|
||||
tags = apz
|
||||
[test_bug982141.html]
|
||||
skip-if = toolkit != 'gonk' # bug 991198
|
||||
@ -32,3 +33,7 @@ skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel ev
|
||||
[test_scroll_subframe_scrollbar.html]
|
||||
skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel events not supported on mobile; see bug 1164274 for mulet
|
||||
[test_frame_reconstruction.html]
|
||||
[test_tap.html]
|
||||
# Windows touch injection doesn't work in automation, but this test can be run locally on a windows touch device.
|
||||
# On OS X we don't support touch events at all.
|
||||
skip-if = (toolkit == 'windows') || (toolkit == 'cocoa')
|
||||
|
46
gfx/layers/apz/test/mochitest/test_tap.html
Normal file
46
gfx/layers/apz/test/mochitest/test_tap.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Sanity panning test</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// this page just serially loads each one of the following test helper pages in
|
||||
// a new window and waits for it to call testDone()
|
||||
var tests = [
|
||||
'helper_tap.html',
|
||||
];
|
||||
|
||||
var testIndex = -1;
|
||||
var w = null;
|
||||
|
||||
function testDone() {
|
||||
if (w) {
|
||||
w.close();
|
||||
}
|
||||
testIndex++;
|
||||
if (testIndex < tests.length) {
|
||||
w = window.open(tests[testIndex], "_blank");
|
||||
} else {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
if (!SpecialPowers.getDOMWindowUtils(window).asyncPanZoomEnabled) {
|
||||
ok(true, "APZ is not enabled, this test is not relevant, sorry!\n");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
testDone();
|
||||
};
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -434,7 +434,7 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
|
||||
MOZ_ASSERT(effectMask->mMaskTransform.Is2D(), "How did we end up with a 3D transform here?!");
|
||||
MOZ_ASSERT(!effectMask->mIs3D);
|
||||
maskTransform = effectMask->mMaskTransform.As2D();
|
||||
maskTransform.PreTranslate(-offset.x, -offset.y);
|
||||
maskTransform.PostTranslate(-offset.x, -offset.y);
|
||||
}
|
||||
|
||||
CompositionOp blendMode = CompositionOp::OP_OVER;
|
||||
|
@ -820,7 +820,8 @@ TextureClient::CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aTextureFlags,
|
||||
TextureAllocationFlags aAllocFlags)
|
||||
{
|
||||
MOZ_ASSERT(aAllocator->IPCOpen());
|
||||
// also test the validity of aAllocator
|
||||
MOZ_ASSERT(aAllocator && aAllocator->IPCOpen());
|
||||
if (!aAllocator || !aAllocator->IPCOpen()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ struct JS_PUBLIC_API(ShortestPaths)
|
||||
BackEdge* back, bool first)
|
||||
{
|
||||
MOZ_ASSERT(back);
|
||||
MOZ_ASSERT(traversal.visited.has(origin));
|
||||
MOZ_ASSERT(origin == shortestPaths.root_ || traversal.visited.has(origin));
|
||||
MOZ_ASSERT(totalPathsRecorded < totalMaxPathsToRecord);
|
||||
|
||||
if (first && !back->init(origin, edge))
|
||||
@ -128,9 +128,7 @@ struct JS_PUBLIC_API(ShortestPaths)
|
||||
// `back->clone()` in the first branch, and the `init` call in the
|
||||
// second branch.
|
||||
|
||||
auto ptr = shortestPaths.paths_.lookupForAdd(edge.referent);
|
||||
if (first) {
|
||||
MOZ_ASSERT(!ptr);
|
||||
BackEdgeVector paths;
|
||||
if (!paths.reserve(shortestPaths.maxNumPaths_))
|
||||
return false;
|
||||
@ -138,16 +136,23 @@ struct JS_PUBLIC_API(ShortestPaths)
|
||||
if (!cloned)
|
||||
return false;
|
||||
paths.infallibleAppend(mozilla::Move(cloned));
|
||||
if (!shortestPaths.paths_.add(ptr, edge.referent, mozilla::Move(paths)))
|
||||
if (!shortestPaths.paths_.putNew(edge.referent, mozilla::Move(paths)))
|
||||
return false;
|
||||
totalPathsRecorded++;
|
||||
} else if (ptr->value().length() < shortestPaths.maxNumPaths_) {
|
||||
MOZ_ASSERT(ptr);
|
||||
BackEdge::Ptr thisBackEdge(js_new<BackEdge>());
|
||||
if (!thisBackEdge || !thisBackEdge->init(origin, edge))
|
||||
return false;
|
||||
ptr->value().infallibleAppend(mozilla::Move(thisBackEdge));
|
||||
totalPathsRecorded++;
|
||||
} else {
|
||||
auto ptr = shortestPaths.paths_.lookup(edge.referent);
|
||||
MOZ_ASSERT(ptr,
|
||||
"This isn't the first time we have seen the target node `edge.referent`. "
|
||||
"We should have inserted it into shortestPaths.paths_ the first time we "
|
||||
"saw it.");
|
||||
|
||||
if (ptr->value().length() < shortestPaths.maxNumPaths_) {
|
||||
BackEdge::Ptr thisBackEdge(js_new<BackEdge>());
|
||||
if (!thisBackEdge || !thisBackEdge->init(origin, edge))
|
||||
return false;
|
||||
ptr->value().infallibleAppend(mozilla::Move(thisBackEdge));
|
||||
totalPathsRecorded++;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(totalPathsRecorded <= totalMaxPathsToRecord);
|
||||
@ -251,7 +256,7 @@ struct JS_PUBLIC_API(ShortestPaths)
|
||||
Handler handler(paths);
|
||||
Traversal traversal(rt, handler, noGC);
|
||||
traversal.wantNames = true;
|
||||
if (!traversal.init() || !traversal.addStartVisited(root) || !traversal.traverse())
|
||||
if (!traversal.init() || !traversal.addStart(root) || !traversal.traverse())
|
||||
return mozilla::Nothing();
|
||||
|
||||
// Take ownership of the back edges we created while traversing the
|
||||
|
@ -653,30 +653,6 @@ ComparisonRight(ParseNode* pn)
|
||||
return BinaryOpRight(pn);
|
||||
}
|
||||
|
||||
static inline ParseNode*
|
||||
AndOrLeft(ParseNode* pn)
|
||||
{
|
||||
return BinaryOpLeft(pn);
|
||||
}
|
||||
|
||||
static inline ParseNode*
|
||||
AndOrRight(ParseNode* pn)
|
||||
{
|
||||
return BinaryOpRight(pn);
|
||||
}
|
||||
|
||||
static inline ParseNode*
|
||||
RelationalLeft(ParseNode* pn)
|
||||
{
|
||||
return BinaryOpLeft(pn);
|
||||
}
|
||||
|
||||
static inline ParseNode*
|
||||
RelationalRight(ParseNode* pn)
|
||||
{
|
||||
return BinaryOpRight(pn);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsExpressionStatement(ParseNode* pn)
|
||||
{
|
||||
|
@ -200,7 +200,6 @@ namespace {
|
||||
#define DEFINE_DEFN_(TypeName) \
|
||||
class TypeName##Defn { \
|
||||
public: \
|
||||
static const SimdType type = SimdType::TypeName; \
|
||||
static const JSFunctionSpec Methods[]; \
|
||||
};
|
||||
|
||||
|
@ -933,7 +933,10 @@ Statistics::endGC()
|
||||
int64_t markRootsTotal = SumPhase(PHASE_MARK_ROOTS, phaseTimes);
|
||||
runtime->addTelemetry(JS_TELEMETRY_GC_MARK_MS, t(markTotal));
|
||||
runtime->addTelemetry(JS_TELEMETRY_GC_SWEEP_MS, t(phaseTimes[PHASE_DAG_NONE][PHASE_SWEEP]));
|
||||
runtime->addTelemetry(JS_TELEMETRY_GC_COMPACT_MS, t(phaseTimes[PHASE_DAG_NONE][PHASE_COMPACT]));
|
||||
if (runtime->gc.isCompactingGc()) {
|
||||
runtime->addTelemetry(JS_TELEMETRY_GC_COMPACT_MS,
|
||||
t(phaseTimes[PHASE_DAG_NONE][PHASE_COMPACT]));
|
||||
}
|
||||
runtime->addTelemetry(JS_TELEMETRY_GC_MARK_ROOTS_MS, t(markRootsTotal));
|
||||
runtime->addTelemetry(JS_TELEMETRY_GC_MARK_GRAY_MS, t(phaseTimes[PHASE_DAG_NONE][PHASE_SWEEP_MARK_GRAY]));
|
||||
runtime->addTelemetry(JS_TELEMETRY_GC_NON_INCREMENTAL, !!nonincrementalReason_);
|
||||
|
1
js/src/jit-test/tests/heap-analysis/bug-1249107.js
Normal file
1
js/src/jit-test/tests/heap-analysis/bug-1249107.js
Normal file
@ -0,0 +1 @@
|
||||
shortestPaths(this, [this], 5)
|
@ -3306,7 +3306,7 @@ IonBuilder::inlineConstructSimdObject(CallInfo& callInfo, SimdTypeDescr* descr)
|
||||
defVal = constant(DoubleNaNValue());
|
||||
} else {
|
||||
MOZ_ASSERT(laneType == MIRType_Float32);
|
||||
defVal = MConstant::NewFloat32(alloc(), GenericNaN());
|
||||
defVal = MConstant::NewFloat32(alloc(), JS::GenericNaN());
|
||||
current->add(defVal);
|
||||
}
|
||||
}
|
||||
|
@ -619,6 +619,21 @@ MacroAssembler::assertStackAlignment(uint32_t alignment, int32_t offset /* = 0 *
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::storeCallResultValue(AnyRegister dest)
|
||||
{
|
||||
unboxValue(JSReturnOperand, dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::storeCallResultValue(TypedOrValueRegister dest)
|
||||
{
|
||||
if (dest.hasValue())
|
||||
storeCallResultValue(dest.valueReg());
|
||||
else
|
||||
storeCallResultValue(dest.typedReg());
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
@ -824,6 +824,15 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
inline void branchPtr(Condition cond, wasm::SymbolicAddress lhs, Register rhs, Label* label)
|
||||
DEFINED_ON(arm, arm64, mips_shared, x86, x64);
|
||||
|
||||
template <typename T>
|
||||
inline CodeOffsetJump branchPtrWithPatch(Condition cond, Register lhs, T rhs, RepatchLabel* label) PER_SHARED_ARCH;
|
||||
template <typename T>
|
||||
inline CodeOffsetJump branchPtrWithPatch(Condition cond, Address lhs, T rhs, RepatchLabel* label) PER_SHARED_ARCH;
|
||||
|
||||
void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label)
|
||||
DEFINED_ON(arm, arm64, mips_shared, x86, x64);
|
||||
void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp, Label* label) PER_ARCH;
|
||||
|
||||
// This function compares a Value (lhs) which is having a private pointer
|
||||
// boxed inside a js::Value, with a raw pointer (rhs).
|
||||
inline void branchPrivatePtr(Condition cond, const Address& lhs, Register rhs, Label* label) PER_ARCH;
|
||||
@ -838,6 +847,13 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
inline void branchTruncateDouble(FloatRegister src, Register dest, Label* fail)
|
||||
DEFINED_ON(arm, arm64, mips_shared, x86, x64);
|
||||
|
||||
template <typename T>
|
||||
inline void branchAdd32(Condition cond, T src, Register dest, Label* label) PER_SHARED_ARCH;
|
||||
template <typename T>
|
||||
inline void branchSub32(Condition cond, T src, Register dest, Label* label) PER_SHARED_ARCH;
|
||||
|
||||
inline void decBranchPtr(Condition cond, Register lhs, Imm32 rhs, Label* label) PER_SHARED_ARCH;
|
||||
|
||||
template <class L>
|
||||
inline void branchTest32(Condition cond, Register lhs, Register rhs, L label) PER_SHARED_ARCH;
|
||||
template <class L>
|
||||
@ -902,6 +918,17 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
|
||||
inline void branchTestNeedsIncrementalBarrier(Condition cond, Label* label);
|
||||
|
||||
inline void branchTestInt32(Condition cond, Register tag, Label* label)
|
||||
DEFINED_ON(arm, arm64, mips_shared, x86, x64);
|
||||
inline void branchTestInt32(Condition cond, const Address& address, Label* label)
|
||||
DEFINED_ON(arm, arm64, mips_shared, x86, x64);
|
||||
inline void branchTestInt32(Condition cond, const BaseIndex& address, Label* label)
|
||||
DEFINED_ON(arm, arm64, mips_shared, x86, x64);
|
||||
inline void branchTestInt32(Condition cond, const ValueOperand& src, Label* label) PER_ARCH;
|
||||
|
||||
inline void branchTestInt32Truthy(bool truthy, const ValueOperand& operand, Label* label)
|
||||
DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
public:
|
||||
|
||||
@ -1012,15 +1039,7 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
moveDouble(ReturnDoubleReg, reg);
|
||||
}
|
||||
|
||||
void storeCallResultValue(AnyRegister dest) {
|
||||
#if defined(JS_NUNBOX32)
|
||||
unboxValue(ValueOperand(JSReturnReg_Type, JSReturnReg_Data), dest);
|
||||
#elif defined(JS_PUNBOX64)
|
||||
unboxValue(ValueOperand(JSReturnReg), dest);
|
||||
#else
|
||||
#error "Bad architecture"
|
||||
#endif
|
||||
}
|
||||
inline void storeCallResultValue(AnyRegister dest);
|
||||
|
||||
void storeCallResultValue(ValueOperand dest) {
|
||||
#if defined(JS_NUNBOX32)
|
||||
@ -1051,12 +1070,7 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
#endif
|
||||
}
|
||||
|
||||
void storeCallResultValue(TypedOrValueRegister dest) {
|
||||
if (dest.hasValue())
|
||||
storeCallResultValue(dest.valueReg());
|
||||
else
|
||||
storeCallResultValue(dest.typedReg());
|
||||
}
|
||||
inline void storeCallResultValue(TypedOrValueRegister dest);
|
||||
|
||||
template <typename T>
|
||||
Register extractString(const T& source, Register scratch) {
|
||||
|
@ -585,6 +585,24 @@ MacroAssembler::branchPtr(Condition cond, wasm::SymbolicAddress lhs, Register rh
|
||||
branchPtr(cond, scratch, rhs, label);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
CodeOffsetJump
|
||||
MacroAssembler::branchPtrWithPatch(Condition cond, Register lhs, T rhs, RepatchLabel* label)
|
||||
{
|
||||
ma_cmp(lhs, rhs);
|
||||
return jumpWithPatch(label, cond);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
CodeOffsetJump
|
||||
MacroAssembler::branchPtrWithPatch(Condition cond, Address lhs, T rhs, RepatchLabel* label)
|
||||
{
|
||||
AutoRegisterScope scratch2(*this, secondScratchReg_);
|
||||
ma_ldr(lhs, scratch2);
|
||||
ma_cmp(scratch2, rhs);
|
||||
return jumpWithPatch(label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchPrivatePtr(Condition cond, const Address& lhs, Register rhs, Label* label)
|
||||
{
|
||||
@ -671,6 +689,29 @@ MacroAssembler::branchTruncateDouble(FloatRegister src, Register dest, Label* fa
|
||||
ma_b(fail, Assembler::Equal);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
MacroAssembler::branchAdd32(Condition cond, T src, Register dest, Label* label)
|
||||
{
|
||||
add32(src, dest);
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
MacroAssembler::branchSub32(Condition cond, T src, Register dest, Label* label)
|
||||
{
|
||||
ma_sub(src, dest, SetCC);
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::decBranchPtr(Condition cond, Register lhs, Imm32 rhs, Label* label)
|
||||
{
|
||||
ma_sub(rhs, lhs, SetCC);
|
||||
as_b(label, cond);
|
||||
}
|
||||
|
||||
template <class L>
|
||||
void
|
||||
MacroAssembler::branchTest32(Condition cond, Register lhs, Register rhs, L label)
|
||||
@ -744,17 +785,40 @@ MacroAssembler::branchTest64(Condition cond, Register64 lhs, Register64 rhs, Reg
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, Register tag, Label* label)
|
||||
{
|
||||
branchTestInt32Impl(cond, tag, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const Address& address, Label* label)
|
||||
{
|
||||
branchTestInt32Impl(cond, address, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const BaseIndex& address, Label* label)
|
||||
{
|
||||
branchTestInt32Impl(cond, address, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const ValueOperand& src, Label* label)
|
||||
{
|
||||
branchTestInt32Impl(cond, src, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32Truthy(bool truthy, const ValueOperand& operand, Label* label)
|
||||
{
|
||||
Condition c = testInt32Truthy(truthy, operand);
|
||||
ma_b(label, c);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
// ===============================================================
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
MacroAssemblerARMCompat::branchAdd32(Condition cond, T src, Register dest, Label* label)
|
||||
{
|
||||
asMasm().add32(src, dest);
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::incrementInt32Value(const Address& addr)
|
||||
{
|
||||
|
@ -2942,7 +2942,7 @@ MacroAssemblerARMCompat::unboxValue(const ValueOperand& src, AnyRegister dest)
|
||||
{
|
||||
if (dest.isFloat()) {
|
||||
Label notInt32, end;
|
||||
branchTestInt32(Assembler::NotEqual, src, ¬Int32);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, src, ¬Int32);
|
||||
convertInt32ToDouble(src.payloadReg(), dest.fpu());
|
||||
ma_b(&end);
|
||||
bind(¬Int32);
|
||||
@ -3031,7 +3031,7 @@ MacroAssemblerARMCompat::loadInt32OrDouble(const Address& src, FloatRegister des
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
|
||||
ma_ldr(ToType(src), scratch);
|
||||
branchTestInt32(Assembler::NotEqual, scratch, ¬Int32);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, scratch, ¬Int32);
|
||||
ma_ldr(ToPayload(src), scratch);
|
||||
convertInt32ToDouble(scratch, dest);
|
||||
ma_b(&end);
|
||||
@ -3059,7 +3059,7 @@ MacroAssemblerARMCompat::loadInt32OrDouble(Register base, Register index,
|
||||
// Since we only have one scratch register, we need to stomp over it with
|
||||
// the tag.
|
||||
ma_ldr(Address(scratch, NUNBOX32_TYPE_OFFSET), scratch);
|
||||
branchTestInt32(Assembler::NotEqual, scratch, ¬Int32);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, scratch, ¬Int32);
|
||||
|
||||
// Implicitly requires NUNBOX32_PAYLOAD_OFFSET == 0: no offset provided
|
||||
ma_ldr(DTRAddr(base, DtrRegImmShift(index, LSL, shift)), scratch);
|
||||
@ -3449,7 +3449,7 @@ MacroAssemblerARMCompat::ensureDouble(const ValueOperand& source, FloatRegister
|
||||
{
|
||||
Label isDouble, done;
|
||||
branchTestDouble(Assembler::Equal, source.typeReg(), &isDouble);
|
||||
branchTestInt32(Assembler::NotEqual, source.typeReg(), failure);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, source.typeReg(), failure);
|
||||
|
||||
convertInt32ToDouble(source.payloadReg(), dest);
|
||||
jump(&done);
|
||||
@ -4011,39 +4011,6 @@ MacroAssemblerARMCompat::jumpWithPatch(RepatchLabel* label, Condition cond, Labe
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
AutoRegisterScope scratch2(asMasm(), secondScratchReg_);
|
||||
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
MOZ_ASSERT(ptr != temp);
|
||||
MOZ_ASSERT(ptr != scratch2);
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
uintptr_t startChunk = nursery.start() >> Nursery::ChunkShift;
|
||||
|
||||
ma_mov(Imm32(startChunk), scratch2);
|
||||
as_rsb(scratch2, scratch2, lsr(ptr, Nursery::ChunkShift));
|
||||
asMasm().branch32(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
scratch2, Imm32(nursery.numChunks()), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::branchValueIsNurseryObject(Condition cond, ValueOperand value,
|
||||
Register temp, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
|
||||
Label done;
|
||||
|
||||
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
|
||||
branchPtrInNurseryRange(cond, value.payloadReg(), temp, label);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
@ -5065,4 +5032,40 @@ MacroAssembler::pushFakeReturnAddress(Register scratch)
|
||||
return pseudoReturnOffset;
|
||||
}
|
||||
|
||||
// ===============================================================
|
||||
// Branch functions
|
||||
|
||||
void
|
||||
MacroAssembler::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
AutoRegisterScope scratch2(*this, secondScratchReg_);
|
||||
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
MOZ_ASSERT(ptr != temp);
|
||||
MOZ_ASSERT(ptr != scratch2);
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
uintptr_t startChunk = nursery.start() >> Nursery::ChunkShift;
|
||||
|
||||
ma_mov(Imm32(startChunk), scratch2);
|
||||
as_rsb(scratch2, scratch2, lsr(ptr, Nursery::ChunkShift));
|
||||
branch32(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
scratch2, Imm32(nursery.numChunks()), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchValueIsNurseryObject(Condition cond, ValueOperand value,
|
||||
Register temp, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
|
||||
Label done;
|
||||
|
||||
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
|
||||
branchPtrInNurseryRange(cond, value.payloadReg(), temp, label);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
|
@ -763,7 +763,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
void loadConstantFloat32(float f, FloatRegister dest);
|
||||
|
||||
template<typename T>
|
||||
void branchTestInt32(Condition cond, const T & t, Label* label) {
|
||||
void branchTestInt32Impl(Condition cond, const T & t, Label* label) {
|
||||
Condition c = testInt32(cond, t);
|
||||
ma_b(label, c);
|
||||
}
|
||||
@ -818,10 +818,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
branchTestValue(cond, val, MagicValue(why), label);
|
||||
}
|
||||
void branchTestInt32Truthy(bool truthy, const ValueOperand& operand, Label* label) {
|
||||
Condition c = testInt32Truthy(truthy, operand);
|
||||
ma_b(label, c);
|
||||
}
|
||||
void branchTestBooleanTruthy(bool truthy, const ValueOperand& operand, Label* label) {
|
||||
Condition c = testBooleanTruthy(truthy, operand);
|
||||
ma_b(label, c);
|
||||
@ -834,10 +830,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
Condition c = testStringTruthy(truthy, value);
|
||||
ma_b(label, c);
|
||||
}
|
||||
void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) {
|
||||
ma_sub(imm, lhs, SetCC);
|
||||
as_b(label, cond);
|
||||
}
|
||||
void moveValue(const Value& val, Register type, Register data);
|
||||
|
||||
CodeOffsetJump jumpWithPatch(RepatchLabel* label, Condition cond = Always,
|
||||
@ -845,18 +837,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
CodeOffsetJump backedgeJump(RepatchLabel* label, Label* documentation) {
|
||||
return jumpWithPatch(label, Always, documentation);
|
||||
}
|
||||
template <typename T>
|
||||
CodeOffsetJump branchPtrWithPatch(Condition cond, Register reg, T ptr, RepatchLabel* label) {
|
||||
ma_cmp(reg, ptr);
|
||||
return jumpWithPatch(label, cond);
|
||||
}
|
||||
template <typename T>
|
||||
CodeOffsetJump branchPtrWithPatch(Condition cond, Address addr, T ptr, RepatchLabel* label) {
|
||||
AutoRegisterScope scratch2(asMasm(), secondScratchReg_);
|
||||
ma_ldr(addr, scratch2);
|
||||
ma_cmp(scratch2, ptr);
|
||||
return jumpWithPatch(label, cond);
|
||||
}
|
||||
|
||||
void loadUnboxedValue(Address address, MIRType type, AnyRegister dest) {
|
||||
if (dest.isFloat())
|
||||
@ -985,13 +965,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
// Common interface.
|
||||
/////////////////////////////////////////////////////////////////
|
||||
public:
|
||||
template <typename T> inline void branchAdd32(Condition cond, T src, Register dest, Label* label);
|
||||
template <typename T>
|
||||
void branchSub32(Condition cond, T src, Register dest, Label* label) {
|
||||
ma_sub(src, dest, SetCC);
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void not32(Register reg);
|
||||
|
||||
void move32(Imm32 imm, Register dest);
|
||||
@ -1548,9 +1521,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
as_vmov(VFPRegister(dest).singleOverlay(), VFPRegister(src).singleOverlay());
|
||||
}
|
||||
|
||||
void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label);
|
||||
void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp, Label* label);
|
||||
|
||||
void loadWasmActivation(Register dest) {
|
||||
loadPtr(Address(GlobalReg, wasm::ActivationGlobalDataOffset - AsmJSGlobalRegBias), dest);
|
||||
}
|
||||
|
@ -654,6 +654,29 @@ MacroAssembler::branchPtr(Condition cond, wasm::SymbolicAddress lhs, Register rh
|
||||
branchPtr(cond, scratch, rhs, label);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
CodeOffsetJump
|
||||
MacroAssembler::branchPtrWithPatch(Condition cond, Register lhs, T rhs, RepatchLabel* label)
|
||||
{
|
||||
cmpPtr(lhs, rhs);
|
||||
return jumpWithPatch(label, cond);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
CodeOffsetJump
|
||||
MacroAssembler::branchPtrWithPatch(Condition cond, Address lhs, T rhs, RepatchLabel* label)
|
||||
{
|
||||
// The scratch register is unused after the condition codes are set.
|
||||
{
|
||||
vixl::UseScratchRegisterScope temps(this);
|
||||
const Register scratch = temps.AcquireX().asUnsized();
|
||||
MOZ_ASSERT(scratch != lhs.base);
|
||||
loadPtr(lhs, scratch);
|
||||
cmpPtr(scratch, rhs);
|
||||
}
|
||||
return jumpWithPatch(label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchPrivatePtr(Condition cond, const Address& lhs, Register rhs, Label* label)
|
||||
{
|
||||
@ -749,6 +772,29 @@ MacroAssembler::branchTruncateDouble(FloatRegister src, Register dest, Label* fa
|
||||
And(dest64, dest64, Operand(0xffffffff));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
MacroAssembler::branchAdd32(Condition cond, T src, Register dest, Label* label)
|
||||
{
|
||||
adds32(src, dest);
|
||||
branch(cond, label);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
MacroAssembler::branchSub32(Condition cond, T src, Register dest, Label* label)
|
||||
{
|
||||
subs32(src, dest);
|
||||
branch(cond, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::decBranchPtr(Condition cond, Register lhs, Imm32 rhs, Label* label)
|
||||
{
|
||||
Subs(ARMRegister(lhs, 64), ARMRegister(lhs, 64), Operand(rhs.value));
|
||||
B(cond, label);
|
||||
}
|
||||
|
||||
template <class L>
|
||||
void
|
||||
MacroAssembler::branchTest32(Condition cond, Register lhs, Register rhs, L label)
|
||||
@ -822,6 +868,37 @@ MacroAssembler::branchTest64(Condition cond, Register64 lhs, Register64 rhs, Reg
|
||||
branchTestPtr(cond, lhs.reg, rhs.reg, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, Register tag, Label* label)
|
||||
{
|
||||
branchTestInt32Impl(cond, tag, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const Address& address, Label* label)
|
||||
{
|
||||
branchTestInt32Impl(cond, address, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const BaseIndex& address, Label* label)
|
||||
{
|
||||
branchTestInt32Impl(cond, address, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const ValueOperand& src, Label* label)
|
||||
{
|
||||
branchTestInt32Impl(cond, src, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32Truthy(bool truthy, const ValueOperand& operand, Label* label)
|
||||
{
|
||||
Condition c = testInt32Truthy(truthy, operand);
|
||||
B(label, c);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
// ===============================================================
|
||||
|
||||
@ -889,6 +966,49 @@ MacroAssemblerCompat::branchTestStackPtr(Condition cond, T t, Label* label)
|
||||
asMasm().branchTestPtr(cond, getStackPointer(), t, label);
|
||||
}
|
||||
|
||||
// If source is a double, load into dest.
|
||||
// If source is int32, convert to double and store in dest.
|
||||
// Else, branch to failure.
|
||||
void
|
||||
MacroAssemblerCompat::ensureDouble(const ValueOperand& source, FloatRegister dest, Label* failure)
|
||||
{
|
||||
Label isDouble, done;
|
||||
|
||||
// TODO: splitTagForTest really should not leak a scratch register.
|
||||
Register tag = splitTagForTest(source);
|
||||
{
|
||||
vixl::UseScratchRegisterScope temps(this);
|
||||
temps.Exclude(ARMRegister(tag, 64));
|
||||
|
||||
branchTestDouble(Assembler::Equal, tag, &isDouble);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, tag, failure);
|
||||
}
|
||||
|
||||
convertInt32ToDouble(source.valueReg(), dest);
|
||||
jump(&done);
|
||||
|
||||
bind(&isDouble);
|
||||
unboxDouble(source, dest);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerCompat::unboxValue(const ValueOperand& src, AnyRegister dest)
|
||||
{
|
||||
if (dest.isFloat()) {
|
||||
Label notInt32, end;
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, src, ¬Int32);
|
||||
convertInt32ToDouble(src.valueReg(), dest.fpu());
|
||||
jump(&end);
|
||||
bind(¬Int32);
|
||||
unboxDouble(src, dest.fpu());
|
||||
bind(&end);
|
||||
} else {
|
||||
unboxNonDouble(src, dest.gpr());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
@ -217,44 +217,6 @@ MacroAssemblerCompat::handleFailureWithHandlerTail(void* handler)
|
||||
Br(x1);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerCompat::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
MOZ_ASSERT(ptr != temp);
|
||||
MOZ_ASSERT(ptr != ScratchReg && ptr != ScratchReg2); // Both may be used internally.
|
||||
MOZ_ASSERT(temp != ScratchReg && temp != ScratchReg2);
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp);
|
||||
asMasm().addPtr(ptr, temp);
|
||||
asMasm().branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
temp, ImmWord(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerCompat::branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
MOZ_ASSERT(temp != ScratchReg && temp != ScratchReg2); // Both may be used internally.
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
|
||||
// Avoid creating a bogus ObjectValue below.
|
||||
if (!nursery.exists())
|
||||
return;
|
||||
|
||||
// 'Value' representing the start of the nursery tagged as a JSObject
|
||||
Value start = ObjectValue(*reinterpret_cast<JSObject*>(nursery.start()));
|
||||
|
||||
movePtr(ImmWord(-ptrdiff_t(start.asRawBits())), temp);
|
||||
asMasm().addPtr(value.valueReg(), temp);
|
||||
asMasm().branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
temp, ImmWord(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerCompat::breakpoint()
|
||||
{
|
||||
@ -720,6 +682,47 @@ MacroAssembler::pushFakeReturnAddress(Register scratch)
|
||||
return pseudoReturnOffset;
|
||||
}
|
||||
|
||||
// ===============================================================
|
||||
// Branch functions
|
||||
|
||||
void
|
||||
MacroAssembler::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
MOZ_ASSERT(ptr != temp);
|
||||
MOZ_ASSERT(ptr != ScratchReg && ptr != ScratchReg2); // Both may be used internally.
|
||||
MOZ_ASSERT(temp != ScratchReg && temp != ScratchReg2);
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp);
|
||||
addPtr(ptr, temp);
|
||||
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
temp, ImmWord(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
MOZ_ASSERT(temp != ScratchReg && temp != ScratchReg2); // Both may be used internally.
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
|
||||
// Avoid creating a bogus ObjectValue below.
|
||||
if (!nursery.exists())
|
||||
return;
|
||||
|
||||
// 'Value' representing the start of the nursery tagged as a JSObject
|
||||
Value start = ObjectValue(*reinterpret_cast<JSObject*>(nursery.start()));
|
||||
|
||||
movePtr(ImmWord(-ptrdiff_t(start.asRawBits())), temp);
|
||||
addPtr(value.valueReg(), temp);
|
||||
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
temp, ImmWord(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
|
||||
} // namespace jit
|
||||
|
@ -439,30 +439,7 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||
return scratch;
|
||||
}
|
||||
|
||||
// If source is a double, load into dest.
|
||||
// If source is int32, convert to double and store in dest.
|
||||
// Else, branch to failure.
|
||||
void ensureDouble(const ValueOperand& source, FloatRegister dest, Label* failure) {
|
||||
Label isDouble, done;
|
||||
|
||||
// TODO: splitTagForTest really should not leak a scratch register.
|
||||
Register tag = splitTagForTest(source);
|
||||
{
|
||||
vixl::UseScratchRegisterScope temps(this);
|
||||
temps.Exclude(ARMRegister(tag, 64));
|
||||
|
||||
branchTestDouble(Assembler::Equal, tag, &isDouble);
|
||||
branchTestInt32(Assembler::NotEqual, tag, failure);
|
||||
}
|
||||
|
||||
convertInt32ToDouble(source.valueReg(), dest);
|
||||
jump(&done);
|
||||
|
||||
bind(&isDouble);
|
||||
unboxDouble(source, dest);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
inline void ensureDouble(const ValueOperand& source, FloatRegister dest, Label* failure);
|
||||
|
||||
void emitSet(Condition cond, Register dest) {
|
||||
Cset(ARMRegister(dest, 64), cond);
|
||||
@ -1350,35 +1327,15 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||
CodeOffsetJump backedgeJump(RepatchLabel* label, Label* documentation = nullptr) {
|
||||
return jumpWithPatch(label, Always, documentation);
|
||||
}
|
||||
template <typename T>
|
||||
CodeOffsetJump branchPtrWithPatch(Condition cond, Register reg, T ptr, RepatchLabel* label) {
|
||||
cmpPtr(reg, ptr);
|
||||
return jumpWithPatch(label, cond);
|
||||
}
|
||||
template <typename T>
|
||||
CodeOffsetJump branchPtrWithPatch(Condition cond, Address addr, T ptr, RepatchLabel* label) {
|
||||
// The scratch register is unused after the condition codes are set.
|
||||
{
|
||||
vixl::UseScratchRegisterScope temps(this);
|
||||
const Register scratch = temps.AcquireX().asUnsized();
|
||||
MOZ_ASSERT(scratch != addr.base);
|
||||
loadPtr(addr, scratch);
|
||||
cmpPtr(scratch, ptr);
|
||||
}
|
||||
return jumpWithPatch(label, cond);
|
||||
}
|
||||
|
||||
void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) {
|
||||
Subs(ARMRegister(lhs, 64), ARMRegister(lhs, 64), Operand(imm.value));
|
||||
B(cond, label);
|
||||
}
|
||||
|
||||
void branchTestUndefined(Condition cond, Register tag, Label* label) {
|
||||
Condition c = testUndefined(cond, tag);
|
||||
B(label, c);
|
||||
}
|
||||
void branchTestInt32(Condition cond, Register tag, Label* label) {
|
||||
Condition c = testInt32(cond, tag);
|
||||
|
||||
template<typename T>
|
||||
void branchTestInt32Impl(Condition cond, T& t, Label* label) {
|
||||
Condition c = testInt32(cond, t);
|
||||
B(label, c);
|
||||
}
|
||||
void branchTestDouble(Condition cond, Register tag, Label* label) {
|
||||
@ -1414,10 +1371,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||
Condition c = testUndefined(cond, address);
|
||||
B(label, c);
|
||||
}
|
||||
void branchTestInt32(Condition cond, const Address& address, Label* label) {
|
||||
Condition c = testInt32(cond, address);
|
||||
B(label, c);
|
||||
}
|
||||
void branchTestDouble(Condition cond, const Address& address, Label* label) {
|
||||
Condition c = testDouble(cond, address);
|
||||
B(label, c);
|
||||
@ -1453,10 +1406,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||
Condition c = testUndefined(cond, src);
|
||||
B(label, c);
|
||||
}
|
||||
void branchTestInt32(Condition cond, const ValueOperand& src, Label* label) {
|
||||
Condition c = testInt32(cond, src);
|
||||
B(label, c);
|
||||
}
|
||||
void branchTestBoolean(Condition cond, const ValueOperand& src, Label* label) {
|
||||
Condition c = testBoolean(cond, src);
|
||||
B(label, c);
|
||||
@ -1492,10 +1441,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||
Condition c = testUndefined(cond, address);
|
||||
B(label, c);
|
||||
}
|
||||
void branchTestInt32(Condition cond, const BaseIndex& address, Label* label) {
|
||||
Condition c = testInt32(cond, address);
|
||||
B(label, c);
|
||||
}
|
||||
void branchTestBoolean(Condition cond, const BaseIndex& address, Label* label) {
|
||||
Condition c = testBoolean(cond, address);
|
||||
B(label, c);
|
||||
@ -1649,20 +1594,8 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||
unboxNonDouble(dest, dest);
|
||||
}
|
||||
|
||||
void unboxValue(const ValueOperand& src, AnyRegister dest) {
|
||||
if (dest.isFloat()) {
|
||||
Label notInt32, end;
|
||||
branchTestInt32(Assembler::NotEqual, src, ¬Int32);
|
||||
convertInt32ToDouble(src.valueReg(), dest.fpu());
|
||||
jump(&end);
|
||||
bind(¬Int32);
|
||||
unboxDouble(src, dest.fpu());
|
||||
bind(&end);
|
||||
} else {
|
||||
unboxNonDouble(src, dest.gpr());
|
||||
}
|
||||
inline void unboxValue(const ValueOperand& src, AnyRegister dest);
|
||||
|
||||
}
|
||||
void unboxString(const ValueOperand& operand, Register dest) {
|
||||
unboxNonDouble(operand, dest);
|
||||
}
|
||||
@ -2036,10 +1969,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||
Tst(payload32, payload32);
|
||||
return truthy ? NonZero : Zero;
|
||||
}
|
||||
void branchTestInt32Truthy(bool truthy, const ValueOperand& operand, Label* label) {
|
||||
Condition c = testInt32Truthy(truthy, operand);
|
||||
B(label, c);
|
||||
}
|
||||
|
||||
void branchTestDoubleTruthy(bool truthy, FloatRegister reg, Label* label) {
|
||||
Fcmp(ARMFPRegister(reg, 64), 0.0);
|
||||
@ -2193,9 +2122,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||
storeValue(JSVAL_TYPE_INT32, scratch, dest);
|
||||
}
|
||||
|
||||
void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label);
|
||||
void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp, Label* label);
|
||||
|
||||
void profilerEnterFrame(Register framePtr, Register scratch) {
|
||||
AbsoluteAddress activation(GetJitContext()->runtime->addressOfProfilingActivation());
|
||||
loadPtr(activation, scratch);
|
||||
@ -2558,17 +2484,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||
Ucvtf(ARMFPRegister(dest, 64), ARMRegister(src.reg, 64));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void branchAdd32(Condition cond, T src, Register dest, Label* label) {
|
||||
adds32(src, dest);
|
||||
branch(cond, label);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void branchSub32(Condition cond, T src, Register dest, Label* label) {
|
||||
subs32(src, dest);
|
||||
branch(cond, label);
|
||||
}
|
||||
void clampCheck(Register r, Label* handleNotAnInt) {
|
||||
MOZ_CRASH("clampCheck");
|
||||
}
|
||||
|
@ -346,6 +346,31 @@ MacroAssembler::branchPtr(Condition cond, wasm::SymbolicAddress lhs, Register rh
|
||||
branchPtr(cond, SecondScratchReg, rhs, label);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
CodeOffsetJump
|
||||
MacroAssembler::branchPtrWithPatch(Condition cond, Register lhs, T rhs, RepatchLabel* label)
|
||||
{
|
||||
movePtr(rhs, ScratchRegister);
|
||||
Label skipJump;
|
||||
ma_b(lhs, ScratchRegister, &skipJump, InvertCondition(cond), ShortJump);
|
||||
CodeOffsetJump off = jumpWithPatch(label);
|
||||
bind(&skipJump);
|
||||
return off;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
CodeOffsetJump
|
||||
MacroAssembler::branchPtrWithPatch(Condition cond, Address lhs, T rhs, RepatchLabel* label)
|
||||
{
|
||||
loadPtr(lhs, SecondScratchReg);
|
||||
movePtr(rhs, ScratchRegister);
|
||||
Label skipJump;
|
||||
ma_b(SecondScratchReg, ScratchRegister, &skipJump, InvertCondition(cond), ShortJump);
|
||||
CodeOffsetJump off = jumpWithPatch(label);
|
||||
bind(&skipJump);
|
||||
return off;
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
|
||||
Label* label)
|
||||
@ -385,6 +410,44 @@ MacroAssembler::branchTruncateDouble(FloatRegister src, Register dest, Label* fa
|
||||
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
MacroAssembler::branchAdd32(Condition cond, T src, Register dest, Label* overflow)
|
||||
{
|
||||
switch (cond) {
|
||||
case Overflow:
|
||||
ma_addTestOverflow(dest, dest, src, overflow);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
MacroAssembler::branchSub32(Condition cond, T src, Register dest, Label* overflow)
|
||||
{
|
||||
switch (cond) {
|
||||
case Overflow:
|
||||
ma_subTestOverflow(dest, dest, src, overflow);
|
||||
break;
|
||||
case NonZero:
|
||||
case Zero:
|
||||
ma_subu(dest, src);
|
||||
ma_b(dest, dest, overflow, cond);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::decBranchPtr(Condition cond, Register lhs, Imm32 rhs, Label* label)
|
||||
{
|
||||
subPtr(rhs, lhs);
|
||||
branchPtr(cond, lhs, Imm32(0), label);
|
||||
}
|
||||
|
||||
template <class L>
|
||||
void
|
||||
MacroAssembler::branchTest32(Condition cond, Register lhs, Register rhs, L label)
|
||||
@ -446,6 +509,29 @@ MacroAssembler::branchTestPtr(Condition cond, const Address& lhs, Imm32 rhs, Lab
|
||||
branchTestPtr(cond, SecondScratchReg, rhs, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, Register tag, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
ma_b(tag, ImmTag(JSVAL_TAG_INT32), label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const Address& address, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
extractTag(address, SecondScratchReg);
|
||||
ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_INT32), label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const BaseIndex& address, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
extractTag(address, SecondScratchReg);
|
||||
ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_INT32), label, cond);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
// ===============================================================
|
||||
|
||||
|
@ -1276,4 +1276,19 @@ MacroAssembler::pushFakeReturnAddress(Register scratch)
|
||||
return retAddr;
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
MOZ_ASSERT(ptr != temp);
|
||||
MOZ_ASSERT(ptr != SecondScratchReg);
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
movePtr(ImmWord(-ptrdiff_t(nursery.start())), SecondScratchReg);
|
||||
addPtr(ptr, SecondScratchReg);
|
||||
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
SecondScratchReg, Imm32(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
|
@ -274,6 +274,21 @@ MacroAssembler::branchTest64(Condition cond, Register64 lhs, Register64 rhs, Reg
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const ValueOperand& value, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
ma_b(value.typeReg(), ImmType(JSVAL_TYPE_INT32), label, cond);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32Truthy(bool b, const ValueOperand& value, Label* label)
|
||||
{
|
||||
as_and(ScratchRegister, value.payloadReg(), value.payloadReg());
|
||||
ma_b(ScratchRegister, ScratchRegister, label, b ? NonZero : Zero);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
// ===============================================================
|
||||
|
||||
@ -300,13 +315,6 @@ MacroAssemblerMIPSCompat::retn(Imm32 n) {
|
||||
as_nop();
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label)
|
||||
{
|
||||
asMasm().subPtr(imm, lhs);
|
||||
asMasm().branchPtr(cond, lhs, Imm32(0), label);
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
@ -1126,36 +1126,6 @@ MacroAssemblerMIPSCompat::branchTestPrimitive(Condition cond, Register tag, Labe
|
||||
(cond == Equal) ? Below : AboveOrEqual);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::branchTestInt32(Condition cond, const ValueOperand& value, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
ma_b(value.typeReg(), ImmType(JSVAL_TYPE_INT32), label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::branchTestInt32(Condition cond, Register tag, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
ma_b(tag, ImmTag(JSVAL_TAG_INT32), label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::branchTestInt32(Condition cond, const Address& address, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
extractTag(address, SecondScratchReg);
|
||||
ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_INT32), label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::branchTestInt32(Condition cond, const BaseIndex& src, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
extractTag(src, SecondScratchReg);
|
||||
ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_INT32), label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat:: branchTestBoolean(Condition cond, const ValueOperand& value,
|
||||
Label* label)
|
||||
@ -1549,7 +1519,7 @@ MacroAssemblerMIPSCompat::unboxValue(const ValueOperand& src, AnyRegister dest)
|
||||
{
|
||||
if (dest.isFloat()) {
|
||||
Label notInt32, end;
|
||||
branchTestInt32(Assembler::NotEqual, src, ¬Int32);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, src, ¬Int32);
|
||||
convertInt32ToDouble(src.payloadReg(), dest.fpu());
|
||||
ma_b(&end, ShortJump);
|
||||
bind(¬Int32);
|
||||
@ -1624,7 +1594,7 @@ MacroAssemblerMIPSCompat::loadInt32OrDouble(const Address& src, FloatRegister de
|
||||
Label notInt32, end;
|
||||
// If it's an int, convert it to double.
|
||||
ma_lw(SecondScratchReg, Address(src.base, src.offset + TAG_OFFSET));
|
||||
branchTestInt32(Assembler::NotEqual, SecondScratchReg, ¬Int32);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, SecondScratchReg, ¬Int32);
|
||||
ma_lw(SecondScratchReg, Address(src.base, src.offset + PAYLOAD_OFFSET));
|
||||
convertInt32ToDouble(SecondScratchReg, dest);
|
||||
ma_b(&end, ShortJump);
|
||||
@ -1646,7 +1616,7 @@ MacroAssemblerMIPSCompat::loadInt32OrDouble(Register base, Register index,
|
||||
computeScaledAddress(BaseIndex(base, index, ShiftToScale(shift)), SecondScratchReg);
|
||||
// Since we only have one scratch, we need to stomp over it with the tag.
|
||||
load32(Address(SecondScratchReg, TAG_OFFSET), SecondScratchReg);
|
||||
branchTestInt32(Assembler::NotEqual, SecondScratchReg, ¬Int32);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, SecondScratchReg, ¬Int32);
|
||||
|
||||
computeScaledAddress(BaseIndex(base, index, ShiftToScale(shift)), SecondScratchReg);
|
||||
load32(Address(SecondScratchReg, PAYLOAD_OFFSET), SecondScratchReg);
|
||||
@ -1668,13 +1638,6 @@ MacroAssemblerMIPSCompat::loadConstantDouble(double dp, FloatRegister dest)
|
||||
ma_lid(dest, dp);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::branchTestInt32Truthy(bool b, const ValueOperand& value, Label* label)
|
||||
{
|
||||
as_and(ScratchRegister, value.payloadReg(), value.payloadReg());
|
||||
ma_b(ScratchRegister, ScratchRegister, label, b ? NonZero : Zero);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::branchTestStringTruthy(bool b, const ValueOperand& value, Label* label)
|
||||
{
|
||||
@ -2052,7 +2015,7 @@ MacroAssemblerMIPSCompat::ensureDouble(const ValueOperand& source, FloatRegister
|
||||
{
|
||||
Label isDouble, done;
|
||||
branchTestDouble(Assembler::Equal, source.typeReg(), &isDouble);
|
||||
branchTestInt32(Assembler::NotEqual, source.typeReg(), failure);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, source.typeReg(), failure);
|
||||
|
||||
convertInt32ToDouble(source.payloadReg(), dest);
|
||||
jump(&done);
|
||||
@ -2327,35 +2290,6 @@ MacroAssemblerMIPSCompat::toggledCall(JitCode* target, bool enabled)
|
||||
return offset;
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
MOZ_ASSERT(ptr != temp);
|
||||
MOZ_ASSERT(ptr != SecondScratchReg);
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
movePtr(ImmWord(-ptrdiff_t(nursery.start())), SecondScratchReg);
|
||||
asMasm().addPtr(ptr, SecondScratchReg);
|
||||
asMasm().branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
SecondScratchReg, Imm32(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::branchValueIsNurseryObject(Condition cond, ValueOperand value,
|
||||
Register temp, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
|
||||
Label done;
|
||||
|
||||
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
|
||||
branchPtrInNurseryRange(cond, value.payloadReg(), temp, label);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::profilerEnterFrame(Register framePtr, Register scratch)
|
||||
{
|
||||
@ -2541,4 +2475,21 @@ MacroAssembler::callWithABINoProfiler(const Address& fun, MoveOp::Type result)
|
||||
callWithABIPost(stackAdjust, result);
|
||||
}
|
||||
|
||||
// ===============================================================
|
||||
// Branch functions
|
||||
|
||||
void
|
||||
MacroAssembler::branchValueIsNurseryObject(Condition cond, ValueOperand value,
|
||||
Register temp, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
|
||||
Label done;
|
||||
|
||||
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
|
||||
branchPtrInNurseryRange(cond, value.payloadReg(), temp, label);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
|
@ -375,11 +375,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
|
||||
void int32ValueToFloat32(const ValueOperand& operand, FloatRegister dest);
|
||||
void loadConstantFloat32(float f, FloatRegister dest);
|
||||
|
||||
void branchTestInt32(Condition cond, const ValueOperand& value, Label* label);
|
||||
void branchTestInt32(Condition cond, Register tag, Label* label);
|
||||
void branchTestInt32(Condition cond, const Address& address, Label* label);
|
||||
void branchTestInt32(Condition cond, const BaseIndex& src, Label* label);
|
||||
|
||||
void branchTestBoolean(Condition cond, const ValueOperand& value, Label* label);
|
||||
void branchTestBoolean(Condition cond, Register tag, Label* label);
|
||||
void branchTestBoolean(Condition cond, const Address& address, Label* label);
|
||||
@ -432,16 +427,12 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
|
||||
branchTestValue(cond, val, MagicValue(why), label);
|
||||
}
|
||||
|
||||
void branchTestInt32Truthy(bool b, const ValueOperand& value, Label* label);
|
||||
|
||||
void branchTestStringTruthy(bool b, const ValueOperand& value, Label* label);
|
||||
|
||||
void branchTestDoubleTruthy(bool b, FloatRegister value, Label* label);
|
||||
|
||||
void branchTestBooleanTruthy(bool b, const ValueOperand& operand, Label* label);
|
||||
|
||||
inline void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label);
|
||||
|
||||
// higher level tag testing code
|
||||
Operand ToPayload(Operand base);
|
||||
Address ToPayload(Address base) {
|
||||
@ -462,27 +453,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
|
||||
CodeOffsetJump backedgeJump(RepatchLabel* label, Label* documentation = nullptr);
|
||||
CodeOffsetJump jumpWithPatch(RepatchLabel* label, Label* documentation = nullptr);
|
||||
|
||||
template <typename T>
|
||||
CodeOffsetJump branchPtrWithPatch(Condition cond, Register reg, T ptr, RepatchLabel* label) {
|
||||
movePtr(ptr, ScratchRegister);
|
||||
Label skipJump;
|
||||
ma_b(reg, ScratchRegister, &skipJump, InvertCondition(cond), ShortJump);
|
||||
CodeOffsetJump off = jumpWithPatch(label);
|
||||
bind(&skipJump);
|
||||
return off;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
CodeOffsetJump branchPtrWithPatch(Condition cond, Address addr, T ptr, RepatchLabel* label) {
|
||||
loadPtr(addr, SecondScratchReg);
|
||||
movePtr(ptr, ScratchRegister);
|
||||
Label skipJump;
|
||||
ma_b(SecondScratchReg, ScratchRegister, &skipJump, InvertCondition(cond), ShortJump);
|
||||
CodeOffsetJump off = jumpWithPatch(label);
|
||||
bind(&skipJump);
|
||||
return off;
|
||||
}
|
||||
|
||||
void loadUnboxedValue(Address address, MIRType type, AnyRegister dest) {
|
||||
if (dest.isFloat())
|
||||
loadInt32OrDouble(address, dest.fpu());
|
||||
@ -908,32 +878,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
|
||||
|
||||
inline void incrementInt32Value(const Address& addr);
|
||||
|
||||
template <typename T>
|
||||
void branchAdd32(Condition cond, T src, Register dest, Label* overflow) {
|
||||
switch (cond) {
|
||||
case Overflow:
|
||||
ma_addTestOverflow(dest, dest, src, overflow);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
void branchSub32(Condition cond, T src, Register dest, Label* overflow) {
|
||||
switch (cond) {
|
||||
case Overflow:
|
||||
ma_subTestOverflow(dest, dest, src, overflow);
|
||||
break;
|
||||
case NonZero:
|
||||
case Zero:
|
||||
ma_subu(dest, src);
|
||||
ma_b(dest, dest, overflow, cond);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
}
|
||||
|
||||
void move32(Imm32 imm, Register dest);
|
||||
void move32(Register src, Register dest);
|
||||
|
||||
@ -1132,10 +1076,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
|
||||
as_movs(dest, src);
|
||||
}
|
||||
|
||||
void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label);
|
||||
void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp,
|
||||
Label* label);
|
||||
|
||||
void loadWasmActivation(Register dest) {
|
||||
loadPtr(Address(GlobalReg, wasm::ActivationGlobalDataOffset - AsmJSGlobalRegBias), dest);
|
||||
}
|
||||
|
@ -210,6 +210,21 @@ MacroAssembler::branchTest64(Condition cond, Register64 lhs, Register64 rhs, Reg
|
||||
branchTestPtr(cond, lhs.reg, rhs.reg, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const ValueOperand& value, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
splitTag(value, SecondScratchReg);
|
||||
ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_INT32), label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32Truthy(bool b, const ValueOperand& value, Label* label)
|
||||
{
|
||||
ma_dext(ScratchRegister, value.valueReg(), Imm32(0), Imm32(32));
|
||||
ma_b(ScratchRegister, ScratchRegister, label, b ? NonZero : Zero);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
// ===============================================================
|
||||
|
||||
@ -237,13 +252,6 @@ MacroAssemblerMIPS64Compat::retn(Imm32 n)
|
||||
as_nop();
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label)
|
||||
{
|
||||
asMasm().subPtr(imm, lhs);
|
||||
asMasm().branchPtr(cond, lhs, Imm32(0), label);
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
@ -1254,37 +1254,6 @@ MacroAssemblerMIPS64Compat::branchTestPrimitive(Condition cond, Register tag, La
|
||||
(cond == Equal) ? Below : AboveOrEqual);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::branchTestInt32(Condition cond, const ValueOperand& value, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
splitTag(value, SecondScratchReg);
|
||||
ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_INT32), label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::branchTestInt32(Condition cond, Register tag, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
ma_b(tag, ImmTag(JSVAL_TAG_INT32), label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::branchTestInt32(Condition cond, const Address& address, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
extractTag(address, SecondScratchReg);
|
||||
ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_INT32), label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::branchTestInt32(Condition cond, const BaseIndex& src, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
extractTag(src, SecondScratchReg);
|
||||
ma_b(SecondScratchReg, ImmTag(JSVAL_TAG_INT32), label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat:: branchTestBoolean(Condition cond, const ValueOperand& value,
|
||||
Label* label)
|
||||
@ -1775,7 +1744,7 @@ MacroAssemblerMIPS64Compat::unboxValue(const ValueOperand& src, AnyRegister dest
|
||||
{
|
||||
if (dest.isFloat()) {
|
||||
Label notInt32, end;
|
||||
branchTestInt32(Assembler::NotEqual, src, ¬Int32);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, src, ¬Int32);
|
||||
convertInt32ToDouble(src.valueReg(), dest.fpu());
|
||||
ma_b(&end, ShortJump);
|
||||
bind(¬Int32);
|
||||
@ -1849,7 +1818,7 @@ MacroAssemblerMIPS64Compat::loadInt32OrDouble(const Address& src, FloatRegister
|
||||
// If it's an int, convert it to double.
|
||||
loadPtr(Address(src.base, src.offset), ScratchRegister);
|
||||
ma_dsrl(SecondScratchReg, ScratchRegister, Imm32(JSVAL_TAG_SHIFT));
|
||||
branchTestInt32(Assembler::NotEqual, SecondScratchReg, ¬Int32);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, SecondScratchReg, ¬Int32);
|
||||
loadPtr(Address(src.base, src.offset), SecondScratchReg);
|
||||
convertInt32ToDouble(SecondScratchReg, dest);
|
||||
ma_b(&end, ShortJump);
|
||||
@ -1870,7 +1839,7 @@ MacroAssemblerMIPS64Compat::loadInt32OrDouble(const BaseIndex& addr, FloatRegist
|
||||
// Since we only have one scratch, we need to stomp over it with the tag.
|
||||
loadPtr(Address(SecondScratchReg, 0), ScratchRegister);
|
||||
ma_dsrl(SecondScratchReg, ScratchRegister, Imm32(JSVAL_TAG_SHIFT));
|
||||
branchTestInt32(Assembler::NotEqual, SecondScratchReg, ¬Int32);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, SecondScratchReg, ¬Int32);
|
||||
|
||||
computeScaledAddress(addr, SecondScratchReg);
|
||||
loadPtr(Address(SecondScratchReg, 0), SecondScratchReg);
|
||||
@ -1892,13 +1861,6 @@ MacroAssemblerMIPS64Compat::loadConstantDouble(double dp, FloatRegister dest)
|
||||
ma_lid(dest, dp);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::branchTestInt32Truthy(bool b, const ValueOperand& value, Label* label)
|
||||
{
|
||||
ma_dext(ScratchRegister, value.valueReg(), Imm32(0), Imm32(32));
|
||||
ma_b(ScratchRegister, ScratchRegister, label, b ? NonZero : Zero);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::branchTestStringTruthy(bool b, const ValueOperand& value, Label* label)
|
||||
{
|
||||
@ -2213,7 +2175,7 @@ MacroAssemblerMIPS64Compat::ensureDouble(const ValueOperand& source, FloatRegist
|
||||
Label isDouble, done;
|
||||
Register tag = splitTagForTest(source);
|
||||
branchTestDouble(Assembler::Equal, tag, &isDouble);
|
||||
branchTestInt32(Assembler::NotEqual, tag, failure);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, tag, failure);
|
||||
|
||||
unboxInt32(source, ScratchRegister);
|
||||
convertInt32ToDouble(ScratchRegister, dest);
|
||||
@ -2499,37 +2461,6 @@ MacroAssemblerMIPS64Compat::toggledCall(JitCode* target, bool enabled)
|
||||
return offset;
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
MOZ_ASSERT(ptr != temp);
|
||||
MOZ_ASSERT(ptr != SecondScratchReg);
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
movePtr(ImmWord(-ptrdiff_t(nursery.start())), SecondScratchReg);
|
||||
asMasm().addPtr(ptr, SecondScratchReg);
|
||||
asMasm().branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
SecondScratchReg, Imm32(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::branchValueIsNurseryObject(Condition cond, ValueOperand value,
|
||||
Register temp, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
|
||||
// 'Value' representing the start of the nursery tagged as a JSObject
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
Value start = ObjectValue(*reinterpret_cast<JSObject *>(nursery.start()));
|
||||
|
||||
movePtr(ImmWord(-ptrdiff_t(start.asRawBits())), SecondScratchReg);
|
||||
asMasm().addPtr(value.valueReg(), SecondScratchReg);
|
||||
asMasm().branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
SecondScratchReg, Imm32(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::profilerEnterFrame(Register framePtr, Register scratch)
|
||||
{
|
||||
@ -2698,4 +2629,23 @@ MacroAssembler::callWithABINoProfiler(const Address& fun, MoveOp::Type result)
|
||||
callWithABIPost(stackAdjust, result);
|
||||
}
|
||||
|
||||
// ===============================================================
|
||||
// Branch functions
|
||||
|
||||
void
|
||||
MacroAssembler::branchValueIsNurseryObject(Condition cond, ValueOperand value,
|
||||
Register temp, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
|
||||
// 'Value' representing the start of the nursery tagged as a JSObject
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
Value start = ObjectValue(*reinterpret_cast<JSObject *>(nursery.start()));
|
||||
|
||||
movePtr(ImmWord(-ptrdiff_t(start.asRawBits())), SecondScratchReg);
|
||||
addPtr(value.valueReg(), SecondScratchReg);
|
||||
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
SecondScratchReg, Imm32(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
|
@ -416,11 +416,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
|
||||
void int32ValueToFloat32(const ValueOperand& operand, FloatRegister dest);
|
||||
void loadConstantFloat32(float f, FloatRegister dest);
|
||||
|
||||
void branchTestInt32(Condition cond, const ValueOperand& value, Label* label);
|
||||
void branchTestInt32(Condition cond, Register tag, Label* label);
|
||||
void branchTestInt32(Condition cond, const Address& address, Label* label);
|
||||
void branchTestInt32(Condition cond, const BaseIndex& src, Label* label);
|
||||
|
||||
void branchTestBoolean(Condition cond, const ValueOperand& value, Label* label);
|
||||
void branchTestBoolean(Condition cond, Register tag, Label* label);
|
||||
void branchTestBoolean(Condition cond, const Address& address, Label* label);
|
||||
@ -473,16 +468,12 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
|
||||
branchTestValue(cond, val, MagicValue(why), label);
|
||||
}
|
||||
|
||||
void branchTestInt32Truthy(bool b, const ValueOperand& value, Label* label);
|
||||
|
||||
void branchTestStringTruthy(bool b, const ValueOperand& value, Label* label);
|
||||
|
||||
void branchTestDoubleTruthy(bool b, FloatRegister value, Label* label);
|
||||
|
||||
void branchTestBooleanTruthy(bool b, const ValueOperand& operand, Label* label);
|
||||
|
||||
inline void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label);
|
||||
|
||||
// higher level tag testing code
|
||||
Address ToPayload(Address value) {
|
||||
return value;
|
||||
@ -493,27 +484,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
|
||||
CodeOffsetJump backedgeJump(RepatchLabel* label, Label* documentation = nullptr);
|
||||
CodeOffsetJump jumpWithPatch(RepatchLabel* label, Label* documentation = nullptr);
|
||||
|
||||
template <typename T>
|
||||
CodeOffsetJump branchPtrWithPatch(Condition cond, Register reg, T ptr, RepatchLabel* label) {
|
||||
movePtr(ptr, ScratchRegister);
|
||||
Label skipJump;
|
||||
ma_b(reg, ScratchRegister, &skipJump, InvertCondition(cond), ShortJump);
|
||||
CodeOffsetJump off = jumpWithPatch(label);
|
||||
bind(&skipJump);
|
||||
return off;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
CodeOffsetJump branchPtrWithPatch(Condition cond, Address addr, T ptr, RepatchLabel* label) {
|
||||
loadPtr(addr, SecondScratchReg);
|
||||
movePtr(ptr, ScratchRegister);
|
||||
Label skipJump;
|
||||
ma_b(SecondScratchReg, ScratchRegister, &skipJump, InvertCondition(cond), ShortJump);
|
||||
CodeOffsetJump off = jumpWithPatch(label);
|
||||
bind(&skipJump);
|
||||
return off;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void loadUnboxedValue(const T& address, MIRType type, AnyRegister dest) {
|
||||
if (dest.isFloat())
|
||||
@ -922,32 +892,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
|
||||
|
||||
inline void incrementInt32Value(const Address& addr);
|
||||
|
||||
template <typename T>
|
||||
void branchAdd32(Condition cond, T src, Register dest, Label* overflow) {
|
||||
switch (cond) {
|
||||
case Overflow:
|
||||
ma_addTestOverflow(dest, dest, src, overflow);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
void branchSub32(Condition cond, T src, Register dest, Label* overflow) {
|
||||
switch (cond) {
|
||||
case Overflow:
|
||||
ma_subTestOverflow(dest, dest, src, overflow);
|
||||
break;
|
||||
case NonZero:
|
||||
case Zero:
|
||||
ma_subu(dest, src);
|
||||
ma_b(dest, dest, overflow, cond);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
}
|
||||
|
||||
void move32(Imm32 imm, Register dest);
|
||||
void move32(Register src, Register dest);
|
||||
|
||||
@ -1140,10 +1084,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
|
||||
as_movs(dest, src);
|
||||
}
|
||||
|
||||
void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label);
|
||||
void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp,
|
||||
Label* label);
|
||||
|
||||
void loadWasmActivation(Register dest) {
|
||||
loadPtr(Address(GlobalReg, wasm::ActivationGlobalDataOffset - AsmJSGlobalRegBias), dest);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@
|
||||
#define I64(v) static_cast<int64_t>(v)
|
||||
#define U64(v) static_cast<uint64_t>(v)
|
||||
#define I128(v) static_cast<__int128_t>(v)
|
||||
#define U128(v) static_cast<unsigned __int128_t>(v)
|
||||
#define U128(v) static_cast<__uint128_t>(v)
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
@ -233,8 +233,6 @@ class MacroAssemblerNone : public Assembler
|
||||
CodeOffsetJump jumpWithPatch(RepatchLabel*, Label* doc = nullptr) { MOZ_CRASH(); }
|
||||
CodeOffsetJump jumpWithPatch(RepatchLabel*, Condition, Label* doc = nullptr) { MOZ_CRASH(); }
|
||||
CodeOffsetJump backedgeJump(RepatchLabel* label, Label* doc = nullptr) { MOZ_CRASH(); }
|
||||
template <typename T, typename S>
|
||||
CodeOffsetJump branchPtrWithPatch(Condition, T, S, RepatchLabel*) { MOZ_CRASH(); }
|
||||
|
||||
template <typename T, typename S> void branchTestValue(Condition, T, S, Label*) { MOZ_CRASH(); }
|
||||
void testNullSet(Condition, ValueOperand, Register) { MOZ_CRASH(); }
|
||||
@ -244,9 +242,6 @@ class MacroAssemblerNone : public Assembler
|
||||
template <typename T, typename S> void cmpPtrSet(Condition, T, S, Register) { MOZ_CRASH(); }
|
||||
template <typename T, typename S> void cmp32Set(Condition, T, S, Register) { MOZ_CRASH(); }
|
||||
|
||||
template <typename T, typename S> void branchAdd32(Condition, T, S, Label*) { MOZ_CRASH(); }
|
||||
template <typename T, typename S> void branchSub32(Condition, T, S, Label*) { MOZ_CRASH(); }
|
||||
template <typename T, typename S> void decBranchPtr(Condition, T, S, Label*) { MOZ_CRASH(); }
|
||||
template <typename T, typename S> void mov(T, S) { MOZ_CRASH(); }
|
||||
template <typename T, typename S> void movq(T, S) { MOZ_CRASH(); }
|
||||
template <typename T, typename S> void movePtr(T, S) { MOZ_CRASH(); }
|
||||
@ -351,7 +346,6 @@ class MacroAssemblerNone : public Assembler
|
||||
Register splitTagForTest(ValueOperand) { MOZ_CRASH(); }
|
||||
|
||||
template <typename T> void branchTestUndefined(Condition, T, Label*) { MOZ_CRASH(); }
|
||||
template <typename T> void branchTestInt32(Condition, T, Label*) { MOZ_CRASH(); }
|
||||
template <typename T> void branchTestBoolean(Condition, T, Label*) { MOZ_CRASH(); }
|
||||
template <typename T> void branchTestDouble(Condition, T, Label*) { MOZ_CRASH(); }
|
||||
template <typename T> void branchTestNull(Condition, T, Label*) { MOZ_CRASH(); }
|
||||
@ -400,7 +394,6 @@ class MacroAssemblerNone : public Assembler
|
||||
void loadConstantFloat32(float, FloatRegister) { MOZ_CRASH(); }
|
||||
Condition testInt32Truthy(bool, ValueOperand) { MOZ_CRASH(); }
|
||||
Condition testStringTruthy(bool, ValueOperand) { MOZ_CRASH(); }
|
||||
void branchTestInt32Truthy(bool, ValueOperand, Label*) { MOZ_CRASH(); }
|
||||
void branchTestBooleanTruthy(bool, ValueOperand, Label*) { MOZ_CRASH(); }
|
||||
void branchTestStringTruthy(bool, ValueOperand, Label*) { MOZ_CRASH(); }
|
||||
void branchTestDoubleTruthy(bool, FloatRegister, Label*) { MOZ_CRASH(); }
|
||||
@ -415,9 +408,6 @@ class MacroAssemblerNone : public Assembler
|
||||
void ensureDouble(ValueOperand, FloatRegister, Label*) { MOZ_CRASH(); }
|
||||
void handleFailureWithHandlerTail(void*) { MOZ_CRASH(); }
|
||||
|
||||
void branchPtrInNurseryRange(Condition, Register, Register, Label*) { MOZ_CRASH(); }
|
||||
void branchValueIsNurseryObject(Condition, ValueOperand, Register, Label*) { MOZ_CRASH(); }
|
||||
|
||||
void buildFakeExitFrame(Register, uint32_t*) { MOZ_CRASH(); }
|
||||
bool buildOOLFakeExitFrame(void*) { MOZ_CRASH(); }
|
||||
void loadWasmActivation(Register) { MOZ_CRASH(); }
|
||||
|
@ -356,6 +356,36 @@ MacroAssembler::branchTest64(Condition cond, Register64 lhs, Register64 rhs, Reg
|
||||
branchTestPtr(cond, lhs.reg, rhs.reg, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, Register tag, Label* label)
|
||||
{
|
||||
cond = testInt32(cond, tag);
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const Address& address, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
branchTestInt32Impl(cond, Operand(address), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const BaseIndex& address, Label* label)
|
||||
{
|
||||
ScratchRegisterScope scratch(*this);
|
||||
splitTag(address, scratch);
|
||||
branchTestInt32(cond, scratch, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const ValueOperand& src, Label* label)
|
||||
{
|
||||
ScratchRegisterScope scratch(*this);
|
||||
splitTag(src, scratch);
|
||||
branchTestInt32(cond, scratch, label);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
// ===============================================================
|
||||
|
||||
@ -381,6 +411,55 @@ MacroAssemblerX64::branchPtrImpl(Condition cond, const T& lhs, const S& rhs, Lab
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX64::unboxValue(const ValueOperand& src, AnyRegister dest)
|
||||
{
|
||||
if (dest.isFloat()) {
|
||||
Label notInt32, end;
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, src, ¬Int32);
|
||||
convertInt32ToDouble(src.valueReg(), dest.fpu());
|
||||
jump(&end);
|
||||
bind(¬Int32);
|
||||
unboxDouble(src, dest.fpu());
|
||||
bind(&end);
|
||||
} else {
|
||||
unboxNonDouble(src, dest.gpr());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX64::loadInt32OrDouble(const Operand& operand, FloatRegister dest)
|
||||
{
|
||||
Label notInt32, end;
|
||||
branchTestInt32Impl(Assembler::NotEqual, operand, ¬Int32);
|
||||
convertInt32ToDouble(operand, dest);
|
||||
jump(&end);
|
||||
bind(¬Int32);
|
||||
loadDouble(operand, dest);
|
||||
bind(&end);
|
||||
}
|
||||
|
||||
// If source is a double, load it into dest. If source is int32,
|
||||
// convert it to double. Else, branch to failure.
|
||||
void
|
||||
MacroAssemblerX64::ensureDouble(const ValueOperand& source, FloatRegister dest, Label* failure)
|
||||
{
|
||||
Label isDouble, done;
|
||||
Register tag = splitTagForTest(source);
|
||||
branchTestDouble(Assembler::Equal, tag, &isDouble);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, tag, failure);
|
||||
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
unboxInt32(source, scratch);
|
||||
convertInt32ToDouble(scratch, dest);
|
||||
jump(&done);
|
||||
|
||||
bind(&isDouble);
|
||||
unboxDouble(source, dest);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
@ -264,44 +264,6 @@ template void
|
||||
MacroAssemblerX64::storeUnboxedValue(ConstantOrRegister value, MIRType valueType, const BaseIndex& dest,
|
||||
MIRType slotType);
|
||||
|
||||
void
|
||||
MacroAssemblerX64::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label)
|
||||
{
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
MOZ_ASSERT(ptr != temp);
|
||||
MOZ_ASSERT(ptr != scratch);
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
movePtr(ImmWord(-ptrdiff_t(nursery.start())), scratch);
|
||||
asMasm().addPtr(ptr, scratch);
|
||||
asMasm().branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
scratch, Imm32(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX64::branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
|
||||
// Avoid creating a bogus ObjectValue below.
|
||||
if (!nursery.exists())
|
||||
return;
|
||||
|
||||
// 'Value' representing the start of the nursery tagged as a JSObject
|
||||
Value start = ObjectValue(*reinterpret_cast<JSObject*>(nursery.start()));
|
||||
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
movePtr(ImmWord(-ptrdiff_t(start.asRawBits())), scratch);
|
||||
asMasm().addPtr(value.valueReg(), scratch);
|
||||
asMasm().branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
scratch, Imm32(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX64::profilerEnterFrame(Register framePtr, Register scratch)
|
||||
{
|
||||
@ -464,4 +426,45 @@ MacroAssembler::callWithABINoProfiler(const Address& fun, MoveOp::Type result)
|
||||
callWithABIPost(stackAdjust, result);
|
||||
}
|
||||
|
||||
// ===============================================================
|
||||
// Branch functions
|
||||
|
||||
void
|
||||
MacroAssembler::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label)
|
||||
{
|
||||
ScratchRegisterScope scratch(*this);
|
||||
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
MOZ_ASSERT(ptr != temp);
|
||||
MOZ_ASSERT(ptr != scratch);
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
movePtr(ImmWord(-ptrdiff_t(nursery.start())), scratch);
|
||||
addPtr(ptr, scratch);
|
||||
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
scratch, Imm32(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
|
||||
// Avoid creating a bogus ObjectValue below.
|
||||
if (!nursery.exists())
|
||||
return;
|
||||
|
||||
// 'Value' representing the start of the nursery tagged as a JSObject
|
||||
Value start = ObjectValue(*reinterpret_cast<JSObject*>(nursery.start()));
|
||||
|
||||
ScratchRegisterScope scratch(*this);
|
||||
movePtr(ImmWord(-ptrdiff_t(start.asRawBits())), scratch);
|
||||
addPtr(value.valueReg(), scratch);
|
||||
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
scratch, Imm32(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
|
@ -545,16 +545,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
return jumpWithPatch(label);
|
||||
}
|
||||
|
||||
template <typename S, typename T>
|
||||
CodeOffsetJump branchPtrWithPatch(Condition cond, S lhs, T ptr, RepatchLabel* label) {
|
||||
cmpPtr(lhs, ptr);
|
||||
return jumpWithPatch(label, cond);
|
||||
}
|
||||
void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) {
|
||||
subq(imm, lhs);
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void movePtr(Register src, Register dest) {
|
||||
movq(src, dest);
|
||||
}
|
||||
@ -691,10 +681,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
cond = testUndefined(cond, tag);
|
||||
j(cond, label);
|
||||
}
|
||||
void branchTestInt32(Condition cond, Register tag, Label* label) {
|
||||
cond = testInt32(cond, tag);
|
||||
j(cond, label);
|
||||
}
|
||||
void branchTestDouble(Condition cond, Register tag, Label* label) {
|
||||
cond = testDouble(cond, tag);
|
||||
j(cond, label);
|
||||
@ -736,15 +722,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
branchTestUndefined(cond, Operand(address), label);
|
||||
}
|
||||
void branchTestInt32(Condition cond, const Operand& operand, Label* label) {
|
||||
void branchTestInt32Impl(Condition cond, const Operand& operand, Label* label) {
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
cmp32(ToUpper32(operand), Imm32(Upper32Of(GetShiftedTag(JSVAL_TYPE_INT32))));
|
||||
j(cond, label);
|
||||
}
|
||||
void branchTestInt32(Condition cond, const Address& address, Label* label) {
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
branchTestInt32(cond, Operand(address), label);
|
||||
}
|
||||
void branchTestDouble(Condition cond, const Operand& operand, Label* label) {
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
@ -786,11 +768,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
cond = testUndefined(cond, src);
|
||||
j(cond, label);
|
||||
}
|
||||
void branchTestInt32(Condition cond, const ValueOperand& src, Label* label) {
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
splitTag(src, scratch);
|
||||
branchTestInt32(cond, scratch, label);
|
||||
}
|
||||
void branchTestBoolean(Condition cond, const ValueOperand& src, Label* label) {
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
splitTag(src, scratch);
|
||||
@ -827,11 +804,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
cond = testUndefined(cond, address);
|
||||
j(cond, label);
|
||||
}
|
||||
void branchTestInt32(Condition cond, const BaseIndex& address, Label* label) {
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
splitTag(address, scratch);
|
||||
branchTestInt32(cond, scratch, label);
|
||||
}
|
||||
void branchTestBoolean(Condition cond, const BaseIndex& address, Label* label) {
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
splitTag(address, scratch);
|
||||
@ -1046,19 +1018,7 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
return scratch;
|
||||
}
|
||||
|
||||
void unboxValue(const ValueOperand& src, AnyRegister dest) {
|
||||
if (dest.isFloat()) {
|
||||
Label notInt32, end;
|
||||
branchTestInt32(Assembler::NotEqual, src, ¬Int32);
|
||||
convertInt32ToDouble(src.valueReg(), dest.fpu());
|
||||
jump(&end);
|
||||
bind(¬Int32);
|
||||
unboxDouble(src, dest.fpu());
|
||||
bind(&end);
|
||||
} else {
|
||||
unboxNonDouble(src, dest.gpr());
|
||||
}
|
||||
}
|
||||
inline void unboxValue(const ValueOperand& src, AnyRegister dest);
|
||||
|
||||
// These two functions use the low 32-bits of the full value register.
|
||||
void boolValueToDouble(const ValueOperand& operand, FloatRegister dest) {
|
||||
@ -1084,10 +1044,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
test32(operand.valueReg(), operand.valueReg());
|
||||
return truthy ? NonZero : Zero;
|
||||
}
|
||||
void branchTestInt32Truthy(bool truthy, const ValueOperand& operand, Label* label) {
|
||||
Condition cond = testInt32Truthy(truthy, operand);
|
||||
j(cond, label);
|
||||
}
|
||||
void branchTestBooleanTruthy(bool truthy, const ValueOperand& operand, Label* label) {
|
||||
test32(operand.valueReg(), operand.valueReg());
|
||||
j(truthy ? NonZero : Zero, label);
|
||||
@ -1103,15 +1059,7 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void loadInt32OrDouble(const Operand& operand, FloatRegister dest) {
|
||||
Label notInt32, end;
|
||||
branchTestInt32(Assembler::NotEqual, operand, ¬Int32);
|
||||
convertInt32ToDouble(operand, dest);
|
||||
jump(&end);
|
||||
bind(¬Int32);
|
||||
loadDouble(operand, dest);
|
||||
bind(&end);
|
||||
}
|
||||
inline void loadInt32OrDouble(const Operand& operand, FloatRegister dest);
|
||||
|
||||
template <typename T>
|
||||
void loadUnboxedValue(const T& src, MIRType type, AnyRegister dest) {
|
||||
@ -1163,24 +1111,7 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
|
||||
inline void incrementInt32Value(const Address& addr);
|
||||
|
||||
// If source is a double, load it into dest. If source is int32,
|
||||
// convert it to double. Else, branch to failure.
|
||||
void ensureDouble(const ValueOperand& source, FloatRegister dest, Label* failure) {
|
||||
Label isDouble, done;
|
||||
Register tag = splitTagForTest(source);
|
||||
branchTestDouble(Assembler::Equal, tag, &isDouble);
|
||||
branchTestInt32(Assembler::NotEqual, tag, failure);
|
||||
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
unboxInt32(source, scratch);
|
||||
convertInt32ToDouble(scratch, dest);
|
||||
jump(&done);
|
||||
|
||||
bind(&isDouble);
|
||||
unboxDouble(source, dest);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
inline void ensureDouble(const ValueOperand& source, FloatRegister dest, Label* failure);
|
||||
|
||||
public:
|
||||
void handleFailureWithHandlerTail(void* handler);
|
||||
@ -1200,9 +1131,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
storeValue(JSVAL_TYPE_INT32, scratch, Dest);
|
||||
}
|
||||
|
||||
void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label);
|
||||
void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp, Label* label);
|
||||
|
||||
// Instrumentation for entering and leaving the profiler.
|
||||
void profilerEnterFrame(Register framePtr, Register scratch);
|
||||
void profilerExitFrame();
|
||||
|
@ -295,6 +295,22 @@ MacroAssembler::branchPtr(Condition cond, const Address& lhs, ImmWord rhs, Label
|
||||
branchPtrImpl(cond, lhs, rhs, label);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
CodeOffsetJump
|
||||
MacroAssembler::branchPtrWithPatch(Condition cond, Register lhs, T rhs, RepatchLabel* label)
|
||||
{
|
||||
cmpPtr(lhs, rhs);
|
||||
return jumpWithPatch(label, cond);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
CodeOffsetJump
|
||||
MacroAssembler::branchPtrWithPatch(Condition cond, Address lhs, T rhs, RepatchLabel* label)
|
||||
{
|
||||
cmpPtr(lhs, rhs);
|
||||
return jumpWithPatch(label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
|
||||
Label* label)
|
||||
@ -342,6 +358,29 @@ MacroAssembler::branchDouble(DoubleCondition cond, FloatRegister lhs, FloatRegis
|
||||
j(ConditionFromDoubleCondition(cond), label);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
MacroAssembler::branchAdd32(Condition cond, T src, Register dest, Label* label)
|
||||
{
|
||||
addl(src, dest);
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
MacroAssembler::branchSub32(Condition cond, T src, Register dest, Label* label)
|
||||
{
|
||||
subl(src, dest);
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::decBranchPtr(Condition cond, Register lhs, Imm32 rhs, Label* label)
|
||||
{
|
||||
subPtr(rhs, lhs);
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
template <class L>
|
||||
void
|
||||
MacroAssembler::branchTest32(Condition cond, Register lhs, Register rhs, L label)
|
||||
@ -389,6 +428,13 @@ MacroAssembler::branchTestPtr(Condition cond, const Address& lhs, Imm32 rhs, Lab
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32Truthy(bool truthy, const ValueOperand& operand, Label* label)
|
||||
{
|
||||
Condition cond = testInt32Truthy(truthy, operand);
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
// ===============================================================
|
||||
|
||||
|
@ -165,16 +165,6 @@ class MacroAssemblerX86Shared : public Assembler
|
||||
CodeOffset cmp32WithPatch(Register lhs, Imm32 rhs) {
|
||||
return cmplWithPatch(rhs, lhs);
|
||||
}
|
||||
template <typename T>
|
||||
void branchAdd32(Condition cond, T src, Register dest, Label* label) {
|
||||
addl(src, dest);
|
||||
j(cond, label);
|
||||
}
|
||||
template <typename T>
|
||||
void branchSub32(Condition cond, T src, Register dest, Label* label) {
|
||||
subl(src, dest);
|
||||
j(cond, label);
|
||||
}
|
||||
void atomic_inc32(const Operand& addr) {
|
||||
lock_incl(addr);
|
||||
}
|
||||
|
@ -365,6 +365,30 @@ MacroAssembler::branchTest64(Condition cond, Register64 lhs, Register64 rhs, Reg
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, Register tag, Label* label)
|
||||
{
|
||||
branchTestInt32Impl(cond, tag, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const Address& address, Label* label)
|
||||
{
|
||||
branchTestInt32Impl(cond, address, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const BaseIndex& address, Label* label)
|
||||
{
|
||||
branchTestInt32Impl(cond, address, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestInt32(Condition cond, const ValueOperand& src, Label* label)
|
||||
{
|
||||
branchTestInt32Impl(cond, src, label);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
// ===============================================================
|
||||
|
||||
@ -416,6 +440,64 @@ MacroAssemblerX86::branchPtrImpl(Condition cond, const T& lhs, const S& rhs, Lab
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86::unboxValue(const ValueOperand& src, AnyRegister dest)
|
||||
{
|
||||
if (dest.isFloat()) {
|
||||
Label notInt32, end;
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, src, ¬Int32);
|
||||
convertInt32ToDouble(src.payloadReg(), dest.fpu());
|
||||
jump(&end);
|
||||
bind(¬Int32);
|
||||
unboxDouble(src, dest.fpu());
|
||||
bind(&end);
|
||||
} else {
|
||||
if (src.payloadReg() != dest.gpr())
|
||||
movl(src.payloadReg(), dest.gpr());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
MacroAssemblerX86::loadInt32OrDouble(const T& src, FloatRegister dest)
|
||||
{
|
||||
Label notInt32, end;
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, src, ¬Int32);
|
||||
convertInt32ToDouble(ToPayload(src), dest);
|
||||
jump(&end);
|
||||
bind(¬Int32);
|
||||
loadDouble(src, dest);
|
||||
bind(&end);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
MacroAssemblerX86::loadUnboxedValue(const T& src, MIRType type, AnyRegister dest)
|
||||
{
|
||||
if (dest.isFloat())
|
||||
loadInt32OrDouble(src, dest.fpu());
|
||||
else
|
||||
movl(Operand(src), dest.gpr());
|
||||
}
|
||||
|
||||
// If source is a double, load it into dest. If source is int32,
|
||||
// convert it to double. Else, branch to failure.
|
||||
void
|
||||
MacroAssemblerX86::ensureDouble(const ValueOperand& source, FloatRegister dest, Label* failure)
|
||||
{
|
||||
Label isDouble, done;
|
||||
branchTestDouble(Assembler::Equal, source.typeReg(), &isDouble);
|
||||
asMasm().branchTestInt32(Assembler::NotEqual, source.typeReg(), failure);
|
||||
|
||||
convertInt32ToDouble(source.payloadReg(), dest);
|
||||
jump(&done);
|
||||
|
||||
bind(&isDouble);
|
||||
unboxDouble(source, dest);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
@ -328,35 +328,6 @@ template void
|
||||
MacroAssemblerX86::storeUnboxedValue(ConstantOrRegister value, MIRType valueType, const BaseIndex& dest,
|
||||
MIRType slotType);
|
||||
|
||||
void
|
||||
MacroAssemblerX86::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
MOZ_ASSERT(ptr != temp);
|
||||
MOZ_ASSERT(temp != InvalidReg); // A temp register is required for x86.
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp);
|
||||
asMasm().addPtr(ptr, temp);
|
||||
asMasm().branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
temp, Imm32(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86::branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
|
||||
Label done;
|
||||
|
||||
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
|
||||
branchPtrInNurseryRange(cond, value.payloadReg(), temp, label);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86::profilerEnterFrame(Register framePtr, Register scratch)
|
||||
{
|
||||
@ -498,4 +469,36 @@ MacroAssembler::callWithABINoProfiler(const Address& fun, MoveOp::Type result)
|
||||
callWithABIPost(stackAdjust, result);
|
||||
}
|
||||
|
||||
// ===============================================================
|
||||
// Branch functions
|
||||
|
||||
void
|
||||
MacroAssembler::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
MOZ_ASSERT(ptr != temp);
|
||||
MOZ_ASSERT(temp != InvalidReg); // A temp register is required for x86.
|
||||
|
||||
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
|
||||
movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp);
|
||||
addPtr(ptr, temp);
|
||||
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
temp, Imm32(nursery.nurserySize()), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
|
||||
Label done;
|
||||
|
||||
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
|
||||
branchPtrInNurseryRange(cond, value.payloadReg(), temp, label);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
|
@ -72,6 +72,9 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
Address ToPayload(Address base) {
|
||||
return base;
|
||||
}
|
||||
BaseIndex ToPayload(BaseIndex base) {
|
||||
return base;
|
||||
}
|
||||
Operand ToType(Operand base) {
|
||||
switch (base.kind()) {
|
||||
case Operand::MEM_REG_DISP:
|
||||
@ -575,19 +578,10 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
return jumpWithPatch(label);
|
||||
}
|
||||
|
||||
template <typename S, typename T>
|
||||
CodeOffsetJump branchPtrWithPatch(Condition cond, S lhs, T ptr, RepatchLabel* label) {
|
||||
branchPtr(cond, lhs, ptr, label);
|
||||
return CodeOffsetJump(size());
|
||||
}
|
||||
void branchPtr(Condition cond, Register lhs, Register rhs, RepatchLabel* label) {
|
||||
cmpPtr(lhs, rhs);
|
||||
j(cond, label);
|
||||
}
|
||||
void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) {
|
||||
subl(imm, lhs);
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void movePtr(ImmWord imm, Register dest) {
|
||||
movl(Imm32(imm.value), dest);
|
||||
@ -667,7 +661,7 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
j(cond, label);
|
||||
}
|
||||
template <typename T>
|
||||
void branchTestInt32(Condition cond, const T& t, Label* label) {
|
||||
void branchTestInt32Impl(Condition cond, const T& t, Label* label) {
|
||||
cond = testInt32(cond, t);
|
||||
j(cond, label);
|
||||
}
|
||||
@ -796,20 +790,7 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
vunpcklps(ScratchDoubleReg, dest, dest);
|
||||
}
|
||||
}
|
||||
void unboxValue(const ValueOperand& src, AnyRegister dest) {
|
||||
if (dest.isFloat()) {
|
||||
Label notInt32, end;
|
||||
branchTestInt32(Assembler::NotEqual, src, ¬Int32);
|
||||
convertInt32ToDouble(src.payloadReg(), dest.fpu());
|
||||
jump(&end);
|
||||
bind(¬Int32);
|
||||
unboxDouble(src, dest.fpu());
|
||||
bind(&end);
|
||||
} else {
|
||||
if (src.payloadReg() != dest.gpr())
|
||||
movl(src.payloadReg(), dest.gpr());
|
||||
}
|
||||
}
|
||||
inline void unboxValue(const ValueOperand& src, AnyRegister dest);
|
||||
void unboxPrivate(const ValueOperand& src, Register dest) {
|
||||
if (src.payloadReg() != dest)
|
||||
movl(src.payloadReg(), dest);
|
||||
@ -865,10 +846,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
test32(operand.payloadReg(), operand.payloadReg());
|
||||
return truthy ? NonZero : Zero;
|
||||
}
|
||||
void branchTestInt32Truthy(bool truthy, const ValueOperand& operand, Label* label) {
|
||||
Condition cond = testInt32Truthy(truthy, operand);
|
||||
j(cond, label);
|
||||
}
|
||||
void branchTestBooleanTruthy(bool truthy, const ValueOperand& operand, Label* label) {
|
||||
test32(operand.payloadReg(), operand.payloadReg());
|
||||
j(truthy ? NonZero : Zero, label);
|
||||
@ -883,23 +860,11 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void loadInt32OrDouble(const Operand& operand, FloatRegister dest) {
|
||||
Label notInt32, end;
|
||||
branchTestInt32(Assembler::NotEqual, operand, ¬Int32);
|
||||
convertInt32ToDouble(ToPayload(operand), dest);
|
||||
jump(&end);
|
||||
bind(¬Int32);
|
||||
loadDouble(operand, dest);
|
||||
bind(&end);
|
||||
}
|
||||
template <typename T>
|
||||
inline void loadInt32OrDouble(const T& src, FloatRegister dest);
|
||||
|
||||
template <typename T>
|
||||
void loadUnboxedValue(const T& src, MIRType type, AnyRegister dest) {
|
||||
if (dest.isFloat())
|
||||
loadInt32OrDouble(Operand(src), dest.fpu());
|
||||
else
|
||||
movl(Operand(src), dest.gpr());
|
||||
}
|
||||
inline void loadUnboxedValue(const T& src, MIRType type, AnyRegister dest);
|
||||
|
||||
template <typename T>
|
||||
void storeUnboxedValue(ConstantOrRegister value, MIRType valueType, const T& dest,
|
||||
@ -934,29 +899,12 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
addl(Imm32(1), payloadOf(addr));
|
||||
}
|
||||
|
||||
// If source is a double, load it into dest. If source is int32,
|
||||
// convert it to double. Else, branch to failure.
|
||||
void ensureDouble(const ValueOperand& source, FloatRegister dest, Label* failure) {
|
||||
Label isDouble, done;
|
||||
branchTestDouble(Assembler::Equal, source.typeReg(), &isDouble);
|
||||
branchTestInt32(Assembler::NotEqual, source.typeReg(), failure);
|
||||
|
||||
convertInt32ToDouble(source.payloadReg(), dest);
|
||||
jump(&done);
|
||||
|
||||
bind(&isDouble);
|
||||
unboxDouble(source, dest);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
inline void ensureDouble(const ValueOperand& source, FloatRegister dest, Label* failure);
|
||||
|
||||
public:
|
||||
// Used from within an Exit frame to handle a pending exception.
|
||||
void handleFailureWithHandlerTail(void* handler);
|
||||
|
||||
void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label);
|
||||
void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp, Label* label);
|
||||
|
||||
// Instrumentation for entering and leaving the profiler.
|
||||
void profilerEnterFrame(Register framePtr, Register scratch);
|
||||
void profilerExitFrame();
|
||||
|
@ -830,6 +830,7 @@ js::Disassemble1(JSContext* cx, HandleScript script, jsbytecode* pc,
|
||||
Sprint(sp, "%4u", PCToLineNumber(script, pc));
|
||||
Sprint(sp, " %s", CodeName[op]);
|
||||
|
||||
int i;
|
||||
switch (JOF_TYPE(cs->format)) {
|
||||
case JOF_BYTE:
|
||||
// Scan the trynotes to find the associated catch block
|
||||
@ -946,9 +947,6 @@ js::Disassemble1(JSContext* cx, HandleScript script, jsbytecode* pc,
|
||||
Sprint(sp, " %u", GET_UINT32(pc));
|
||||
break;
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
case JOF_UINT16:
|
||||
i = (int)GET_UINT16(pc);
|
||||
goto print_int;
|
||||
@ -972,7 +970,6 @@ js::Disassemble1(JSContext* cx, HandleScript script, jsbytecode* pc,
|
||||
print_int:
|
||||
Sprint(sp, " %d", i);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
char numBuf[12];
|
||||
|
@ -128,17 +128,6 @@ GetDirectProxyHandlerObject(JSObject* proxy)
|
||||
return proxy->as<ProxyObject>().extra(ScriptedDirectProxyHandler::HANDLER_EXTRA).toObjectOrNull();
|
||||
}
|
||||
|
||||
static inline void
|
||||
ReportInvalidTrapResult(JSContext* cx, JSObject* proxy, JSAtom* atom)
|
||||
{
|
||||
RootedValue v(cx, ObjectOrNullValue(proxy));
|
||||
JSAutoByteString bytes;
|
||||
if (!AtomToPrintableString(cx, atom, &bytes))
|
||||
return;
|
||||
ReportValueError2(cx, JSMSG_INVALID_TRAP_RESULT, JSDVG_IGNORE_STACK, v,
|
||||
nullptr, bytes.ptr());
|
||||
}
|
||||
|
||||
// ES6 implements both getPrototype and setPrototype traps. We don't have them yet (see bug
|
||||
// 888969). For now, use these, to account for proxy revocation.
|
||||
bool
|
||||
|
@ -75,6 +75,7 @@
|
||||
#include "js/TrackedOptimizationInfo.h"
|
||||
#include "perf/jsperf.h"
|
||||
#include "shell/jsoptparse.h"
|
||||
#include "shell/jsshell.h"
|
||||
#include "shell/OSObject.h"
|
||||
#include "vm/ArgumentsObject.h"
|
||||
#include "vm/Compression.h"
|
||||
@ -359,7 +360,7 @@ GetLine(FILE* file, const char * prompt)
|
||||
return nullptr;
|
||||
|
||||
char* current = buffer;
|
||||
while (true) {
|
||||
do {
|
||||
while (true) {
|
||||
if (fgets(current, size - len, file))
|
||||
break;
|
||||
@ -387,11 +388,7 @@ GetLine(FILE* file, const char * prompt)
|
||||
buffer = tmp;
|
||||
}
|
||||
current = buffer + len;
|
||||
}
|
||||
|
||||
if (len && !ferror(file))
|
||||
return buffer;
|
||||
free(buffer);
|
||||
} while (true);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -4407,6 +4404,7 @@ SingleStepCallback(void* arg, jit::Simulator* sim, void* pc)
|
||||
mozilla::DebugOnly<void*> lastStackAddress = nullptr;
|
||||
StackChars stack;
|
||||
uint32_t frameNo = 0;
|
||||
AutoEnterOOMUnsafeRegion oomUnsafe;
|
||||
for (JS::ProfilingFrameIterator i(rt, state); !i.done(); ++i) {
|
||||
MOZ_ASSERT(i.stackAddress() != nullptr);
|
||||
MOZ_ASSERT(lastStackAddress <= i.stackAddress());
|
||||
@ -4414,9 +4412,12 @@ SingleStepCallback(void* arg, jit::Simulator* sim, void* pc)
|
||||
JS::ProfilingFrameIterator::Frame frames[16];
|
||||
uint32_t nframes = i.extractStack(frames, 0, 16);
|
||||
for (uint32_t i = 0; i < nframes; i++) {
|
||||
if (frameNo > 0)
|
||||
stack.append(",", 1);
|
||||
stack.append(frames[i].label, strlen(frames[i].label));
|
||||
if (frameNo > 0) {
|
||||
if (!stack.append(",", 1))
|
||||
oomUnsafe.crash("stack.append");
|
||||
}
|
||||
if (!stack.append(frames[i].label, strlen(frames[i].label)))
|
||||
oomUnsafe.crash("stack.append");
|
||||
frameNo++;
|
||||
}
|
||||
}
|
||||
@ -4426,7 +4427,8 @@ SingleStepCallback(void* arg, jit::Simulator* sim, void* pc)
|
||||
stacks.back().length() != stack.length() ||
|
||||
!PodEqual(stacks.back().begin(), stack.begin(), stack.length()))
|
||||
{
|
||||
stacks.append(Move(stack));
|
||||
if (!stacks.append(Move(stack)))
|
||||
oomUnsafe.crash("stacks.append");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -23,7 +23,7 @@ enum JSShellErrNum {
|
||||
const JSErrorFormatString*
|
||||
my_GetErrorMessage(void* userRef, const unsigned errorNumber);
|
||||
|
||||
static void
|
||||
void
|
||||
my_ErrorReporter(JSContext* cx, const char* message, JSErrorReport* report);
|
||||
|
||||
JSString*
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "jsobj.h"
|
||||
#include "jsscript.h"
|
||||
|
||||
#include "gc/Heap.h"
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "jit/Ion.h"
|
||||
#include "vm/ArrayObject.h"
|
||||
@ -356,7 +357,7 @@ StatsArenaCallback(JSRuntime* rt, void* data, gc::Arena* arena,
|
||||
|
||||
// The admin space includes (a) the header and (b) the padding between the
|
||||
// end of the header and the start of the first GC thing.
|
||||
size_t allocationSpace = Arena::thingsSpan(arena->aheader.getAllocKind());
|
||||
size_t allocationSpace = gc::Arena::thingsSpan(arena->aheader.getAllocKind());
|
||||
rtStats->currZoneStats->gcHeapArenaAdmin += gc::ArenaSize - allocationSpace;
|
||||
|
||||
// We don't call the callback on unused things. So we compute the
|
||||
|
@ -605,6 +605,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
||||
mCurrentReferenceFrame(aReferenceFrame),
|
||||
mCurrentAGR(&mRootAGR),
|
||||
mRootAGR(aReferenceFrame, nullptr),
|
||||
mUsedAGRBudget(0),
|
||||
mDirtyRect(-1,-1,-1,-1),
|
||||
mGlassDisplayItem(nullptr),
|
||||
mPendingScrollInfoItems(nullptr),
|
||||
@ -1087,8 +1088,12 @@ nsDisplayListBuilder::IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParen
|
||||
|
||||
if (nsLayoutUtils::IsPopup(aFrame))
|
||||
return true;
|
||||
if (ActiveLayerTracker::IsOffsetOrMarginStyleAnimated(aFrame))
|
||||
return true;
|
||||
if (ActiveLayerTracker::IsOffsetOrMarginStyleAnimated(aFrame)) {
|
||||
const bool inBudget = AddToAGRBudget(aFrame);
|
||||
if (inBudget) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!aFrame->GetParent() &&
|
||||
nsLayoutUtils::ViewportHasDisplayPort(aFrame->PresContext())) {
|
||||
// Viewport frames in a display port need to be animated geometry roots
|
||||
@ -1255,7 +1260,7 @@ nsDisplayListBuilder::GetWindowDraggingRegion() const
|
||||
}
|
||||
|
||||
const uint32_t gWillChangeAreaMultiplier = 3;
|
||||
static uint32_t GetWillChangeCost(const nsSize& aSize) {
|
||||
static uint32_t GetLayerizationCost(const nsSize& aSize) {
|
||||
// There's significant overhead for each layer created from Gecko
|
||||
// (IPC+Shared Objects) and from the backend (like an OpenGL texture).
|
||||
// Therefore we set a minimum cost threshold of a 64x64 area.
|
||||
@ -1272,7 +1277,7 @@ static uint32_t GetWillChangeCost(const nsSize& aSize) {
|
||||
bool
|
||||
nsDisplayListBuilder::AddToWillChangeBudget(nsIFrame* aFrame,
|
||||
const nsSize& aSize) {
|
||||
if (mBudgetSet.Contains(aFrame)) {
|
||||
if (mWillChangeBudgetSet.Contains(aFrame)) {
|
||||
return true; // Already accounted
|
||||
}
|
||||
|
||||
@ -1288,14 +1293,14 @@ nsDisplayListBuilder::AddToWillChangeBudget(nsIFrame* aFrame,
|
||||
uint32_t budgetLimit = nsPresContext::AppUnitsToIntCSSPixels(area.width) *
|
||||
nsPresContext::AppUnitsToIntCSSPixels(area.height);
|
||||
|
||||
uint32_t cost = GetWillChangeCost(aSize);
|
||||
uint32_t cost = GetLayerizationCost(aSize);
|
||||
bool onBudget = (budget.mBudget + cost) /
|
||||
gWillChangeAreaMultiplier < budgetLimit;
|
||||
|
||||
if (onBudget) {
|
||||
budget.mBudget += cost;
|
||||
mWillChangeBudget.Put(key, budget);
|
||||
mBudgetSet.PutEntry(aFrame);
|
||||
mWillChangeBudgetSet.PutEntry(aFrame);
|
||||
}
|
||||
|
||||
return onBudget;
|
||||
@ -1308,7 +1313,7 @@ nsDisplayListBuilder::IsInWillChangeBudget(nsIFrame* aFrame,
|
||||
|
||||
if (!onBudget) {
|
||||
nsString usageStr;
|
||||
usageStr.AppendInt(GetWillChangeCost(aSize));
|
||||
usageStr.AppendInt(GetLayerizationCost(aSize));
|
||||
|
||||
nsString multiplierStr;
|
||||
multiplierStr.AppendInt(gWillChangeAreaMultiplier);
|
||||
@ -1327,6 +1332,40 @@ nsDisplayListBuilder::IsInWillChangeBudget(nsIFrame* aFrame,
|
||||
return onBudget;
|
||||
}
|
||||
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
const float gAGRBudgetAreaMultiplier = 0.3;
|
||||
#else
|
||||
const float gAGRBudgetAreaMultiplier = 3.0;
|
||||
#endif
|
||||
|
||||
bool
|
||||
nsDisplayListBuilder::AddToAGRBudget(nsIFrame* aFrame)
|
||||
{
|
||||
if (mAGRBudgetSet.Contains(aFrame)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const nsPresContext* presContext = aFrame->PresContext()->GetRootPresContext();
|
||||
if (!presContext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const nsRect area = presContext->GetVisibleArea();
|
||||
const uint32_t budgetLimit = gAGRBudgetAreaMultiplier *
|
||||
nsPresContext::AppUnitsToIntCSSPixels(area.width) *
|
||||
nsPresContext::AppUnitsToIntCSSPixels(area.height);
|
||||
|
||||
const uint32_t cost = GetLayerizationCost(aFrame->GetSize());
|
||||
const bool onBudget = mUsedAGRBudget + cost < budgetLimit;
|
||||
|
||||
if (onBudget) {
|
||||
mUsedAGRBudget += cost;
|
||||
mAGRBudgetSet.PutEntry(aFrame);
|
||||
}
|
||||
|
||||
return onBudget;
|
||||
}
|
||||
|
||||
nsDisplayList*
|
||||
nsDisplayListBuilder::EnterScrollInfoItemHoisting(nsDisplayList* aScrollInfoItemStorage)
|
||||
{
|
||||
|
@ -1164,6 +1164,13 @@ private:
|
||||
|
||||
nsDataHashtable<nsPtrHashKey<nsIFrame>, AnimatedGeometryRoot*> mFrameToAnimatedGeometryRootMap;
|
||||
|
||||
/**
|
||||
* Add the current frame to the AGR budget if possible and remember
|
||||
* the outcome. Subsequent calls will return the same value as
|
||||
* returned here.
|
||||
*/
|
||||
bool AddToAGRBudget(nsIFrame* aFrame);
|
||||
|
||||
struct PresShellState {
|
||||
nsIPresShell* mPresShell;
|
||||
nsIFrame* mCaretFrame;
|
||||
@ -1217,7 +1224,12 @@ private:
|
||||
|
||||
// Any frame listed in this set is already counted in the budget
|
||||
// and thus is in-budget.
|
||||
nsTHashtable<nsPtrHashKey<nsIFrame> > mBudgetSet;
|
||||
nsTHashtable<nsPtrHashKey<nsIFrame> > mWillChangeBudgetSet;
|
||||
|
||||
// Area of animated geometry root budget already allocated
|
||||
uint32_t mUsedAGRBudget;
|
||||
// Set of frames already counted in budget
|
||||
nsTHashtable<nsPtrHashKey<nsIFrame> > mAGRBudgetSet;
|
||||
|
||||
// rects are relative to the frame's reference frame
|
||||
nsDataHashtable<nsPtrHashKey<nsIFrame>, nsRect> mDirtyRectForScrolledContents;
|
||||
|
@ -455,7 +455,7 @@ public:
|
||||
* presenting the document. The returned value is in the standard
|
||||
* nscoord units (as scaled by the device context).
|
||||
*/
|
||||
nsRect GetVisibleArea() { return mVisibleArea; }
|
||||
nsRect GetVisibleArea() const { return mVisibleArea; }
|
||||
|
||||
/**
|
||||
* Set the currently visible area. The units for r are standard
|
||||
|
21
layout/reftests/bugs/1239564-ref.html
Normal file
21
layout/reftests/bugs/1239564-ref.html
Normal file
@ -0,0 +1,21 @@
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<title>Testcase for bug 1239564</title>
|
||||
<style>
|
||||
#circle {
|
||||
border-radius: 300px;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
background-color: red;
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top:0;
|
||||
bottom: 0;
|
||||
transform: scale(3);
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div id="circle"></div>
|
||||
</body></html>
|
29
layout/reftests/bugs/1239564.html
Normal file
29
layout/reftests/bugs/1239564.html
Normal file
@ -0,0 +1,29 @@
|
||||
<html class="reftest-wait"><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<title>Testcase for bug 1239564</title>
|
||||
<style>
|
||||
#circle {
|
||||
border-radius: 300px;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
background-color: red;
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top:0;
|
||||
bottom: 0;
|
||||
will-change: transform;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div id="circle"></div>
|
||||
<script>
|
||||
var c = document.getElementById('circle');
|
||||
function doTest() {
|
||||
c.style.transform = "translateZ(1px) scale(3)";
|
||||
document.documentElement.removeAttribute('class');
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
</script>
|
||||
</body></html>
|
@ -1944,3 +1944,4 @@ fuzzy(1,74) fuzzy-if(gtkWidget,6,79) == 1174332-1.html 1174332-1-ref.html
|
||||
== 1222226-1.html 1222226-1-ref.html
|
||||
pref(layout.css.overflow-clip-box.enabled,true) == 1226278.html 1226278-ref.html
|
||||
== 1230466.html about:blank
|
||||
fuzzy(100,2000) == 1239564.html 1239564-ref.html
|
||||
|
@ -23,6 +23,8 @@ import android.graphics.RectF;
|
||||
import android.os.SystemClock;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -106,6 +108,8 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
*/
|
||||
private volatile boolean mContentDocumentIsDisplayed;
|
||||
|
||||
private SynthesizedEventState mPointerState;
|
||||
|
||||
public GeckoLayerClient(Context context, LayerView view, EventDispatcher eventDispatcher) {
|
||||
// we can fill these in with dummy values because they are always written
|
||||
// to before being read
|
||||
@ -709,6 +713,141 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
layersUpdated, paintSyncId);
|
||||
}
|
||||
|
||||
class PointerInfo {
|
||||
public int pointerId;
|
||||
public int screenX;
|
||||
public int screenY;
|
||||
public double pressure;
|
||||
public int orientation;
|
||||
|
||||
public MotionEvent.PointerCoords getCoords() {
|
||||
MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
|
||||
coords.orientation = orientation;
|
||||
coords.pressure = (float)pressure;
|
||||
coords.x = screenX;
|
||||
coords.y = screenY;
|
||||
return coords;
|
||||
}
|
||||
}
|
||||
|
||||
class SynthesizedEventState {
|
||||
public final ArrayList<PointerInfo> pointers;
|
||||
public long downTime;
|
||||
|
||||
SynthesizedEventState() {
|
||||
pointers = new ArrayList<PointerInfo>();
|
||||
}
|
||||
|
||||
int getPointerIndex(int pointerId) {
|
||||
for (int i = 0; i < pointers.size(); i++) {
|
||||
if (pointers.get(i).pointerId == pointerId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int addPointer(int pointerId) {
|
||||
PointerInfo info = new PointerInfo();
|
||||
info.pointerId = pointerId;
|
||||
pointers.add(info);
|
||||
return pointers.size() - 1;
|
||||
}
|
||||
|
||||
int[] getPointerIds() {
|
||||
int[] ids = new int[pointers.size()];
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
ids[i] = pointers.get(i).pointerId;
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
MotionEvent.PointerCoords[] getPointerCoords() {
|
||||
MotionEvent.PointerCoords[] coords = new MotionEvent.PointerCoords[pointers.size()];
|
||||
for (int i = 0; i < coords.length; i++) {
|
||||
coords[i] = pointers.get(i).getCoords();
|
||||
}
|
||||
return coords;
|
||||
}
|
||||
}
|
||||
|
||||
@WrapForJNI
|
||||
public void synthesizeNativeTouchPoint(int pointerId, int eventType, int screenX,
|
||||
int screenY, double pressure, int orientation)
|
||||
{
|
||||
if (mPointerState == null) {
|
||||
mPointerState = new SynthesizedEventState();
|
||||
}
|
||||
|
||||
// Find the pointer if it already exists
|
||||
int pointerIndex = mPointerState.getPointerIndex(pointerId);
|
||||
|
||||
// Event-specific handling
|
||||
switch (eventType) {
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
if (pointerIndex < 0) {
|
||||
Log.d(LOGTAG, "Requested synthesis of a pointer-up for a pointer that doesn't exist!");
|
||||
return;
|
||||
}
|
||||
if (mPointerState.pointers.size() == 1) {
|
||||
// Last pointer is going up
|
||||
eventType = MotionEvent.ACTION_UP;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
if (pointerIndex < 0) {
|
||||
Log.d(LOGTAG, "Requested synthesis of a pointer-cancel for a pointer that doesn't exist!");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
if (pointerIndex < 0) {
|
||||
// Adding a new pointer
|
||||
pointerIndex = mPointerState.addPointer(pointerId);
|
||||
if (pointerIndex == 0) {
|
||||
// first pointer
|
||||
eventType = MotionEvent.ACTION_DOWN;
|
||||
mPointerState.downTime = SystemClock.uptimeMillis();
|
||||
}
|
||||
} else {
|
||||
// We're moving an existing pointer
|
||||
eventType = MotionEvent.ACTION_MOVE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Update the pointer with the new info
|
||||
PointerInfo info = mPointerState.pointers.get(pointerIndex);
|
||||
info.screenX = screenX;
|
||||
info.screenY = screenY;
|
||||
info.pressure = pressure;
|
||||
info.orientation = orientation;
|
||||
|
||||
// Dispatch the event
|
||||
int action = (pointerIndex << MotionEvent.ACTION_POINTER_INDEX_SHIFT);
|
||||
action &= MotionEvent.ACTION_POINTER_INDEX_MASK;
|
||||
action |= (eventType & MotionEvent.ACTION_MASK);
|
||||
final MotionEvent event = MotionEvent.obtain(mPointerState.downTime,
|
||||
SystemClock.uptimeMillis(), action, mPointerState.pointers.size(),
|
||||
mPointerState.getPointerIds(), mPointerState.getPointerCoords(),
|
||||
0, 0, 0, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
|
||||
mView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
event.offsetLocation(0, mView.getSurfaceTranslation());
|
||||
mView.dispatchTouchEvent(event);
|
||||
}
|
||||
});
|
||||
|
||||
// Forget about removed pointers
|
||||
if (eventType == MotionEvent.ACTION_POINTER_UP ||
|
||||
eventType == MotionEvent.ACTION_UP ||
|
||||
eventType == MotionEvent.ACTION_CANCEL)
|
||||
{
|
||||
mPointerState.pointers.remove(pointerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@WrapForJNI(allowMultithread = true)
|
||||
public LayerRenderer.Frame createFrame() {
|
||||
// Create the shaders and textures if necessary.
|
||||
|
@ -1315,7 +1315,7 @@ static nsresult pref_InitInitialObjects()
|
||||
// channel, telemetry is on by default, otherwise not. This is necessary
|
||||
// so that beta users who are testing final release builds don't flipflop
|
||||
// defaults.
|
||||
if (Preferences::GetDefaultType(kTelemetryPref) == PREF_INVALID) {
|
||||
if (Preferences::GetDefaultType(kTelemetryPref) == nsIPrefBranch::PREF_INVALID) {
|
||||
bool prerelease = false;
|
||||
#ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
|
||||
prerelease = true;
|
||||
|
@ -127,7 +127,21 @@ NS_IMETHODIMP nsPrefBranch::GetPrefType(const char *aPrefName, int32_t *_retval)
|
||||
{
|
||||
NS_ENSURE_ARG(aPrefName);
|
||||
const char *pref = getPrefName(aPrefName);
|
||||
*_retval = PREF_GetPrefType(pref);
|
||||
switch (PREF_GetPrefType(pref)) {
|
||||
case PrefType::String:
|
||||
*_retval = PREF_STRING;
|
||||
break;
|
||||
case PrefType::Int:
|
||||
*_retval = PREF_INT;
|
||||
break;
|
||||
case PrefType::Bool:
|
||||
*_retval = PREF_BOOL;
|
||||
break;
|
||||
case PrefType::Invalid:
|
||||
default:
|
||||
*_retval = PREF_INVALID;
|
||||
break;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ static void
|
||||
clearPrefEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
|
||||
{
|
||||
PrefHashEntry *pref = static_cast<PrefHashEntry *>(entry);
|
||||
if (pref->flags & PREF_STRING)
|
||||
if (pref->prefFlags.IsTypeString())
|
||||
{
|
||||
if (pref->defaultPref.stringVal)
|
||||
PL_strfree(pref->defaultPref.stringVal);
|
||||
@ -117,13 +117,7 @@ static char *ArenaStrDup(const char* str, PLArenaPool* aArena)
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#define PREF_IS_LOCKED(pref) ((pref)->flags & PREF_LOCKED)
|
||||
#define PREF_HAS_DEFAULT_VALUE(pref) ((pref)->flags & PREF_HAS_DEFAULT)
|
||||
#define PREF_HAS_USER_VALUE(pref) ((pref)->flags & PREF_USERSET)
|
||||
#define PREF_TYPE(pref) (PrefType)((pref)->flags & PREF_VALUETYPE_MASK)
|
||||
|
||||
static bool pref_ValueChanged(PrefValue oldValue, PrefValue newValue, PrefType type);
|
||||
|
||||
/* -- Privates */
|
||||
struct CallbackNode {
|
||||
char* domain;
|
||||
@ -249,7 +243,7 @@ PREF_SetCharPref(const char *pref_name, const char *value, bool set_default)
|
||||
PrefValue pref;
|
||||
pref.stringVal = (char*)value;
|
||||
|
||||
return pref_HashPref(pref_name, pref, PREF_STRING, set_default ? kPrefSetDefault : 0);
|
||||
return pref_HashPref(pref_name, pref, PrefType::String, set_default ? kPrefSetDefault : 0);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -258,7 +252,7 @@ PREF_SetIntPref(const char *pref_name, int32_t value, bool set_default)
|
||||
PrefValue pref;
|
||||
pref.intVal = value;
|
||||
|
||||
return pref_HashPref(pref_name, pref, PREF_INT, set_default ? kPrefSetDefault : 0);
|
||||
return pref_HashPref(pref_name, pref, PrefType::Int, set_default ? kPrefSetDefault : 0);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -267,7 +261,7 @@ PREF_SetBoolPref(const char *pref_name, bool value, bool set_default)
|
||||
PrefValue pref;
|
||||
pref.boolVal = value;
|
||||
|
||||
return pref_HashPref(pref_name, pref, PREF_BOOL, set_default ? kPrefSetDefault : 0);
|
||||
return pref_HashPref(pref_name, pref, PrefType::Bool, set_default ? kPrefSetDefault : 0);
|
||||
}
|
||||
|
||||
enum WhichValue { DEFAULT_VALUE, USER_VALUE };
|
||||
@ -335,12 +329,12 @@ pref_savePrefs(PLDHashTable* aTable)
|
||||
// where we're getting our pref from
|
||||
PrefValue* sourcePref;
|
||||
|
||||
if (PREF_HAS_USER_VALUE(pref) &&
|
||||
if (pref->prefFlags.HasUserValue() &&
|
||||
(pref_ValueChanged(pref->defaultPref,
|
||||
pref->userPref,
|
||||
(PrefType) PREF_TYPE(pref)) ||
|
||||
!(pref->flags & PREF_HAS_DEFAULT) ||
|
||||
pref->flags & PREF_STICKY_DEFAULT)) {
|
||||
pref->prefFlags.GetPrefType()) ||
|
||||
!(pref->prefFlags.HasDefault()) ||
|
||||
pref->prefFlags.HasStickyDefault())) {
|
||||
sourcePref = &pref->userPref;
|
||||
} else {
|
||||
// do not save default prefs that haven't changed
|
||||
@ -348,15 +342,15 @@ pref_savePrefs(PLDHashTable* aTable)
|
||||
}
|
||||
|
||||
// strings are in quotes!
|
||||
if (pref->flags & PREF_STRING) {
|
||||
if (pref->prefFlags.IsTypeString()) {
|
||||
prefValue = '\"';
|
||||
str_escape(sourcePref->stringVal, prefValue);
|
||||
prefValue += '\"';
|
||||
|
||||
} else if (pref->flags & PREF_INT) {
|
||||
} else if (pref->prefFlags.IsTypeInt()) {
|
||||
prefValue.AppendInt(sourcePref->intVal);
|
||||
|
||||
} else if (pref->flags & PREF_BOOL) {
|
||||
} else if (pref->prefFlags.IsTypeBool()) {
|
||||
prefValue = (sourcePref->boolVal) ? "true" : "false";
|
||||
}
|
||||
|
||||
@ -389,14 +383,14 @@ GetPrefValueFromEntry(PrefHashEntry *aHashEntry, dom::PrefSetting* aPref,
|
||||
settingValue = &aPref->defaultValue().get_PrefValue();
|
||||
}
|
||||
|
||||
switch (aHashEntry->flags & PREF_VALUETYPE_MASK) {
|
||||
case PREF_STRING:
|
||||
switch (aHashEntry->prefFlags.GetPrefType()) {
|
||||
case PrefType::String:
|
||||
*settingValue = nsDependentCString(value->stringVal);
|
||||
return;
|
||||
case PREF_INT:
|
||||
case PrefType::Int:
|
||||
*settingValue = value->intVal;
|
||||
return;
|
||||
case PREF_BOOL:
|
||||
case PrefType::Bool:
|
||||
*settingValue = !!value->boolVal;
|
||||
return;
|
||||
default:
|
||||
@ -408,12 +402,12 @@ void
|
||||
pref_GetPrefFromEntry(PrefHashEntry *aHashEntry, dom::PrefSetting* aPref)
|
||||
{
|
||||
aPref->name() = aHashEntry->key;
|
||||
if (PREF_HAS_DEFAULT_VALUE(aHashEntry)) {
|
||||
if (aHashEntry->prefFlags.HasDefault()) {
|
||||
GetPrefValueFromEntry(aHashEntry, aPref, DEFAULT_VALUE);
|
||||
} else {
|
||||
aPref->defaultValue() = null_t();
|
||||
}
|
||||
if (PREF_HAS_USER_VALUE(aHashEntry)) {
|
||||
if (aHashEntry->prefFlags.HasUserValue()) {
|
||||
GetPrefValueFromEntry(aHashEntry, aPref, USER_VALUE);
|
||||
} else {
|
||||
aPref->userValue() = null_t();
|
||||
@ -451,11 +445,7 @@ bool PREF_HasUserPref(const char *pref_name)
|
||||
return false;
|
||||
|
||||
PrefHashEntry *pref = pref_HashTableLookup(pref_name);
|
||||
if (!pref) return false;
|
||||
|
||||
/* convert PREF_HAS_USER_VALUE to bool */
|
||||
return (PREF_HAS_USER_VALUE(pref) != 0);
|
||||
|
||||
return pref && pref->prefFlags.HasUserValue();
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -468,12 +458,12 @@ PREF_CopyCharPref(const char *pref_name, char ** return_buffer, bool get_default
|
||||
char* stringVal;
|
||||
PrefHashEntry* pref = pref_HashTableLookup(pref_name);
|
||||
|
||||
if (pref && (pref->flags & PREF_STRING))
|
||||
{
|
||||
if (get_default || PREF_IS_LOCKED(pref) || !PREF_HAS_USER_VALUE(pref))
|
||||
if (pref && (pref->prefFlags.IsTypeString())) {
|
||||
if (get_default || pref->prefFlags.IsLocked() || !pref->prefFlags.HasUserValue()) {
|
||||
stringVal = pref->defaultPref.stringVal;
|
||||
else
|
||||
} else {
|
||||
stringVal = pref->userPref.stringVal;
|
||||
}
|
||||
|
||||
if (stringVal) {
|
||||
*return_buffer = NS_strdup(stringVal);
|
||||
@ -490,18 +480,17 @@ nsresult PREF_GetIntPref(const char *pref_name,int32_t * return_int, bool get_de
|
||||
|
||||
nsresult rv = NS_ERROR_UNEXPECTED;
|
||||
PrefHashEntry* pref = pref_HashTableLookup(pref_name);
|
||||
if (pref && (pref->flags & PREF_INT))
|
||||
{
|
||||
if (get_default || PREF_IS_LOCKED(pref) || !PREF_HAS_USER_VALUE(pref))
|
||||
{
|
||||
if (pref && (pref->prefFlags.IsTypeInt())) {
|
||||
if (get_default || pref->prefFlags.IsLocked() || !pref->prefFlags.HasUserValue()) {
|
||||
int32_t tempInt = pref->defaultPref.intVal;
|
||||
/* check to see if we even had a default */
|
||||
if (!(pref->flags & PREF_HAS_DEFAULT))
|
||||
if (!pref->prefFlags.HasDefault()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
*return_int = tempInt;
|
||||
}
|
||||
else
|
||||
} else {
|
||||
*return_int = pref->userPref.intVal;
|
||||
}
|
||||
rv = NS_OK;
|
||||
}
|
||||
return rv;
|
||||
@ -515,18 +504,15 @@ nsresult PREF_GetBoolPref(const char *pref_name, bool * return_value, bool get_d
|
||||
nsresult rv = NS_ERROR_UNEXPECTED;
|
||||
PrefHashEntry* pref = pref_HashTableLookup(pref_name);
|
||||
//NS_ASSERTION(pref, pref_name);
|
||||
if (pref && (pref->flags & PREF_BOOL))
|
||||
{
|
||||
if (get_default || PREF_IS_LOCKED(pref) || !PREF_HAS_USER_VALUE(pref))
|
||||
{
|
||||
if (pref && (pref->prefFlags.IsTypeBool())) {
|
||||
if (get_default || pref->prefFlags.IsLocked() || !pref->prefFlags.HasUserValue()) {
|
||||
bool tempBool = pref->defaultPref.boolVal;
|
||||
/* check to see if we even had a default */
|
||||
if (pref->flags & PREF_HAS_DEFAULT) {
|
||||
if (pref->prefFlags.HasDefault()) {
|
||||
*return_value = tempBool;
|
||||
rv = NS_OK;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
*return_value = pref->userPref.boolVal;
|
||||
rv = NS_OK;
|
||||
}
|
||||
@ -584,11 +570,10 @@ PREF_ClearUserPref(const char *pref_name)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
PrefHashEntry* pref = pref_HashTableLookup(pref_name);
|
||||
if (pref && PREF_HAS_USER_VALUE(pref))
|
||||
{
|
||||
pref->flags &= ~PREF_USERSET;
|
||||
if (pref && pref->prefFlags.HasUserValue()) {
|
||||
pref->prefFlags.SetHasUserValue(false);
|
||||
|
||||
if (!(pref->flags & PREF_HAS_DEFAULT)) {
|
||||
if (!pref->prefFlags.HasDefault()) {
|
||||
gHashTable->RemoveEntry(pref);
|
||||
}
|
||||
|
||||
@ -612,11 +597,11 @@ PREF_ClearAllUserPrefs()
|
||||
for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
|
||||
auto pref = static_cast<PrefHashEntry*>(iter.Get());
|
||||
|
||||
if (PREF_HAS_USER_VALUE(pref)) {
|
||||
if (pref->prefFlags.HasUserValue()) {
|
||||
prefStrings.push_back(std::string(pref->key));
|
||||
|
||||
pref->flags &= ~PREF_USERSET;
|
||||
if (!(pref->flags & PREF_HAS_DEFAULT)) {
|
||||
pref->prefFlags.SetHasUserValue(false);
|
||||
if (!pref->prefFlags.HasDefault()) {
|
||||
iter.Remove();
|
||||
}
|
||||
}
|
||||
@ -640,18 +625,14 @@ nsresult PREF_LockPref(const char *key, bool lockit)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if (lockit) {
|
||||
if (!PREF_IS_LOCKED(pref))
|
||||
{
|
||||
pref->flags |= PREF_LOCKED;
|
||||
if (!pref->prefFlags.IsLocked()) {
|
||||
pref->prefFlags.SetLocked(true);
|
||||
gIsAnyPrefLocked = true;
|
||||
pref_DoCallback(key);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PREF_IS_LOCKED(pref))
|
||||
{
|
||||
pref->flags &= ~PREF_LOCKED;
|
||||
} else {
|
||||
if (pref->prefFlags.IsLocked()) {
|
||||
pref->prefFlags.SetLocked(false);
|
||||
pref_DoCallback(key);
|
||||
}
|
||||
}
|
||||
@ -664,15 +645,23 @@ nsresult PREF_LockPref(const char *key, bool lockit)
|
||||
static bool pref_ValueChanged(PrefValue oldValue, PrefValue newValue, PrefType type)
|
||||
{
|
||||
bool changed = true;
|
||||
if (type & PREF_STRING)
|
||||
{
|
||||
if (oldValue.stringVal && newValue.stringVal)
|
||||
switch(type) {
|
||||
case PrefType::String:
|
||||
if (oldValue.stringVal && newValue.stringVal) {
|
||||
changed = (strcmp(oldValue.stringVal, newValue.stringVal) != 0);
|
||||
}
|
||||
else if (type & PREF_INT)
|
||||
}
|
||||
break;
|
||||
case PrefType::Int:
|
||||
changed = oldValue.intVal != newValue.intVal;
|
||||
else if (type & PREF_BOOL)
|
||||
break;
|
||||
case PrefType::Bool:
|
||||
changed = oldValue.boolVal != newValue.boolVal;
|
||||
break;
|
||||
case PrefType::Invalid:
|
||||
default:
|
||||
changed = false;
|
||||
break;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
@ -681,20 +670,21 @@ static bool pref_ValueChanged(PrefValue oldValue, PrefValue newValue, PrefType t
|
||||
* ensure that they are not changing the type of a preference that has
|
||||
* a default value.
|
||||
*/
|
||||
static void pref_SetValue(PrefValue* existingValue, uint16_t *existingFlags,
|
||||
PrefValue newValue, PrefType newType)
|
||||
static PrefTypeFlags pref_SetValue(PrefValue* existingValue, PrefTypeFlags flags,
|
||||
PrefValue newValue, PrefType newType)
|
||||
{
|
||||
if ((*existingFlags & PREF_STRING) && existingValue->stringVal) {
|
||||
if (flags.IsTypeString() && existingValue->stringVal) {
|
||||
PL_strfree(existingValue->stringVal);
|
||||
}
|
||||
*existingFlags = (*existingFlags & ~PREF_VALUETYPE_MASK) | newType;
|
||||
if (newType & PREF_STRING) {
|
||||
flags.SetPrefType(newType);
|
||||
if (flags.IsTypeString()) {
|
||||
PR_ASSERT(newValue.stringVal);
|
||||
existingValue->stringVal = newValue.stringVal ? PL_strdup(newValue.stringVal) : nullptr;
|
||||
}
|
||||
else {
|
||||
*existingValue = newValue;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
PrefHashEntry* pref_HashTableLookup(const char *key)
|
||||
@ -723,63 +713,53 @@ nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, uint32_t
|
||||
if (!pref->key) {
|
||||
|
||||
// initialize the pref entry
|
||||
pref->flags = type;
|
||||
pref->prefFlags.Reset().SetPrefType(type);
|
||||
pref->key = ArenaStrDup(key, &gPrefNameArena);
|
||||
memset(&pref->defaultPref, 0, sizeof(pref->defaultPref));
|
||||
memset(&pref->userPref, 0, sizeof(pref->userPref));
|
||||
}
|
||||
else if ((pref->flags & PREF_HAS_DEFAULT) && PREF_TYPE(pref) != type)
|
||||
{
|
||||
} else if (pref->prefFlags.HasDefault() && !pref->prefFlags.IsPrefType(type)) {
|
||||
NS_WARNING(nsPrintfCString("Trying to overwrite value of default pref %s with the wrong type!", key).get());
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
bool valueChanged = false;
|
||||
if (flags & kPrefSetDefault)
|
||||
{
|
||||
if (!PREF_IS_LOCKED(pref))
|
||||
{ /* ?? change of semantics? */
|
||||
if (flags & kPrefSetDefault) {
|
||||
if (!pref->prefFlags.IsLocked()) {
|
||||
/* ?? change of semantics? */
|
||||
if (pref_ValueChanged(pref->defaultPref, value, type) ||
|
||||
!(pref->flags & PREF_HAS_DEFAULT))
|
||||
{
|
||||
pref_SetValue(&pref->defaultPref, &pref->flags, value, type);
|
||||
pref->flags |= PREF_HAS_DEFAULT;
|
||||
if (flags & kPrefStickyDefault)
|
||||
pref->flags |= PREF_STICKY_DEFAULT;
|
||||
if (!PREF_HAS_USER_VALUE(pref))
|
||||
!pref->prefFlags.HasDefault()) {
|
||||
pref->prefFlags = pref_SetValue(&pref->defaultPref, pref->prefFlags, value, type).SetHasDefault(true);
|
||||
if (flags & kPrefStickyDefault) {
|
||||
pref->prefFlags.SetHasStickyDefault(true);
|
||||
}
|
||||
if (!pref->prefFlags.HasUserValue()) {
|
||||
valueChanged = true;
|
||||
}
|
||||
}
|
||||
// What if we change the default to be the same as the user value?
|
||||
// Should we clear the user value?
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* If new value is same as the default value and it's not a "sticky"
|
||||
pref, then un-set the user value.
|
||||
Otherwise, set the user value only if it has changed */
|
||||
if ((pref->flags & PREF_HAS_DEFAULT) &&
|
||||
!(pref->flags & PREF_STICKY_DEFAULT) &&
|
||||
if ((pref->prefFlags.HasDefault()) &&
|
||||
!(pref->prefFlags.HasStickyDefault()) &&
|
||||
!pref_ValueChanged(pref->defaultPref, value, type) &&
|
||||
!(flags & kPrefForceSet))
|
||||
{
|
||||
if (PREF_HAS_USER_VALUE(pref))
|
||||
{
|
||||
!(flags & kPrefForceSet)) {
|
||||
if (pref->prefFlags.HasUserValue()) {
|
||||
/* XXX should we free a user-set string value if there is one? */
|
||||
pref->flags &= ~PREF_USERSET;
|
||||
if (!PREF_IS_LOCKED(pref)) {
|
||||
pref->prefFlags.SetHasUserValue(false);
|
||||
if (!pref->prefFlags.IsLocked()) {
|
||||
gDirty = true;
|
||||
valueChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!PREF_HAS_USER_VALUE(pref) ||
|
||||
PREF_TYPE(pref) != type ||
|
||||
pref_ValueChanged(pref->userPref, value, type) )
|
||||
{
|
||||
pref_SetValue(&pref->userPref, &pref->flags, value, type);
|
||||
pref->flags |= PREF_USERSET;
|
||||
if (!PREF_IS_LOCKED(pref)) {
|
||||
} else if (!pref->prefFlags.HasUserValue() ||
|
||||
!pref->prefFlags.IsPrefType(type) ||
|
||||
pref_ValueChanged(pref->userPref, value, type) ) {
|
||||
pref->prefFlags = pref_SetValue(&pref->userPref, pref->prefFlags, value, type).SetHasUserValue(true);
|
||||
if (!pref->prefFlags.IsLocked()) {
|
||||
gDirty = true;
|
||||
valueChanged = true;
|
||||
}
|
||||
@ -808,17 +788,11 @@ PREF_GetPrefType(const char *pref_name)
|
||||
{
|
||||
if (gHashTable) {
|
||||
PrefHashEntry* pref = pref_HashTableLookup(pref_name);
|
||||
if (pref)
|
||||
{
|
||||
if (pref->flags & PREF_STRING)
|
||||
return PREF_STRING;
|
||||
else if (pref->flags & PREF_INT)
|
||||
return PREF_INT;
|
||||
else if (pref->flags & PREF_BOOL)
|
||||
return PREF_BOOL;
|
||||
if (pref) {
|
||||
return pref->prefFlags.GetPrefType();
|
||||
}
|
||||
}
|
||||
return PREF_INVALID;
|
||||
return PrefType::Invalid;
|
||||
}
|
||||
|
||||
/* -- */
|
||||
@ -829,8 +803,9 @@ PREF_PrefIsLocked(const char *pref_name)
|
||||
bool result = false;
|
||||
if (gIsAnyPrefLocked && gHashTable) {
|
||||
PrefHashEntry* pref = pref_HashTableLookup(pref_name);
|
||||
if (pref && PREF_IS_LOCKED(pref))
|
||||
if (pref && pref->prefFlags.IsLocked()) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -973,10 +948,16 @@ void PREF_ReaderCallback(void *closure,
|
||||
PrefType type,
|
||||
bool isDefault,
|
||||
bool isStickyDefault)
|
||||
|
||||
{
|
||||
uint32_t flags = isDefault ? kPrefSetDefault : kPrefForceSet;
|
||||
if (isDefault && isStickyDefault) {
|
||||
flags |= kPrefStickyDefault;
|
||||
uint32_t flags = 0;
|
||||
if (isDefault) {
|
||||
flags |= kPrefSetDefault;
|
||||
if (isStickyDefault) {
|
||||
flags |= kPrefStickyDefault;
|
||||
}
|
||||
} else {
|
||||
flags |= kPrefForceSet;
|
||||
}
|
||||
pref_HashPref(pref, value, type, flags);
|
||||
}
|
||||
|
@ -28,14 +28,6 @@ typedef union
|
||||
bool boolVal;
|
||||
} PrefValue;
|
||||
|
||||
struct PrefHashEntry : PLDHashEntryHdr
|
||||
{
|
||||
uint16_t flags; // This field goes first to minimize struct size on 64-bit.
|
||||
const char *key;
|
||||
PrefValue defaultPref;
|
||||
PrefValue userPref;
|
||||
};
|
||||
|
||||
/*
|
||||
// <font color=blue>
|
||||
// The Init function initializes the preference context and creates
|
||||
@ -45,7 +37,7 @@ struct PrefHashEntry : PLDHashEntryHdr
|
||||
void PREF_Init();
|
||||
|
||||
/*
|
||||
// Cleanup should be called at program exit to free the
|
||||
// Cleanup should be called at program exit to free the
|
||||
// list of registered callbacks.
|
||||
*/
|
||||
void PREF_Cleanup();
|
||||
@ -53,23 +45,88 @@ void PREF_CleanupPrefs();
|
||||
|
||||
/*
|
||||
// <font color=blue>
|
||||
// Preference flags, including the native type of the preference
|
||||
// Preference flags, including the native type of the preference. Changing any of these
|
||||
// values will require modifying the code inside of PrefTypeFlags class.
|
||||
// </font>
|
||||
*/
|
||||
|
||||
typedef enum { PREF_INVALID = 0,
|
||||
PREF_LOCKED = 1, PREF_USERSET = 2, PREF_CONFIG = 4, PREF_REMOTE = 8,
|
||||
PREF_LILOCAL = 16, PREF_STRING = 32, PREF_INT = 64, PREF_BOOL = 128,
|
||||
PREF_HAS_DEFAULT = 256,
|
||||
// pref is default pref with "sticky" semantics
|
||||
PREF_STICKY_DEFAULT = 512,
|
||||
PREF_VALUETYPE_MASK = (PREF_STRING | PREF_INT | PREF_BOOL)
|
||||
} PrefType;
|
||||
enum class PrefType {
|
||||
Invalid = 0,
|
||||
String = 1,
|
||||
Int = 2,
|
||||
Bool = 3,
|
||||
};
|
||||
|
||||
// Keep the type of the preference, as well as the flags guiding its behaviour.
|
||||
class PrefTypeFlags
|
||||
{
|
||||
public:
|
||||
PrefTypeFlags() : mValue(AsInt(PrefType::Invalid)) {}
|
||||
explicit PrefTypeFlags(PrefType aType) : mValue(AsInt(aType)) {}
|
||||
PrefTypeFlags& Reset() { mValue = AsInt(PrefType::Invalid); return *this; }
|
||||
|
||||
bool IsTypeValid() const { return !IsPrefType(PrefType::Invalid); }
|
||||
bool IsTypeString() const { return IsPrefType(PrefType::String); }
|
||||
bool IsTypeInt() const { return IsPrefType(PrefType::Int); }
|
||||
bool IsTypeBool() const { return IsPrefType(PrefType::Bool); }
|
||||
bool IsPrefType(PrefType type) const { return GetPrefType() == type; }
|
||||
|
||||
PrefTypeFlags& SetPrefType(PrefType aType) {
|
||||
mValue = mValue - AsInt(GetPrefType()) + AsInt(aType);
|
||||
return *this;
|
||||
}
|
||||
PrefType GetPrefType() const {
|
||||
return (PrefType)(mValue & (AsInt(PrefType::String) |
|
||||
AsInt(PrefType::Int) |
|
||||
AsInt(PrefType::Bool)));
|
||||
}
|
||||
|
||||
bool HasDefault() const { return mValue & PREF_FLAG_HAS_DEFAULT; }
|
||||
PrefTypeFlags& SetHasDefault(bool aSetOrUnset) { return SetFlag(PREF_FLAG_HAS_DEFAULT, aSetOrUnset); }
|
||||
|
||||
bool HasStickyDefault() const { return mValue & PREF_FLAG_STICKY_DEFAULT; }
|
||||
PrefTypeFlags& SetHasStickyDefault(bool aSetOrUnset) { return SetFlag(PREF_FLAG_STICKY_DEFAULT, aSetOrUnset); }
|
||||
|
||||
bool IsLocked() const { return mValue & PREF_FLAG_LOCKED; }
|
||||
PrefTypeFlags& SetLocked(bool aSetOrUnset) { return SetFlag(PREF_FLAG_LOCKED, aSetOrUnset); }
|
||||
|
||||
bool HasUserValue() const { return mValue & PREF_FLAG_USERSET; }
|
||||
PrefTypeFlags& SetHasUserValue(bool aSetOrUnset) { return SetFlag(PREF_FLAG_USERSET, aSetOrUnset); }
|
||||
|
||||
private:
|
||||
static uint16_t AsInt(PrefType aType) { return (uint16_t)aType; }
|
||||
|
||||
PrefTypeFlags& SetFlag(uint16_t aFlag, bool aSetOrUnset) {
|
||||
mValue = aSetOrUnset ? mValue | aFlag : mValue & ~aFlag;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Pack both the value of type (PrefType) and flags into the same int. This is why
|
||||
// the flag enum starts at 4, as PrefType occupies the bottom two bits.
|
||||
enum {
|
||||
PREF_FLAG_LOCKED = 4,
|
||||
PREF_FLAG_USERSET = 8,
|
||||
PREF_FLAG_CONFIG = 16,
|
||||
PREF_FLAG_REMOTE = 32,
|
||||
PREF_FLAG_LILOCAL = 64,
|
||||
PREF_FLAG_HAS_DEFAULT = 128,
|
||||
PREF_FLAG_STICKY_DEFAULT = 256,
|
||||
};
|
||||
uint16_t mValue;
|
||||
};
|
||||
|
||||
struct PrefHashEntry : PLDHashEntryHdr
|
||||
{
|
||||
PrefTypeFlags prefFlags; // This field goes first to minimize struct size on 64-bit.
|
||||
const char *key;
|
||||
PrefValue defaultPref;
|
||||
PrefValue userPref;
|
||||
};
|
||||
|
||||
/*
|
||||
// <font color=blue>
|
||||
// Set the various types of preferences. These functions take a dotted
|
||||
// notation of the preference name (e.g. "browser.startup.homepage").
|
||||
// notation of the preference name (e.g. "browser.startup.homepage").
|
||||
// Note that this will cause the preference to be saved to the file if
|
||||
// it is different from the default. In other words, these are used
|
||||
// to set the _user_ preferences.
|
||||
@ -103,8 +160,8 @@ bool PREF_HasUserPref(const char* pref_name);
|
||||
// </font>
|
||||
*/
|
||||
nsresult PREF_GetIntPref(const char *pref,
|
||||
int32_t * return_int, bool get_default);
|
||||
nsresult PREF_GetBoolPref(const char *pref, bool * return_val, bool get_default);
|
||||
int32_t * return_int, bool get_default);
|
||||
nsresult PREF_GetBoolPref(const char *pref, bool * return_val, bool get_default);
|
||||
/*
|
||||
// <font color=blue>
|
||||
// These functions are similar to the above "Get" version with the significant
|
||||
@ -173,10 +230,10 @@ typedef void (*PrefChangedFunc) (const char *, void *);
|
||||
// matched all the parameters; otherwise it returns PREF_ERROR.
|
||||
// </font>
|
||||
*/
|
||||
void PREF_RegisterCallback( const char* domain,
|
||||
PrefChangedFunc callback, void* instance_data );
|
||||
nsresult PREF_UnregisterCallback( const char* domain,
|
||||
PrefChangedFunc callback, void* instance_data );
|
||||
void PREF_RegisterCallback(const char* domain,
|
||||
PrefChangedFunc callback, void* instance_data );
|
||||
nsresult PREF_UnregisterCallback(const char* domain,
|
||||
PrefChangedFunc callback, void* instance_data );
|
||||
|
||||
/*
|
||||
* Used by nsPrefService as the callback function of the 'pref' parser
|
||||
|
@ -114,17 +114,17 @@ pref_DoCallback(PrefParseState *ps)
|
||||
PrefValue value;
|
||||
|
||||
switch (ps->vtype) {
|
||||
case PREF_STRING:
|
||||
case PrefType::String:
|
||||
value.stringVal = ps->vb;
|
||||
break;
|
||||
case PREF_INT:
|
||||
case PrefType::Int:
|
||||
if ((ps->vb[0] == '-' || ps->vb[0] == '+') && ps->vb[1] == '\0') {
|
||||
NS_WARNING("malformed integer value");
|
||||
return false;
|
||||
}
|
||||
value.intVal = atoi(ps->vb);
|
||||
break;
|
||||
case PREF_BOOL:
|
||||
case PrefType::Bool:
|
||||
value.boolVal = (ps->vb == kTrue);
|
||||
break;
|
||||
default:
|
||||
@ -154,7 +154,7 @@ PREF_FinalizeParseState(PrefParseState *ps)
|
||||
* Pseudo-BNF
|
||||
* ----------
|
||||
* function = LJUNK function-name JUNK function-args
|
||||
* function-name = "user_pref" | "pref"
|
||||
* function-name = "user_pref" | "pref" | "sticky_pref"
|
||||
* function-args = "(" JUNK pref-name JUNK "," JUNK pref-value JUNK ")" JUNK ";"
|
||||
* pref-name = quoted-string
|
||||
* pref-value = quoted-string | "true" | "false" | integer-value
|
||||
@ -188,7 +188,7 @@ PREF_ParseBuf(PrefParseState *ps, const char *buf, int bufLen)
|
||||
if (ps->lbcur != ps->lb) { /* reset state */
|
||||
ps->lbcur = ps->lb;
|
||||
ps->vb = nullptr;
|
||||
ps->vtype = PREF_INVALID;
|
||||
ps->vtype = PrefType::Invalid;
|
||||
ps->fdefault = false;
|
||||
ps->fstickydefault = false;
|
||||
}
|
||||
@ -200,10 +200,15 @@ PREF_ParseBuf(PrefParseState *ps, const char *buf, int bufLen)
|
||||
state = PREF_PARSE_UNTIL_EOL;
|
||||
break;
|
||||
case 'u': /* indicating user_pref */
|
||||
case 'p': /* indicating pref */
|
||||
case 's': /* indicating sticky_pref */
|
||||
ps->smatch = (c == 'u' ? kUserPref :
|
||||
(c == 's' ? kPrefSticky : kPref));
|
||||
case 'p': /* indicating pref */
|
||||
if (c == 'u') {
|
||||
ps->smatch = kUserPref;
|
||||
} else if (c == 's') {
|
||||
ps->smatch = kPrefSticky;
|
||||
} else {
|
||||
ps->smatch = kPref;
|
||||
}
|
||||
ps->sindex = 1;
|
||||
ps->nextstate = PREF_PARSE_UNTIL_OPEN_PAREN;
|
||||
state = PREF_PARSE_MATCH_STRING;
|
||||
@ -248,6 +253,8 @@ PREF_ParseBuf(PrefParseState *ps, const char *buf, int bufLen)
|
||||
case PREF_PARSE_UNTIL_NAME:
|
||||
if (c == '\"' || c == '\'') {
|
||||
ps->fdefault = (ps->smatch == kPref || ps->smatch == kPrefSticky);
|
||||
ps->fdefault = (ps->smatch == kPref ||
|
||||
ps->smatch == kPrefSticky);
|
||||
ps->fstickydefault = (ps->smatch == kPrefSticky);
|
||||
ps->quotechar = c;
|
||||
ps->nextstate = PREF_PARSE_UNTIL_COMMA; /* return here when done */
|
||||
@ -284,21 +291,21 @@ PREF_ParseBuf(PrefParseState *ps, const char *buf, int bufLen)
|
||||
/* the pref value type is unknown. so, we scan for the first
|
||||
* character of the value, and determine the type from that. */
|
||||
if (c == '\"' || c == '\'') {
|
||||
ps->vtype = PREF_STRING;
|
||||
ps->vtype = PrefType::String;
|
||||
ps->quotechar = c;
|
||||
ps->nextstate = PREF_PARSE_UNTIL_CLOSE_PAREN;
|
||||
state = PREF_PARSE_QUOTED_STRING;
|
||||
}
|
||||
else if (c == 't' || c == 'f') {
|
||||
ps->vb = (char *) (c == 't' ? kTrue : kFalse);
|
||||
ps->vtype = PREF_BOOL;
|
||||
ps->vtype = PrefType::Bool;
|
||||
ps->smatch = ps->vb;
|
||||
ps->sindex = 1;
|
||||
ps->nextstate = PREF_PARSE_UNTIL_CLOSE_PAREN;
|
||||
state = PREF_PARSE_MATCH_STRING;
|
||||
}
|
||||
else if (isdigit(c) || (c == '-') || (c == '+')) {
|
||||
ps->vtype = PREF_INT;
|
||||
ps->vtype = PrefType::Int;
|
||||
/* write c to line buffer... */
|
||||
if (ps->lbcur == ps->lbend && !pref_GrowBuf(ps))
|
||||
return false; /* out of memory */
|
||||
@ -511,13 +518,12 @@ PREF_ParseBuf(PrefParseState *ps, const char *buf, int bufLen)
|
||||
break;
|
||||
case PREF_PARSE_UNTIL_CLOSE_PAREN:
|
||||
/* tolerate only whitespace and embedded comments */
|
||||
if (c == ')')
|
||||
if (c == ')') {
|
||||
state = PREF_PARSE_UNTIL_SEMICOLON;
|
||||
else if (c == '/') {
|
||||
} else if (c == '/') {
|
||||
ps->nextstate = state; /* return here when done with comment */
|
||||
state = PREF_PARSE_COMMENT_MAYBE_START;
|
||||
}
|
||||
else if (!isspace(c)) {
|
||||
} else if (!isspace(c)) {
|
||||
NS_WARNING("malformed pref file");
|
||||
return false;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ typedef struct PrefParseState {
|
||||
char *lbend; /* line buffer end */
|
||||
char *vb; /* value buffer (ptr into lb) */
|
||||
PrefType vtype; /* PREF_STRING,INT,BOOL */
|
||||
bool fdefault; /* true if (default) pref */
|
||||
bool fdefault; /* true if (default) pref */
|
||||
bool fstickydefault; /* true if (sticky) pref */
|
||||
} PrefParseState;
|
||||
|
||||
|
@ -37,7 +37,7 @@ inline size_t Store16(uint8_t* dst, size_t offset, int x) {
|
||||
*reinterpret_cast<uint16_t*>(dst + offset) =
|
||||
((x & 0xFF) << 8) | ((x & 0xFF00) >> 8);
|
||||
#elif (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||||
*reinterpret_cast<uint16_t*>(dst + offset) = reinterpret_cast<uint16_t>(x);
|
||||
*reinterpret_cast<uint16_t*>(dst + offset) = static_cast<uint16_t>(x);
|
||||
#else
|
||||
dst[offset] = x >> 8;
|
||||
dst[offset + 1] = x;
|
||||
@ -59,7 +59,7 @@ inline void Store16(int val, size_t* offset, uint8_t* dst) {
|
||||
*offset += 2;
|
||||
#elif (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||||
*reinterpret_cast<uint16_t*>(dst + *offset) =
|
||||
reinterpret_cast<uint16_t>(val);
|
||||
static_cast<uint16_t>(val);
|
||||
*offset += 2;
|
||||
#else
|
||||
dst[(*offset)++] = val >> 8;
|
||||
|
@ -545,7 +545,6 @@ already_AddRefed<CacheEntryHandle> CacheEntry::ReopenTruncated(bool aMemoryOnly,
|
||||
mUseDisk && !aMemoryOnly,
|
||||
mSkipSizeCheck,
|
||||
mPinned,
|
||||
true, // always create
|
||||
true, // truncate existing (this one)
|
||||
getter_AddRefs(handle));
|
||||
|
||||
@ -1072,13 +1071,12 @@ NS_IMETHODIMP CacheEntry::GetIsForcedValid(bool *aIsForcedValid)
|
||||
}
|
||||
|
||||
nsAutoCString key;
|
||||
|
||||
nsresult rv = HashingKeyWithStorage(key);
|
||||
nsresult rv = HashingKey(key);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
*aIsForcedValid = CacheStorageService::Self()->IsForcedValidEntry(key);
|
||||
*aIsForcedValid = CacheStorageService::Self()->IsForcedValidEntry(mStorageID, key);
|
||||
LOG(("CacheEntry::GetIsForcedValid [this=%p, IsForcedValid=%d]", this, *aIsForcedValid));
|
||||
|
||||
return NS_OK;
|
||||
@ -1089,12 +1087,12 @@ NS_IMETHODIMP CacheEntry::ForceValidFor(uint32_t aSecondsToTheFuture)
|
||||
LOG(("CacheEntry::ForceValidFor [this=%p, aSecondsToTheFuture=%d]", this, aSecondsToTheFuture));
|
||||
|
||||
nsAutoCString key;
|
||||
nsresult rv = HashingKeyWithStorage(key);
|
||||
nsresult rv = HashingKey(key);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
CacheStorageService::Self()->ForceEntryValidFor(key, aSecondsToTheFuture);
|
||||
CacheStorageService::Self()->ForceEntryValidFor(mStorageID, key, aSecondsToTheFuture);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1325,6 +1323,8 @@ NS_IMETHODIMP CacheEntry::AsyncDoom(nsICacheEntryDoomCallback *aCallback)
|
||||
if (mIsDoomed || mDoomCallback)
|
||||
return NS_ERROR_IN_PROGRESS; // to aggregate have DOOMING state
|
||||
|
||||
RemoveForcedValidity();
|
||||
|
||||
mIsDoomed = true;
|
||||
mDoomCallback = aCallback;
|
||||
}
|
||||
@ -1623,6 +1623,8 @@ void CacheEntry::DoomAlreadyRemoved()
|
||||
|
||||
mozilla::MutexAutoLock lock(mLock);
|
||||
|
||||
RemoveForcedValidity();
|
||||
|
||||
mIsDoomed = true;
|
||||
|
||||
// Pretend pinning is know. This entry is now doomed for good, so don't
|
||||
@ -1666,6 +1668,25 @@ void CacheEntry::DoomFile()
|
||||
OnFileDoomed(rv);
|
||||
}
|
||||
|
||||
void CacheEntry::RemoveForcedValidity()
|
||||
{
|
||||
mLock.AssertCurrentThreadOwns();
|
||||
|
||||
nsresult rv;
|
||||
|
||||
if (mIsDoomed) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString entryKey;
|
||||
rv = HashingKey(entryKey);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
CacheStorageService::Self()->RemoveEntryForceValid(mStorageID, entryKey);
|
||||
}
|
||||
|
||||
void CacheEntry::BackgroundOp(uint32_t aOperations, bool aForceAsync)
|
||||
{
|
||||
mLock.AssertCurrentThreadOwns();
|
||||
|
@ -266,6 +266,9 @@ private:
|
||||
|
||||
// Called only from DoomAlreadyRemoved()
|
||||
void DoomFile();
|
||||
// When this entry is doomed the first time, this method removes
|
||||
// any force-valid timing info for this entry.
|
||||
void RemoveForcedValidity();
|
||||
|
||||
already_AddRefed<CacheEntryHandle> ReopenTruncated(bool aMemoryOnly,
|
||||
nsICacheEntryOpenCallback* aCallback);
|
||||
|
@ -104,7 +104,6 @@ NS_IMETHODIMP CacheStorage::AsyncOpenURI(nsIURI *aURI,
|
||||
RefPtr<CacheEntryHandle> entry;
|
||||
rv = CacheStorageService::Self()->AddStorageEntry(
|
||||
this, noRefURI, aIdExtension,
|
||||
true, // create always
|
||||
truncate, // replace any existing one?
|
||||
getter_AddRefs(entry));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -131,7 +130,6 @@ NS_IMETHODIMP CacheStorage::OpenTruncate(nsIURI *aURI, const nsACString & aIdExt
|
||||
RefPtr<CacheEntryHandle> handle;
|
||||
rv = CacheStorageService::Self()->AddStorageEntry(
|
||||
this, noRefURI, aIdExtension,
|
||||
true, // create always
|
||||
true, // replace any existing one
|
||||
getter_AddRefs(handle));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -769,6 +769,11 @@ NS_IMETHODIMP CacheStorageService::Clear()
|
||||
{
|
||||
mozilla::MutexAutoLock lock(mLock);
|
||||
|
||||
{
|
||||
mozilla::MutexAutoLock forcedValidEntriesLock(mForcedValidEntriesLock);
|
||||
mForcedValidEntries.Clear();
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(!mShutdown, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsTArray<nsCString> keys;
|
||||
@ -1021,7 +1026,7 @@ CacheStorageService::RemoveEntry(CacheEntry* aEntry, bool aOnlyUnreferenced)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aEntry->IsUsingDisk() && IsForcedValidEntry(entryKey)) {
|
||||
if (!aEntry->IsUsingDisk() && IsForcedValidEntry(aEntry->GetStorageID(), entryKey)) {
|
||||
LOG((" forced valid, not removing"));
|
||||
return false;
|
||||
}
|
||||
@ -1094,13 +1099,19 @@ CacheStorageService::RecordMemoryOnlyEntry(CacheEntry* aEntry,
|
||||
|
||||
// Checks if a cache entry is forced valid (will be loaded directly from cache
|
||||
// without further validation) - see nsICacheEntry.idl for further details
|
||||
bool CacheStorageService::IsForcedValidEntry(nsACString &aCacheEntryKey)
|
||||
bool CacheStorageService::IsForcedValidEntry(nsACString const &aContextKey,
|
||||
nsACString const &aEntryKey)
|
||||
{
|
||||
return IsForcedValidEntry(aContextKey + aEntryKey);
|
||||
}
|
||||
|
||||
bool CacheStorageService::IsForcedValidEntry(nsACString const &aContextEntryKey)
|
||||
{
|
||||
mozilla::MutexAutoLock lock(mForcedValidEntriesLock);
|
||||
|
||||
TimeStamp validUntil;
|
||||
|
||||
if (!mForcedValidEntries.Get(aCacheEntryKey, &validUntil)) {
|
||||
if (!mForcedValidEntries.Get(aContextEntryKey, &validUntil)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1114,13 +1125,14 @@ bool CacheStorageService::IsForcedValidEntry(nsACString &aCacheEntryKey)
|
||||
}
|
||||
|
||||
// Entry timeout has been reached
|
||||
mForcedValidEntries.Remove(aCacheEntryKey);
|
||||
mForcedValidEntries.Remove(aContextEntryKey);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allows a cache entry to be loaded directly from cache without further
|
||||
// validation - see nsICacheEntry.idl for further details
|
||||
void CacheStorageService::ForceEntryValidFor(nsACString &aCacheEntryKey,
|
||||
void CacheStorageService::ForceEntryValidFor(nsACString const &aContextKey,
|
||||
nsACString const &aEntryKey,
|
||||
uint32_t aSecondsToTheFuture)
|
||||
{
|
||||
mozilla::MutexAutoLock lock(mForcedValidEntriesLock);
|
||||
@ -1131,7 +1143,15 @@ void CacheStorageService::ForceEntryValidFor(nsACString &aCacheEntryKey,
|
||||
// This will be the timeout
|
||||
TimeStamp validUntil = now + TimeDuration::FromSeconds(aSecondsToTheFuture);
|
||||
|
||||
mForcedValidEntries.Put(aCacheEntryKey, validUntil);
|
||||
mForcedValidEntries.Put(aContextKey + aEntryKey, validUntil);
|
||||
}
|
||||
|
||||
void CacheStorageService::RemoveEntryForceValid(nsACString const &aContextKey,
|
||||
nsACString const &aEntryKey)
|
||||
{
|
||||
mozilla::MutexAutoLock lock(mForcedValidEntriesLock);
|
||||
|
||||
mForcedValidEntries.Remove(aContextKey + aEntryKey);
|
||||
}
|
||||
|
||||
// Cleans out the old entries in mForcedValidEntries
|
||||
@ -1378,7 +1398,6 @@ nsresult
|
||||
CacheStorageService::AddStorageEntry(CacheStorage const* aStorage,
|
||||
nsIURI* aURI,
|
||||
const nsACString & aIdExtension,
|
||||
bool aCreateIfNotExist,
|
||||
bool aReplace,
|
||||
CacheEntryHandle** aResult)
|
||||
{
|
||||
@ -1393,7 +1412,7 @@ CacheStorageService::AddStorageEntry(CacheStorage const* aStorage,
|
||||
aStorage->WriteToDisk(),
|
||||
aStorage->SkipSizeCheck(),
|
||||
aStorage->Pinning(),
|
||||
aCreateIfNotExist, aReplace,
|
||||
aReplace,
|
||||
aResult);
|
||||
}
|
||||
|
||||
@ -1404,7 +1423,6 @@ CacheStorageService::AddStorageEntry(nsCSubstring const& aContextKey,
|
||||
bool aWriteToDisk,
|
||||
bool aSkipSizeCheck,
|
||||
bool aPin,
|
||||
bool aCreateIfNotExist,
|
||||
bool aReplace,
|
||||
CacheEntryHandle** aResult)
|
||||
{
|
||||
@ -1440,7 +1458,7 @@ CacheStorageService::AddStorageEntry(nsCSubstring const& aContextKey,
|
||||
if (entryExists && !aReplace) {
|
||||
// check whether we want to turn this entry to a memory-only.
|
||||
if (MOZ_UNLIKELY(!aWriteToDisk) && MOZ_LIKELY(entry->IsUsingDisk())) {
|
||||
LOG((" entry is persistnet but we want mem-only, replacing it"));
|
||||
LOG((" entry is persistent but we want mem-only, replacing it"));
|
||||
aReplace = true;
|
||||
}
|
||||
}
|
||||
@ -1457,10 +1475,20 @@ CacheStorageService::AddStorageEntry(nsCSubstring const& aContextKey,
|
||||
|
||||
entry = nullptr;
|
||||
entryExists = false;
|
||||
|
||||
// Would only lead to deleting force-valid timestamp again. We don't need the
|
||||
// replace information anymore after this point anyway.
|
||||
aReplace = false;
|
||||
}
|
||||
|
||||
// Ensure entry for the particular URL, if not read/only
|
||||
if (!entryExists && (aCreateIfNotExist || aReplace)) {
|
||||
// Ensure entry for the particular URL
|
||||
if (!entryExists) {
|
||||
// When replacing with a new entry, always remove the current force-valid timestamp,
|
||||
// this is the only place to do it.
|
||||
if (aReplace) {
|
||||
RemoveEntryForceValid(aContextKey, entryKey);
|
||||
}
|
||||
|
||||
// Entry is not in the hashtable or has just been truncated...
|
||||
entry = new CacheEntry(aContextKey, aURI, aIdExtension, aWriteToDisk, aSkipSizeCheck, aPin);
|
||||
entries->Put(entryKey, entry);
|
||||
@ -1639,6 +1667,10 @@ CacheStorageService::DoomStorageEntry(CacheStorage const* aStorage,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!entry) {
|
||||
RemoveEntryForceValid(contextKey, entryKey);
|
||||
}
|
||||
}
|
||||
|
||||
if (entry) {
|
||||
@ -1764,6 +1796,21 @@ CacheStorageService::DoomStorageEntries(nsCSubstring const& aContextKey,
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
mozilla::MutexAutoLock lock(mForcedValidEntriesLock);
|
||||
|
||||
for (auto iter = mForcedValidEntries.Iter(); !iter.Done(); iter.Next()) {
|
||||
bool matches;
|
||||
DebugOnly<nsresult> rv = CacheFileUtils::KeyMatchesLoadContextInfo(
|
||||
iter.Key(), aContext, &matches);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
if (matches) {
|
||||
iter.Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// An artificial callback. This is a candidate for removal tho. In the new
|
||||
// cache any 'doom' or 'evict' function ensures that the entry or entries
|
||||
// being doomed is/are not accessible after the function returns. So there is
|
||||
@ -1824,24 +1871,28 @@ CacheStorageService::CacheFileDoomed(nsILoadContextInfo* aLoadContextInfo,
|
||||
|
||||
mozilla::MutexAutoLock lock(mLock);
|
||||
|
||||
if (mShutdown)
|
||||
if (mShutdown) {
|
||||
return;
|
||||
}
|
||||
|
||||
CacheEntryTable* entries;
|
||||
if (!sGlobalEntryTables->Get(contextKey, &entries))
|
||||
return;
|
||||
|
||||
RefPtr<CacheEntry> entry;
|
||||
if (!entries->Get(entryKey, getter_AddRefs(entry)))
|
||||
return;
|
||||
|
||||
if (!entry->IsFileDoomed())
|
||||
return;
|
||||
if (sGlobalEntryTables->Get(contextKey, &entries) &&
|
||||
entries->Get(entryKey, getter_AddRefs(entry))) {
|
||||
if (entry->IsFileDoomed()) {
|
||||
// Need to remove under the lock to avoid possible race leading
|
||||
// to duplication of the entry per its key.
|
||||
RemoveExactEntry(entries, entryKey, entry, false);
|
||||
entry->DoomAlreadyRemoved();
|
||||
}
|
||||
|
||||
// Need to remove under the lock to avoid possible race leading
|
||||
// to duplication of the entry per its key.
|
||||
RemoveExactEntry(entries, entryKey, entry, false);
|
||||
entry->DoomAlreadyRemoved();
|
||||
// Entry found, but it's not the entry that has been found doomed
|
||||
// by the lower eviction layer. Just leave everything unchanged.
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveEntryForceValid(contextKey, entryKey);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -158,23 +158,35 @@ private:
|
||||
* directly from cache) for the given number of seconds
|
||||
* See nsICacheEntry.idl for more details
|
||||
*/
|
||||
void ForceEntryValidFor(nsACString &aCacheEntryKey,
|
||||
void ForceEntryValidFor(nsACString const &aContextKey,
|
||||
nsACString const &aEntryKey,
|
||||
uint32_t aSecondsToTheFuture);
|
||||
|
||||
/**
|
||||
* Remove the validity info
|
||||
*/
|
||||
void RemoveEntryForceValid(nsACString const &aContextKey,
|
||||
nsACString const &aEntryKey);
|
||||
|
||||
/**
|
||||
* Retrieves the status of the cache entry to see if it has been forced valid
|
||||
* (so it will loaded directly from cache without further validation)
|
||||
*/
|
||||
bool IsForcedValidEntry(nsACString const &aContextKey,
|
||||
nsACString const &aEntryKey);
|
||||
|
||||
private:
|
||||
friend class CacheIndex;
|
||||
|
||||
/**
|
||||
* Retrieves the status of the cache entry to see if it has been forced valid
|
||||
* (so it will loaded directly from cache without further validation)
|
||||
* CacheIndex uses this to prevent a cache entry from being prememptively
|
||||
* thrown away when forced valid
|
||||
* See nsICacheEntry.idl for more details
|
||||
*/
|
||||
bool IsForcedValidEntry(nsACString &aCacheEntryKey);
|
||||
bool IsForcedValidEntry(nsACString const &aEntryKeyWithContext);
|
||||
|
||||
private:
|
||||
// These are helpers for telemetry monitorying of the memory pools.
|
||||
// These are helpers for telemetry monitoring of the memory pools.
|
||||
void TelemetryPrune(TimeStamp &now);
|
||||
void TelemetryRecordEntryCreation(CacheEntry const* entry);
|
||||
void TelemetryRecordEntryRemoval(CacheEntry const* entry);
|
||||
@ -190,7 +202,6 @@ private:
|
||||
nsresult AddStorageEntry(CacheStorage const* aStorage,
|
||||
nsIURI* aURI,
|
||||
const nsACString & aIdExtension,
|
||||
bool aCreateIfNotExist,
|
||||
bool aReplace,
|
||||
CacheEntryHandle** aResult);
|
||||
|
||||
@ -286,7 +297,6 @@ private:
|
||||
bool aWriteToDisk,
|
||||
bool aSkipSizeCheck,
|
||||
bool aPin,
|
||||
bool aCreateIfNotExist,
|
||||
bool aReplace,
|
||||
CacheEntryHandle** aResult);
|
||||
|
||||
|
@ -377,7 +377,7 @@ class BuildMonitor(MozbuildObject):
|
||||
'Swap in/out (MB): {sin}/{sout}')
|
||||
|
||||
o = dict(
|
||||
version=2,
|
||||
version=3,
|
||||
argv=sys.argv,
|
||||
start=self.start_time,
|
||||
end=self.end_time,
|
||||
@ -411,22 +411,15 @@ class BuildMonitor(MozbuildObject):
|
||||
|
||||
o['resources'].append(entry)
|
||||
|
||||
# TODO: it would be nice to collect data on the storage device as well
|
||||
o['system'] = dict(
|
||||
architecture=list(platform.architecture()),
|
||||
machine=platform.machine(),
|
||||
python_version=platform.python_version(),
|
||||
release=platform.release(),
|
||||
system=platform.system(),
|
||||
version=platform.version(),
|
||||
)
|
||||
|
||||
# If the imports for this file ran before the in-tree virtualenv
|
||||
# was bootstrapped (for instance, for a clobber build in automation),
|
||||
# psutil might not be available.
|
||||
#
|
||||
# Treat psutil as optional to avoid an outright failure to log resources
|
||||
# TODO: it would be nice to collect data on the storage device as well
|
||||
# in this case.
|
||||
o['system'] = {}
|
||||
if psutil:
|
||||
o['system'].update(dict(
|
||||
logical_cpu_count=psutil.cpu_count(),
|
||||
@ -435,17 +428,6 @@ class BuildMonitor(MozbuildObject):
|
||||
vmem_total=psutil.virtual_memory()[0],
|
||||
))
|
||||
|
||||
if platform.system() == 'Linux':
|
||||
dist = list(platform.linux_distribution())
|
||||
o['system']['linux_distribution'] = dist
|
||||
elif platform.system() == 'Windows':
|
||||
win32_ver=list((platform.win32_ver())),
|
||||
o['system']['win32_ver'] = win32_ver
|
||||
elif platform.system() == 'Darwin':
|
||||
# mac version is a special Cupertino snowflake
|
||||
r, v, m = platform.mac_ver()
|
||||
o['system']['mac_ver'] = [r, list(v), m]
|
||||
|
||||
return o
|
||||
|
||||
def _log_resource_usage(self, prefix, m_type, duration, cpu_percent,
|
||||
|
@ -56,7 +56,7 @@ var currentResources;
|
||||
* Interface for a build resources JSON file.
|
||||
*/
|
||||
function BuildResources(data) {
|
||||
if (data.version != 1 && data.version != 2) {
|
||||
if (data.version < 1 || data.version > 3) {
|
||||
throw new Error("Unsupported version of the JSON format: " + data.version);
|
||||
}
|
||||
|
||||
|
@ -82,8 +82,7 @@ SECStatus
|
||||
IsCertBuiltInRoot(CERTCertificate* cert, bool& result)
|
||||
{
|
||||
result = false;
|
||||
ScopedPK11SlotList slots;
|
||||
slots = PK11_GetAllSlotsForCert(cert, nullptr);
|
||||
UniquePK11SlotList slots(PK11_GetAllSlotsForCert(cert, nullptr));
|
||||
if (!slots) {
|
||||
if (PORT_GetError() == SEC_ERROR_NO_TOKEN) {
|
||||
// no list
|
||||
|
@ -1017,7 +1017,7 @@ LoadLoadableRoots(/*optional*/ const char* dir, const char* modNameUTF8)
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ScopedSECMODModule rootsModule(SECMOD_LoadUserModule(pkcs11ModuleSpec.get(),
|
||||
UniqueSECMODModule rootsModule(SECMOD_LoadUserModule(pkcs11ModuleSpec.get(),
|
||||
nullptr, false));
|
||||
if (!rootsModule) {
|
||||
return SECFailure;
|
||||
@ -1035,7 +1035,7 @@ void
|
||||
UnloadLoadableRoots(const char* modNameUTF8)
|
||||
{
|
||||
PR_ASSERT(modNameUTF8);
|
||||
ScopedSECMODModule rootsModule(SECMOD_FindModule(modNameUTF8));
|
||||
UniqueSECMODModule rootsModule(SECMOD_FindModule(modNameUTF8));
|
||||
|
||||
if (rootsModule) {
|
||||
SECMOD_UnloadUserModule(rootsModule.get());
|
||||
|
@ -6,6 +6,9 @@
|
||||
// Require spacing around =>
|
||||
"arrow-spacing": 2,
|
||||
|
||||
// No space before always a space after a comma
|
||||
"comma-spacing": [2, {"before": false, "after": true}],
|
||||
|
||||
// Commas at the end of the line not the start
|
||||
"comma-style": 2,
|
||||
|
||||
@ -105,6 +108,9 @@
|
||||
// No using with
|
||||
"no-with": 2,
|
||||
|
||||
// Always require semicolon at end of statement
|
||||
"semi": [2, "always"],
|
||||
|
||||
// Require space before blocks
|
||||
"space-before-blocks": 2,
|
||||
|
||||
|
@ -55,14 +55,18 @@ function onCertSelected()
|
||||
|
||||
function doOK()
|
||||
{
|
||||
dialogParams.SetInt(0,1);
|
||||
var index = parseInt(document.getElementById("nicknames").value);
|
||||
// Signal that the user accepted.
|
||||
dialogParams.SetInt(0, 1);
|
||||
|
||||
// Signal the index of the selected cert in the list of cert nicknames
|
||||
// provided.
|
||||
let index = parseInt(document.getElementById("nicknames").value);
|
||||
dialogParams.SetInt(1, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
function doCancel()
|
||||
{
|
||||
dialogParams.SetInt(0,0);
|
||||
dialogParams.SetInt(0, 0); // Signal that the user cancelled.
|
||||
return true;
|
||||
}
|
||||
|
@ -28,15 +28,16 @@ function onLoad()
|
||||
|
||||
function doOK()
|
||||
{
|
||||
var tokenList = document.getElementById("tokens");
|
||||
var token = tokenList.value;
|
||||
dialogParams.SetInt(0,1);
|
||||
dialogParams.SetString(0, token);
|
||||
let tokenList = document.getElementById("tokens");
|
||||
// Signal that the user accepted.
|
||||
dialogParams.SetInt(0, 1);
|
||||
// Signal the name of the token the user chose.
|
||||
dialogParams.SetString(0, tokenList.value);
|
||||
return true;
|
||||
}
|
||||
|
||||
function doCancel()
|
||||
{
|
||||
dialogParams.SetInt(0,0);
|
||||
dialogParams.SetInt(0, 0); // Signal that the user cancelled.
|
||||
return true;
|
||||
}
|
||||
|
@ -80,17 +80,24 @@ function onCertSelected()
|
||||
|
||||
function doOK()
|
||||
{
|
||||
dialogParams.SetInt(0,1);
|
||||
var index = parseInt(document.getElementById("nicknames").value);
|
||||
// Signal that the user accepted.
|
||||
dialogParams.SetInt(0, 1);
|
||||
let index = parseInt(document.getElementById("nicknames").value);
|
||||
// Signal the index of the selected cert in the list of cert nicknames
|
||||
// provided.
|
||||
dialogParams.SetInt(1, index);
|
||||
// Signal whether the user wanted to remember the selection.
|
||||
dialogParams.SetInt(2, rememberBox.checked);
|
||||
return true;
|
||||
}
|
||||
|
||||
function doCancel()
|
||||
{
|
||||
dialogParams.SetInt(0,0);
|
||||
// Signal that the user cancelled.
|
||||
dialogParams.SetInt(0, 0);
|
||||
// Signal some invalid index value since a cert hasn't actually been chosen.
|
||||
dialogParams.SetInt(1, -1); // invalid value
|
||||
// Signal whether the user wanted to remember the "selection".
|
||||
dialogParams.SetInt(2, rememberBox.checked);
|
||||
return true;
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ function setWindowName()
|
||||
var impactReference = document.getElementById('impact');
|
||||
document.title = title;
|
||||
|
||||
setText("confirm",confirm);
|
||||
setText("confirm", confirm);
|
||||
|
||||
let box = document.getElementById("certlist");
|
||||
for (let x = 0; x < numberOfCerts; x++) {
|
||||
@ -71,7 +71,7 @@ function setWindowName()
|
||||
box.appendChild(listItem);
|
||||
}
|
||||
|
||||
setText("impact",impact);
|
||||
setText("impact", impact);
|
||||
}
|
||||
|
||||
function doOK()
|
||||
|
@ -468,7 +468,7 @@ function doLoadDevice()
|
||||
var name_box = document.getElementById("device_name");
|
||||
var path_box = document.getElementById("device_path");
|
||||
try {
|
||||
getPKCS11().addModule(name_box.value, path_box.value, 0,0);
|
||||
getPKCS11().addModule(name_box.value, path_box.value, 0, 0);
|
||||
} catch (e) {
|
||||
if (e.result == Components.results.NS_ERROR_ILLEGAL_VALUE) {
|
||||
doPrompt(getNSSString("AddModuleDup"));
|
||||
|
@ -48,6 +48,6 @@ function doOK()
|
||||
|
||||
function doCancel()
|
||||
{
|
||||
params.SetInt(1,0);
|
||||
params.SetInt(1, 0); // Signal that the user cancelled.
|
||||
return true;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ badCertListener.prototype = {
|
||||
this.handle_test_result();
|
||||
return true; // suppress error UI
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function initExceptionDialog() {
|
||||
gNeedReset = false;
|
||||
|
@ -65,7 +65,7 @@ function onLoad()
|
||||
var sel = document.getElementById("tokenMenu");
|
||||
sel.setAttribute("hidden", "true");
|
||||
var tag = document.getElementById("tokenName");
|
||||
tag.setAttribute("value",tokenName);
|
||||
tag.setAttribute("value", tokenName);
|
||||
}
|
||||
|
||||
process();
|
||||
|
@ -21,7 +21,7 @@ function setText(id, value) {
|
||||
}
|
||||
|
||||
const nsICertificateDialogs = Components.interfaces.nsICertificateDialogs;
|
||||
const nsCertificateDialogs = "@mozilla.org/nsCertificateDialogs;1"
|
||||
const nsCertificateDialogs = "@mozilla.org/nsCertificateDialogs;1";
|
||||
|
||||
function viewCertHelper(parent, cert) {
|
||||
if (!cert) {
|
||||
|
@ -11,7 +11,7 @@ const nsIASN1Object = Components.interfaces.nsIASN1Object;
|
||||
const nsIASN1Sequence = Components.interfaces.nsIASN1Sequence;
|
||||
const nsIASN1PrintableItem = Components.interfaces.nsIASN1PrintableItem;
|
||||
const nsIASN1Tree = Components.interfaces.nsIASN1Tree;
|
||||
const nsASN1Tree = "@mozilla.org/security/nsASN1Tree;1"
|
||||
const nsASN1Tree = "@mozilla.org/security/nsASN1Tree;1";
|
||||
const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
|
||||
|
||||
var bundle;
|
||||
@ -23,12 +23,19 @@ function doPrompt(msg)
|
||||
prompts.alert(window, null, msg);
|
||||
}
|
||||
|
||||
function AddCertChain(node, chain, idPrefix)
|
||||
/**
|
||||
* Fills out the "Certificate Hierarchy" tree of the cert viewer "Details" tab.
|
||||
*
|
||||
* @param {tree} node
|
||||
* Parent tree node to append to.
|
||||
* @param {nsIArray<nsIX509Cert>} chain
|
||||
* Chain where cert element n is issued by cert element n + 1.
|
||||
*/
|
||||
function AddCertChain(node, chain)
|
||||
{
|
||||
var child = document.getElementById(node);
|
||||
var currCert;
|
||||
var displayVal;
|
||||
var addTwistie;
|
||||
for (let i = chain.length - 1; i >= 0; i--) {
|
||||
currCert = chain.queryElementAt(i, nsIX509Cert);
|
||||
if (currCert.commonName) {
|
||||
@ -36,18 +43,22 @@ function AddCertChain(node, chain, idPrefix)
|
||||
} else {
|
||||
displayVal = currCert.windowTitle;
|
||||
}
|
||||
if (0 == i) {
|
||||
addTwistie = false;
|
||||
} else {
|
||||
addTwistie = true;
|
||||
}
|
||||
child = addChildrenToTree(child, displayVal, currCert.dbKey,addTwistie);
|
||||
let addTwistie = i != 0;
|
||||
child = addChildrenToTree(child, displayVal, currCert.dbKey, addTwistie);
|
||||
}
|
||||
}
|
||||
|
||||
function AddUsage(usage,verifyInfoBox)
|
||||
/**
|
||||
* Adds a "verified usage" of a cert to the "General" tab of the cert viewer.
|
||||
*
|
||||
* @param {String} usage
|
||||
* Verified usage to add.
|
||||
* @param {Node} verifyInfoBox
|
||||
* Parent node to append to.
|
||||
*/
|
||||
function AddUsage(usage, verifyInfoBox)
|
||||
{
|
||||
var text = document.createElement("textbox");
|
||||
let text = document.createElement("textbox");
|
||||
text.setAttribute("value", usage);
|
||||
text.setAttribute("style", "margin: 2px 5px");
|
||||
text.setAttribute("readonly", "true");
|
||||
@ -86,33 +97,33 @@ function setWindowName()
|
||||
//
|
||||
|
||||
// The chain of trust
|
||||
var chain = cert.getChain();
|
||||
AddCertChain("treesetDump", chain, "dump_");
|
||||
AddCertChain("treesetDump", cert.getChain());
|
||||
DisplayGeneralDataFromCert(cert);
|
||||
BuildPrettyPrint(cert);
|
||||
cert.requestUsagesArrayAsync(new listener());
|
||||
}
|
||||
|
||||
function addChildrenToTree(parentTree,label,value,addTwistie)
|
||||
function addChildrenToTree(parentTree, label, value, addTwistie)
|
||||
{
|
||||
var treeChild1 = document.createElement("treechildren");
|
||||
var treeElement = addTreeItemToTreeChild(treeChild1,label,value,addTwistie);
|
||||
let treeChild1 = document.createElement("treechildren");
|
||||
let treeElement = addTreeItemToTreeChild(treeChild1, label, value,
|
||||
addTwistie);
|
||||
parentTree.appendChild(treeChild1);
|
||||
return treeElement;
|
||||
}
|
||||
|
||||
function addTreeItemToTreeChild(treeChild,label,value,addTwistie)
|
||||
function addTreeItemToTreeChild(treeChild, label, value, addTwistie)
|
||||
{
|
||||
var treeElem1 = document.createElement("treeitem");
|
||||
let treeElem1 = document.createElement("treeitem");
|
||||
if (addTwistie) {
|
||||
treeElem1.setAttribute("container","true");
|
||||
treeElem1.setAttribute("open","true");
|
||||
treeElem1.setAttribute("container", "true");
|
||||
treeElem1.setAttribute("open", "true");
|
||||
}
|
||||
var treeRow = document.createElement("treerow");
|
||||
var treeCell = document.createElement("treecell");
|
||||
treeCell.setAttribute("label",label);
|
||||
let treeRow = document.createElement("treerow");
|
||||
let treeCell = document.createElement("treecell");
|
||||
treeCell.setAttribute("label", label);
|
||||
if (value) {
|
||||
treeCell.setAttribute("display",value);
|
||||
treeCell.setAttribute("display", value);
|
||||
}
|
||||
treeRow.appendChild(treeCell);
|
||||
treeElem1.appendChild(treeRow);
|
||||
@ -163,12 +174,12 @@ listener.prototype.QueryInterface =
|
||||
}
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
};
|
||||
|
||||
listener.prototype.notify =
|
||||
function(cert, result) {
|
||||
DisplayVerificationData(cert, result);
|
||||
}
|
||||
};
|
||||
|
||||
function DisplayVerificationData(cert, result)
|
||||
{
|
||||
@ -221,38 +232,31 @@ function DisplayVerificationData(cert, result)
|
||||
if (count > 0) {
|
||||
var verifyInfoBox = document.getElementById('verify_info_box');
|
||||
for (let i = 0; i < count; i++) {
|
||||
AddUsage(usageList[i],verifyInfoBox);
|
||||
AddUsage(usageList[i], verifyInfoBox);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays information about a cert in the "General" tab of the cert viewer.
|
||||
*
|
||||
* @param {nsIX509Cert} cert
|
||||
* Cert to display information about.
|
||||
*/
|
||||
function DisplayGeneralDataFromCert(cert)
|
||||
{
|
||||
// Common Name
|
||||
addAttributeFromCert('commonname', cert.commonName);
|
||||
// Organization
|
||||
addAttributeFromCert('organization', cert.organization);
|
||||
// Organizational Unit
|
||||
addAttributeFromCert('orgunit', cert.organizationalUnit);
|
||||
// Serial Number
|
||||
addAttributeFromCert('serialnumber',cert.serialNumber);
|
||||
// SHA-256 Fingerprint
|
||||
addAttributeFromCert('sha256fingerprint', cert.sha256Fingerprint);
|
||||
// SHA1 Fingerprint
|
||||
addAttributeFromCert('sha1fingerprint',cert.sha1Fingerprint);
|
||||
// Validity start
|
||||
addAttributeFromCert('validitystart', cert.validity.notBeforeLocalDay);
|
||||
// Validity end
|
||||
addAttributeFromCert('validityend', cert.validity.notAfterLocalDay);
|
||||
addAttributeFromCert("commonname", cert.commonName);
|
||||
addAttributeFromCert("organization", cert.organization);
|
||||
addAttributeFromCert("orgunit", cert.organizationalUnit);
|
||||
addAttributeFromCert("serialnumber", cert.serialNumber);
|
||||
addAttributeFromCert("sha256fingerprint", cert.sha256Fingerprint);
|
||||
addAttributeFromCert("sha1fingerprint", cert.sha1Fingerprint);
|
||||
addAttributeFromCert("validitystart", cert.validity.notBeforeLocalDay);
|
||||
addAttributeFromCert("validityend", cert.validity.notAfterLocalDay);
|
||||
|
||||
//Now to populate the fields that correspond to the issuer.
|
||||
var issuerCommonname, issuerOrg, issuerOrgUnit;
|
||||
issuerCommonname = cert.issuerCommonName;
|
||||
issuerOrg = cert.issuerOrganization;
|
||||
issuerOrgUnit = cert.issuerOrganizationUnit;
|
||||
addAttributeFromCert('issuercommonname', issuerCommonname);
|
||||
addAttributeFromCert('issuerorganization', issuerOrg);
|
||||
addAttributeFromCert('issuerorgunit', issuerOrgUnit);
|
||||
addAttributeFromCert("issuercommonname", cert.issuerCommonName);
|
||||
addAttributeFromCert("issuerorganization", cert.issuerOrganization);
|
||||
addAttributeFromCert("issuerorgunit", cert.issuerOrganizationUnit);
|
||||
}
|
||||
|
||||
function updateCertDump()
|
||||
|
@ -1088,7 +1088,7 @@ GatherEKUTelemetry(const ScopedCERTCertList& certList)
|
||||
}
|
||||
|
||||
// Parse the EKU extension
|
||||
ScopedCERTOidSequence ekuSequence(
|
||||
UniqueCERTOidSequence ekuSequence(
|
||||
CERT_DecodeOidSequence(&ekuExtension->value));
|
||||
if (!ekuSequence) {
|
||||
return;
|
||||
|
@ -4,6 +4,9 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// This header provides smart pointers and various helpers for code that needs
|
||||
// to interact with NSS.
|
||||
|
||||
#ifndef mozilla_ScopedNSSTypes_h
|
||||
#define mozilla_ScopedNSSTypes_h
|
||||
|
||||
@ -70,6 +73,7 @@ MapSECStatus(SECStatus rv)
|
||||
}
|
||||
|
||||
// Alphabetical order by NSS type
|
||||
// Deprecated: use the equivalent UniquePtr templates instead.
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc,
|
||||
PRFileDesc,
|
||||
PR_Close)
|
||||
@ -88,25 +92,13 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedCERTCertList,
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedCERTName,
|
||||
CERTName,
|
||||
CERT_DestroyName)
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedCERTOidSequence,
|
||||
CERTOidSequence,
|
||||
CERT_DestroyOidSequence)
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedCERTCertNicknames,
|
||||
CERTCertNicknames,
|
||||
CERT_FreeNicknames)
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedCERTSubjectPublicKeyInfo,
|
||||
CERTSubjectPublicKeyInfo,
|
||||
SECKEY_DestroySubjectPublicKeyInfo)
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedCERTValidity,
|
||||
CERTValidity,
|
||||
CERT_DestroyValidity)
|
||||
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedNSSCMSMessage,
|
||||
NSSCMSMessage,
|
||||
NSS_CMSMessage_Destroy)
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedNSSCMSSignedData,
|
||||
NSSCMSSignedData,
|
||||
NSS_CMSSignedData_Destroy)
|
||||
// Deprecated: use the equivalent UniquePtr templates instead.
|
||||
|
||||
namespace psm {
|
||||
|
||||
@ -115,30 +107,15 @@ PK11_DestroyContext_true(PK11Context * ctx) {
|
||||
PK11_DestroyContext(ctx, true);
|
||||
}
|
||||
|
||||
inline void
|
||||
SGN_DestroyContext_true(SGNContext* ctx) {
|
||||
SGN_DestroyContext(ctx, true);
|
||||
}
|
||||
|
||||
inline void
|
||||
VFY_DestroyContext_true(VFYContext * ctx) {
|
||||
VFY_DestroyContext(ctx, true);
|
||||
}
|
||||
|
||||
} // namespace mozilla::psm
|
||||
|
||||
// Deprecated: use the equivalent UniquePtr templates instead.
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11Context,
|
||||
PK11Context,
|
||||
mozilla::psm::PK11_DestroyContext_true)
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSGNContext,
|
||||
SGNContext,
|
||||
mozilla::psm::SGN_DestroyContext_true)
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSGNDigestInfo,
|
||||
SGNDigestInfo,
|
||||
SGN_DestroyDigestInfo)
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedVFYContext,
|
||||
VFYContext,
|
||||
mozilla::psm::VFY_DestroyContext_true)
|
||||
|
||||
/** A more convenient way of dealing with digests calculated into
|
||||
* stack-allocated buffers. NSS must be initialized on the main thread before
|
||||
@ -231,23 +208,16 @@ private:
|
||||
SECItem item;
|
||||
};
|
||||
|
||||
// Deprecated: use the equivalent UniquePtr templates instead.
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11SlotInfo,
|
||||
PK11SlotInfo,
|
||||
PK11_FreeSlot)
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11SlotList,
|
||||
PK11SlotList,
|
||||
PK11_FreeSlotList)
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11SymKey,
|
||||
PK11SymKey,
|
||||
PK11_FreeSymKey)
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11GenericObject,
|
||||
PK11GenericObject,
|
||||
PK11_DestroyGenericObject)
|
||||
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSEC_PKCS7ContentInfo,
|
||||
SEC_PKCS7ContentInfo,
|
||||
SEC_PKCS7DestroyContentInfo)
|
||||
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSEC_PKCS12DecoderContext,
|
||||
SEC_PKCS12DecoderContext,
|
||||
SEC_PKCS12DecoderFinish)
|
||||
@ -263,6 +233,7 @@ PORT_FreeArena_false(PLArenaPool* arena)
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Deprecated: use the equivalent UniquePtr templates instead.
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPLArenaPool,
|
||||
PLArenaPool,
|
||||
internal::PORT_FreeArena_false)
|
||||
@ -325,10 +296,10 @@ inline void SECKEYEncryptedPrivateKeyInfo_true(SECKEYEncryptedPrivateKeyInfo * e
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Deprecated: use the equivalent UniquePtr templates instead.
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECItem,
|
||||
SECItem,
|
||||
internal::SECITEM_FreeItem_true)
|
||||
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECKEYPrivateKey,
|
||||
SECKEYPrivateKey,
|
||||
SECKEY_DestroyPrivateKey)
|
||||
@ -341,8 +312,6 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECKEYPublicKey,
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECAlgorithmID,
|
||||
SECAlgorithmID,
|
||||
internal::SECOID_DestroyAlgorithmID_true)
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECMODModule, SECMODModule,
|
||||
SECMOD_DestroyModule)
|
||||
|
||||
// Emulates MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE, but for UniquePtrs.
|
||||
#define MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(name, Type, Deleter) \
|
||||
@ -355,21 +324,40 @@ typedef UniquePtr<Type, name##DeletePolicy> name;
|
||||
MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTCertificatePolicies,
|
||||
CERTCertificatePolicies,
|
||||
CERT_DestroyCertificatePoliciesExtension)
|
||||
MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTCertNicknames,
|
||||
CERTCertNicknames,
|
||||
CERT_FreeNicknames)
|
||||
MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTOidSequence,
|
||||
CERTOidSequence,
|
||||
CERT_DestroyOidSequence)
|
||||
MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTUserNotice,
|
||||
CERTUserNotice,
|
||||
CERT_DestroyUserNotice)
|
||||
|
||||
MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueNSSCMSMessage,
|
||||
NSSCMSMessage,
|
||||
NSS_CMSMessage_Destroy)
|
||||
MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueNSSCMSSignedData,
|
||||
NSSCMSSignedData,
|
||||
NSS_CMSSignedData_Destroy)
|
||||
|
||||
MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePK11SlotList,
|
||||
PK11SlotList,
|
||||
PK11_FreeSlotList)
|
||||
|
||||
MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePLArenaPool,
|
||||
PLArenaPool,
|
||||
internal::PORT_FreeArena_false)
|
||||
|
||||
MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueSECItem,
|
||||
SECItem,
|
||||
internal::SECITEM_FreeItem_true)
|
||||
MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueSECKEYPublicKey,
|
||||
SECKEYPublicKey,
|
||||
SECKEY_DestroyPublicKey)
|
||||
MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueSECMODModule,
|
||||
SECMODModule,
|
||||
SECMOD_DestroyModule)
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_ScopedNSSTypes_h
|
||||
|
@ -103,7 +103,8 @@ NS_IMETHODIMP nsCertPicker::PickByUsage(nsIInterfaceRequestor *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
ScopedCERTCertNicknames nicknames(getNSSCertNicknamesFromCertList(certList.get()));
|
||||
UniqueCERTCertNicknames nicknames(
|
||||
getNSSCertNicknamesFromCertList(certList.get()));
|
||||
if (!nicknames) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ nsPkcs11::DeleteModule(const nsAString& aModuleName)
|
||||
// before we call SECMOD_DeleteModule, below.
|
||||
#ifndef MOZ_NO_SMART_CARDS
|
||||
{
|
||||
mozilla::ScopedSECMODModule module(SECMOD_FindModule(moduleName.get()));
|
||||
mozilla::UniqueSECMODModule module(SECMOD_FindModule(moduleName.get()));
|
||||
if (!module) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -100,7 +100,7 @@ nsPkcs11::AddModule(const nsAString& aModuleName,
|
||||
}
|
||||
|
||||
#ifndef MOZ_NO_SMART_CARDS
|
||||
mozilla::ScopedSECMODModule module(SECMOD_FindModule(moduleName.get()));
|
||||
mozilla::UniqueSECMODModule module(SECMOD_FindModule(moduleName.get()));
|
||||
if (!module) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ VerifyCMSDetachedSignatureIncludingCertificate(
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ScopedNSSCMSMessage
|
||||
UniqueNSSCMSMessage
|
||||
cmsMsg(NSS_CMSMessage_CreateFromDER(const_cast<SECItem*>(&buffer), nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr));
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "CertVerifier.h"
|
||||
#include "ExtendedValidation.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "pkix/pkixnss.h"
|
||||
#include "pkix/pkixtypes.h"
|
||||
#include "nsNSSComponent.h" // for PIPNSS string bundle calls.
|
||||
@ -923,14 +924,13 @@ nsNSSCertificate::GetAllTokenNames(uint32_t* aLength, char16_t*** aTokenNames)
|
||||
*aTokenNames = nullptr;
|
||||
|
||||
// Get the slots from NSS
|
||||
ScopedPK11SlotList slots;
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Getting slots for \"%s\"\n", mCert->nickname));
|
||||
slots = PK11_GetAllSlotsForCert(mCert.get(), nullptr);
|
||||
UniquePK11SlotList slots(PK11_GetAllSlotsForCert(mCert.get(), nullptr));
|
||||
if (!slots) {
|
||||
if (PORT_GetError() == SEC_ERROR_NO_TOKEN)
|
||||
if (PORT_GetError() == SEC_ERROR_NO_TOKEN) {
|
||||
return NS_OK; // List of slots is empty, return empty array
|
||||
else
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// read the token names from slots
|
||||
@ -1149,7 +1149,7 @@ nsNSSCertificate::ExportAsCMS(uint32_t chainMode,
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ScopedNSSCMSMessage cmsg(NSS_CMSMessage_Create(nullptr));
|
||||
UniqueNSSCMSMessage cmsg(NSS_CMSMessage_Create(nullptr));
|
||||
if (!cmsg) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("nsNSSCertificate::ExportAsCMS - can't create CMS message\n"));
|
||||
@ -1157,8 +1157,8 @@ nsNSSCertificate::ExportAsCMS(uint32_t chainMode,
|
||||
}
|
||||
|
||||
// first, create SignedData with the certificate only (no chain)
|
||||
ScopedNSSCMSSignedData sigd(
|
||||
NSS_CMSSignedData_CreateCertsOnly(cmsg, mCert.get(), false));
|
||||
UniqueNSSCMSSignedData sigd(
|
||||
NSS_CMSSignedData_CreateCertsOnly(cmsg.get(), mCert.get(), false));
|
||||
if (!sigd) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("nsNSSCertificate::ExportAsCMS - can't create SignedData\n"));
|
||||
@ -1182,7 +1182,7 @@ nsNSSCertificate::ExportAsCMS(uint32_t chainMode,
|
||||
ScopedCERTCertificateList certChain(
|
||||
CERT_CertChainFromCert(issuerCert, certUsageAnyCA, includeRoot));
|
||||
if (certChain) {
|
||||
if (NSS_CMSSignedData_AddCertList(sigd, certChain) == SECSuccess) {
|
||||
if (NSS_CMSSignedData_AddCertList(sigd.get(), certChain) == SECSuccess) {
|
||||
certChain.forget();
|
||||
}
|
||||
else {
|
||||
@ -1193,7 +1193,7 @@ nsNSSCertificate::ExportAsCMS(uint32_t chainMode,
|
||||
}
|
||||
else {
|
||||
// try to add the issuerCert, at least
|
||||
if (NSS_CMSSignedData_AddCertificate(sigd, issuerCert)
|
||||
if (NSS_CMSSignedData_AddCertificate(sigd.get(), issuerCert)
|
||||
== SECSuccess) {
|
||||
issuerCert.forget();
|
||||
}
|
||||
@ -1206,10 +1206,10 @@ nsNSSCertificate::ExportAsCMS(uint32_t chainMode,
|
||||
}
|
||||
}
|
||||
|
||||
NSSCMSContentInfo* cinfo = NSS_CMSMessage_GetContentInfo(cmsg);
|
||||
if (NSS_CMSContentInfo_SetContent_SignedData(cmsg, cinfo, sigd)
|
||||
NSSCMSContentInfo* cinfo = NSS_CMSMessage_GetContentInfo(cmsg.get());
|
||||
if (NSS_CMSContentInfo_SetContent_SignedData(cmsg.get(), cinfo, sigd.get())
|
||||
== SECSuccess) {
|
||||
sigd.forget();
|
||||
Unused << sigd.release();
|
||||
}
|
||||
else {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
@ -1225,7 +1225,7 @@ nsNSSCertificate::ExportAsCMS(uint32_t chainMode,
|
||||
}
|
||||
|
||||
SECItem certP7 = { siBuffer, nullptr, 0 };
|
||||
NSSCMSEncoderContext* ecx = NSS_CMSEncoder_Start(cmsg, nullptr, nullptr,
|
||||
NSSCMSEncoderContext* ecx = NSS_CMSEncoder_Start(cmsg.get(), nullptr, nullptr,
|
||||
&certP7, arena, nullptr,
|
||||
nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr);
|
||||
|
@ -2092,7 +2092,7 @@ ClientAuthDataRunnable::RunOnTargetThread()
|
||||
ScopedSECKEYPrivateKey privKey;
|
||||
ScopedCERTCertList certList;
|
||||
CERTCertListNode* node;
|
||||
ScopedCERTCertNicknames nicknames;
|
||||
UniqueCERTCertNicknames nicknames;
|
||||
int keyError = 0; // used for private key retrieval error
|
||||
SSM_UserCertChoice certChoice;
|
||||
int32_t NumberOfCerts = 0;
|
||||
@ -2296,7 +2296,7 @@ ClientAuthDataRunnable::RunOnTargetThread()
|
||||
goto noCert;
|
||||
}
|
||||
|
||||
nicknames = getNSSCertNicknamesFromCertList(certList.get());
|
||||
nicknames.reset(getNSSCertNicknamesFromCertList(certList.get()));
|
||||
|
||||
if (!nicknames) {
|
||||
goto loser;
|
||||
|
@ -23,7 +23,7 @@ FakeSSLStatus.prototype = {
|
||||
}
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
// This is a template to help porting global private browsing tests
|
||||
// to per-window private browsing tests
|
||||
|
@ -11,8 +11,8 @@
|
||||
.getInterface(SpecialPowers.Ci.nsIWebNavigation)
|
||||
.goBack();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
</script>
|
||||
</head>
|
||||
</html>
|
||||
|
@ -13,7 +13,7 @@
|
||||
window.location =
|
||||
"https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step3.html?runtest";
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
|
||||
function afterNavigationTest()
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user