From 4b6b71262b1626ea064d71f317141e0aab9e33fc Mon Sep 17 00:00:00 2001 From: Dragana Damjanovic Date: Mon, 8 Jan 2018 19:28:10 +0100 Subject: [PATCH 01/33] Bug 1426710 - The telemetry on how often a backup connection wins should be histogram. r=mayhemer --- netwerk/protocol/http/nsHttpConnectionMgr.cpp | 6 +++--- toolkit/components/telemetry/Histograms.json | 8 ++++++++ toolkit/components/telemetry/Scalars.yaml | 15 --------------- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index 3efc2799eda6..ac9942210990 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -4335,10 +4335,10 @@ nsHalfOpenSocket::OnOutputStreamReady(nsIAsyncOutputStream *out) // connection. We want to collect this telemetry only for cases where // TFO is not used. mBackupConnStatsSet = true; - Telemetry::ScalarSet(Telemetry::ScalarID::NETWORK_HTTP_BACKUP_CONN_WON, - (out == mBackupStreamOut)); + Telemetry::Accumulate(Telemetry::NETWORK_HTTP_BACKUP_CONN_WON_1, + (out == mBackupStreamOut)); } - + nsresult rv = SetupConn(out, false); if (mEnt) { mEnt->mDoNotDestroy = false; diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 97d28ec38fa5..79a395fee5d3 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -2441,6 +2441,14 @@ "alert_emails": ["necko@mozilla.com", "ddamjanovic@mozilla.com"], "bug_numbers": [1390881] }, + "NETWORK_HTTP_BACKUP_CONN_WON_1" : { + "record_in_processes": ["main"], + "expires_in_version": "61", + "kind": "boolean", + "description": "For connection where TFO has not be use, collect telemetry on whether the backup connection or the primary connection was faster.", + "alert_emails": ["necko@mozilla.com", "ddamjanovic@mozilla.com"], + "bug_numbers": [1426710] + }, "TLS_EARLY_DATA_NEGOTIATED": { "record_in_processes": ["main", "content"], "expires_in_version": "62", diff --git a/toolkit/components/telemetry/Scalars.yaml b/toolkit/components/telemetry/Scalars.yaml index a00d910873ca..3ba287d1afc4 100644 --- a/toolkit/components/telemetry/Scalars.yaml +++ b/toolkit/components/telemetry/Scalars.yaml @@ -1267,21 +1267,6 @@ screenshots: record_in_processes: - 'main' -network.http: - backup_conn_won: - bug_numbers: - - 1402811 - description: > - For connection where TFO has not be use, collect telemetry on whether the - backup connection or the primary connection was faster. - expires: "61" - kind: boolean - notification_emails: - - necko@mozilla.com - - ddamjanovic@mozilla.com - record_in_processes: - - 'main' - idb.type: persistent_count: bug_numbers: From 0c092c0ffe04ef9cb014eef4ba93ba60a068ef51 Mon Sep 17 00:00:00 2001 From: David Keeler Date: Thu, 4 Jan 2018 11:31:22 -0800 Subject: [PATCH 02/33] bug 1428498 - don't require importing the server certificate for overrides to succeed r=jcj Previously, adding a permanent certificate error override would depend on successfully importing the server's certificate into the user's certificate database. Consequently, if the user's database were in read-only mode (or if the database couldn't be created due to code page issues on Windows), this would prevent adding new certificate error overrides. It turns out this isn't even necessary, because the implementation relies on the stored hash of the certificate rather than the certificate itself. The stored certificate is only for display purposes (and there's a fallback if the certificate can't be stored). There are remaining issues with non-ASCII characters in 8.3 paths on Windows when the code page isn't western, but this is a larger issue that must be addressed in other layers (i.e. NSS/NSPR). MozReview-Commit-ID: KEzjxtAoeb4 --HG-- rename : security/manager/ssl/tests/unit/test_cert_overrides.js => security/manager/ssl/tests/unit/test_cert_overrides_read_only.js extra : rebase_source : b41e863d8c85d80335dd56c8f5765b19b1de4e0c --- .../manager/ssl/nsCertOverrideService.cpp | 13 ++- security/manager/ssl/tests/unit/head_psm.js | 10 +- .../unit/test_cert_overrides_read_only.js | 93 ++++++++++++++++++ .../test_cert_overrides_read_only/cert9.db | Bin 0 -> 28672 bytes .../test_cert_overrides_read_only/key4.db | Bin 0 -> 36864 bytes security/manager/ssl/tests/unit/xpcshell.ini | 3 + 6 files changed, 110 insertions(+), 9 deletions(-) create mode 100644 security/manager/ssl/tests/unit/test_cert_overrides_read_only.js create mode 100644 security/manager/ssl/tests/unit/test_cert_overrides_read_only/cert9.db create mode 100644 security/manager/ssl/tests/unit/test_cert_overrides_read_only/key4.db diff --git a/security/manager/ssl/nsCertOverrideService.cpp b/security/manager/ssl/nsCertOverrideService.cpp index d98748a4d5d2..c35ad054b170 100644 --- a/security/manager/ssl/nsCertOverrideService.cpp +++ b/security/manager/ssl/nsCertOverrideService.cpp @@ -11,6 +11,7 @@ #include "SharedSSLState.h" #include "mozilla/Assertions.h" #include "mozilla/Telemetry.h" +#include "mozilla/Unused.h" #include "nsAppDirectoryServiceDefs.h" #include "nsCRT.h" #include "nsILineInputStream.h" @@ -378,11 +379,13 @@ nsCertOverrideService::RememberValidityOverride(const nsACString& aHostName, return NS_ERROR_FAILURE; } - SECStatus srv = PK11_ImportCert(slot.get(), nsscert.get(), CK_INVALID_HANDLE, - nickname.get(), false); - if (srv != SECSuccess) { - return NS_ERROR_FAILURE; - } + // This can fail (for example, if we're in read-only mode). Luckily, we + // don't even need it to succeed - we always match on the stored hash of the + // certificate rather than the full certificate. It makes the display a bit + // less informative (since we won't have a certificate to display), but it's + // better than failing the entire operation. + Unused << PK11_ImportCert(slot.get(), nsscert.get(), CK_INVALID_HANDLE, + nickname.get(), false); } nsAutoCString fpStr; diff --git a/security/manager/ssl/tests/unit/head_psm.js b/security/manager/ssl/tests/unit/head_psm.js index 7b7e01dabe8b..6e0d41125549 100644 --- a/security/manager/ssl/tests/unit/head_psm.js +++ b/security/manager/ssl/tests/unit/head_psm.js @@ -339,9 +339,9 @@ function run_test() { } */ -function add_tls_server_setup(serverBinName, certsPath) { +function add_tls_server_setup(serverBinName, certsPath, addDefaultRoot = true) { add_test(function() { - _setupTLSServerTest(serverBinName, certsPath); + _setupTLSServerTest(serverBinName, certsPath, addDefaultRoot); }); } @@ -491,11 +491,13 @@ function _getBinaryUtil(binaryUtilName) { } // Do not call this directly; use add_tls_server_setup -function _setupTLSServerTest(serverBinName, certsPath) { +function _setupTLSServerTest(serverBinName, certsPath, addDefaultRoot) { let certdb = Cc["@mozilla.org/security/x509certdb;1"] .getService(Ci.nsIX509CertDB); // The trusted CA that is typically used for "good" certificates. - addCertFromFile(certdb, `${certsPath}/test-ca.pem`, "CTu,u,u"); + if (addDefaultRoot) { + addCertFromFile(certdb, `${certsPath}/test-ca.pem`, "CTu,u,u"); + } const CALLBACK_PORT = 8444; diff --git a/security/manager/ssl/tests/unit/test_cert_overrides_read_only.js b/security/manager/ssl/tests/unit/test_cert_overrides_read_only.js new file mode 100644 index 000000000000..91b52d119d37 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_overrides_read_only.js @@ -0,0 +1,93 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +"use strict"; + +// Tests that permanent certificate error overrides can be added even if the +// certificate/key databases are in read-only mode. + +// Helper function for add_read_only_cert_override_test. Probably doesn't need +// to be called directly. +function add_read_only_cert_override(aHost, aExpectedBits, aSecurityInfo) { + let sslstatus = aSecurityInfo.QueryInterface(Ci.nsISSLStatusProvider) + .SSLStatus; + let bits = + (sslstatus.isUntrusted ? Ci.nsICertOverrideService.ERROR_UNTRUSTED : 0) | + (sslstatus.isDomainMismatch ? Ci.nsICertOverrideService.ERROR_MISMATCH : 0) | + (sslstatus.isNotValidAtThisTime ? Ci.nsICertOverrideService.ERROR_TIME : 0); + + Assert.equal(bits, aExpectedBits, + "Actual and expected override bits should match"); + let cert = sslstatus.serverCert; + let certOverrideService = Cc["@mozilla.org/security/certoverride;1"] + .getService(Ci.nsICertOverrideService); + // Setting the last argument to false here ensures that we attempt to store a + // permanent override (which is what was failing in bug 1427273). + certOverrideService.rememberValidityOverride(aHost, 8443, cert, aExpectedBits, + false); +} + +// Given a host, expected error bits (see nsICertOverrideService.idl), and an +// expected error code, tests that an initial connection to the host fails with +// the expected errors and that adding an override results in a subsequent +// connection succeeding. +function add_read_only_cert_override_test(aHost, aExpectedBits, aExpectedError) { + add_connection_test(aHost, aExpectedError, null, + add_read_only_cert_override.bind(this, aHost, aExpectedBits)); + add_connection_test(aHost, PRErrorCodeSuccess, null, aSecurityInfo => { + Assert.ok(aSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN, + "Cert override flag should be set on the security state"); + }); +} + +function run_test() { + let profile = do_get_profile(); + const KEY_DB_NAME = "key4.db"; + const CERT_DB_NAME = "cert9.db"; + let srcKeyDBFile = do_get_file(`test_cert_overrides_read_only/${KEY_DB_NAME}`); + srcKeyDBFile.copyTo(profile, KEY_DB_NAME); + let srcCertDBFile = do_get_file(`test_cert_overrides_read_only/${CERT_DB_NAME}`); + srcCertDBFile.copyTo(profile, CERT_DB_NAME); + + // set the databases to read-only + let keyDBFile = do_get_profile(); + keyDBFile.append(KEY_DB_NAME); + keyDBFile.permissions = 0o400; + let certDBFile = do_get_profile(); + certDBFile.append(CERT_DB_NAME); + certDBFile.permissions = 0o400; + + Services.prefs.setIntPref("security.OCSP.enabled", 1); + // Specifying false as the last argument means we don't try to add the default + // test root CA (which would fail). + add_tls_server_setup("BadCertServer", "bad_certs", false); + + let fakeOCSPResponder = new HttpServer(); + fakeOCSPResponder.registerPrefixHandler("/", function (request, response) { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + }); + fakeOCSPResponder.start(8888); + + // Since we can't add the root CA to the (read-only) trust db, all of these + // will result in an "unknown issuer error" and need the "untrusted" error bit + // set in addition to whatever other specific error bits are necessary. + add_read_only_cert_override_test("expired.example.com", + Ci.nsICertOverrideService.ERROR_TIME | + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER); + add_read_only_cert_override_test("selfsigned.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER); + add_read_only_cert_override_test("mismatch.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER); + + add_test(function () { + fakeOCSPResponder.stop(run_next_test); + }); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_cert_overrides_read_only/cert9.db b/security/manager/ssl/tests/unit/test_cert_overrides_read_only/cert9.db new file mode 100644 index 0000000000000000000000000000000000000000..3d452f335c286da96cd47711ed7bcbb92ed9f841 GIT binary patch literal 28672 zcmeH~&2G~`6ou_JO%b7L7f2Ceky#Q6q4}|0cY~Uyt`t$yHlz|=pvq2MDG*xGBoa>m zJKl;NFTq=|WbXCYX}e*G6dg;xJu`RinVHYiNb~OOcrwq$)y?habS{jycI*U_hRGQOV8P8Zp9GTQ78lFl#@z5ZeHUT{vF^hK2yFH$9S z`}GDpoU_9;&GKnAqJGbTa}OO%`>%Uy4-PSJ_wF*O2B8>QU4cQ!}P!%uN~+2NXgI z5rtg}F@-$}DTU02J+_iXWJgIJN*42wi;`rcB>5;wMoN;Cl4PYMc_~R|N{%SH>YRP$;BX&Qo0e_c}YeRMm z*)8PSQ68GWgkS;lx=@3Jf^%cA9StSpyf zWw{(H%jH;E`dV2o$I8;z$~(SvW@uvDO9#hEIz3L(5pr_8l=)I#Rgw=vF*aK+C!^(z z!&HtlCLYtbm5iOn1}55TtF?MFY5899^YLYBZ}gYxVt&Kz%j$pkQdM%@{?tCApW7`8 zI~4GM00@8p2!H?xfB*=900@8p2!H?xtSW)Wv@zWOSM~E^UmySiAOHd&00JNY0w4ea zAOHd&zyxsr$3XxA5C8!X009sH0T2KI5C8!X0D;vffcyXIe`D+r1V8`;KmY_l00ck) z1V8`;KmY`A|Hl~s0T2KI5C8!X009sH0T2KI5CDPICxH9^>VISG5ClK~1V8`;KmY_l N00ck)1V8`;{sM?+P}%?h literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_cert_overrides_read_only/key4.db b/security/manager/ssl/tests/unit/test_cert_overrides_read_only/key4.db new file mode 100644 index 0000000000000000000000000000000000000000..44d0cb172812d17b8f8de88bce066142d1c0cf2f GIT binary patch literal 36864 zcmeI)&u`mg7zc1WKio7~)gC6IfdX%C4UF-=w&SK^hoz|p5nbDbPIQ7PavDzxr0Zy0 z;KE@XwhQ787moZJpb3P=PUFOlX-5u#wrOzVeIDEMs;Uw6O z+c;64zg_vh@@eJu@{{s*`G?~sVLt>Q009U<00Izz!2eHRJTp_R)yx~OM8RMj?uJpY z8bm?*Uh4Gx_LeWU+AC|mNcW1x(NJvmx)<8L%i=BnvbeO~y?DtN8|$L8v3`E7+u0I5 ze{-$f@lOl=Q|qpZ-|WU~C9B%0na1eaF#Kfl;aGR}gM(;~Klju8zDldv70aqt>*l*W zVCREiG`u#MZ0?Uf3Zif(SzLF0)!!D}NlVBEh{ZrjyK%0_8Sik$I2eTEY>0IzgFBC8 zIF0iKtNKFS?8nPK7`z|uL|I1hP{t(gK9ZuOYIO2e^;CK`qsinT+|ObPhhpO1BPlJ_ zxaFBM)q36hVu>$V7LZlBBr3ja+5UfX;o2)3y{*$Ckou*sTVU&#LpAT9J&Ja<=wpjM zw)i6rX}Q!isqv^;qNYX7GBp7;1Klihl#E+Wl$4=ld>l$ql46vk93?48NlH?ZqLid8 zB`HkF9cq*1#p~l_JFYp|=46|bZBDj1+2&-MlO3Mr@GOUCIXuhZSswR#-0N|#$Gu+M z%b6Z$F7ZhAQ4D1Bnc9-(+I*%quhx}%vlZ=5O3HP3w8Ntv9<4ihNIa0nxGd#LI=0JF zE=#$5RF{wH@^xwQ+$N_rIjzZacfzLQI!%g9O3F=2I Date: Thu, 7 Dec 2017 12:13:14 -0700 Subject: [PATCH 03/33] Bug 1423999: Improved UIA detection that eliminates handle duplication; r=Jamie MozReview-Commit-ID: 5CqjkyDoPs8 --HG-- extra : amend_source : 877a3d6cadab0645274c9542249fc35cfd682d41 --- accessible/windows/msaa/CompatibilityUIA.cpp | 324 ++++++++++--------- accessible/windows/msaa/NtUndoc.h | 44 +++ accessible/windows/msaa/moz.build | 4 + mozglue/build/WindowsDllServices.h | 4 +- widget/windows/nsAppShell.cpp | 32 +- 5 files changed, 246 insertions(+), 162 deletions(-) diff --git a/accessible/windows/msaa/CompatibilityUIA.cpp b/accessible/windows/msaa/CompatibilityUIA.cpp index 907dc731dc33..72fb30661ae7 100644 --- a/accessible/windows/msaa/CompatibilityUIA.cpp +++ b/accessible/windows/msaa/CompatibilityUIA.cpp @@ -7,10 +7,13 @@ #include "Compatibility.h" #include "mozilla/Telemetry.h" +#include "mozilla/WindowsVersion.h" +#include "nsDataHashtable.h" #include "nsPrintfCString.h" #include "nsReadableUtils.h" #include "nsString.h" +#include "nsTHashtable.h" #include "nsUnicharUtils.h" #include "nsWinUtils.h" @@ -31,32 +34,102 @@ #endif // defined(UIA_LOGGING) -static bool -GetLocalObjectHandle(DWORD aSrcPid, HANDLE aSrcHandle, nsAutoHandle& aProcess, - nsAutoHandle& aLocal) +struct ByteArrayDeleter { - aLocal.reset(); - - if (!aProcess) { - HANDLE rawProcess = ::OpenProcess(PROCESS_DUP_HANDLE, FALSE, aSrcPid); - if (!rawProcess) { - LOG_ERROR(OpenProcess); - return false; - } - - aProcess.own(rawProcess); + void operator()(void* aBuf) + { + delete[] reinterpret_cast(aBuf); } +}; - HANDLE rawDuped; - if (!::DuplicateHandle(aProcess.get(), aSrcHandle, ::GetCurrentProcess(), - &rawDuped, GENERIC_READ, FALSE, 0)) { - LOG_ERROR(DuplicateHandle); +typedef UniquePtr ObjDirInfoPtr; + +// ComparatorFnT returns true to continue searching, or else false to indicate +// search completion. +template +static bool +FindNamedObject(ComparatorFnT aComparator) +{ + // We want to enumerate every named kernel object in our session. We do this + // by opening a directory object using a path constructed using the session + // id under which our process resides. + DWORD sessionId; + if (!::ProcessIdToSessionId(::GetCurrentProcessId(), &sessionId)) { return false; } - aLocal.own(rawDuped); + nsAutoString path; + path.AppendPrintf("\\Sessions\\%u\\BaseNamedObjects", sessionId); - return true; + UNICODE_STRING baseNamedObjectsName; + ::RtlInitUnicodeString(&baseNamedObjectsName, path.get()); + + OBJECT_ATTRIBUTES attributes; + InitializeObjectAttributes(&attributes, &baseNamedObjectsName, 0, + nullptr, nullptr); + + HANDLE rawBaseNamedObjects; + NTSTATUS ntStatus = ::NtOpenDirectoryObject(&rawBaseNamedObjects, + DIRECTORY_QUERY | DIRECTORY_TRAVERSE, + &attributes); + if (!NT_SUCCESS(ntStatus)) { + return false; + } + + nsAutoHandle baseNamedObjects(rawBaseNamedObjects); + + ULONG context = 0, returnedLen; + + ULONG objDirInfoBufLen = 1024 * sizeof(OBJECT_DIRECTORY_INFORMATION); + ObjDirInfoPtr objDirInfo( + reinterpret_cast(new char[objDirInfoBufLen])); + + // Now query that directory object for every named object that it contains. + + BOOL firstCall = TRUE; + + do { + ntStatus = ::NtQueryDirectoryObject(baseNamedObjects, objDirInfo.get(), + objDirInfoBufLen, FALSE, firstCall, + &context, &returnedLen); +#if defined(HAVE_64BIT_BUILD) + if (!NT_SUCCESS(ntStatus)) { + return false; + } +#else + if (ntStatus == STATUS_BUFFER_TOO_SMALL) { + // This case only occurs on 32-bit builds running atop WOW64. + // (See https://bugzilla.mozilla.org/show_bug.cgi?id=1423999#c3) + objDirInfo.reset(reinterpret_cast(new char[returnedLen])); + objDirInfoBufLen = returnedLen; + continue; + } else if (!NT_SUCCESS(ntStatus)) { + return false; + } +#endif + + // NtQueryDirectoryObject gave us an array of OBJECT_DIRECTORY_INFORMATION + // structures whose final entry is zeroed out. + OBJECT_DIRECTORY_INFORMATION* curDir = objDirInfo.get(); + while (curDir->mName.Length && curDir->mTypeName.Length) { + // We use nsDependentSubstring here because UNICODE_STRINGs are not + // guaranteed to be null-terminated. + nsDependentSubstring objName(curDir->mName.Buffer, + curDir->mName.Length / sizeof(wchar_t)); + nsDependentSubstring typeName(curDir->mTypeName.Buffer, + curDir->mTypeName.Length / sizeof(wchar_t)); + + if (!aComparator(objName, typeName)) { + return true; + } + + ++curDir; + } + + firstCall = FALSE; + } while (ntStatus == STATUS_MORE_ENTRIES); + + return false; } namespace mozilla { @@ -74,15 +147,6 @@ Compatibility::OnUIAMessage(WPARAM aWParam, LPARAM aLParam) Telemetry::AutoTimer timer; - static auto pNtQuerySystemInformation = - reinterpret_cast( - ::GetProcAddress(::GetModuleHandleW(L"ntdll.dll"), - "NtQuerySystemInformation")); - - static auto pNtQueryObject = - reinterpret_cast( - ::GetProcAddress(::GetModuleHandleW(L"ntdll.dll"), "NtQueryObject")); - // UIA creates a section containing the substring "HOOK_SHMEM_" NS_NAMED_LITERAL_STRING(kStrHookShmem, "HOOK_SHMEM_"); @@ -90,7 +154,27 @@ Compatibility::OnUIAMessage(WPARAM aWParam, LPARAM aLParam) // current thread id and the UIA message's WPARAM and LPARAM. nsAutoString partialSectionSuffix; partialSectionSuffix.AppendPrintf("_%08x_%08x_%08x", ::GetCurrentThreadId(), - aLParam, aWParam); + static_cast(aLParam), aWParam); + + // Find any named Section that matches the naming convention of the UIA shared + // memory. + nsAutoHandle section; + auto comparator = [&](const nsDependentSubstring& aName, + const nsDependentSubstring& aType) -> bool { + if (aType.Equals(NS_LITERAL_STRING("Section")) && + FindInReadable(kStrHookShmem, aName) && + StringEndsWith(aName, partialSectionSuffix)) { + section.own(::OpenFileMapping(GENERIC_READ, FALSE, + PromiseFlatString(aName).get())); + return false; + } + + return true; + }; + + if (!FindNamedObject(comparator) || !section) { + return Nothing(); + } NTSTATUS ntStatus; @@ -105,7 +189,7 @@ Compatibility::OnUIAMessage(WPARAM aWParam, LPARAM aLParam) while (true) { handleInfoBuf = MakeUnique(handleInfoBufLen); - ntStatus = pNtQuerySystemInformation( + ntStatus = ::NtQuerySystemInformation( (SYSTEM_INFORMATION_CLASS) SystemExtendedHandleInformation, handleInfoBuf.get(), handleInfoBufLen, &handleInfoBufLen); if (ntStatus == STATUS_INFO_LENGTH_MISMATCH) { @@ -119,161 +203,99 @@ Compatibility::OnUIAMessage(WPARAM aWParam, LPARAM aLParam) break; } - // Now we iterate through the system handle list, searching for a section - // handle whose name matches the section name used by UIA. - - static Maybe sSectionObjTypeIndex; - const DWORD ourPid = ::GetCurrentProcessId(); - Maybe kernelObject; - - ULONG lastPid = 0; - nsAutoHandle process; + static Maybe sectionObjTypeIndex; + nsTHashtable nonSectionObjTypes; + nsDataHashtable objMap; auto handleInfo = reinterpret_cast(handleInfoBuf.get()); for (ULONG index = 0; index < handleInfo->mHandleCount; ++index) { SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX& curHandle = handleInfo->mHandles[index]; - if (lastPid && lastPid == curHandle.mPid && !process) { - // During the previous iteration, we could not obtain a handle for this - // pid. Skip any remaining handles belonging to that pid. + HANDLE handle = reinterpret_cast(curHandle.mHandle); + + // The mapping of the curHandle.mObjectTypeIndex field depends on the + // underlying OS kernel. As we scan through the handle list, we record the + // type indices such that we may use those values to skip over handles that + // refer to non-section objects. + if (sectionObjTypeIndex) { + // If we know the type index for Sections, that's the fastest check... + if (sectionObjTypeIndex.value() != curHandle.mObjectTypeIndex) { + // Not a section + continue; + } + } else if (nonSectionObjTypes.Contains(static_cast( + curHandle.mObjectTypeIndex))) { + // Otherwise we check whether or not the object type is definitely _not_ + // a Section... continue; - } - - // As a perf optimization, we reuse the same process handle as long as we're - // still looking at the same pid. Once the pid changes, we need to reset - // process so that we open a new handle to the newly-seen process. - if (lastPid != curHandle.mPid) { - process.reset(); - } - - nsAutoHandle handle; - - if (kernelObject.isSome() && kernelObject.value() == curHandle.mObject) { - // If we know the value of the underlying kernel object, we can immediately - // check for equality by comparing against curHandle.mObject - remotePid = Some(static_cast(curHandle.mPid)); - break; - } else if (sSectionObjTypeIndex.isSome()) { - // Otherwise, if we know which object type value corresponds to a Section - // object, we can use that to eliminate any handles that are not sections. - if (curHandle.mObjectTypeIndex != sSectionObjTypeIndex.value()) { - // Not a section handle - continue; - } - } else { - // Otherwise we need to query the handle to determine its type. Note that - // each handle in the system list is relative to its owning process, so - // we cannot do anything with it until we duplicate the handle into our - // own process. - - lastPid = curHandle.mPid; - - if (!GetLocalObjectHandle((DWORD) curHandle.mPid, - (HANDLE) curHandle.mHandle, - process, handle)) { - // We don't have access to do this, assume this handle isn't relevant - continue; - } - - // Now we have our own handle to the object, lets find out what type of - // object this handle represents. Any handle whose type is not "Section" - // is of no interest to us. + } else if (ourPid == curHandle.mPid) { + // Otherwise we need to issue some system calls to find out the object + // type corresponding to the current handle's type index. ULONG objTypeBufLen; - ntStatus = pNtQueryObject(handle, ObjectTypeInformation, nullptr, - 0, &objTypeBufLen); + ntStatus = ::NtQueryObject(handle, ObjectTypeInformation, + nullptr, 0, &objTypeBufLen); if (ntStatus != STATUS_INFO_LENGTH_MISMATCH) { continue; } auto objTypeBuf = MakeUnique(objTypeBufLen); - ntStatus = pNtQueryObject(handle, ObjectTypeInformation, objTypeBuf.get(), - objTypeBufLen, &objTypeBufLen); + ntStatus = ::NtQueryObject(handle, ObjectTypeInformation, objTypeBuf.get(), + objTypeBufLen, &objTypeBufLen); if (!NT_SUCCESS(ntStatus)) { - // We don't have access to do this, assume this handle isn't relevant continue; } auto objType = reinterpret_cast(objTypeBuf.get()); - nsDependentString objTypeName(objType->TypeName.Buffer, - objType->TypeName.Length / sizeof(wchar_t)); + // Now we check whether the object's type name matches "Section" + nsDependentSubstring objTypeName(objType->TypeName.Buffer, + objType->TypeName.Length / sizeof(wchar_t)); if (!objTypeName.Equals(NS_LITERAL_STRING("Section"))) { - // Not a section, so we don't care about this handle anymore. + nonSectionObjTypes.PutEntry(static_cast(curHandle.mObjectTypeIndex)); continue; } - // We have a section, save this handle's type code so that we can go - // faster in future iterations. - sSectionObjTypeIndex = Some(curHandle.mObjectTypeIndex); + sectionObjTypeIndex = Some(curHandle.mObjectTypeIndex); } - // If we reached this point without needing to query the handle, then we - // need to open it here so that we can query its name. - lastPid = curHandle.mPid; + // At this point we know that curHandle references a Section object. + // Now we can do some actual tests on it. - if ((!process || !handle) && - !GetLocalObjectHandle((DWORD) curHandle.mPid, (HANDLE) curHandle.mHandle, - process, handle)) { - // We don't have access to do this, assume this handle isn't relevant - continue; - } + if (ourPid != curHandle.mPid) { + if (kernelObject && kernelObject.value() == curHandle.mObject) { + // The kernel objects match -- we have found the remote pid! + remotePid = Some(curHandle.mPid); + break; + } - // At this point, |handle| is a valid section handle. Let's try to find - // out the name of its underlying object. - ULONG objNameBufLen; - ntStatus = pNtQueryObject(handle, - (OBJECT_INFORMATION_CLASS)ObjectNameInformation, - nullptr, 0, &objNameBufLen); - if (ntStatus != STATUS_INFO_LENGTH_MISMATCH) { - continue; - } - - auto objNameBuf = MakeUnique(objNameBufLen); - ntStatus = pNtQueryObject(handle, - (OBJECT_INFORMATION_CLASS)ObjectNameInformation, - objNameBuf.get(), objNameBufLen, &objNameBufLen); - if (!NT_SUCCESS(ntStatus)) { - continue; - } - - auto objNameInfo = reinterpret_cast(objNameBuf.get()); - if (!objNameInfo->mName.Length) { - // This section is unnamed. We don't care about those. - continue; - } - - nsDependentString objName(objNameInfo->mName.Buffer, - objNameInfo->mName.Length / sizeof(wchar_t)); - - // Check to see if the section's name matches our expected name. - if (!FindInReadable(kStrHookShmem, objName) || - !StringEndsWith(objName, partialSectionSuffix)) { - // The names don't match, continue searching. - continue; - } - - // At this point we have a section handle whose name matches the one that - // we're looking for. - - if (curHandle.mPid == ourPid) { - // Our own process also has a handle to the section of interest. While we - // don't want our own pid, this *does* give us an opportunity to speed up - // future iterations by examining each handle for its kernel object (which - // is the same for all processes) instead of searching by name. + // An object that is not ours. Since we do not yet know which kernel + // object we're interested in, we'll save the current object for later. + objMap.Put(curHandle.mObject, curHandle.mPid); + } else if (handle == section.get()) { + // This is the file mapping that we opened above. We save this mObject + // in order to compare to Section objects opened by other processes. kernelObject = Some(curHandle.mObject); - continue; } - - // Bingo! We want this pid! - remotePid = Some(static_cast(curHandle.mPid)); - - break; } + if (!kernelObject) { + return Nothing(); + } + + if (!remotePid) { + // We found kernelObject *after* we saw the remote process's copy. Now we + // must look it up in objMap. + DWORD pid; + if (objMap.Get(kernelObject.value(), &pid)) { + remotePid = Some(pid); + } + } + + if (!remotePid) { return Nothing(); } diff --git a/accessible/windows/msaa/NtUndoc.h b/accessible/windows/msaa/NtUndoc.h index e9689518069b..053bb97dc84b 100644 --- a/accessible/windows/msaa/NtUndoc.h +++ b/accessible/windows/msaa/NtUndoc.h @@ -9,10 +9,22 @@ #include +#if defined(__cplusplus) +extern "C" { +#endif + #ifndef STATUS_INFO_LENGTH_MISMATCH #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) #endif +#ifndef STATUS_BUFFER_TOO_SMALL +#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L) +#endif + +#ifndef STATUS_MORE_ENTRIES +#define STATUS_MORE_ENTRIES ((NTSTATUS)0x00000105L) +#endif + enum UndocSystemInformationClass { SystemExtendedHandleInformation = 64 @@ -47,4 +59,36 @@ struct OBJECT_NAME_INFORMATION UNICODE_STRING mName; }; +// The following declarations are documented on MSDN but are not included in +// public user-mode headers. + +enum DirectoryObjectAccessFlags +{ + DIRECTORY_QUERY = 0x0001, + DIRECTORY_TRAVERSE = 0x0002, + DIRECTORY_CREATE_OBJECT = 0x0004, + DIRECTORY_CREATE_SUBDIRECTORY = 0x0008, + DIRECTORY_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | 0x000F +}; + +NTSTATUS WINAPI +NtOpenDirectoryObject(PHANDLE aDirectoryHandle, ACCESS_MASK aDesiredAccess, + POBJECT_ATTRIBUTES aObjectAttributes); + +struct OBJECT_DIRECTORY_INFORMATION +{ + UNICODE_STRING mName; + UNICODE_STRING mTypeName; +}; + +NTSTATUS WINAPI +NtQueryDirectoryObject(HANDLE aDirectoryHandle, PVOID aOutBuffer, + ULONG aBufferLength, BOOLEAN aReturnSingleEntry, + BOOLEAN aRestartScan, PULONG aContext, + PULONG aOutReturnLength); + +#if defined(__cplusplus) +} // extern "C" +#endif + #endif // mozilla_NtUndoc_h diff --git a/accessible/windows/msaa/moz.build b/accessible/windows/msaa/moz.build index 1af552ed0e68..499df9db21a5 100644 --- a/accessible/windows/msaa/moz.build +++ b/accessible/windows/msaa/moz.build @@ -46,6 +46,10 @@ SOURCES += [ 'ServiceProvider.cpp', ] +OS_LIBS += [ + 'ntdll', +] + if CONFIG['MOZ_XUL']: UNIFIED_SOURCES += [ 'XULListboxAccessibleWrap.cpp', diff --git a/mozglue/build/WindowsDllServices.h b/mozglue/build/WindowsDllServices.h index 1632ca1f7aa1..b31c7535c410 100644 --- a/mozglue/build/WindowsDllServices.h +++ b/mozglue/build/WindowsDllServices.h @@ -64,8 +64,8 @@ class DllServices : public detail::DllServicesBase public: virtual void DispatchDllLoadNotification(PCUNICODE_STRING aDllName) override final { - nsDependentString strDllName(aDllName->Buffer, - aDllName->Length / sizeof(wchar_t)); + nsDependentSubstring strDllName(aDllName->Buffer, + aDllName->Length / sizeof(wchar_t)); nsCOMPtr runnable( NewRunnableMethod("DllServices::NotifyDllLoad", diff --git a/widget/windows/nsAppShell.cpp b/widget/windows/nsAppShell.cpp index 352c03d8146e..638c7ca2af77 100644 --- a/widget/windows/nsAppShell.cpp +++ b/widget/windows/nsAppShell.cpp @@ -170,6 +170,8 @@ nsAppShell::~nsAppShell() static ULONG gUiaMsg; static HHOOK gUiaHook; +static uint32_t gUiaAttempts; +static const uint32_t kMaxUiaAttempts = 5; static void InitUIADetection(); @@ -182,17 +184,29 @@ UiaHookProc(int aCode, WPARAM aWParam, LPARAM aLParam) auto cwp = reinterpret_cast(aLParam); if (gUiaMsg && cwp->message == gUiaMsg) { - Maybe shouldCallNextHook = - a11y::Compatibility::OnUIAMessage(cwp->wParam, cwp->lParam); + if (gUiaAttempts < kMaxUiaAttempts) { + ++gUiaAttempts; - // Unconditionally remove the hook, as UIA detection is too expensive to - // leave running for every single request. - if (::UnhookWindowsHookEx(gUiaHook)) { - gUiaHook = nullptr; - } + Maybe shouldCallNextHook = + a11y::Compatibility::OnUIAMessage(cwp->wParam, cwp->lParam); + if (shouldCallNextHook.isSome()) { + // We've got an instantiator, disconnect this hook. + if (::UnhookWindowsHookEx(gUiaHook)) { + gUiaHook = nullptr; + } - if (shouldCallNextHook.isSome() && !shouldCallNextHook.value()) { - return 0; + if (!shouldCallNextHook.value()) { + return 0; + } + } else { + // Our hook might be firing after UIA; let's try reinstalling ourselves. + InitUIADetection(); + } + } else { + // We've maxed out our attempts. Let's unhook. + if (::UnhookWindowsHookEx(gUiaHook)) { + gUiaHook = nullptr; + } } } From 8dfd9e72ac7d39daea4f80df6c1e5081dae7f568 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Mon, 8 Jan 2018 15:43:46 -0500 Subject: [PATCH 04/33] Bug 1428874 - pass gfxMacFont synthetic bold status to ScaledFontMac. r=gankro MozReview-Commit-ID: Dn3l5UJlDQL --- gfx/thebes/gfxMacFont.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gfx/thebes/gfxMacFont.cpp b/gfx/thebes/gfxMacFont.cpp index af0187649280..86be69b5fb3d 100644 --- a/gfx/thebes/gfxMacFont.cpp +++ b/gfx/thebes/gfxMacFont.cpp @@ -508,7 +508,8 @@ gfxMacFont::GetScaledFont(DrawTarget *aTarget) GetUnscaledFont(), GetAdjustedSize(), Color::FromABGR(mFontSmoothingBackgroundColor), - !mStyle.useGrayscaleAntialiasing); + !mStyle.useGrayscaleAntialiasing, + IsSyntheticBold()); if (!mAzureScaledFont) { return nullptr; } From 5cd6c645250bf05e70e59af96bd7eae6a15f19b0 Mon Sep 17 00:00:00 2001 From: Kyle Machulis Date: Fri, 5 Jan 2018 13:28:24 -0800 Subject: [PATCH 05/33] Bug 952453 - Remove mozNotification API; r=mattn r=baku MozReview-Commit-ID: 3TMxnPRSh1j --HG-- rename : dom/tests/mochitest/notification/desktop-notification/test_system_principal.xul => dom/notification/test/chrome/test_notification_system_principal.xul rename : dom/tests/mochitest/notification/desktop-notification/create_notification.html => dom/notification/test/mochitest/create_notification.html rename : dom/tests/mochitest/notification/desktop-notification/test_notification_tag.html => dom/notification/test/mochitest/test_notification_tag.html --- dom/base/Navigator.cpp | 23 -- dom/base/Navigator.h | 3 - dom/notification/DesktopNotification.cpp | 332 ------------------ dom/notification/DesktopNotification.h | 178 ---------- dom/notification/moz.build | 4 +- dom/notification/test/chrome/chrome.ini | 1 + .../test_notification_system_principal.xul} | 0 .../test/mochitest}/create_notification.html | 0 dom/notification/test/mochitest/mochitest.ini | 2 + .../mochitest}/test_notification_tag.html | 0 .../mochitest/general/test_interfaces.js | 4 - .../desktop-notification/moz.build | 6 - .../notification_common.js | 70 ---- .../test_basic_notification.html | 50 --- .../test_basic_notification_click.html | 53 --- .../test_leak_windowClose.html | 34 -- dom/webidl/DesktopNotification.webidl | 26 -- dom/webidl/Navigator.webidl | 6 - dom/webidl/moz.build | 4 - modules/libpref/init/all.js | 3 - widget/cocoa/OSXNotificationCenter.h | 5 + 21 files changed, 10 insertions(+), 794 deletions(-) delete mode 100644 dom/notification/DesktopNotification.cpp delete mode 100644 dom/notification/DesktopNotification.h create mode 100644 dom/notification/test/chrome/chrome.ini rename dom/{tests/mochitest/notification/desktop-notification/test_system_principal.xul => notification/test/chrome/test_notification_system_principal.xul} (100%) rename dom/{tests/mochitest/notification/desktop-notification => notification/test/mochitest}/create_notification.html (100%) rename dom/{tests/mochitest/notification/desktop-notification => notification/test/mochitest}/test_notification_tag.html (100%) delete mode 100644 dom/tests/mochitest/notification/desktop-notification/moz.build delete mode 100644 dom/tests/mochitest/notification/desktop-notification/notification_common.js delete mode 100644 dom/tests/mochitest/notification/desktop-notification/test_basic_notification.html delete mode 100644 dom/tests/mochitest/notification/desktop-notification/test_basic_notification_click.html delete mode 100644 dom/tests/mochitest/notification/desktop-notification/test_leak_windowClose.html delete mode 100644 dom/webidl/DesktopNotification.webidl diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index cdda6fd67448..9e63e708eb1e 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -13,7 +13,6 @@ #include "nsMimeTypeArray.h" #include "mozilla/MemoryReporting.h" #include "mozilla/dom/BodyExtractor.h" -#include "mozilla/dom/DesktopNotification.h" #include "mozilla/dom/FetchBinding.h" #include "mozilla/dom/File.h" #include "nsGeolocation.h" @@ -195,7 +194,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlugins) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPermissions) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGeolocation) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNotification) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBatteryManager) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBatteryPromise) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConnection) @@ -238,11 +236,6 @@ Navigator::Invalidate() mGeolocation = nullptr; } - if (mNotification) { - mNotification->Shutdown(); - mNotification = nullptr; - } - if (mBatteryManager) { mBatteryManager->Shutdown(); mBatteryManager = nullptr; @@ -1316,22 +1309,6 @@ Navigator::MozGetUserMediaDevices(const MediaStreamConstraints& aConstraints, aInnerWindowID, aCallID); } -DesktopNotificationCenter* -Navigator::GetMozNotification(ErrorResult& aRv) -{ - if (mNotification) { - return mNotification; - } - - if (!mWindow || !mWindow->GetDocShell()) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } - - mNotification = new DesktopNotificationCenter(mWindow); - return mNotification; -} - //***************************************************************************** // Navigator::nsINavigatorBattery //***************************************************************************** diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h index eb31ff7b3699..04326a96a3f2 100644 --- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h @@ -59,7 +59,6 @@ class BatteryManager; class Promise; -class DesktopNotificationCenter; class MozIdleObserver; class Gamepad; class GamepadServiceTest; @@ -178,7 +177,6 @@ public: void AddIdleObserver(MozIdleObserver& aObserver, ErrorResult& aRv); void RemoveIdleObserver(MozIdleObserver& aObserver, ErrorResult& aRv); - DesktopNotificationCenter* GetMozNotification(ErrorResult& aRv); already_AddRefed MozTCPSocket(); network::Connection* GetConnection(ErrorResult& aRv); MediaDevices* GetMediaDevices(ErrorResult& aRv); @@ -275,7 +273,6 @@ private: RefPtr mPlugins; RefPtr mPermissions; RefPtr mGeolocation; - RefPtr mNotification; RefPtr mBatteryManager; RefPtr mBatteryPromise; RefPtr mConnection; diff --git a/dom/notification/DesktopNotification.cpp b/dom/notification/DesktopNotification.cpp deleted file mode 100644 index 2ba872398282..000000000000 --- a/dom/notification/DesktopNotification.cpp +++ /dev/null @@ -1,332 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "mozilla/dom/DesktopNotification.h" -#include "mozilla/dom/DesktopNotificationBinding.h" -#include "mozilla/dom/AppNotificationServiceOptionsBinding.h" -#include "mozilla/dom/ToJSValue.h" -#include "mozilla/EventStateManager.h" -#include "nsComponentManagerUtils.h" -#include "nsContentPermissionHelper.h" -#include "nsXULAppAPI.h" -#include "mozilla/dom/PBrowserChild.h" -#include "mozilla/Preferences.h" -#include "nsGlobalWindow.h" -#include "nsIScriptSecurityManager.h" -#include "nsServiceManagerUtils.h" -#include "PermissionMessageUtils.h" -#include "nsILoadContext.h" - -namespace mozilla { -namespace dom { - -/* - * Simple Request - */ -class DesktopNotificationRequest : public nsIContentPermissionRequest - , public Runnable -{ - virtual ~DesktopNotificationRequest() - { - } - - nsCOMPtr mRequester; -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSICONTENTPERMISSIONREQUEST - - explicit DesktopNotificationRequest(DesktopNotification* aNotification) - : Runnable("dom::DesktopNotificationRequest") - , mDesktopNotification(aNotification) - { - mRequester = new nsContentPermissionRequester(mDesktopNotification->GetOwner()); - } - - NS_IMETHOD Run() override - { - nsCOMPtr window = mDesktopNotification->GetOwner(); - nsContentPermissionUtils::AskPermission(this, window); - return NS_OK; - } - - RefPtr mDesktopNotification; -}; - -/* ------------------------------------------------------------------------ */ -/* AlertServiceObserver */ -/* ------------------------------------------------------------------------ */ - -NS_IMPL_ISUPPORTS(AlertServiceObserver, nsIObserver) - -/* ------------------------------------------------------------------------ */ -/* DesktopNotification */ -/* ------------------------------------------------------------------------ */ - -uint32_t DesktopNotification::sCount = 0; - -nsresult -DesktopNotification::PostDesktopNotification() -{ - if (!mObserver) { - mObserver = new AlertServiceObserver(this); - } - - nsCOMPtr alerts = do_GetService("@mozilla.org/alerts-service;1"); - if (!alerts) { - return NS_ERROR_NOT_IMPLEMENTED; - } - - // Generate a unique name (which will also be used as a cookie) because - // the nsIAlertsService will coalesce notifications with the same name. - // In the case of IPC, the parent process will use the cookie to map - // to nsIObservers, thus cookies must be unique to differentiate observers. - nsString uniqueName = NS_LITERAL_STRING("desktop-notification:"); - uniqueName.AppendInt(sCount++); - nsCOMPtr owner = GetOwner(); - if (!owner) { - return NS_ERROR_FAILURE; - } - nsCOMPtr doc = owner->GetDoc(); - nsIPrincipal* principal = doc->NodePrincipal(); - nsCOMPtr loadContext = doc->GetLoadContext(); - bool inPrivateBrowsing = loadContext && loadContext->UsePrivateBrowsing(); - nsCOMPtr alert = - do_CreateInstance(ALERT_NOTIFICATION_CONTRACTID); - NS_ENSURE_TRUE(alert, NS_ERROR_FAILURE); - nsresult rv = alert->Init(uniqueName, mIconURL, mTitle, - mDescription, - true, - uniqueName, - NS_LITERAL_STRING("auto"), - EmptyString(), - EmptyString(), - principal, - inPrivateBrowsing, - false /* requireInteraction */); - NS_ENSURE_SUCCESS(rv, rv); - return alerts->ShowAlert(alert, mObserver); -} - -DesktopNotification::DesktopNotification(const nsAString & title, - const nsAString & description, - const nsAString & iconURL, - nsPIDOMWindowInner* aWindow, - bool aIsHandlingUserInput, - nsIPrincipal* principal) - : DOMEventTargetHelper(aWindow) - , mTitle(title) - , mDescription(description) - , mIconURL(iconURL) - , mPrincipal(principal) - , mIsHandlingUserInput(aIsHandlingUserInput) - , mAllow(false) - , mShowHasBeenCalled(false) -{ - if (Preferences::GetBool("notification.disabled", false)) { - return; - } - - // If we are in testing mode (running mochitests, for example) - // and we are suppose to allow requests, then just post an allow event. - if (Preferences::GetBool("notification.prompt.testing", false) && - Preferences::GetBool("notification.prompt.testing.allow", true)) { - mAllow = true; - } -} - -void -DesktopNotification::Init() -{ - RefPtr request = new DesktopNotificationRequest(this); - - NS_DispatchToMainThread(request); -} - -DesktopNotification::~DesktopNotification() -{ - if (mObserver) { - mObserver->Disconnect(); - } -} - -void -DesktopNotification::DispatchNotificationEvent(const nsString& aName) -{ - if (NS_FAILED(CheckInnerWindowCorrectness())) { - return; - } - - RefPtr event = NS_NewDOMEvent(this, nullptr, nullptr); - // it doesn't bubble, and it isn't cancelable - event->InitEvent(aName, false, false); - event->SetTrusted(true); - bool dummy; - DispatchEvent(event, &dummy); -} - -nsresult -DesktopNotification::SetAllow(bool aAllow) -{ - mAllow = aAllow; - - // if we have called Show() already, lets go ahead and post a notification - if (mShowHasBeenCalled && aAllow) { - return PostDesktopNotification(); - } - - return NS_OK; -} - -void -DesktopNotification::HandleAlertServiceNotification(const char *aTopic) -{ - if (NS_FAILED(CheckInnerWindowCorrectness())) { - return; - } - - if (!strcmp("alertclickcallback", aTopic)) { - DispatchNotificationEvent(NS_LITERAL_STRING("click")); - } else if (!strcmp("alertfinished", aTopic)) { - DispatchNotificationEvent(NS_LITERAL_STRING("close")); - } -} - -void -DesktopNotification::Show(ErrorResult& aRv) -{ - mShowHasBeenCalled = true; - - if (!mAllow) { - return; - } - - aRv = PostDesktopNotification(); -} - -JSObject* -DesktopNotification::WrapObject(JSContext* aCx, JS::Handle aGivenProto) -{ - return DesktopNotificationBinding::Wrap(aCx, this, aGivenProto); -} - -/* ------------------------------------------------------------------------ */ -/* DesktopNotificationCenter */ -/* ------------------------------------------------------------------------ */ - -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(DesktopNotificationCenter) -NS_IMPL_CYCLE_COLLECTING_ADDREF(DesktopNotificationCenter) -NS_IMPL_CYCLE_COLLECTING_RELEASE(DesktopNotificationCenter) -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DesktopNotificationCenter) - NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY - NS_INTERFACE_MAP_ENTRY(nsISupports) -NS_INTERFACE_MAP_END - -already_AddRefed -DesktopNotificationCenter::CreateNotification(const nsAString& aTitle, - const nsAString& aDescription, - const nsAString& aIconURL) -{ - MOZ_ASSERT(mOwner); - - RefPtr notification = - new DesktopNotification(aTitle, - aDescription, - aIconURL, - mOwner, - EventStateManager::IsHandlingUserInput(), - mPrincipal); - notification->Init(); - return notification.forget(); -} - -JSObject* -DesktopNotificationCenter::WrapObject(JSContext* aCx, JS::Handle aGivenProto) -{ - return DesktopNotificationCenterBinding::Wrap(aCx, this, aGivenProto); -} - -/* ------------------------------------------------------------------------ */ -/* DesktopNotificationRequest */ -/* ------------------------------------------------------------------------ */ - -NS_IMPL_ISUPPORTS_INHERITED(DesktopNotificationRequest, Runnable, - nsIContentPermissionRequest) - -NS_IMETHODIMP -DesktopNotificationRequest::GetPrincipal(nsIPrincipal * *aRequestingPrincipal) -{ - if (!mDesktopNotification) { - return NS_ERROR_NOT_INITIALIZED; - } - - NS_IF_ADDREF(*aRequestingPrincipal = mDesktopNotification->mPrincipal); - return NS_OK; -} - -NS_IMETHODIMP -DesktopNotificationRequest::GetWindow(mozIDOMWindow** aRequestingWindow) -{ - if (!mDesktopNotification) { - return NS_ERROR_NOT_INITIALIZED; - } - - NS_IF_ADDREF(*aRequestingWindow = mDesktopNotification->GetOwner()); - return NS_OK; -} - -NS_IMETHODIMP -DesktopNotificationRequest::GetElement(nsIDOMElement * *aElement) -{ - NS_ENSURE_ARG_POINTER(aElement); - *aElement = nullptr; - return NS_OK; -} - -NS_IMETHODIMP -DesktopNotificationRequest::GetIsHandlingUserInput(bool *aIsHandlingUserInput) -{ - *aIsHandlingUserInput = mDesktopNotification->mIsHandlingUserInput; - return NS_OK; -} - -NS_IMETHODIMP -DesktopNotificationRequest::Cancel() -{ - nsresult rv = mDesktopNotification->SetAllow(false); - mDesktopNotification = nullptr; - return rv; -} - -NS_IMETHODIMP -DesktopNotificationRequest::Allow(JS::HandleValue aChoices) -{ - MOZ_ASSERT(aChoices.isUndefined()); - nsresult rv = mDesktopNotification->SetAllow(true); - mDesktopNotification = nullptr; - return rv; -} - -NS_IMETHODIMP -DesktopNotificationRequest::GetRequester(nsIContentPermissionRequester** aRequester) -{ - NS_ENSURE_ARG_POINTER(aRequester); - - nsCOMPtr requester = mRequester; - requester.forget(aRequester); - return NS_OK; -} - -NS_IMETHODIMP -DesktopNotificationRequest::GetTypes(nsIArray** aTypes) -{ - nsTArray emptyOptions; - return nsContentPermissionUtils::CreatePermissionArray(NS_LITERAL_CSTRING("desktop-notification"), - NS_LITERAL_CSTRING("unused"), - emptyOptions, - aTypes); -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/notification/DesktopNotification.h b/dom/notification/DesktopNotification.h deleted file mode 100644 index 763b5744393d..000000000000 --- a/dom/notification/DesktopNotification.h +++ /dev/null @@ -1,178 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_DesktopNotification_h -#define mozilla_dom_DesktopNotification_h - -#include "nsIPrincipal.h" -#include "nsIAlertsService.h" -#include "nsIContentPermissionPrompt.h" - -#include "nsIObserver.h" -#include "nsString.h" -#include "nsWeakPtr.h" -#include "nsCycleCollectionParticipant.h" -#include "nsIDOMWindow.h" -#include "nsIScriptObjectPrincipal.h" - -#include "nsIDOMEvent.h" - -#include "mozilla/Attributes.h" -#include "mozilla/DOMEventTargetHelper.h" -#include "mozilla/ErrorResult.h" -#include "nsWrapperCache.h" - - -namespace mozilla { -namespace dom { - -class AlertServiceObserver; -class DesktopNotification; - -/* - * DesktopNotificationCenter - * Object hangs off of the navigator object and hands out DesktopNotification objects - */ -class DesktopNotificationCenter final : public nsISupports, - public nsWrapperCache -{ -public: - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DesktopNotificationCenter) - - explicit DesktopNotificationCenter(nsPIDOMWindowInner* aWindow) - { - MOZ_ASSERT(aWindow); - mOwner = aWindow; - - nsCOMPtr sop = do_QueryInterface(aWindow); - MOZ_ASSERT(sop); - - mPrincipal = sop->GetPrincipal(); - MOZ_ASSERT(mPrincipal); - } - - void Shutdown() { - mOwner = nullptr; - } - - nsPIDOMWindowInner* GetParentObject() const - { - return mOwner; - } - - virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; - - already_AddRefed - CreateNotification(const nsAString& title, - const nsAString& description, - const nsAString& iconURL); - -private: - virtual ~DesktopNotificationCenter() - { - } - - nsCOMPtr mOwner; - nsCOMPtr mPrincipal; -}; - -class DesktopNotificationRequest; - -class DesktopNotification final : public DOMEventTargetHelper -{ - friend class DesktopNotificationRequest; - -public: - - DesktopNotification(const nsAString& aTitle, - const nsAString& aDescription, - const nsAString& aIconURL, - nsPIDOMWindowInner* aWindow, - bool aIsHandlingUserInput, - nsIPrincipal* principal); - - virtual ~DesktopNotification(); - - void Init(); - - /* - * PostDesktopNotification - * Uses alert service to display a notification - */ - nsresult PostDesktopNotification(); - - nsresult SetAllow(bool aAllow); - - /* - * Creates and dispatches a dom event of type aName - */ - void DispatchNotificationEvent(const nsString& aName); - - void HandleAlertServiceNotification(const char *aTopic); - - // WebIDL - - nsPIDOMWindowInner* GetParentObject() const - { - return GetOwner(); - } - - virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; - - void Show(ErrorResult& aRv); - - IMPL_EVENT_HANDLER(click) - IMPL_EVENT_HANDLER(close) - -protected: - - nsString mTitle; - nsString mDescription; - nsString mIconURL; - - RefPtr mObserver; - nsCOMPtr mPrincipal; - bool mIsHandlingUserInput; - bool mAllow; - bool mShowHasBeenCalled; - - static uint32_t sCount; -}; - -class AlertServiceObserver: public nsIObserver -{ - public: - NS_DECL_ISUPPORTS - - explicit AlertServiceObserver(DesktopNotification* notification) - : mNotification(notification) {} - - void Disconnect() { mNotification = nullptr; } - - NS_IMETHOD - Observe(nsISupports* aSubject, - const char* aTopic, - const char16_t* aData) override - { - - // forward to parent - if (mNotification) { - mNotification->HandleAlertServiceNotification(aTopic); - } - return NS_OK; - }; - - private: - virtual ~AlertServiceObserver() {} - - DesktopNotification* mNotification; -}; - -} // namespace dom -} // namespace mozilla - -#endif /* mozilla_dom_DesktopNotification_h */ diff --git a/dom/notification/moz.build b/dom/notification/moz.build index 819743b1fd28..7137cda48ba4 100644 --- a/dom/notification/moz.build +++ b/dom/notification/moz.build @@ -17,13 +17,11 @@ EXTRA_JS_MODULES += [ ] EXPORTS.mozilla.dom += [ - 'DesktopNotification.h', 'Notification.h', 'NotificationEvent.h', ] UNIFIED_SOURCES += [ - 'DesktopNotification.cpp', 'Notification.cpp', 'NotificationEvent.cpp', ] @@ -40,6 +38,8 @@ LOCAL_INCLUDES += [ BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini'] XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini'] MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini'] +MOCHITEST_CHROME_MANIFESTS += ['test/chrome/chrome.ini'] + if CONFIG['CC_TYPE'] in ('clang', 'gcc'): CXXFLAGS += ['-Wno-error=shadow'] diff --git a/dom/notification/test/chrome/chrome.ini b/dom/notification/test/chrome/chrome.ini new file mode 100644 index 000000000000..e049dc98c108 --- /dev/null +++ b/dom/notification/test/chrome/chrome.ini @@ -0,0 +1 @@ +[test_notification_system_principal.xul] \ No newline at end of file diff --git a/dom/tests/mochitest/notification/desktop-notification/test_system_principal.xul b/dom/notification/test/chrome/test_notification_system_principal.xul similarity index 100% rename from dom/tests/mochitest/notification/desktop-notification/test_system_principal.xul rename to dom/notification/test/chrome/test_notification_system_principal.xul diff --git a/dom/tests/mochitest/notification/desktop-notification/create_notification.html b/dom/notification/test/mochitest/create_notification.html similarity index 100% rename from dom/tests/mochitest/notification/desktop-notification/create_notification.html rename to dom/notification/test/mochitest/create_notification.html diff --git a/dom/notification/test/mochitest/mochitest.ini b/dom/notification/test/mochitest/mochitest.ini index c0de5ed461a4..32045f1c80f9 100644 --- a/dom/notification/test/mochitest/mochitest.ini +++ b/dom/notification/test/mochitest/mochitest.ini @@ -1,6 +1,7 @@ [DEFAULT] support-files = + create_notification.html MockServices.js NotificationTest.js @@ -8,3 +9,4 @@ support-files = [test_notification_storage.html] [test_bug931307.html] skip-if = (os == 'android') # Bug 1258975 on android. +[test_notification_tag.html] \ No newline at end of file diff --git a/dom/tests/mochitest/notification/desktop-notification/test_notification_tag.html b/dom/notification/test/mochitest/test_notification_tag.html similarity index 100% rename from dom/tests/mochitest/notification/desktop-notification/test_notification_tag.html rename to dom/notification/test/mochitest/test_notification_tag.html diff --git a/dom/tests/mochitest/general/test_interfaces.js b/dom/tests/mochitest/general/test_interfaces.js index 56979977fd87..259f0d186867 100644 --- a/dom/tests/mochitest/general/test_interfaces.js +++ b/dom/tests/mochitest/general/test_interfaces.js @@ -270,10 +270,6 @@ var interfaceNamesInGlobalScope = "DataTransferItemList", // IMPORTANT: Do not change this list without review from a DOM peer! "DelayNode", -// IMPORTANT: Do not change this list without review from a DOM peer! - "DesktopNotification", -// IMPORTANT: Do not change this list without review from a DOM peer! - "DesktopNotificationCenter", // IMPORTANT: Do not change this list without review from a DOM peer! "DeviceLightEvent", // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/tests/mochitest/notification/desktop-notification/moz.build b/dom/tests/mochitest/notification/desktop-notification/moz.build deleted file mode 100644 index 28919c271d33..000000000000 --- a/dom/tests/mochitest/notification/desktop-notification/moz.build +++ /dev/null @@ -1,6 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - diff --git a/dom/tests/mochitest/notification/desktop-notification/notification_common.js b/dom/tests/mochitest/notification/desktop-notification/notification_common.js deleted file mode 100644 index 921b1e753cd8..000000000000 --- a/dom/tests/mochitest/notification/desktop-notification/notification_common.js +++ /dev/null @@ -1,70 +0,0 @@ -const MOCK_ALERTS_CID = SpecialPowers.wrap(SpecialPowers.Components).ID("{48068bc2-40ab-4904-8afd-4cdfb3a385f3}"); -const ALERTS_SERVICE_CONTRACT_ID = "@mozilla.org/alerts-service;1"; - -const MOCK_SYSTEM_ALERTS_CID = SpecialPowers.wrap(SpecialPowers.Components).ID("{e86d888c-e41b-4b78-9104-2f2742a532de}"); -const SYSTEM_ALERTS_SERVICE_CONTRACT_ID = "@mozilla.org/system-alerts-service;1"; - -var registrar = SpecialPowers.wrap(SpecialPowers.Components).manager. - QueryInterface(SpecialPowers.Ci.nsIComponentRegistrar); - -var mockAlertsService = { - showAlert: function(alert, alertListener) { - // probably should do this async.... - SpecialPowers.wrap(alertListener).observe(null, "alertshow", alert.cookie); - - if (SpecialPowers.getBoolPref("notification.prompt.testing.click_on_notification") == true) { - SpecialPowers.wrap(alertListener).observe(null, "alertclickcallback", alert.cookie); - } - - SpecialPowers.wrap(alertListener).observe(null, "alertfinished", alert.cookie); - }, - - showAlertNotification: function(imageUrl, title, text, textClickable, - cookie, alertListener, name, bidi, - lang, data) { - return this.showAlert({ - cookie: cookie - }, alertListener); - }, - - QueryInterface: function(aIID) { - if (SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsISupports) || - SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsIAlertsService)) { - return this; - } - throw SpecialPowers.Components.results.NS_ERROR_NO_INTERFACE; - }, - - createInstance: function(aOuter, aIID) { - if (aOuter != null) { - throw SpecialPowers.Components.results.NS_ERROR_NO_AGGREGATION; - } - return this.QueryInterface(aIID); - } -}; -mockAlertsService = SpecialPowers.wrapCallbackObject(mockAlertsService); - -function setup_notifications(allowPrompt, forceClick, callback) { - SpecialPowers.pushPrefEnv({'set': [["notification.prompt.testing", true], - ["notification.prompt.testing.allow", allowPrompt], - ["notification.prompt.testing.click_on_notification", forceClick]]}, - callback); - - registrar.registerFactory(MOCK_SYSTEM_ALERTS_CID, "system alerts service", - SYSTEM_ALERTS_SERVICE_CONTRACT_ID, - mockAlertsService); - - registrar.registerFactory(MOCK_ALERTS_CID, "alerts service", - ALERTS_SERVICE_CONTRACT_ID, - mockAlertsService); -} - -function reset_notifications() { - registrar.unregisterFactory(MOCK_SYSTEM_ALERTS_CID, mockAlertsService); - registrar.unregisterFactory(MOCK_ALERTS_CID, mockAlertsService); -} - -function is_feature_enabled() { - return navigator.mozNotification && SpecialPowers.getBoolPref("notification.feature.enabled"); -} - diff --git a/dom/tests/mochitest/notification/desktop-notification/test_basic_notification.html b/dom/tests/mochitest/notification/desktop-notification/test_basic_notification.html deleted file mode 100644 index 75f3c84b4ab9..000000000000 --- a/dom/tests/mochitest/notification/desktop-notification/test_basic_notification.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - Basic functional test - - - - - -Basic property tests -

- -
-
- - - diff --git a/dom/tests/mochitest/notification/desktop-notification/test_basic_notification_click.html b/dom/tests/mochitest/notification/desktop-notification/test_basic_notification_click.html deleted file mode 100644 index defa0f412099..000000000000 --- a/dom/tests/mochitest/notification/desktop-notification/test_basic_notification_click.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - Basic functional test - - - - - -Basic property tests -

- -
-
- - - diff --git a/dom/tests/mochitest/notification/desktop-notification/test_leak_windowClose.html b/dom/tests/mochitest/notification/desktop-notification/test_leak_windowClose.html deleted file mode 100644 index 136ea049565f..000000000000 --- a/dom/tests/mochitest/notification/desktop-notification/test_leak_windowClose.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - Test for leak when window closes - - - - - - - -

I like to write tests

- - diff --git a/dom/webidl/DesktopNotification.webidl b/dom/webidl/DesktopNotification.webidl deleted file mode 100644 index 18bfce9dc5fe..000000000000 --- a/dom/webidl/DesktopNotification.webidl +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -interface MozObserver; - -[HeaderFile="mozilla/dom/DesktopNotification.h"] -interface DesktopNotificationCenter -{ - [NewObject] - DesktopNotification createNotification(DOMString title, - DOMString description, - optional DOMString iconURL = ""); -}; - -interface DesktopNotification : EventTarget -{ - [Throws] - void show(); - - attribute EventHandler onclick; - - attribute EventHandler onclose; -}; diff --git a/dom/webidl/Navigator.webidl b/dom/webidl/Navigator.webidl index 5ec8743ab92f..f10fa4b0cd3f 100644 --- a/dom/webidl/Navigator.webidl +++ b/dom/webidl/Navigator.webidl @@ -200,12 +200,6 @@ partial interface Navigator { void removeIdleObserver(MozIdleObserver aIdleObserver); }; -// nsIDOMNavigatorDesktopNotification -partial interface Navigator { - [Throws, Pref="notification.feature.enabled", UnsafeInPrerendering] - readonly attribute DesktopNotificationCenter mozNotification; -}; - // NetworkInformation partial interface Navigator { [Throws, Pref="dom.netinfo.enabled"] diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index 25aad128ef7a..3929d2b9d928 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -97,9 +97,6 @@ with Files("DelayNode.webidl"): with Files("DynamicsCompressorNode.webidl"): BUG_COMPONENT = ("Core", "Web Audio") -with Files("DesktopNotification.webidl"): - BUG_COMPONENT = ("Toolkit", "Notifications and Alerts") - with Files("FakePluginTagInit.webidl"): BUG_COMPONENT = ("Core", "Plug-ins") @@ -478,7 +475,6 @@ WEBIDL_FILES = [ 'DecoderDoctorNotification.webidl', 'DedicatedWorkerGlobalScope.webidl', 'DelayNode.webidl', - 'DesktopNotification.webidl', 'DeviceMotionEvent.webidl', 'Directory.webidl', 'Document.webidl', diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 2118cb4058a3..10b7611fb275 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5026,9 +5026,6 @@ pref("extensions.webcompat-reporter.enabled", false); pref("network.buffer.cache.count", 24); pref("network.buffer.cache.size", 32768); -// Desktop Notification -pref("notification.feature.enabled", false); - // Web Notification pref("dom.webnotifications.enabled", true); pref("dom.webnotifications.serviceworker.enabled", true); diff --git a/widget/cocoa/OSXNotificationCenter.h b/widget/cocoa/OSXNotificationCenter.h index 30767b5c55a6..4c356dad2c99 100644 --- a/widget/cocoa/OSXNotificationCenter.h +++ b/widget/cocoa/OSXNotificationCenter.h @@ -13,6 +13,11 @@ #include "nsTArray.h" #include "mozilla/RefPtr.h" +// mozNotificationCenterDelegate is used to access the macOS notification +// center. It is not related to the DesktopNotificationCenter object, which was +// removed in bug 952453. While there are no direct references to this class +// elsewhere, removing this will cause push notifications on macOS to stop +// working. @class mozNotificationCenterDelegate; #if !defined(MAC_OS_X_VERSION_10_8) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8) From efe66e5e3a5d50e91ed7fd980af23fc816bbc4c9 Mon Sep 17 00:00:00 2001 From: Kyle Machulis Date: Fri, 5 Jan 2018 13:32:18 -0800 Subject: [PATCH 06/33] Bug 952453 - Fix test_notification_tag to point to correct location for create_notification.html; r=mattn MozReview-Commit-ID: 9T3zhihWGvC --- dom/notification/test/mochitest/test_notification_tag.html | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dom/notification/test/mochitest/test_notification_tag.html b/dom/notification/test/mochitest/test_notification_tag.html index 37bcb16c0299..86efaece6abc 100644 --- a/dom/notification/test/mochitest/test_notification_tag.html +++ b/dom/notification/test/mochitest/test_notification_tag.html @@ -91,12 +91,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=782211 // Load two frames with the same origin that create notification with the same tag. // Both pages should generate notifications with the same name, and thus the second // notification should replace the first. - frames["sameDomain"].location.href = "http://test1.example.org:80/tests/dom/tests/mochitest/notification/create_notification.html"; - frames["anotherSameDomain"].location.href = "http://test1.example.org:80/tests/dom/tests/mochitest/notification/create_notification.html"; - + frames["sameDomain"].location.href = "http://test1.example.org:80/tests/dom/notification/test/mochitest/create_notification.html"; + frames["anotherSameDomain"].location.href = "http://test1.example.org:80/tests/dom/notification/test/mochitest/create_notification.html"; // Load a frame with a different origin that creates a notification with the same tag. // The notification name should be different and thus no notifications should be replaced. - frames["crossDomain"].location.href = "http://test2.example.org:80/tests/dom/tests/mochitest/notification/create_notification.html"; + frames["crossDomain"].location.href = "http://test2.example.org:80/tests/dom/notification/test/mochitest/create_notification.html"; } SpecialPowers.pushPrefEnv({'set': [["notification.prompt.testing", true], From 14221de9402e7cc70789ef4ff6d67d142d851736 Mon Sep 17 00:00:00 2001 From: Robert Longson Date: Mon, 8 Jan 2018 14:17:25 -0800 Subject: [PATCH 07/33] (no bug): Fix typo in code-comment, in nsSVGElement.cpp. r=dholbert DONTBUILD because comment-only --- dom/svg/nsSVGElement.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dom/svg/nsSVGElement.cpp b/dom/svg/nsSVGElement.cpp index aa1d342ffcee..df53980a3178 100644 --- a/dom/svg/nsSVGElement.cpp +++ b/dom/svg/nsSVGElement.cpp @@ -2385,12 +2385,12 @@ nsSVGElement::DidAnimateTransformList(int32_t aModType) transformAttr, aModType); // When script changes the 'transform' attribute, Element::SetAttrAndNotify - // will call nsNodeUtills::AttributeChanged, under which + // will call nsNodeUtils::AttributeChanged, under which // SVGTransformableElement::GetAttributeChangeHint will be called and an // appropriate change event posted to update our frame's overflow rects. // The SetAttrAndNotify doesn't happen for transform changes caused by // 'animateTransform' though (and sending out the mutation events that - // nsNodeUtills::AttributeChanged dispatches would be inappropriate + // nsNodeUtils::AttributeChanged dispatches would be inappropriate // anyway), so we need to post the change event ourself. nsChangeHint changeHint = GetAttributeChangeHint(transformAttr, aModType); if (changeHint) { From 48ac04d542e238a4ee445b592bb62900d8a25737 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 9 Jan 2018 08:22:02 +0900 Subject: [PATCH 08/33] Bug 1420449 - Fixup after bug 1427312. r=me --- taskcluster/taskgraph/transforms/diffoscope.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/taskcluster/taskgraph/transforms/diffoscope.py b/taskcluster/taskgraph/transforms/diffoscope.py index 7a80f5923514..6236138ec847 100644 --- a/taskcluster/taskgraph/transforms/diffoscope.py +++ b/taskcluster/taskgraph/transforms/diffoscope.py @@ -53,9 +53,10 @@ diff_description_schema = Schema({ @transforms.add def validate(config, tasks): for task in tasks: - yield validate_schema( + validate_schema( diff_description_schema, task, "In diff task {!r}:".format(task.get('name', 'unknown'))) + yield task @transforms.add From 71de2763a6ee29a574025db14c0dfa367b29a017 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Wed, 3 Jan 2018 18:31:31 +1300 Subject: [PATCH 09/33] Bug 1427476 - Don't try to retain display lists for popups since their display root isn't the root frame of a document. r=miko --HG-- extra : rebase_source : a924322e5cae1ba25526bc258ab18af50d37d66a --- layout/base/nsLayoutUtils.cpp | 5 ++++- layout/generic/nsFrame.cpp | 4 +++- layout/painting/RetainedDisplayListBuilder.cpp | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 594cff43d9de..095d8333a1c3 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -3636,7 +3636,10 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame, const bool isForPainting = (aFlags & PaintFrameFlags::PAINT_WIDGET_LAYERS) && aBuilderMode == nsDisplayListBuilderMode::PAINTING; - const bool retainingEnabled = isForPainting && AreRetainedDisplayListsEnabled(); + // Only allow retaining for painting when preffed on, and for root frames (since + // the modified frame tracking is per-root-frame). + const bool retainingEnabled = + isForPainting && AreRetainedDisplayListsEnabled() && !aFrame->GetParent(); RetainedDisplayListBuilder* retainedBuilder = GetOrCreateRetainedDisplayListBuilder(aFrame, retainingEnabled, buildCaret); diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 67bd331a9302..5c20786934c6 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -997,7 +997,9 @@ nsIFrame::RemoveDisplayItemDataForDeletion() void nsIFrame::MarkNeedsDisplayItemRebuild() { - if (!nsLayoutUtils::AreRetainedDisplayListsEnabled() || IsFrameModified()) { + if (!nsLayoutUtils::AreRetainedDisplayListsEnabled() || + IsFrameModified() || + HasAnyStateBits(NS_FRAME_IN_POPUP)) { // Skip frames that are already marked modified. return; } diff --git a/layout/painting/RetainedDisplayListBuilder.cpp b/layout/painting/RetainedDisplayListBuilder.cpp index 9bac90963b65..c8c35fe644be 100644 --- a/layout/painting/RetainedDisplayListBuilder.cpp +++ b/layout/painting/RetainedDisplayListBuilder.cpp @@ -603,6 +603,10 @@ RetainedDisplayListBuilder::ComputeRebuildRegion(nsTArray& aModifiedF aOutFramesWithProps->AppendElement(f); } + if (f->HasAnyStateBits(NS_FRAME_IN_POPUP)) { + continue; + } + // TODO: There is almost certainly a faster way of doing this, probably can be combined with the ancestor // walk for TransformFrameRectToAncestor. AnimatedGeometryRoot* agr = mBuilder.FindAnimatedGeometryRootFor(f)->GetAsyncAGR(); From b4f92760970b19f58e87e56a77ed02d721e2222f Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Tue, 9 Jan 2018 11:56:44 +1300 Subject: [PATCH 10/33] Bug 1427914 - Move the AnyContentAncestorModified check up into ComputeVisibleRectForFrame since it affects the resulting dirty rect. r=miko --HG-- extra : rebase_source : b450b026ba3e28b76e2176f7e58bbbd138c9d342 --- layout/painting/nsDisplayList.cpp | 26 -------------------------- layout/painting/nsDisplayList.h | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 62658a9ea7e0..190bc9f02503 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -1169,24 +1169,6 @@ nsDisplayListBuilder::FindAnimatedGeometryRootFor(nsDisplayItem* aItem) return FindAnimatedGeometryRootFor(aItem->Frame()); } -static bool -AnyContentAncestorModified(nsIFrame* aFrame, - nsIFrame* aStopAtFrame = nullptr) -{ - for (nsIFrame* f = aFrame; f; - f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) { - if (f->IsFrameModified()) { - return true; - } - - if (aStopAtFrame && f == aStopAtFrame) { - break; - } - } - - return false; -} - bool nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame) { @@ -1200,14 +1182,6 @@ bool nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, return false; } - // If the nearest stacking context for the modified frame is an ancestor of - // of it, and if the stacking context is a descendant of the containing block - // of this OOF frame, we override the dirty rect to ensure that the frame will - // get marked. - if (AnyContentAncestorModified(aFrame, aDirtyFrame)) { - dirty = visible; - } - // Only MarkFrameForDisplay if we're dirty. If this is a nested out-of-flow frame, then it will // also mark any outer frames to ensure that building reaches the dirty feame. if (!dirty.IsEmpty() || diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h index e43c6a6b67d6..4628f230eb92 100644 --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -1458,6 +1458,23 @@ public: nsRect mVisibleRect; nsRect mDirtyRect; + static bool + AnyContentAncestorModified(nsIFrame* aFrame, + nsIFrame* aStopAtFrame = nullptr) + { + for (nsIFrame* f = aFrame; f; + f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) { + if (f->IsFrameModified()) { + return true; + } + + if (aStopAtFrame && f == aStopAtFrame) { + break; + } + } + + return false; + } static nsRect ComputeVisibleRectForFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, @@ -1503,6 +1520,14 @@ public: visible.IntersectRect(visible, overflowRect); aOutDirtyRect->IntersectRect(*aOutDirtyRect, overflowRect); + + // If the nearest stacking context for the modified frame is an ancestor of + // of it, and if the stacking context is a descendant of the containing block + // of this OOF frame, we override the dirty rect to ensure that the frame will + // get marked. + if (AnyContentAncestorModified(aFrame, aFrame->GetParent())) { + *aOutDirtyRect = visible; + } return visible; } From 878412c69ae64f65289b1d2ae20665d523fc341f Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Tue, 9 Jan 2018 11:59:56 +1300 Subject: [PATCH 11/33] Bug 1427968 - Don't check for the force descend flag when checking for the presence of OutOfFlowDisplayData. r=miko --HG-- extra : rebase_source : 4ac2cce6aa0dd6e6299601da880770d938c6a513 --- layout/painting/nsDisplayList.cpp | 2 +- layout/painting/nsDisplayList.h | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 190bc9f02503..7a2f856b46c3 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -1189,7 +1189,7 @@ bool nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, MarkFrameForDisplay(aFrame, aDirtyFrame); } - return (aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO); + return true; } static void UnmarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame) { diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h index 4628f230eb92..204db39e9845 100644 --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -1550,8 +1550,7 @@ public: static OutOfFlowDisplayData* GetOutOfFlowData(nsIFrame* aFrame) { - if (!(aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) || - !aFrame->GetParent()) { + if (!aFrame->GetParent()) { return nullptr; } return aFrame->GetParent()->GetProperty(OutOfFlowDisplayDataProperty()); From b9fc4558b8fbccfc91a8008636f4aabc329989a0 Mon Sep 17 00:00:00 2001 From: Gerald Squelart Date: Sat, 25 Nov 2017 10:02:20 +1100 Subject: [PATCH 12/33] Bug 1418840 - Use the modified frames list for the subdoc that painting will use, which isn't always the current subdoc of the FrameOuter. r=mstange --HG-- extra : rebase_source : a01a93a91da776e3fc43debc5990440f8dc8dafc --- .../painting/RetainedDisplayListBuilder.cpp | 58 ++++++++++++++----- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/layout/painting/RetainedDisplayListBuilder.cpp b/layout/painting/RetainedDisplayListBuilder.cpp index c8c35fe644be..4ca467c20ad7 100644 --- a/layout/painting/RetainedDisplayListBuilder.cpp +++ b/layout/painting/RetainedDisplayListBuilder.cpp @@ -7,6 +7,7 @@ #include "RetainedDisplayListBuilder.h" #include "nsSubDocumentFrame.h" +#include "nsViewManager.h" /** * Code for doing display list building for a modified subset of the window, @@ -518,20 +519,48 @@ TakeAndAddModifiedFramesFromRootFrame(nsTArray& aFrames, frames->Clear(); } +struct CbData { + nsDisplayListBuilder* builder; + nsTArray modifiedFrames; +}; + static bool SubDocEnumCb(nsIDocument* aDocument, void* aData) { MOZ_ASSERT(aDocument); MOZ_ASSERT(aData); - nsTArray* modifiedFrames = - static_cast*>(aData); + CbData* data = static_cast(aData); + + // Although this is the actual subdocument, it might not be + // what painting uses. Walk up to the nsSubDocumentFrame owning + // us, and then ask that which subdoc it's going to paint. nsIPresShell* presShell = aDocument->GetShell(); - nsIFrame* rootFrame = presShell ? presShell->GetRootFrame() : nullptr; + if (presShell) { + nsView* rootView = presShell->GetViewManager()->GetRootView(); + MOZ_ASSERT(rootView); - if (rootFrame) { - TakeAndAddModifiedFramesFromRootFrame(*modifiedFrames, rootFrame); + // There should be an anonymous inner view between the root view + // of the subdoc, and the view for the nsSubDocumentFrame. + nsView* innerView = rootView->GetParent(); + MOZ_ASSERT(innerView); + + nsView* subDocView = innerView->GetParent(); + MOZ_ASSERT(subDocView); + + nsIFrame* subDocFrame = subDocView->GetFrame(); + MOZ_ASSERT(subDocFrame); + nsSubDocumentFrame* subdocumentFrame = do_QueryFrame(subDocFrame); + MOZ_ASSERT(subdocumentFrame); + + presShell = subdocumentFrame->GetSubdocumentPresShellForPainting( + data->builder->IsIgnoringPaintSuppression() ? nsSubDocumentFrame::IGNORE_PAINT_SUPPRESSION : 0); + nsIFrame* rootFrame = presShell ? presShell->GetRootFrame() : nullptr; + + if (rootFrame) { + TakeAndAddModifiedFramesFromRootFrame(data->modifiedFrames, rootFrame); + } } aDocument->EnumerateSubDocuments(SubDocEnumCb, aData); @@ -539,20 +568,21 @@ SubDocEnumCb(nsIDocument* aDocument, void* aData) } static nsTArray -GetModifiedFrames(nsIFrame* aDisplayRootFrame) +GetModifiedFrames(nsDisplayListBuilder* aBuilder) { - MOZ_ASSERT(aDisplayRootFrame); + MOZ_ASSERT(aBuilder->RootReferenceFrame()); - nsTArray modifiedFrames; - TakeAndAddModifiedFramesFromRootFrame(modifiedFrames, aDisplayRootFrame); + CbData data; + data.builder = aBuilder; + TakeAndAddModifiedFramesFromRootFrame(data.modifiedFrames, aBuilder->RootReferenceFrame()); - nsIDocument* rootdoc = aDisplayRootFrame->PresContext()->Document(); + nsIDocument* rootdoc = aBuilder->RootReferenceFrame()->PresContext()->Document(); if (rootdoc) { - rootdoc->EnumerateSubDocuments(SubDocEnumCb, &modifiedFrames); + rootdoc->EnumerateSubDocuments(SubDocEnumCb, &data); } - return modifiedFrames; + return Move(data.modifiedFrames); } // ComputeRebuildRegion debugging @@ -786,7 +816,7 @@ void RetainedDisplayListBuilder::ClearModifiedFrameProps() { nsTArray modifiedFrames = - GetModifiedFrames(mBuilder.RootReferenceFrame()); + GetModifiedFrames(&mBuilder); ClearFrameProps(modifiedFrames); } @@ -802,7 +832,7 @@ RetainedDisplayListBuilder::AttemptPartialUpdate(nscolor aBackstop) mBuilder.EnterPresShell(mBuilder.RootReferenceFrame()); nsTArray modifiedFrames = - GetModifiedFrames(mBuilder.RootReferenceFrame()); + GetModifiedFrames(&mBuilder); // Do not allow partial builds if the retained display list is empty, or if // ShouldBuildPartial heuristic fails. From 05a9191b3240c9ef15b0f458104d717f892a6c52 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 8 Jan 2018 17:43:51 -0600 Subject: [PATCH 13/33] Bug 1428453 - Baldr: move code and remove dead argument/field (r=bbouvier) MozReview-Commit-ID: IHXAThgE5VH --HG-- extra : rebase_source : 123a1376c40d00cbbf3b838e61b0b451dd975313 --- js/src/jscntxt.h | 3 ++ js/src/vm/Runtime.h | 3 -- js/src/vm/Stack.cpp | 2 +- js/src/wasm/WasmCode.cpp | 80 ++++++++++++++--------------- js/src/wasm/WasmCode.h | 2 +- js/src/wasm/WasmFrameIter.cpp | 82 ++++++++++++++---------------- js/src/wasm/WasmFrameIter.h | 5 +- js/src/wasm/WasmGenerator.cpp | 4 +- js/src/wasm/WasmProcess.cpp | 2 +- js/src/wasm/WasmSignalHandlers.cpp | 5 +- js/src/wasm/WasmTypes.h | 2 - 11 files changed, 91 insertions(+), 99 deletions(-) diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index e04e8c65a4ea..3a49af316dad 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -20,6 +20,9 @@ #include "vm/ErrorReporting.h" #include "vm/MallocProvider.h" #include "vm/Runtime.h" +#ifdef XP_DARWIN +# include "wasm/WasmSignalHandlers.h" +#endif #ifdef _MSC_VER #pragma warning(push) diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index 1316c53f0660..fe6e795abdd6 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -22,9 +22,6 @@ #include "jsatom.h" #include "jsscript.h" -#ifdef XP_DARWIN -# include "wasm/WasmSignalHandlers.h" -#endif #include "builtin/AtomicsObject.h" #include "builtin/Intl.h" #include "builtin/Promise.h" diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index 53a5ff086c80..c6f39b43589e 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -1709,7 +1709,7 @@ jit::JitActivation::startWasmInterrupt(const JS::ProfilingFrameIterator::Registe bool ignoredUnwound; wasm::UnwindState unwindState; - MOZ_ALWAYS_TRUE(wasm::StartUnwinding(*this, state, &unwindState, &ignoredUnwound)); + MOZ_ALWAYS_TRUE(wasm::StartUnwinding(state, &unwindState, &ignoredUnwound)); void* pc = unwindState.pc; MOZ_ASSERT(wasm::LookupCode(pc)->lookupRange(pc)->isFunction()); diff --git a/js/src/wasm/WasmCode.cpp b/js/src/wasm/WasmCode.cpp index a01a72696707..97194666bd29 100644 --- a/js/src/wasm/WasmCode.cpp +++ b/js/src/wasm/WasmCode.cpp @@ -767,46 +767,6 @@ struct CallSiteRetAddrOffset } }; -size_t -Code::serializedSize() const -{ - return metadata().serializedSize() + - segment(Tier::Serialized).serializedSize(); -} - -uint8_t* -Code::serialize(uint8_t* cursor, const LinkData& linkData) const -{ - MOZ_RELEASE_ASSERT(!metadata().debugEnabled); - - cursor = metadata().serialize(cursor); - cursor = segment(Tier::Serialized).serialize(cursor, linkData.linkData(Tier::Serialized)); - return cursor; -} - -const uint8_t* -Code::deserialize(const uint8_t* cursor, const SharedBytes& bytecode, const LinkData& linkData, - Metadata& metadata) -{ - cursor = metadata.deserialize(cursor); - if (!cursor) - return nullptr; - - UniqueCodeSegment codeSegment = js::MakeUnique(); - if (!codeSegment) - return nullptr; - - cursor = codeSegment->deserialize(cursor, *bytecode, linkData.linkData(Tier::Serialized), - metadata); - if (!cursor) - return nullptr; - - segment1_ = takeOwnership(Move(codeSegment)); - metadata_ = &metadata; - - return cursor; -} - const CallSite* Code::lookupCallSite(void* returnAddress) const { @@ -959,3 +919,43 @@ Code::addSizeOfMiscIfNotSeen(MallocSizeOf mallocSizeOf, for (auto t : tiers()) segment(t).addSizeOfMisc(mallocSizeOf, code, data); } + +size_t +Code::serializedSize() const +{ + return metadata().serializedSize() + + segment(Tier::Serialized).serializedSize(); +} + +uint8_t* +Code::serialize(uint8_t* cursor, const LinkData& linkData) const +{ + MOZ_RELEASE_ASSERT(!metadata().debugEnabled); + + cursor = metadata().serialize(cursor); + cursor = segment(Tier::Serialized).serialize(cursor, linkData.linkData(Tier::Serialized)); + return cursor; +} + +const uint8_t* +Code::deserialize(const uint8_t* cursor, const SharedBytes& bytecode, const LinkData& linkData, + Metadata& metadata) +{ + cursor = metadata.deserialize(cursor); + if (!cursor) + return nullptr; + + UniqueCodeSegment codeSegment = js::MakeUnique(); + if (!codeSegment) + return nullptr; + + cursor = codeSegment->deserialize(cursor, *bytecode, linkData.linkData(Tier::Serialized), + metadata); + if (!cursor) + return nullptr; + + segment1_ = takeOwnership(Move(codeSegment)); + metadata_ = &metadata; + + return cursor; +} diff --git a/js/src/wasm/WasmCode.h b/js/src/wasm/WasmCode.h index 466c14d5910f..772a661a6bb6 100644 --- a/js/src/wasm/WasmCode.h +++ b/js/src/wasm/WasmCode.h @@ -130,7 +130,7 @@ class CodeSegment code_ = code; } - const Code* code() const { MOZ_ASSERT(code_); return code_; } + const Code& code() const { MOZ_ASSERT(code_); return *code_; } Tier tier() const { return tier_; } uint8_t* base() const { return bytes_.get(); } diff --git a/js/src/wasm/WasmFrameIter.cpp b/js/src/wasm/WasmFrameIter.cpp index 9ef5b5132926..1723d63385b4 100644 --- a/js/src/wasm/WasmFrameIter.cpp +++ b/js/src/wasm/WasmFrameIter.cpp @@ -42,17 +42,6 @@ WasmFrameIter::WasmFrameIter(JitActivation* activation, wasm::Frame* fp) { MOZ_ASSERT(fp_); - // Normally, execution exits wasm code via an exit stub which sets exitFP - // to the exit stub's frame. Thus, in this case, we want to start iteration - // at the caller of the exit frame, whose Code, CodeRange and CallSite are - // indicated by the returnAddress of the exit stub's frame. - - if (!activation->isWasmInterrupted()) { - popFrame(); - MOZ_ASSERT(!done()); - return; - } - // When asynchronously interrupted, exitFP is set to the interrupted frame // itself and so we do not want to skip it. Instead, we can recover the // Code and CodeRange from the JitActivation, which are set when control @@ -61,12 +50,23 @@ WasmFrameIter::WasmFrameIter(JitActivation* activation, wasm::Frame* fp) // for which we can use the beginning of the function from the CodeRange // instead. - code_ = &fp_->tls->instance->code(); - MOZ_ASSERT(code_ == LookupCode(activation->wasmUnwindPC())); + if (activation->isWasmInterrupted()) { + code_ = &fp_->tls->instance->code(); + MOZ_ASSERT(code_ == LookupCode(activation->wasmUnwindPC())); - codeRange_ = code_->lookupRange(activation->wasmUnwindPC()); - MOZ_ASSERT(codeRange_->kind() == CodeRange::Function); + codeRange_ = code_->lookupRange(activation->wasmUnwindPC()); + MOZ_ASSERT(codeRange_->kind() == CodeRange::Function); + MOZ_ASSERT(!done()); + return; + } + + // Otherwise, execution exits wasm code via an exit stub which sets exitFP + // to the exit stub's frame. Thus, in this case, we want to start iteration + // at the caller of the exit frame, whose Code, CodeRange and CallSite are + // indicated by the returnAddress of the exit stub's frame. + + popFrame(); MOZ_ASSERT(!done()); } @@ -547,8 +547,7 @@ wasm::GenerateJitExitEpilogue(MacroAssembler& masm, unsigned framePushed, Callab // ProfilingFrameIterator ProfilingFrameIterator::ProfilingFrameIterator() - : activation_(nullptr), - code_(nullptr), + : code_(nullptr), codeRange_(nullptr), callerFP_(nullptr), callerPC_(nullptr), @@ -559,8 +558,7 @@ ProfilingFrameIterator::ProfilingFrameIterator() } ProfilingFrameIterator::ProfilingFrameIterator(const JitActivation& activation) - : activation_(&activation), - code_(nullptr), + : code_(nullptr), codeRange_(nullptr), callerFP_(nullptr), callerPC_(nullptr), @@ -571,8 +569,7 @@ ProfilingFrameIterator::ProfilingFrameIterator(const JitActivation& activation) } ProfilingFrameIterator::ProfilingFrameIterator(const JitActivation& activation, const Frame* fp) - : activation_(&activation), - code_(nullptr), + : code_(nullptr), codeRange_(nullptr), callerFP_(nullptr), callerPC_(nullptr), @@ -584,7 +581,7 @@ ProfilingFrameIterator::ProfilingFrameIterator(const JitActivation& activation, } static inline void -AssertMatchesCallSite(const JitActivation& activation, void* callerPC, Frame* callerFP) +AssertMatchesCallSite(void* callerPC, Frame* callerFP) { #ifdef DEBUG const Code* code = LookupCode(callerPC); @@ -633,7 +630,7 @@ ProfilingFrameIterator::initFromExitFP(const Frame* fp) fp = fp->callerFP; callerPC_ = fp->returnAddress; callerFP_ = fp->callerFP; - AssertMatchesCallSite(*activation_, callerPC_, callerFP_); + AssertMatchesCallSite(callerPC_, callerFP_); break; case CodeRange::ImportJitExit: case CodeRange::ImportInterpExit: @@ -652,8 +649,8 @@ ProfilingFrameIterator::initFromExitFP(const Frame* fp) } bool -js::wasm::StartUnwinding(const JitActivation& activation, const RegisterState& registers, - UnwindState* unwindState, bool* unwoundCaller) +js::wasm::StartUnwinding(const RegisterState& registers, UnwindState* unwindState, + bool* unwoundCaller) { // Shorthands. uint8_t* const pc = (uint8_t*) registers.pc; @@ -673,7 +670,7 @@ js::wasm::StartUnwinding(const JitActivation& activation, const RegisterState& r const CodeSegment* codeSegment = LookupCodeSegment(pc); if (codeSegment) { - code = codeSegment->code(); + code = &codeSegment->code(); codeRange = code->lookupRange(pc); codeBase = codeSegment->base(); } else if (!LookupBuiltinThunk(pc, &codeRange, &codeBase)) { @@ -731,14 +728,14 @@ js::wasm::StartUnwinding(const JitActivation& activation, const RegisterState& r // fp holds the caller's fp. fixedPC = (uint8_t*) registers.lr; fixedFP = fp; - AssertMatchesCallSite(activation, fixedPC, fixedFP); + AssertMatchesCallSite(fixedPC, fixedFP); } else #elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) if (offsetFromEntry == BeforePushRetAddr || codeRange->isThunk()) { // The return address is still in lr and fp holds the caller's fp. fixedPC = (uint8_t*) registers.lr; fixedFP = fp; - AssertMatchesCallSite(activation, fixedPC, fixedFP); + AssertMatchesCallSite(fixedPC, fixedFP); } else #endif if (offsetFromEntry == PushedRetAddr || codeRange->isThunk()) { @@ -746,26 +743,26 @@ js::wasm::StartUnwinding(const JitActivation& activation, const RegisterState& r // points to the caller's fp. fixedPC = sp[0]; fixedFP = fp; - AssertMatchesCallSite(activation, fixedPC, fixedFP); + AssertMatchesCallSite(fixedPC, fixedFP); } else if (offsetFromEntry >= PushedTLS && offsetFromEntry < PushedFP) { // The return address and caller's TLS have been pushed on the // stack; fp is still the caller's fp. fixedPC = sp[1]; fixedFP = fp; - AssertMatchesCallSite(activation, fixedPC, fixedFP); + AssertMatchesCallSite(fixedPC, fixedFP); } else if (offsetFromEntry == PushedFP) { // The full Frame has been pushed; fp is still the caller's fp. MOZ_ASSERT(fp == reinterpret_cast(sp)->callerFP); fixedPC = reinterpret_cast(sp)->returnAddress; fixedFP = fp; - AssertMatchesCallSite(activation, fixedPC, fixedFP); + AssertMatchesCallSite(fixedPC, fixedFP); } else if (offsetInCode >= codeRange->ret() - PoppedFP && offsetInCode < codeRange->ret() - PoppedTLSReg) { // The fixedFP field of the Frame has been popped into fp. fixedPC = sp[1]; fixedFP = fp; - AssertMatchesCallSite(activation, fixedPC, fixedFP); + AssertMatchesCallSite(fixedPC, fixedFP); #if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) } else if (offsetInCode >= codeRange->ret() - PoppedTLSReg && offsetInCode < codeRange->ret()) @@ -774,20 +771,20 @@ js::wasm::StartUnwinding(const JitActivation& activation, const RegisterState& r // exit reason hasn't been popped yet. fixedPC = sp[0]; fixedFP = fp; - AssertMatchesCallSite(activation, fixedPC, fixedFP); + AssertMatchesCallSite(fixedPC, fixedFP); } else if (offsetInCode == codeRange->ret()) { // Both the TLS, fixedFP and ra have been popped and fp now // points to the caller's frame. fixedPC = (uint8_t*) registers.lr; fixedFP = fp; - AssertMatchesCallSite(activation, fixedPC, fixedFP); + AssertMatchesCallSite(fixedPC, fixedFP); #else } else if (offsetInCode == codeRange->ret()) { // Both the TLS and fixedFP fields have been popped and fp now // points to the caller's frame. fixedPC = sp[0]; fixedFP = fp; - AssertMatchesCallSite(activation, fixedPC, fixedFP); + AssertMatchesCallSite(fixedPC, fixedFP); #endif } else { if (codeRange->kind() == CodeRange::ImportJitExit) { @@ -804,7 +801,7 @@ js::wasm::StartUnwinding(const JitActivation& activation, const RegisterState& r fixedPC = pc; fixedFP = fp; *unwoundCaller = false; - AssertMatchesCallSite(activation, fp->returnAddress, fp->callerFP); + AssertMatchesCallSite(fp->returnAddress, fp->callerFP); break; } break; @@ -815,7 +812,7 @@ js::wasm::StartUnwinding(const JitActivation& activation, const RegisterState& r fixedPC = pc; fixedFP = fp; *unwoundCaller = false; - AssertMatchesCallSite(activation, fp->returnAddress, fp->callerFP); + AssertMatchesCallSite(fp->returnAddress, fp->callerFP); break; case CodeRange::InterpEntry: // The entry trampoline is the final frame in an wasm JitActivation. The @@ -843,8 +840,7 @@ js::wasm::StartUnwinding(const JitActivation& activation, const RegisterState& r ProfilingFrameIterator::ProfilingFrameIterator(const JitActivation& activation, const RegisterState& state) - : activation_(&activation), - code_(nullptr), + : code_(nullptr), codeRange_(nullptr), callerFP_(nullptr), callerPC_(nullptr), @@ -862,7 +858,7 @@ ProfilingFrameIterator::ProfilingFrameIterator(const JitActivation& activation, bool unwoundCaller; UnwindState unwindState; - if (!StartUnwinding(*activation_, state, &unwindState, &unwoundCaller)) { + if (!StartUnwinding(state, &unwindState, &unwoundCaller)) { MOZ_ASSERT(done()); return; } @@ -924,7 +920,7 @@ ProfilingFrameIterator::operator++() case CodeRange::FarJumpIsland: stackAddress_ = callerFP_; callerPC_ = callerFP_->returnAddress; - AssertMatchesCallSite(*activation_, callerPC_, callerFP_->callerFP); + AssertMatchesCallSite(callerPC_, callerFP_->callerFP); callerFP_ = callerFP_->callerFP; break; case CodeRange::InterpEntry: @@ -1096,7 +1092,7 @@ wasm::LookupFaultingInstance(const CodeSegment& codeSegment, void* pc, void* fp) // simulators which call this function at every load/store before even // knowing whether there is a fault. - const CodeRange* codeRange = codeSegment.code()->lookupRange(pc); + const CodeRange* codeRange = codeSegment.code().lookupRange(pc); if (!codeRange || !codeRange->isFunction()) return nullptr; @@ -1107,7 +1103,7 @@ wasm::LookupFaultingInstance(const CodeSegment& codeSegment, void* pc, void* fp) return nullptr; Instance* instance = reinterpret_cast(fp)->tls->instance; - MOZ_RELEASE_ASSERT(&instance->code() == codeSegment.code()); + MOZ_RELEASE_ASSERT(&instance->code() == &codeSegment.code()); return instance; } diff --git a/js/src/wasm/WasmFrameIter.h b/js/src/wasm/WasmFrameIter.h index 8668b82c45fa..292bc0b5dafc 100644 --- a/js/src/wasm/WasmFrameIter.h +++ b/js/src/wasm/WasmFrameIter.h @@ -160,7 +160,6 @@ class ExitReason // asynchronously-interrupted thread's state. class ProfilingFrameIterator { - const jit::JitActivation* activation_; const Code* code_; const CodeRange* codeRange_; Frame* callerFP_; @@ -253,8 +252,8 @@ typedef JS::ProfilingFrameIterator::RegisterState RegisterState; // frame should be ignored. bool -StartUnwinding(const jit::JitActivation& activation, const RegisterState& registers, - UnwindState* unwindState, bool* unwoundCaller); +StartUnwinding(const RegisterState& registers, UnwindState* unwindState, + bool* unwoundCaller); } // namespace wasm } // namespace js diff --git a/js/src/wasm/WasmGenerator.cpp b/js/src/wasm/WasmGenerator.cpp index 7a875028a8df..070966ad92d5 100644 --- a/js/src/wasm/WasmGenerator.cpp +++ b/js/src/wasm/WasmGenerator.cpp @@ -206,8 +206,8 @@ ModuleGenerator::init(Metadata* maybeAsmJSMetadata) if (!metadataTier_->codeRanges.reserve(2 * env_->numFuncDefs())) return false; - const size_t CallSitesPerByteCode = 10; - if (!metadataTier_->callSites.reserve(codeSectionSize / CallSitesPerByteCode)) + const size_t ByteCodesPerCallSite = 10; + if (!metadataTier_->callSites.reserve(codeSectionSize / ByteCodesPerCallSite)) return false; const size_t MemoryAccessesPerByteCode = 10; diff --git a/js/src/wasm/WasmProcess.cpp b/js/src/wasm/WasmProcess.cpp index 9a9920bdb22a..d2b405faa129 100644 --- a/js/src/wasm/WasmProcess.cpp +++ b/js/src/wasm/WasmProcess.cpp @@ -235,7 +235,7 @@ const Code* wasm::LookupCode(const void* pc) { const CodeSegment* found = LookupCodeSegment(pc); - return found ? found->code() : nullptr; + return found ? &found->code() : nullptr; } void diff --git a/js/src/wasm/WasmSignalHandlers.cpp b/js/src/wasm/WasmSignalHandlers.cpp index 0f0ed976f12a..25953a9003dc 100644 --- a/js/src/wasm/WasmSignalHandlers.cpp +++ b/js/src/wasm/WasmSignalHandlers.cpp @@ -1432,9 +1432,8 @@ wasm::InInterruptibleCode(JSContext* cx, uint8_t* pc, const CodeSegment** cs) if (!*cs) return false; - const Code* code = (*cs)->code(); - - const CodeRange* codeRange = code->lookupRange(pc); + const Code& code = (*cs)->code(); + const CodeRange* codeRange = code.lookupRange(pc); return codeRange && codeRange->isFunction(); } diff --git a/js/src/wasm/WasmTypes.h b/js/src/wasm/WasmTypes.h index f07ae6042af2..a1d76deefc28 100644 --- a/js/src/wasm/WasmTypes.h +++ b/js/src/wasm/WasmTypes.h @@ -41,8 +41,6 @@ namespace js { -class PropertyName; -class WasmFunctionCallObject; namespace jit { struct BaselineScript; enum class RoundingMode; From d99d8b74c3321c5f16106542be8cffb52316b228 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 8 Jan 2018 17:47:34 -0600 Subject: [PATCH 14/33] Bug 1428453 - Baldr: prefix current trap mechanism names with 'Old' (r=bbouvier) MozReview-Commit-ID: JeNcXpbKL2s --HG-- extra : rebase_source : 452f6891e9f97ce254e6d8616595bf9d37737d8f --- js/src/jit/CodeGenerator.cpp | 10 ++-- js/src/jit/MacroAssembler.cpp | 22 ++++----- js/src/jit/MacroAssembler.h | 2 +- js/src/jit/arm/Assembler-arm.cpp | 6 +-- js/src/jit/arm/Assembler-arm.h | 4 +- js/src/jit/arm/CodeGenerator-arm.cpp | 16 +++---- js/src/jit/arm/MacroAssembler-arm.cpp | 10 ++-- js/src/jit/arm/MacroAssembler-arm.h | 4 +- js/src/jit/arm64/Assembler-arm64.h | 2 +- js/src/jit/arm64/MacroAssembler-arm64.h | 6 +-- .../jit/mips-shared/Assembler-mips-shared.cpp | 4 +- .../jit/mips-shared/Assembler-mips-shared.h | 2 +- .../mips-shared/CodeGenerator-mips-shared.cpp | 14 +++--- .../MacroAssembler-mips-shared.cpp | 18 +++---- .../mips-shared/MacroAssembler-mips-shared.h | 4 +- js/src/jit/mips32/CodeGenerator-mips32.cpp | 6 +-- js/src/jit/mips32/MacroAssembler-mips32.cpp | 8 ++-- js/src/jit/mips32/MacroAssembler-mips32.h | 2 +- js/src/jit/mips64/CodeGenerator-mips64.cpp | 6 +-- js/src/jit/mips64/MacroAssembler-mips64.cpp | 8 ++-- js/src/jit/mips64/MacroAssembler-mips64.h | 2 +- js/src/jit/none/MacroAssembler-none.h | 2 +- js/src/jit/shared/Assembler-shared.h | 48 +++++++++---------- js/src/jit/shared/CodeGenerator-shared.h | 4 +- js/src/jit/x64/CodeGenerator-x64.cpp | 6 +-- js/src/jit/x86-shared/Assembler-x86-shared.h | 8 ++-- .../x86-shared/CodeGenerator-x86-shared.cpp | 18 +++---- .../x86-shared/MacroAssembler-x86-shared.cpp | 4 +- .../x86-shared/MacroAssembler-x86-shared.h | 2 +- js/src/jit/x86/CodeGenerator-x86.cpp | 6 +-- js/src/wasm/WasmBaselineCompile.cpp | 28 +++++------ js/src/wasm/WasmBuiltins.cpp | 12 ++--- js/src/wasm/WasmFrameIter.cpp | 12 ++--- js/src/wasm/WasmGenerator.cpp | 34 ++++++------- js/src/wasm/WasmGenerator.h | 18 +++---- js/src/wasm/WasmStubs.cpp | 10 ++-- js/src/wasm/WasmTypes.cpp | 4 +- js/src/wasm/WasmTypes.h | 16 +++---- 38 files changed, 194 insertions(+), 194 deletions(-) diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 33d626ddfb0a..ff911c2e3a1b 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -9478,7 +9478,7 @@ CodeGenerator::generateWasm(wasm::SigIdDesc sigId, wasm::BytecodeOffset trapOffs // Since we just overflowed the stack, to be on the safe side, pop the // stack so that, when the trap exit stub executes, it is a safe // distance away from the end of the native stack. - wasm::TrapDesc trap(trapOffset, wasm::Trap::StackOverflow, /* framePushed = */ 0); + wasm::OldTrapDesc trap(trapOffset, wasm::Trap::StackOverflow, /* framePushed = */ 0); if (frameSize() > 0) { masm.bind(&onOverflow); masm.addToStackPtr(Imm32(frameSize())); @@ -9496,7 +9496,7 @@ CodeGenerator::generateWasm(wasm::SigIdDesc sigId, wasm::BytecodeOffset trapOffs if (!generateOutOfLineCode()) return false; - masm.wasmEmitTrapOutOfLineCode(); + masm.wasmEmitOldTrapOutOfLineCode(); masm.flush(); if (masm.oom()) @@ -12350,7 +12350,7 @@ CodeGenerator::visitWasmTrap(LWasmTrap* lir) MOZ_ASSERT(gen->compilingWasm()); const MWasmTrap* mir = lir->mir(); - masm.jump(trap(mir, mir->trap())); + masm.jump(oldTrap(mir, mir->trap())); } void @@ -12363,7 +12363,7 @@ CodeGenerator::visitWasmBoundsCheck(LWasmBoundsCheck* ins) Register ptr = ToRegister(ins->ptr()); Register boundsCheckLimit = ToRegister(ins->boundsCheckLimit()); masm.wasmBoundsCheck(Assembler::AboveOrEqual, ptr, boundsCheckLimit, - trap(mir, wasm::Trap::OutOfBounds)); + oldTrap(mir, wasm::Trap::OutOfBounds)); #endif } @@ -12373,7 +12373,7 @@ CodeGenerator::visitWasmAlignmentCheck(LWasmAlignmentCheck* ins) const MWasmAlignmentCheck* mir = ins->mir(); Register ptr = ToRegister(ins->ptr()); masm.branchTest32(Assembler::NonZero, ptr, Imm32(mir->byteSize() - 1), - trap(mir, wasm::Trap::UnalignedAccess)); + oldTrap(mir, wasm::Trap::UnalignedAccess)); } void diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index f8042ba300fc..a2c33b3bd162 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -2844,7 +2844,7 @@ MacroAssembler::callWithABINoProfiler(void* fun, MoveOp::Type result, CheckUnsaf } void -MacroAssembler::callWithABI(wasm::BytecodeOffset callOffset, wasm::SymbolicAddress imm, +MacroAssembler::callWithABI(wasm::BytecodeOffset bytecode, wasm::SymbolicAddress imm, MoveOp::Type result) { MOZ_ASSERT(wasm::NeedsBuiltinThunk(imm)); @@ -2861,7 +2861,7 @@ MacroAssembler::callWithABI(wasm::BytecodeOffset callOffset, wasm::SymbolicAddre // points when placing arguments. loadWasmTlsRegFromFrame(); - call(wasm::CallSiteDesc(callOffset.bytecodeOffset, wasm::CallSite::Symbolic), imm); + call(wasm::CallSiteDesc(bytecode.offset, wasm::CallSite::Symbolic), imm); callWithABIPost(stackAdjust, result, /* callFromWasm = */ true); Pop(WasmTlsReg); @@ -3006,7 +3006,7 @@ MacroAssembler::wasmCallIndirect(const wasm::CallSiteDesc& desc, const wasm::Cal if (needsBoundsCheck) { loadWasmGlobalPtr(callee.tableLengthGlobalDataOffset(), scratch); - wasm::TrapDesc oobTrap(trapOffset, wasm::Trap::OutOfBounds, framePushed()); + wasm::OldTrapDesc oobTrap(trapOffset, wasm::Trap::OutOfBounds, framePushed()); branch32(Assembler::Condition::AboveOrEqual, index, scratch, oobTrap); } @@ -3014,7 +3014,7 @@ MacroAssembler::wasmCallIndirect(const wasm::CallSiteDesc& desc, const wasm::Cal loadWasmGlobalPtr(callee.tableBaseGlobalDataOffset(), scratch); // Load the callee from the table. - wasm::TrapDesc nullTrap(trapOffset, wasm::Trap::IndirectCallToNull, framePushed()); + wasm::OldTrapDesc nullTrap(trapOffset, wasm::Trap::IndirectCallToNull, framePushed()); if (callee.wasmTableIsExternal()) { static_assert(sizeof(wasm::ExternalTableElem) == 8 || sizeof(wasm::ExternalTableElem) == 16, "elements of external tables are two words"); @@ -3040,21 +3040,21 @@ MacroAssembler::wasmCallIndirect(const wasm::CallSiteDesc& desc, const wasm::Cal } void -MacroAssembler::wasmEmitTrapOutOfLineCode() +MacroAssembler::wasmEmitOldTrapOutOfLineCode() { - for (const wasm::TrapSite& site : trapSites()) { + for (const wasm::OldTrapSite& site : oldTrapSites()) { // Trap out-of-line codes are created for two kinds of trap sites: // - jumps, which are bound directly to the trap out-of-line path // - memory accesses, which can fault and then have control transferred // to the out-of-line path directly via signal handler setting pc switch (site.kind) { - case wasm::TrapSite::Jump: { + case wasm::OldTrapSite::Jump: { RepatchLabel jump; jump.use(site.codeOffset); bind(&jump); break; } - case wasm::TrapSite::MemoryAccess: { + case wasm::OldTrapSite::MemoryAccess: { append(wasm::MemoryAccess(site.codeOffset, currentOffset())); break; } @@ -3072,7 +3072,7 @@ MacroAssembler::wasmEmitTrapOutOfLineCode() // directly to the trap exit stub. This takes advantage of the fact // that there is already a CallSite for call_indirect and the // current pre-prologue stack/register state. - append(wasm::TrapFarJump(site.trap, farJumpWithPatch())); + append(wasm::OldTrapFarJump(site.trap, farJumpWithPatch())); } else { // Inherit the frame depth of the trap site. This value is captured // by the wasm::CallSite to allow unwinding this frame. @@ -3098,7 +3098,7 @@ MacroAssembler::wasmEmitTrapOutOfLineCode() // trap-handling function. The frame iterator knows to skip the trap // exit's frame so that unwinding begins at the frame and offset of // the trapping instruction. - wasm::CallSiteDesc desc(site.bytecodeOffset, wasm::CallSiteDesc::TrapExit); + wasm::CallSiteDesc desc(site.offset, wasm::CallSiteDesc::OldTrapExit); call(desc, site.trap); } @@ -3113,7 +3113,7 @@ MacroAssembler::wasmEmitTrapOutOfLineCode() // iterator to find the right CodeRange while walking the stack. breakpoint(); - trapSites().clear(); + oldTrapSites().clear(); } void diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 79b12cc133f1..1dda6a53c1f0 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -1506,7 +1506,7 @@ class MacroAssembler : public MacroAssemblerSpecific // Emit the out-of-line trap code to which trapping jumps/branches are // bound. This should be called once per function after all other codegen, // including "normal" OutOfLineCode. - void wasmEmitTrapOutOfLineCode(); + void wasmEmitOldTrapOutOfLineCode(); // Perform a stack-overflow test, branching to the given Label on overflow. void wasmEmitStackCheck(Register sp, Register scratch, Label* onOverflow); diff --git a/js/src/jit/arm/Assembler-arm.cpp b/js/src/jit/arm/Assembler-arm.cpp index a0f2e1b402b5..2c2a99b04fdb 100644 --- a/js/src/jit/arm/Assembler-arm.cpp +++ b/js/src/jit/arm/Assembler-arm.cpp @@ -2453,7 +2453,7 @@ Assembler::as_b(Label* l, Condition c) } BufferOffset -Assembler::as_b(wasm::TrapDesc target, Condition c) +Assembler::as_b(wasm::OldTrapDesc target, Condition c) { Label l; BufferOffset ret = as_b(&l, c); @@ -2894,12 +2894,12 @@ Assembler::bind(Label* label, BufferOffset boff) } void -Assembler::bindLater(Label* label, wasm::TrapDesc target) +Assembler::bindLater(Label* label, wasm::OldTrapDesc target) { if (label->used()) { BufferOffset b(label); do { - append(wasm::TrapSite(target, b.getOffset())); + append(wasm::OldTrapSite(target, b.getOffset())); } while (nextLink(b, &b)); } label->reset(); diff --git a/js/src/jit/arm/Assembler-arm.h b/js/src/jit/arm/Assembler-arm.h index b8777408bac3..7eed65197edf 100644 --- a/js/src/jit/arm/Assembler-arm.h +++ b/js/src/jit/arm/Assembler-arm.h @@ -1614,7 +1614,7 @@ class Assembler : public AssemblerShared BufferOffset as_b(BOffImm off, Condition c, Label* documentation = nullptr); BufferOffset as_b(Label* l, Condition c = Always); - BufferOffset as_b(wasm::TrapDesc target, Condition c = Always); + BufferOffset as_b(wasm::OldTrapDesc target, Condition c = Always); BufferOffset as_b(BOffImm off, Condition c, BufferOffset inst); // blx can go to either an immediate or a register. When blx'ing to a @@ -1722,7 +1722,7 @@ class Assembler : public AssemblerShared bool nextLink(BufferOffset b, BufferOffset* next); void bind(Label* label, BufferOffset boff = BufferOffset()); void bind(RepatchLabel* label); - void bindLater(Label* label, wasm::TrapDesc target); + void bindLater(Label* label, wasm::OldTrapDesc target); uint32_t currentOffset() { return nextOffset().getOffset(); } diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp index c7be4884715b..5d87af4acfe0 100644 --- a/js/src/jit/arm/CodeGenerator-arm.cpp +++ b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -531,7 +531,7 @@ CodeGeneratorARM::divICommon(MDiv* mir, Register lhs, Register rhs, Register out masm.ma_cmp(rhs, Imm32(-1), scratch, Assembler::Equal); if (mir->canTruncateOverflow()) { if (mir->trapOnError()) { - masm.ma_b(trap(mir, wasm::Trap::IntegerOverflow), Assembler::Equal); + masm.ma_b(oldTrap(mir, wasm::Trap::IntegerOverflow), Assembler::Equal); } else { // (-INT32_MIN)|0 = INT32_MIN Label skip; @@ -551,7 +551,7 @@ CodeGeneratorARM::divICommon(MDiv* mir, Register lhs, Register rhs, Register out masm.as_cmp(rhs, Imm8(0)); if (mir->canTruncateInfinities()) { if (mir->trapOnError()) { - masm.ma_b(trap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Equal); + masm.ma_b(oldTrap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Equal); } else { // Infinity|0 == 0 Label skip; @@ -714,7 +714,7 @@ CodeGeneratorARM::modICommon(MMod* mir, Register lhs, Register rhs, Register out // wasm allows negative lhs and return 0 in this case. MOZ_ASSERT(mir->isTruncated()); masm.as_cmp(rhs, Imm8(0)); - masm.ma_b(trap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Equal); + masm.ma_b(oldTrap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Equal); return; } @@ -2120,7 +2120,7 @@ CodeGeneratorARM::visitWasmAddOffset(LWasmAddOffset* lir) ScratchRegisterScope scratch(masm); masm.ma_add(base, Imm32(mir->offset()), out, scratch, SetCC); - masm.ma_b(trap(mir, wasm::Trap::OutOfBounds), Assembler::CarrySet); + masm.ma_b(oldTrap(mir, wasm::Trap::OutOfBounds), Assembler::CarrySet); } template @@ -2417,7 +2417,7 @@ CodeGeneratorARM::generateUDivModZeroCheck(Register rhs, Register output, Label* masm.as_cmp(rhs, Imm8(0)); if (mir->isTruncated()) { if (mir->trapOnError()) { - masm.ma_b(trap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Equal); + masm.ma_b(oldTrap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Equal); } else { Label skip; masm.ma_b(&skip, Assembler::NotEqual); @@ -2768,7 +2768,7 @@ CodeGeneratorARM::visitDivOrModI64(LDivOrModI64* lir) if (lir->canBeDivideByZero()) { Register temp = WasmGetTemporaryForDivOrMod(lhs, rhs); masm.branchTest64(Assembler::Zero, rhs, rhs, temp, - trap(lir, wasm::Trap::IntegerDivideByZero)); + oldTrap(lir, wasm::Trap::IntegerDivideByZero)); } auto* mir = lir->mir(); @@ -2781,7 +2781,7 @@ CodeGeneratorARM::visitDivOrModI64(LDivOrModI64* lir) if (mir->isMod()) masm.xor64(output, output); else - masm.jump(trap(lir, wasm::Trap::IntegerOverflow)); + masm.jump(oldTrap(lir, wasm::Trap::IntegerOverflow)); masm.jump(&done); masm.bind(¬min); } @@ -2814,7 +2814,7 @@ CodeGeneratorARM::visitUDivOrModI64(LUDivOrModI64* lir) if (lir->canBeDivideByZero()) { Register temp = WasmGetTemporaryForDivOrMod(lhs, rhs); masm.branchTest64(Assembler::Zero, rhs, rhs, temp, - trap(lir, wasm::Trap::IntegerDivideByZero)); + oldTrap(lir, wasm::Trap::IntegerDivideByZero)); } masm.setupWasmABICall(); diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 11e32f59f97f..4d0b3625db6d 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -1390,7 +1390,7 @@ MacroAssemblerARM::ma_b(Label* dest, Assembler::Condition c) } BufferOffset -MacroAssemblerARM::ma_b(wasm::TrapDesc target, Assembler::Condition c) +MacroAssemblerARM::ma_b(wasm::OldTrapDesc target, Assembler::Condition c) { return as_b(target, c); } @@ -5751,12 +5751,12 @@ MacroAssemblerARM::outOfLineWasmTruncateToIntCheck(FloatRegister input, MIRType // Handle errors. bind(&fail); - asMasm().jump(wasm::TrapDesc(trapOffset, wasm::Trap::IntegerOverflow, - asMasm().framePushed())); + asMasm().jump(wasm::OldTrapDesc(trapOffset, wasm::Trap::IntegerOverflow, + asMasm().framePushed())); bind(&inputIsNaN); - asMasm().jump(wasm::TrapDesc(trapOffset, wasm::Trap::InvalidConversionToInteger, - asMasm().framePushed())); + asMasm().jump(wasm::OldTrapDesc(trapOffset, wasm::Trap::InvalidConversionToInteger, + asMasm().framePushed())); } void diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index f75d26aec1fe..4d8fd6e9f3e9 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -346,7 +346,7 @@ class MacroAssemblerARM : public Assembler // Branches when done from within arm-specific code. BufferOffset ma_b(Label* dest, Condition c = Always); - BufferOffset ma_b(wasm::TrapDesc target, Condition c = Always); + BufferOffset ma_b(wasm::OldTrapDesc target, Condition c = Always); void ma_b(void* target, Condition c = Always); void ma_bx(Register dest, Condition c = Always); @@ -677,7 +677,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM ma_ldr(addr, scratch, scratch2); ma_bx(scratch); } - void jump(wasm::TrapDesc target) { + void jump(wasm::OldTrapDesc target) { as_b(target); } diff --git a/js/src/jit/arm64/Assembler-arm64.h b/js/src/jit/arm64/Assembler-arm64.h index 4014a50ad415..e13601a51213 100644 --- a/js/src/jit/arm64/Assembler-arm64.h +++ b/js/src/jit/arm64/Assembler-arm64.h @@ -215,7 +215,7 @@ class Assembler : public vixl::Assembler void bind(Label* label) { bind(label, nextOffset()); } void bind(Label* label, BufferOffset boff); void bind(RepatchLabel* label); - void bindLater(Label* label, wasm::TrapDesc target) { + void bindLater(Label* label, wasm::OldTrapDesc target) { MOZ_CRASH("NYI"); } diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index ce04e2f975b6..fd9c70db3011 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -493,10 +493,10 @@ class MacroAssemblerCompat : public vixl::MacroAssembler } using vixl::MacroAssembler::B; - void B(wasm::TrapDesc) { + void B(wasm::OldTrapDesc) { MOZ_CRASH("NYI"); } - void B(wasm::TrapDesc, Condition cond) { + void B(wasm::OldTrapDesc, Condition cond) { MOZ_CRASH("NYI"); } @@ -673,7 +673,7 @@ class MacroAssemblerCompat : public vixl::MacroAssembler loadPtr(addr, ip0); Br(vixl::ip0); } - void jump(wasm::TrapDesc target) { + void jump(wasm::OldTrapDesc target) { MOZ_CRASH("NYI"); } diff --git a/js/src/jit/mips-shared/Assembler-mips-shared.cpp b/js/src/jit/mips-shared/Assembler-mips-shared.cpp index 825c9039e7e4..c811dd10cf5e 100644 --- a/js/src/jit/mips-shared/Assembler-mips-shared.cpp +++ b/js/src/jit/mips-shared/Assembler-mips-shared.cpp @@ -1809,7 +1809,7 @@ AssemblerMIPSShared::bind(Label* label, BufferOffset boff) } void -AssemblerMIPSShared::bindLater(Label* label, wasm::TrapDesc target) +AssemblerMIPSShared::bindLater(Label* label, wasm::OldTrapDesc target) { if (label->used()) { int32_t next; @@ -1818,7 +1818,7 @@ AssemblerMIPSShared::bindLater(Label* label, wasm::TrapDesc target) do { Instruction* inst = editSrc(b); - append(wasm::TrapSite(target, b.getOffset())); + append(wasm::OldTrapSite(target, b.getOffset())); next = inst[1].encode(); inst[1].makeNop(); diff --git a/js/src/jit/mips-shared/Assembler-mips-shared.h b/js/src/jit/mips-shared/Assembler-mips-shared.h index a7ee19a7d7f1..d8ae55838de1 100644 --- a/js/src/jit/mips-shared/Assembler-mips-shared.h +++ b/js/src/jit/mips-shared/Assembler-mips-shared.h @@ -1231,7 +1231,7 @@ class AssemblerMIPSShared : public AssemblerShared // label operations void bind(Label* label, BufferOffset boff = BufferOffset()); - void bindLater(Label* label, wasm::TrapDesc target); + void bindLater(Label* label, wasm::OldTrapDesc target); virtual void bind(InstImm* inst, uintptr_t branch, uintptr_t target) = 0; void bind(CodeOffset* label) { label->bind(currentOffset()); diff --git a/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp b/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp index 58384c680bcb..7c0a67615bfb 100644 --- a/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp +++ b/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp @@ -568,7 +568,7 @@ CodeGeneratorMIPSShared::visitDivI(LDivI* ins) // Handle divide by zero. if (mir->canBeDivideByZero()) { if (mir->trapOnError()) { - masm.ma_b(rhs, rhs, trap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Zero); + masm.ma_b(rhs, rhs, oldTrap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Zero); } else if (mir->canTruncateInfinities()) { // Truncated division by zero is zero (Infinity|0 == 0) Label notzero; @@ -590,7 +590,7 @@ CodeGeneratorMIPSShared::visitDivI(LDivI* ins) masm.move32(Imm32(-1), temp); if (mir->trapOnError()) { - masm.ma_b(rhs, temp, trap(mir, wasm::Trap::IntegerOverflow), Assembler::Equal); + masm.ma_b(rhs, temp, oldTrap(mir, wasm::Trap::IntegerOverflow), Assembler::Equal); } else if (mir->canTruncateOverflow()) { // (-INT32_MIN)|0 == INT32_MIN Label skip; @@ -718,7 +718,7 @@ CodeGeneratorMIPSShared::visitModI(LModI* ins) if (mir->canBeDivideByZero()) { if (mir->isTruncated()) { if (mir->trapOnError()) { - masm.ma_b(rhs, rhs, trap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Zero); + masm.ma_b(rhs, rhs, oldTrap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Zero); } else { Label skip; masm.ma_b(rhs, Imm32(0), &skip, Assembler::NotEqual, ShortJump); @@ -1559,10 +1559,10 @@ CodeGeneratorMIPSShared::visitOutOfLineWasmTruncateCheck(OutOfLineWasmTruncateCh // Handle errors. masm.bind(&fail); - masm.jump(trap(ool, wasm::Trap::IntegerOverflow)); + masm.jump(oldTrap(ool, wasm::Trap::IntegerOverflow)); masm.bind(&inputIsNaN); - masm.jump(trap(ool, wasm::Trap::InvalidConversionToInteger)); + masm.jump(oldTrap(ool, wasm::Trap::InvalidConversionToInteger)); } void @@ -2415,7 +2415,7 @@ CodeGeneratorMIPSShared::visitUDivOrMod(LUDivOrMod* ins) if (ins->canBeDivideByZero()) { if (ins->mir()->isTruncated()) { if (ins->trapOnError()) { - masm.ma_b(rhs, rhs, trap(ins, wasm::Trap::IntegerDivideByZero), Assembler::Zero); + masm.ma_b(rhs, rhs, oldTrap(ins, wasm::Trap::IntegerDivideByZero), Assembler::Zero); } else { // Infinity|0 == 0 Label notzero; @@ -2767,7 +2767,7 @@ CodeGeneratorMIPSShared::visitWasmAddOffset(LWasmAddOffset* lir) Register base = ToRegister(lir->base()); Register out = ToRegister(lir->output()); - masm.ma_addTestCarry(out, base, Imm32(mir->offset()), trap(mir, wasm::Trap::OutOfBounds)); + masm.ma_addTestCarry(out, base, Imm32(mir->offset()), oldTrap(mir, wasm::Trap::OutOfBounds)); } template diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp index 97efbc7bbcda..aec6c0416978 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp @@ -337,8 +337,8 @@ template void MacroAssemblerMIPSShared::ma_addTestCarry(Register rd, Register rs, Register rt, Label* overflow); template void -MacroAssemblerMIPSShared::ma_addTestCarry(Register rd, Register rs, Register rt, - wasm::TrapDesc overflow); +MacroAssemblerMIPSShared::ma_addTestCarry(Register rd, Register rs, Register rt, + wasm::OldTrapDesc overflow); template void @@ -352,8 +352,8 @@ template void MacroAssemblerMIPSShared::ma_addTestCarry(Register rd, Register rs, Imm32 imm, Label* overflow); template void -MacroAssemblerMIPSShared::ma_addTestCarry(Register rd, Register rs, Imm32 imm, - wasm::TrapDesc overflow); +MacroAssemblerMIPSShared::ma_addTestCarry(Register rd, Register rs, Imm32 imm, + wasm::OldTrapDesc overflow); // Subtract. void @@ -796,7 +796,7 @@ MacroAssemblerMIPSShared::ma_b(Register lhs, ImmPtr imm, Label* l, Condition c, template void -MacroAssemblerMIPSShared::ma_b(Register lhs, T rhs, wasm::TrapDesc target, Condition c, +MacroAssemblerMIPSShared::ma_b(Register lhs, T rhs, wasm::OldTrapDesc target, Condition c, JumpKind jumpKind) { Label label; @@ -805,13 +805,13 @@ MacroAssemblerMIPSShared::ma_b(Register lhs, T rhs, wasm::TrapDesc target, Condi } template void MacroAssemblerMIPSShared::ma_b(Register lhs, Register rhs, - wasm::TrapDesc target, Condition c, + wasm::OldTrapDesc target, Condition c, JumpKind jumpKind); template void MacroAssemblerMIPSShared::ma_b(Register lhs, Imm32 rhs, - wasm::TrapDesc target, Condition c, + wasm::OldTrapDesc target, Condition c, JumpKind jumpKind); template void MacroAssemblerMIPSShared::ma_b(Register lhs, ImmTag rhs, - wasm::TrapDesc target, Condition c, + wasm::OldTrapDesc target, Condition c, JumpKind jumpKind); void @@ -821,7 +821,7 @@ MacroAssemblerMIPSShared::ma_b(Label* label, JumpKind jumpKind) } void -MacroAssemblerMIPSShared::ma_b(wasm::TrapDesc target, JumpKind jumpKind) +MacroAssemblerMIPSShared::ma_b(wasm::OldTrapDesc target, JumpKind jumpKind) { Label label; asMasm().branchWithCode(getBranchCode(BranchIsJump), &label, jumpKind); diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared.h index 37d992cfdcfd..9300fe1ad0c3 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared.h +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared.h @@ -164,11 +164,11 @@ class MacroAssemblerMIPSShared : public Assembler ma_b(lhs, ScratchRegister, l, c, jumpKind); } template - void ma_b(Register lhs, T rhs, wasm::TrapDesc target, Condition c, + void ma_b(Register lhs, T rhs, wasm::OldTrapDesc target, Condition c, JumpKind jumpKind = LongJump); void ma_b(Label* l, JumpKind jumpKind = LongJump); - void ma_b(wasm::TrapDesc target, JumpKind jumpKind = LongJump); + void ma_b(wasm::OldTrapDesc target, JumpKind jumpKind = LongJump); // fp instructions void ma_lis(FloatRegister dest, float value); diff --git a/js/src/jit/mips32/CodeGenerator-mips32.cpp b/js/src/jit/mips32/CodeGenerator-mips32.cpp index 54bec1046207..f445b81fb4e5 100644 --- a/js/src/jit/mips32/CodeGenerator-mips32.cpp +++ b/js/src/jit/mips32/CodeGenerator-mips32.cpp @@ -380,7 +380,7 @@ CodeGeneratorMIPS::visitDivOrModI64(LDivOrModI64* lir) // Handle divide by zero. if (lir->canBeDivideByZero()) - masm.branchTest64(Assembler::Zero, rhs, rhs, temp, trap(lir, wasm::Trap::IntegerDivideByZero)); + masm.branchTest64(Assembler::Zero, rhs, rhs, temp, oldTrap(lir, wasm::Trap::IntegerDivideByZero)); // Handle an integer overflow exception from INT64_MIN / -1. if (lir->canBeNegativeOverflow()) { @@ -390,7 +390,7 @@ CodeGeneratorMIPS::visitDivOrModI64(LDivOrModI64* lir) if (lir->mir()->isMod()) { masm.xor64(output, output); } else { - masm.jump(trap(lir, wasm::Trap::IntegerOverflow)); + masm.jump(oldTrap(lir, wasm::Trap::IntegerOverflow)); } masm.jump(&done); masm.bind(¬min); @@ -433,7 +433,7 @@ CodeGeneratorMIPS::visitUDivOrModI64(LUDivOrModI64* lir) // Prevent divide by zero. if (lir->canBeDivideByZero()) - masm.branchTest64(Assembler::Zero, rhs, rhs, temp, trap(lir, wasm::Trap::IntegerDivideByZero)); + masm.branchTest64(Assembler::Zero, rhs, rhs, temp, oldTrap(lir, wasm::Trap::IntegerDivideByZero)); masm.setupWasmABICall(); masm.passABIArg(lhs.high); diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index af0b379c9bba..a8b73988d48f 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -238,8 +238,8 @@ template void MacroAssemblerMIPS::ma_addTestOverflow(Register rd, Register rs, Register rt, Label* overflow); template void -MacroAssemblerMIPS::ma_addTestOverflow(Register rd, Register rs, Register rt, - wasm::TrapDesc overflow); +MacroAssemblerMIPS::ma_addTestOverflow(Register rd, Register rs, Register rt, + wasm::OldTrapDesc overflow); template void @@ -270,8 +270,8 @@ template void MacroAssemblerMIPS::ma_addTestOverflow(Register rd, Register rs, Imm32 imm, Label* overflow); template void -MacroAssemblerMIPS::ma_addTestOverflow(Register rd, Register rs, Imm32 imm, - wasm::TrapDesc overflow); +MacroAssemblerMIPS::ma_addTestOverflow(Register rd, Register rs, Imm32 imm, + wasm::OldTrapDesc overflow); // Subtract. void diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index c144f0d164fb..bd7faf769e00 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -306,7 +306,7 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS branch(code); } - void jump(wasm::TrapDesc target) { + void jump(wasm::OldTrapDesc target) { ma_b(target); } diff --git a/js/src/jit/mips64/CodeGenerator-mips64.cpp b/js/src/jit/mips64/CodeGenerator-mips64.cpp index b58e4dd7f357..35af66e2d2bd 100644 --- a/js/src/jit/mips64/CodeGenerator-mips64.cpp +++ b/js/src/jit/mips64/CodeGenerator-mips64.cpp @@ -362,7 +362,7 @@ CodeGeneratorMIPS64::visitDivOrModI64(LDivOrModI64* lir) // Handle divide by zero. if (lir->canBeDivideByZero()) - masm.ma_b(rhs, rhs, trap(lir, wasm::Trap::IntegerDivideByZero), Assembler::Zero); + masm.ma_b(rhs, rhs, oldTrap(lir, wasm::Trap::IntegerDivideByZero), Assembler::Zero); // Handle an integer overflow exception from INT64_MIN / -1. if (lir->canBeNegativeOverflow()) { @@ -372,7 +372,7 @@ CodeGeneratorMIPS64::visitDivOrModI64(LDivOrModI64* lir) if (lir->mir()->isMod()) { masm.ma_xor(output, output); } else { - masm.jump(trap(lir, wasm::Trap::IntegerOverflow)); + masm.jump(oldTrap(lir, wasm::Trap::IntegerOverflow)); } masm.jump(&done); masm.bind(¬min); @@ -399,7 +399,7 @@ CodeGeneratorMIPS64::visitUDivOrModI64(LUDivOrModI64* lir) // Prevent divide by zero. if (lir->canBeDivideByZero()) - masm.ma_b(rhs, rhs, trap(lir, wasm::Trap::IntegerDivideByZero), Assembler::Zero); + masm.ma_b(rhs, rhs, oldTrap(lir, wasm::Trap::IntegerDivideByZero), Assembler::Zero); masm.as_ddivu(lhs, rhs); diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index 8d3ddcd9e0a4..31516b41746e 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -489,8 +489,8 @@ template void MacroAssemblerMIPS64::ma_addTestOverflow(Register rd, Register rs, Register rt, Label* overflow); template void -MacroAssemblerMIPS64::ma_addTestOverflow(Register rd, Register rs, Register rt, - wasm::TrapDesc overflow); +MacroAssemblerMIPS64::ma_addTestOverflow(Register rd, Register rs, Register rt, + wasm::OldTrapDesc overflow); template void @@ -511,8 +511,8 @@ template void MacroAssemblerMIPS64::ma_addTestOverflow(Register rd, Register rs, Imm32 imm, Label* overflow); template void -MacroAssemblerMIPS64::ma_addTestOverflow(Register rd, Register rs, Imm32 imm, - wasm::TrapDesc overflow); +MacroAssemblerMIPS64::ma_addTestOverflow(Register rd, Register rs, Imm32 imm, + wasm::OldTrapDesc overflow); // Subtract. void diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index 6947455a331a..b9ab59e7722b 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -335,7 +335,7 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 branch(code); } - void jump(wasm::TrapDesc target) { + void jump(wasm::OldTrapDesc target) { ma_b(target); } diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index aa833f92fd86..c49aa13f0c9d 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -210,7 +210,7 @@ class MacroAssemblerNone : public Assembler void flushBuffer() { MOZ_CRASH(); } template void bind(T) { MOZ_CRASH(); } - void bindLater(Label*, wasm::TrapDesc) { MOZ_CRASH(); } + void bindLater(Label*, wasm::OldTrapDesc) { MOZ_CRASH(); } template void j(Condition, T) { MOZ_CRASH(); } template void jump(T) { MOZ_CRASH(); } void writeCodePointer(CodeOffset* label) { MOZ_CRASH(); } diff --git a/js/src/jit/shared/Assembler-shared.h b/js/src/jit/shared/Assembler-shared.h index 65a0d9b1956c..0821061ba3e5 100644 --- a/js/src/jit/shared/Assembler-shared.h +++ b/js/src/jit/shared/Assembler-shared.h @@ -811,47 +811,47 @@ struct CallFarJump typedef Vector CallFarJumpVector; -// The TrapDesc struct describes a wasm trap that is about to be emitted. This +// The OldTrapDesc struct describes a wasm trap that is about to be emitted. This // includes the logical wasm bytecode offset to report, the kind of instruction // causing the trap, and the stack depth right before control is transferred to // the trap out-of-line path. -struct TrapDesc : BytecodeOffset +struct OldTrapDesc : BytecodeOffset { enum Kind { Jump, MemoryAccess }; Kind kind; Trap trap; uint32_t framePushed; - TrapDesc(BytecodeOffset offset, Trap trap, uint32_t framePushed, Kind kind = Jump) + OldTrapDesc(BytecodeOffset offset, Trap trap, uint32_t framePushed, Kind kind = Jump) : BytecodeOffset(offset), kind(kind), trap(trap), framePushed(framePushed) {} }; -// A TrapSite captures all relevant information at the point of emitting the +// An OldTrapSite captures all relevant information at the point of emitting the // in-line trapping instruction for the purpose of generating the out-of-line // trap code (at the end of the function). -struct TrapSite : TrapDesc +struct OldTrapSite : OldTrapDesc { uint32_t codeOffset; - TrapSite(TrapDesc trap, uint32_t codeOffset) - : TrapDesc(trap), codeOffset(codeOffset) + OldTrapSite(OldTrapDesc trap, uint32_t codeOffset) + : OldTrapDesc(trap), codeOffset(codeOffset) {} }; -typedef Vector TrapSiteVector; +typedef Vector OldTrapSiteVector; -// A TrapFarJump records the offset of a jump that needs to be patched to a trap +// An OldTrapFarJump records the offset of a jump that needs to be patched to a trap // exit at the end of the module when trap exits are emitted. -struct TrapFarJump +struct OldTrapFarJump { Trap trap; jit::CodeOffset jump; - TrapFarJump(Trap trap, jit::CodeOffset jump) + OldTrapFarJump(Trap trap, jit::CodeOffset jump) : trap(trap), jump(jump) {} @@ -860,7 +860,7 @@ struct TrapFarJump } }; -typedef Vector TrapFarJumpVector; +typedef Vector OldTrapFarJumpVector; } // namespace wasm @@ -871,8 +871,8 @@ class AssemblerShared { wasm::CallSiteVector callSites_; wasm::CallSiteTargetVector callSiteTargets_; - wasm::TrapSiteVector trapSites_; - wasm::TrapFarJumpVector trapFarJumps_; + wasm::OldTrapSiteVector oldTrapSites_; + wasm::OldTrapFarJumpVector oldTrapFarJumps_; wasm::CallFarJumpVector callFarJumps_; wasm::MemoryAccessVector memoryAccesses_; wasm::SymbolicAccessVector symbolicAccesses_; @@ -930,11 +930,11 @@ class AssemblerShared enoughMemory_ &= callSites_.emplaceBack(desc, retAddr.offset()); enoughMemory_ &= callSiteTargets_.emplaceBack(mozilla::Forward(args)...); } - void append(wasm::TrapSite trapSite) { - enoughMemory_ &= trapSites_.append(trapSite); + void append(wasm::OldTrapSite trapSite) { + enoughMemory_ &= oldTrapSites_.append(trapSite); } - void append(wasm::TrapFarJump jmp) { - enoughMemory_ &= trapFarJumps_.append(jmp); + void append(wasm::OldTrapFarJump jmp) { + enoughMemory_ &= oldTrapFarJumps_.append(jmp); } void append(wasm::CallFarJump jmp) { enoughMemory_ &= callFarJumps_.append(jmp); @@ -945,11 +945,11 @@ class AssemblerShared void append(const wasm::MemoryAccessDesc& access, size_t codeOffset, size_t framePushed) { if (access.hasTrap()) { // If a memory access is trapping (wasm, SIMD.js, Atomics), create a - // TrapSite now which will generate a trap out-of-line path at the end + // OldTrapSite now which will generate a trap out-of-line path at the end // of the function which will *then* append a MemoryAccess. - wasm::TrapDesc trap(access.trapOffset(), wasm::Trap::OutOfBounds, framePushed, - wasm::TrapSite::MemoryAccess); - append(wasm::TrapSite(trap, codeOffset)); + wasm::OldTrapDesc trap(access.trapOffset(), wasm::Trap::OutOfBounds, framePushed, + wasm::OldTrapSite::MemoryAccess); + append(wasm::OldTrapSite(trap, codeOffset)); } else { // Otherwise, this is a plain asm.js access. On WASM_HUGE_MEMORY // platforms, asm.js uses signal handlers to remove bounds checks @@ -966,8 +966,8 @@ class AssemblerShared wasm::CallSiteVector& callSites() { return callSites_; } wasm::CallSiteTargetVector& callSiteTargets() { return callSiteTargets_; } - wasm::TrapSiteVector& trapSites() { return trapSites_; } - wasm::TrapFarJumpVector& trapFarJumps() { return trapFarJumps_; } + wasm::OldTrapSiteVector& oldTrapSites() { return oldTrapSites_; } + wasm::OldTrapFarJumpVector& oldTrapFarJumps() { return oldTrapFarJumps_; } wasm::CallFarJumpVector& callFarJumps() { return callFarJumps_; } wasm::MemoryAccessVector& memoryAccesses() { return memoryAccesses_; } wasm::SymbolicAccessVector& symbolicAccesses() { return symbolicAccesses_; } diff --git a/js/src/jit/shared/CodeGenerator-shared.h b/js/src/jit/shared/CodeGenerator-shared.h index 7b4339bb8fec..68ac83e2716c 100644 --- a/js/src/jit/shared/CodeGenerator-shared.h +++ b/js/src/jit/shared/CodeGenerator-shared.h @@ -503,8 +503,8 @@ class CodeGeneratorShared : public LElementVisitor #endif template - wasm::TrapDesc trap(T* mir, wasm::Trap trap) { - return wasm::TrapDesc(mir->bytecodeOffset(), trap, masm.framePushed()); + wasm::OldTrapDesc oldTrap(T* mir, wasm::Trap trap) { + return wasm::OldTrapDesc(mir->bytecodeOffset(), trap, masm.framePushed()); } private: diff --git a/js/src/jit/x64/CodeGenerator-x64.cpp b/js/src/jit/x64/CodeGenerator-x64.cpp index 9da854d8e67f..94cd3108942d 100644 --- a/js/src/jit/x64/CodeGenerator-x64.cpp +++ b/js/src/jit/x64/CodeGenerator-x64.cpp @@ -285,7 +285,7 @@ CodeGeneratorX64::visitDivOrModI64(LDivOrModI64* lir) // Handle divide by zero. if (lir->canBeDivideByZero()) { - masm.branchTestPtr(Assembler::Zero, rhs, rhs, trap(lir, wasm::Trap::IntegerDivideByZero)); + masm.branchTestPtr(Assembler::Zero, rhs, rhs, oldTrap(lir, wasm::Trap::IntegerDivideByZero)); } // Handle an integer overflow exception from INT64_MIN / -1. @@ -296,7 +296,7 @@ CodeGeneratorX64::visitDivOrModI64(LDivOrModI64* lir) if (lir->mir()->isMod()) masm.xorl(output, output); else - masm.jump(trap(lir, wasm::Trap::IntegerOverflow)); + masm.jump(oldTrap(lir, wasm::Trap::IntegerOverflow)); masm.jump(&done); masm.bind(¬min); } @@ -328,7 +328,7 @@ CodeGeneratorX64::visitUDivOrModI64(LUDivOrModI64* lir) // Prevent divide by zero. if (lir->canBeDivideByZero()) - masm.branchTestPtr(Assembler::Zero, rhs, rhs, trap(lir, wasm::Trap::IntegerDivideByZero)); + masm.branchTestPtr(Assembler::Zero, rhs, rhs, oldTrap(lir, wasm::Trap::IntegerDivideByZero)); // Zero extend the lhs into rdx to make (rdx:rax). masm.xorl(rdx, rdx); diff --git a/js/src/jit/x86-shared/Assembler-x86-shared.h b/js/src/jit/x86-shared/Assembler-x86-shared.h index dd3cf6452c3a..90b5f18f2977 100644 --- a/js/src/jit/x86-shared/Assembler-x86-shared.h +++ b/js/src/jit/x86-shared/Assembler-x86-shared.h @@ -922,12 +922,12 @@ class AssemblerX86Shared : public AssemblerShared void j(Condition cond, RepatchLabel* label) { jSrc(cond, label); } void jmp(RepatchLabel* label) { jmpSrc(label); } - void j(Condition cond, wasm::TrapDesc target) { + void j(Condition cond, wasm::OldTrapDesc target) { Label l; j(cond, &l); bindLater(&l, target); } - void jmp(wasm::TrapDesc target) { + void jmp(wasm::OldTrapDesc target) { Label l; jmp(&l); bindLater(&l, target); @@ -963,11 +963,11 @@ class AssemblerX86Shared : public AssemblerShared } label->bind(dst.offset()); } - void bindLater(Label* label, wasm::TrapDesc target) { + void bindLater(Label* label, wasm::OldTrapDesc target) { if (label->used()) { JmpSrc jmp(label->offset()); do { - append(wasm::TrapSite(target, jmp.offset())); + append(wasm::OldTrapSite(target, jmp.offset())); } while (masm.nextJump(jmp, &jmp)); } label->reset(); diff --git a/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp index d93f9eaddd67..d6363febded2 100644 --- a/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp @@ -435,7 +435,7 @@ CodeGeneratorX86Shared::visitWasmAddOffset(LWasmAddOffset* lir) masm.move32(base, out); masm.add32(Imm32(mir->offset()), out); - masm.j(Assembler::CarrySet, trap(mir, wasm::Trap::OutOfBounds)); + masm.j(Assembler::CarrySet, oldTrap(mir, wasm::Trap::OutOfBounds)); } void @@ -1026,7 +1026,7 @@ CodeGeneratorX86Shared::visitUDivOrMod(LUDivOrMod* ins) masm.test32(rhs, rhs); if (ins->mir()->isTruncated()) { if (ins->trapOnError()) { - masm.j(Assembler::Zero, trap(ins, wasm::Trap::IntegerDivideByZero)); + masm.j(Assembler::Zero, oldTrap(ins, wasm::Trap::IntegerDivideByZero)); } else { ool = new(alloc()) ReturnZero(output); masm.j(Assembler::Zero, ool->entry()); @@ -1074,7 +1074,7 @@ CodeGeneratorX86Shared::visitUDivOrModConstant(LUDivOrModConstant *ins) { if (d == 0) { if (ins->mir()->isTruncated()) { if (ins->trapOnError()) - masm.jump(trap(ins, wasm::Trap::IntegerDivideByZero)); + masm.jump(oldTrap(ins, wasm::Trap::IntegerDivideByZero)); else masm.xorl(output, output); } else { @@ -1213,7 +1213,7 @@ CodeGeneratorX86Shared::visitDivPowTwoI(LDivPowTwoI* ins) if (!mir->isTruncated()) bailoutIf(Assembler::Overflow, ins->snapshot()); else if (mir->trapOnError()) - masm.j(Assembler::Overflow, trap(mir, wasm::Trap::IntegerOverflow)); + masm.j(Assembler::Overflow, oldTrap(mir, wasm::Trap::IntegerOverflow)); } else if (mir->isUnsigned() && !mir->isTruncated()) { // Unsigned division by 1 can overflow if output is not // truncated. @@ -1332,7 +1332,7 @@ CodeGeneratorX86Shared::visitDivI(LDivI* ins) if (mir->canBeDivideByZero()) { masm.test32(rhs, rhs); if (mir->trapOnError()) { - masm.j(Assembler::Zero, trap(mir, wasm::Trap::IntegerDivideByZero)); + masm.j(Assembler::Zero, oldTrap(mir, wasm::Trap::IntegerDivideByZero)); } else if (mir->canTruncateInfinities()) { // Truncated division by zero is zero (Infinity|0 == 0) if (!ool) @@ -1351,7 +1351,7 @@ CodeGeneratorX86Shared::visitDivI(LDivI* ins) masm.j(Assembler::NotEqual, ¬min); masm.cmp32(rhs, Imm32(-1)); if (mir->trapOnError()) { - masm.j(Assembler::Equal, trap(mir, wasm::Trap::IntegerOverflow)); + masm.j(Assembler::Equal, oldTrap(mir, wasm::Trap::IntegerOverflow)); } else if (mir->canTruncateOverflow()) { // (-INT32_MIN)|0 == INT32_MIN and INT32_MIN is already in the // output register (lhs == eax). @@ -1501,7 +1501,7 @@ CodeGeneratorX86Shared::visitModI(LModI* ins) masm.test32(rhs, rhs); if (mir->isTruncated()) { if (mir->trapOnError()) { - masm.j(Assembler::Zero, trap(mir, wasm::Trap::IntegerDivideByZero)); + masm.j(Assembler::Zero, oldTrap(mir, wasm::Trap::IntegerDivideByZero)); } else { if (!ool) ool = new(alloc()) ReturnZero(edx); @@ -2523,7 +2523,7 @@ CodeGeneratorX86Shared::visitOutOfLineSimdFloatToIntCheck(OutOfLineSimdFloatToIn masm.jump(ool->rejoin()); if (gen->compilingWasm()) { - masm.bindLater(&onConversionError, trap(ool, wasm::Trap::ImpreciseSimdConversion)); + masm.bindLater(&onConversionError, oldTrap(ool, wasm::Trap::ImpreciseSimdConversion)); } else { masm.bind(&onConversionError); bailout(ool->ins()->snapshot()); @@ -2603,7 +2603,7 @@ CodeGeneratorX86Shared::visitFloat32x4ToUint32x4(LFloat32x4ToUint32x4* ins) masm.cmp32(temp, Imm32(0)); if (gen->compilingWasm()) - masm.j(Assembler::NotEqual, trap(mir, wasm::Trap::ImpreciseSimdConversion)); + masm.j(Assembler::NotEqual, oldTrap(mir, wasm::Trap::ImpreciseSimdConversion)); else bailoutIf(Assembler::NotEqual, ins->snapshot()); } diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp b/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp index 3be5d040e304..b037f2ee7122 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp @@ -686,10 +686,10 @@ struct MOZ_RAII AutoHandleWasmTruncateToIntErrors ~AutoHandleWasmTruncateToIntErrors() { // Handle errors. masm.bind(&fail); - masm.jump(wasm::TrapDesc(off, wasm::Trap::IntegerOverflow, masm.framePushed())); + masm.jump(wasm::OldTrapDesc(off, wasm::Trap::IntegerOverflow, masm.framePushed())); masm.bind(&inputIsNaN); - masm.jump(wasm::TrapDesc(off, wasm::Trap::InvalidConversionToInteger, masm.framePushed())); + masm.jump(wasm::OldTrapDesc(off, wasm::Trap::InvalidConversionToInteger, masm.framePushed())); } }; diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h index 723479882b00..d541a2912cf4 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h @@ -202,7 +202,7 @@ class MacroAssemblerX86Shared : public Assembler void jump(const Address& addr) { jmp(Operand(addr)); } - void jump(wasm::TrapDesc target) { + void jump(wasm::OldTrapDesc target) { jmp(target); } diff --git a/js/src/jit/x86/CodeGenerator-x86.cpp b/js/src/jit/x86/CodeGenerator-x86.cpp index d2466494cc4c..a5329bb5f13a 100644 --- a/js/src/jit/x86/CodeGenerator-x86.cpp +++ b/js/src/jit/x86/CodeGenerator-x86.cpp @@ -1031,7 +1031,7 @@ CodeGeneratorX86::visitDivOrModI64(LDivOrModI64* lir) // Handle divide by zero. if (lir->canBeDivideByZero()) - masm.branchTest64(Assembler::Zero, rhs, rhs, temp, trap(lir, wasm::Trap::IntegerDivideByZero)); + masm.branchTest64(Assembler::Zero, rhs, rhs, temp, oldTrap(lir, wasm::Trap::IntegerDivideByZero)); MDefinition* mir = lir->mir(); @@ -1043,7 +1043,7 @@ CodeGeneratorX86::visitDivOrModI64(LDivOrModI64* lir) if (mir->isMod()) masm.xor64(output, output); else - masm.jump(trap(lir, wasm::Trap::IntegerOverflow)); + masm.jump(oldTrap(lir, wasm::Trap::IntegerOverflow)); masm.jump(&done); masm.bind(¬min); } @@ -1079,7 +1079,7 @@ CodeGeneratorX86::visitUDivOrModI64(LUDivOrModI64* lir) // Prevent divide by zero. if (lir->canBeDivideByZero()) - masm.branchTest64(Assembler::Zero, rhs, rhs, temp, trap(lir, wasm::Trap::IntegerDivideByZero)); + masm.branchTest64(Assembler::Zero, rhs, rhs, temp, oldTrap(lir, wasm::Trap::IntegerDivideByZero)); masm.setupWasmABICall(); masm.passABIArg(lhs.high); diff --git a/js/src/wasm/WasmBaselineCompile.cpp b/js/src/wasm/WasmBaselineCompile.cpp index 57e3cecd88f8..b4165b5dc4f4 100644 --- a/js/src/wasm/WasmBaselineCompile.cpp +++ b/js/src/wasm/WasmBaselineCompile.cpp @@ -3020,7 +3020,7 @@ class BaseCompiler final : public BaseCompilerInterface if (fr.initialSize() > debugFrameReserved) masm.addToStackPtr(Imm32(fr.initialSize() - debugFrameReserved)); BytecodeOffset prologueTrapOffset(func_.lineOrBytecode); - masm.jump(TrapDesc(prologueTrapOffset, Trap::StackOverflow, debugFrameReserved)); + masm.jump(OldTrapDesc(prologueTrapOffset, Trap::StackOverflow, debugFrameReserved)); masm.bind(&returnLabel_); @@ -3045,7 +3045,7 @@ class BaseCompiler final : public BaseCompilerInterface if (!generateOutOfLineCode()) return false; - masm.wasmEmitTrapOutOfLineCode(); + masm.wasmEmitOldTrapOutOfLineCode(); offsets_.end = masm.currentOffset(); @@ -3453,12 +3453,12 @@ class BaseCompiler final : public BaseCompilerInterface } void checkDivideByZeroI32(RegI32 rhs, RegI32 srcDest, Label* done) { - masm.branchTest32(Assembler::Zero, rhs, rhs, trap(Trap::IntegerDivideByZero)); + masm.branchTest32(Assembler::Zero, rhs, rhs, oldTrap(Trap::IntegerDivideByZero)); } void checkDivideByZeroI64(RegI64 r) { ScratchI32 scratch(*this); - masm.branchTest64(Assembler::Zero, r, r, scratch, trap(Trap::IntegerDivideByZero)); + masm.branchTest64(Assembler::Zero, r, r, scratch, oldTrap(Trap::IntegerDivideByZero)); } void checkDivideSignedOverflowI32(RegI32 rhs, RegI32 srcDest, Label* done, bool zeroOnOverflow) { @@ -3469,7 +3469,7 @@ class BaseCompiler final : public BaseCompilerInterface moveImm32(0, srcDest); masm.jump(done); } else { - masm.branch32(Assembler::Equal, rhs, Imm32(-1), trap(Trap::IntegerOverflow)); + masm.branch32(Assembler::Equal, rhs, Imm32(-1), oldTrap(Trap::IntegerOverflow)); } masm.bind(¬Min); } @@ -3482,7 +3482,7 @@ class BaseCompiler final : public BaseCompilerInterface masm.xor64(srcDest, srcDest); masm.jump(done); } else { - masm.jump(trap(Trap::IntegerOverflow)); + masm.jump(oldTrap(Trap::IntegerOverflow)); } masm.bind(¬min); } @@ -3809,7 +3809,7 @@ class BaseCompiler final : public BaseCompilerInterface void unreachableTrap() { - masm.jump(trap(Trap::Unreachable)); + masm.jump(oldTrap(Trap::Unreachable)); #ifdef DEBUG masm.breakpoint(); #endif @@ -3940,7 +3940,7 @@ class BaseCompiler final : public BaseCompilerInterface (access->isAtomic() && !check->omitAlignmentCheck && !check->onlyPointerAlignment)) { masm.branchAdd32(Assembler::CarrySet, Imm32(access->offset()), ptr, - trap(Trap::OutOfBounds)); + oldTrap(Trap::OutOfBounds)); access->clearOffset(); check->onlyPointerAlignment = true; } @@ -3951,7 +3951,7 @@ class BaseCompiler final : public BaseCompilerInterface MOZ_ASSERT(check->onlyPointerAlignment); // We only care about the low pointer bits here. masm.branchTest32(Assembler::NonZero, ptr, Imm32(access->byteSize() - 1), - trap(Trap::UnalignedAccess)); + oldTrap(Trap::UnalignedAccess)); } // Ensure no tls if we don't need it. @@ -3972,7 +3972,7 @@ class BaseCompiler final : public BaseCompilerInterface if (!check->omitBoundsCheck) { masm.wasmBoundsCheck(Assembler::AboveOrEqual, ptr, Address(tls, offsetof(TlsData, boundsCheckLimit)), - trap(Trap::OutOfBounds)); + oldTrap(Trap::OutOfBounds)); } #endif } @@ -4905,11 +4905,11 @@ class BaseCompiler final : public BaseCompilerInterface return iter_.bytecodeOffset(); } - TrapDesc trap(Trap t) const { + OldTrapDesc oldTrap(Trap t) const { // Use masm.framePushed() because the value needed by the trap machinery // is the size of the frame overall, not the height of the stack area of // the frame. - return TrapDesc(bytecodeOffset(), t, masm.framePushed()); + return OldTrapDesc(bytecodeOffset(), t, masm.framePushed()); } //////////////////////////////////////////////////////////// @@ -8395,7 +8395,7 @@ BaseCompiler::emitWait(ValType type, uint32_t byteSize) default: MOZ_CRASH(); } - masm.branchTest32(Assembler::Signed, ReturnReg, ReturnReg, trap(Trap::ThrowReported)); + masm.branchTest32(Assembler::Signed, ReturnReg, ReturnReg, oldTrap(Trap::ThrowReported)); return true; } @@ -8414,7 +8414,7 @@ BaseCompiler::emitWake() return true; emitInstanceCall(lineOrBytecode, SigPII_, ExprType::I32, SymbolicAddress::Wake); - masm.branchTest32(Assembler::Signed, ReturnReg, ReturnReg, trap(Trap::ThrowReported)); + masm.branchTest32(Assembler::Signed, ReturnReg, ReturnReg, oldTrap(Trap::ThrowReported)); return true; } diff --git a/js/src/wasm/WasmBuiltins.cpp b/js/src/wasm/WasmBuiltins.cpp index 4cb0507a9ff7..27b527b2d3ff 100644 --- a/js/src/wasm/WasmBuiltins.cpp +++ b/js/src/wasm/WasmBuiltins.cpp @@ -234,7 +234,7 @@ WasmHandleThrow() } static void -WasmReportTrap(int32_t trapIndex) +WasmOldReportTrap(int32_t trapIndex) { JSContext* cx = TlsContext.get(); @@ -439,9 +439,9 @@ AddressOf(SymbolicAddress imm, ABIFunctionType* abiType) case SymbolicAddress::HandleThrow: *abiType = Args_General0; return FuncCast(WasmHandleThrow, *abiType); - case SymbolicAddress::ReportTrap: + case SymbolicAddress::OldReportTrap: *abiType = Args_General1; - return FuncCast(WasmReportTrap, *abiType); + return FuncCast(WasmOldReportTrap, *abiType); case SymbolicAddress::ReportOutOfBounds: *abiType = Args_General0; return FuncCast(WasmReportOutOfBounds, *abiType); @@ -595,7 +595,7 @@ wasm::NeedsBuiltinThunk(SymbolicAddress sym) case SymbolicAddress::HandleExecutionInterrupt: // GenerateInterruptExit case SymbolicAddress::HandleDebugTrap: // GenerateDebugTrapStub case SymbolicAddress::HandleThrow: // GenerateThrowStub - case SymbolicAddress::ReportTrap: // GenerateTrapExit + case SymbolicAddress::OldReportTrap: // GenerateOldTrapExit case SymbolicAddress::ReportOutOfBounds: // GenerateOutOfBoundsExit case SymbolicAddress::ReportUnalignedAccess: // GeneratesUnalignedExit case SymbolicAddress::CallImport_Void: // GenerateImportInterpExit @@ -891,8 +891,8 @@ wasm::EnsureBuiltinThunksInitialized() MOZ_ASSERT(masm.callSites().empty()); MOZ_ASSERT(masm.callSiteTargets().empty()); MOZ_ASSERT(masm.callFarJumps().empty()); - MOZ_ASSERT(masm.trapSites().empty()); - MOZ_ASSERT(masm.trapFarJumps().empty()); + MOZ_ASSERT(masm.oldTrapSites().empty()); + MOZ_ASSERT(masm.oldTrapFarJumps().empty()); MOZ_ASSERT(masm.callFarJumps().empty()); MOZ_ASSERT(masm.memoryAccesses().empty()); MOZ_ASSERT(masm.symbolicAccesses().empty()); diff --git a/js/src/wasm/WasmFrameIter.cpp b/js/src/wasm/WasmFrameIter.cpp index 1723d63385b4..da282f9451d5 100644 --- a/js/src/wasm/WasmFrameIter.cpp +++ b/js/src/wasm/WasmFrameIter.cpp @@ -446,7 +446,7 @@ wasm::GenerateFunctionPrologue(MacroAssembler& masm, unsigned framePushed, const // Generate table entry: offsets->begin = masm.currentOffset(); BytecodeOffset trapOffset(0); // ignored by masm.wasmEmitTrapOutOfLineCode - TrapDesc trap(trapOffset, Trap::IndirectCallBadSig, masm.framePushed()); + OldTrapDesc trap(trapOffset, Trap::IndirectCallBadSig, masm.framePushed()); switch (sigId.kind()) { case SigIdDesc::Kind::Global: { Register scratch = WasmTableCallScratchReg; @@ -635,7 +635,7 @@ ProfilingFrameIterator::initFromExitFP(const Frame* fp) case CodeRange::ImportJitExit: case CodeRange::ImportInterpExit: case CodeRange::BuiltinThunk: - case CodeRange::TrapExit: + case CodeRange::OldTrapExit: case CodeRange::DebugTrap: case CodeRange::OutOfBoundsExit: case CodeRange::UnalignedExit: @@ -714,7 +714,7 @@ js::wasm::StartUnwinding(const RegisterState& registers, UnwindState* unwindStat case CodeRange::ImportJitExit: case CodeRange::ImportInterpExit: case CodeRange::BuiltinThunk: - case CodeRange::TrapExit: + case CodeRange::OldTrapExit: case CodeRange::DebugTrap: #if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) if ((offsetFromEntry >= BeforePushRetAddr && offsetFromEntry < PushedFP) || codeRange->isThunk()) { @@ -913,7 +913,7 @@ ProfilingFrameIterator::operator++() case CodeRange::ImportJitExit: case CodeRange::ImportInterpExit: case CodeRange::BuiltinThunk: - case CodeRange::TrapExit: + case CodeRange::OldTrapExit: case CodeRange::DebugTrap: case CodeRange::OutOfBoundsExit: case CodeRange::UnalignedExit: @@ -941,7 +941,7 @@ ThunkedNativeToDescription(SymbolicAddress func) case SymbolicAddress::HandleExecutionInterrupt: case SymbolicAddress::HandleDebugTrap: case SymbolicAddress::HandleThrow: - case SymbolicAddress::ReportTrap: + case SymbolicAddress::OldReportTrap: case SymbolicAddress::ReportOutOfBounds: case SymbolicAddress::ReportUnalignedAccess: case SymbolicAddress::CallImport_Void: @@ -1071,7 +1071,7 @@ ProfilingFrameIterator::label() const case CodeRange::ImportJitExit: return importJitDescription; case CodeRange::BuiltinThunk: return builtinNativeDescription; case CodeRange::ImportInterpExit: return importInterpDescription; - case CodeRange::TrapExit: return trapDescription; + case CodeRange::OldTrapExit: return trapDescription; case CodeRange::DebugTrap: return debugTrapDescription; case CodeRange::OutOfBoundsExit: return "out-of-bounds stub (in wasm)"; case CodeRange::UnalignedExit: return "unaligned trap stub (in wasm)"; diff --git a/js/src/wasm/WasmGenerator.cpp b/js/src/wasm/WasmGenerator.cpp index 070966ad92d5..6c2dfdb10ab3 100644 --- a/js/src/wasm/WasmGenerator.cpp +++ b/js/src/wasm/WasmGenerator.cpp @@ -47,9 +47,9 @@ CompiledCode::swap(MacroAssembler& masm) callSites.swap(masm.callSites()); callSiteTargets.swap(masm.callSiteTargets()); - trapSites.swap(masm.trapSites()); + oldTrapSites.swap(masm.oldTrapSites()); callFarJumps.swap(masm.callFarJumps()); - trapFarJumps.swap(masm.trapFarJumps()); + oldTrapFarJumps.swap(masm.oldTrapFarJumps()); memoryAccesses.swap(masm.memoryAccesses()); symbolicAccesses.swap(masm.symbolicAccesses()); codeLabels.swap(masm.codeLabels()); @@ -75,7 +75,7 @@ ModuleGenerator::ModuleGenerator(const CompileArgs& args, ModuleEnvironment* env lifo_(GENERATOR_LIFO_DEFAULT_CHUNK_SIZE), masmAlloc_(&lifo_), masm_(MacroAssembler::WasmToken(), masmAlloc_), - trapCodeOffsets_(), + oldTrapCodeOffsets_(), debugTrapCodeOffset_(), lastPatchedCallSite_(0), startOfUnpatchedCallsites_(0), @@ -86,7 +86,7 @@ ModuleGenerator::ModuleGenerator(const CompileArgs& args, ModuleEnvironment* env finishedFuncDefs_(false) { MOZ_ASSERT(IsCompilingWasm()); - std::fill(trapCodeOffsets_.begin(), trapCodeOffsets_.end(), 0); + std::fill(oldTrapCodeOffsets_.begin(), oldTrapCodeOffsets_.end(), 0); } ModuleGenerator::~ModuleGenerator() @@ -436,14 +436,14 @@ ModuleGenerator::linkCallSites() masm_.patchCall(callerOffset, p->value()); break; } - case CallSiteDesc::TrapExit: { + case CallSiteDesc::OldTrapExit: { if (!existingTrapFarJumps[target.trap()]) { - // See MacroAssembler::wasmEmitTrapOutOfLineCode for why we must + // See MacroAssembler::wasmEmitOldTrapOutOfLineCode for why we must // reload the TLS register on this path. Offsets offsets; offsets.begin = masm_.currentOffset(); masm_.loadPtr(Address(FramePointer, offsetof(Frame, tls)), WasmTlsReg); - if (!trapFarJumps_.emplaceBack(target.trap(), masm_.farJumpWithPatch())) + if (!oldTrapFarJumps_.emplaceBack(target.trap(), masm_.farJumpWithPatch())) return false; offsets.end = masm_.currentOffset(); if (masm_.oom()) @@ -503,9 +503,9 @@ ModuleGenerator::noteCodeRange(uint32_t codeRangeIndex, const CodeRange& codeRan case CodeRange::ImportInterpExit: metadataTier_->funcImports[codeRange.funcIndex()].initInterpExitOffset(codeRange.begin()); break; - case CodeRange::TrapExit: - MOZ_ASSERT(!trapCodeOffsets_[codeRange.trap()]); - trapCodeOffsets_[codeRange.trap()] = codeRange.begin(); + case CodeRange::OldTrapExit: + MOZ_ASSERT(!oldTrapCodeOffsets_[codeRange.trap()]); + oldTrapCodeOffsets_[codeRange.trap()] = codeRange.begin(); break; case CodeRange::DebugTrap: MOZ_ASSERT(!debugTrapCodeOffset_); @@ -580,10 +580,10 @@ ModuleGenerator::linkCompiledCode(const CompiledCode& code) if (!callSiteTargets_.appendAll(code.callSiteTargets)) return false; - MOZ_ASSERT(code.trapSites.empty()); + MOZ_ASSERT(code.oldTrapSites.empty()); - auto trapFarJumpOp = [=](uint32_t, TrapFarJump* tfj) { tfj->offsetBy(offsetInModule); }; - if (!AppendForEach(&trapFarJumps_, code.trapFarJumps, trapFarJumpOp)) + auto trapFarJumpOp = [=](uint32_t, OldTrapFarJump* tfj) { tfj->offsetBy(offsetInModule); }; + if (!AppendForEach(&oldTrapFarJumps_, code.oldTrapFarJumps, trapFarJumpOp)) return false; auto callFarJumpOp = [=](uint32_t, CallFarJump* cfj) { cfj->offsetBy(offsetInModule); }; @@ -788,8 +788,8 @@ ModuleGenerator::finishCode() for (CallFarJump far : callFarJumps_) masm_.patchFarJump(far.jump, funcCodeRange(far.funcIndex).funcNormalEntry()); - for (TrapFarJump far : trapFarJumps_) - masm_.patchFarJump(far.jump, trapCodeOffsets_[far.trap]); + for (OldTrapFarJump far : oldTrapFarJumps_) + masm_.patchFarJump(far.jump, oldTrapCodeOffsets_[far.trap]); for (CodeOffset farJump : debugTrapFarJumps_) masm_.patchFarJump(farJump, debugTrapCodeOffset_); @@ -798,8 +798,8 @@ ModuleGenerator::finishCode() MOZ_ASSERT(masm_.callSites().empty()); MOZ_ASSERT(masm_.callSiteTargets().empty()); - MOZ_ASSERT(masm_.trapSites().empty()); - MOZ_ASSERT(masm_.trapFarJumps().empty()); + MOZ_ASSERT(masm_.oldTrapSites().empty()); + MOZ_ASSERT(masm_.oldTrapFarJumps().empty()); MOZ_ASSERT(masm_.callFarJumps().empty()); MOZ_ASSERT(masm_.memoryAccesses().empty()); MOZ_ASSERT(masm_.symbolicAccesses().empty()); diff --git a/js/src/wasm/WasmGenerator.h b/js/src/wasm/WasmGenerator.h index 83c9014723d4..fc35114ce7af 100644 --- a/js/src/wasm/WasmGenerator.h +++ b/js/src/wasm/WasmGenerator.h @@ -64,8 +64,8 @@ struct CompiledCode CodeRangeVector codeRanges; CallSiteVector callSites; CallSiteTargetVector callSiteTargets; - TrapSiteVector trapSites; - TrapFarJumpVector trapFarJumps; + OldTrapSiteVector oldTrapSites; + OldTrapFarJumpVector oldTrapFarJumps; CallFarJumpVector callFarJumps; MemoryAccessVector memoryAccesses; SymbolicAccessVector symbolicAccesses; @@ -78,8 +78,8 @@ struct CompiledCode codeRanges.clear(); callSites.clear(); callSiteTargets.clear(); - trapSites.clear(); - trapFarJumps.clear(); + oldTrapSites.clear(); + oldTrapFarJumps.clear(); callFarJumps.clear(); memoryAccesses.clear(); symbolicAccesses.clear(); @@ -92,8 +92,8 @@ struct CompiledCode codeRanges.empty() && callSites.empty() && callSiteTargets.empty() && - trapSites.empty() && - trapFarJumps.empty() && + oldTrapSites.empty() && + oldTrapFarJumps.empty() && callFarJumps.empty() && memoryAccesses.empty() && symbolicAccesses.empty() && @@ -145,7 +145,7 @@ struct CompileTask class MOZ_STACK_CLASS ModuleGenerator { typedef Vector CompileTaskVector; - typedef EnumeratedArray Uint32TrapArray; + typedef EnumeratedArray OldTrapOffsetArray; typedef Vector CodeOffsetVector; // Constant parameters @@ -168,9 +168,9 @@ class MOZ_STACK_CLASS ModuleGenerator jit::TempAllocator masmAlloc_; jit::MacroAssembler masm_; Uint32Vector funcToCodeRange_; - Uint32TrapArray trapCodeOffsets_; + OldTrapOffsetArray oldTrapCodeOffsets_; uint32_t debugTrapCodeOffset_; - TrapFarJumpVector trapFarJumps_; + OldTrapFarJumpVector oldTrapFarJumps_; CallFarJumpVector callFarJumps_; CallSiteTargetVector callSiteTargets_; uint32_t lastPatchedCallSite_; diff --git a/js/src/wasm/WasmStubs.cpp b/js/src/wasm/WasmStubs.cpp index 512aefba660e..a546fb35275f 100644 --- a/js/src/wasm/WasmStubs.cpp +++ b/js/src/wasm/WasmStubs.cpp @@ -533,7 +533,7 @@ GenerateImportFunction(jit::MacroAssembler& masm, const FuncImport& fi, SigIdDes GenerateFunctionEpilogue(masm, framePushed, offsets); - masm.wasmEmitTrapOutOfLineCode(); + masm.wasmEmitOldTrapOutOfLineCode(); return FinishOffsets(masm, offsets); } @@ -1001,12 +1001,12 @@ wasm::GenerateBuiltinThunk(MacroAssembler& masm, ABIFunctionType abiType, ExitRe return FinishOffsets(masm, offsets); } -// Generate a stub that calls into ReportTrap with the right trap reason. +// Generate a stub that calls into WasmOldReportTrap with the right trap reason. // This stub is called with ABIStackAlignment by a trap out-of-line path. An // exit prologue/epilogue is used so that stack unwinding picks up the // current JitActivation. Unwinding will begin at the caller of this trap exit. static bool -GenerateTrapExit(MacroAssembler& masm, Trap trap, Label* throwLabel, CallableOffsets* offsets) +GenerateOldTrapExit(MacroAssembler& masm, Trap trap, Label* throwLabel, CallableOffsets* offsets) { masm.haltingAlign(CodeAlignment); @@ -1028,7 +1028,7 @@ GenerateTrapExit(MacroAssembler& masm, Trap trap, Label* throwLabel, CallableOff MOZ_ASSERT(i.done()); masm.assertStackAlignment(ABIStackAlignment); - masm.call(SymbolicAddress::ReportTrap); + masm.call(SymbolicAddress::OldReportTrap); masm.jump(throwLabel); @@ -1369,7 +1369,7 @@ wasm::GenerateStubs(const ModuleEnvironment& env, const FuncImportVector& import for (Trap trap : MakeEnumeratedRange(Trap::Limit)) { CallableOffsets offsets; - if (!GenerateTrapExit(masm, trap, &throwLabel, &offsets)) + if (!GenerateOldTrapExit(masm, trap, &throwLabel, &offsets)) return false; if (!code->codeRanges.emplaceBack(trap, offsets)) return false; diff --git a/js/src/wasm/WasmTypes.cpp b/js/src/wasm/WasmTypes.cpp index 154c71af0e2a..586580af5b81 100644 --- a/js/src/wasm/WasmTypes.cpp +++ b/js/src/wasm/WasmTypes.cpp @@ -728,7 +728,7 @@ CodeRange::CodeRange(Kind kind, CallableOffsets offsets) PodZero(&u); #ifdef DEBUG switch (kind_) { - case TrapExit: + case OldTrapExit: case DebugTrap: case BuiltinThunk: break; @@ -773,7 +773,7 @@ CodeRange::CodeRange(Trap trap, CallableOffsets offsets) : begin_(offsets.begin), ret_(offsets.ret), end_(offsets.end), - kind_(TrapExit) + kind_(OldTrapExit) { MOZ_ASSERT(begin_ < ret_); MOZ_ASSERT(ret_ < end_); diff --git a/js/src/wasm/WasmTypes.h b/js/src/wasm/WasmTypes.h index a1d76deefc28..f2c75861dbaa 100644 --- a/js/src/wasm/WasmTypes.h +++ b/js/src/wasm/WasmTypes.h @@ -1011,7 +1011,7 @@ class CodeRange ImportJitExit, // fast-path calling from wasm into JIT code ImportInterpExit, // slow-path calling from wasm into C++ interp BuiltinThunk, // fast-path calling from wasm into a C++ native - TrapExit, // calls C++ to report and jumps to throw stub + OldTrapExit, // calls C++ to report and jumps to throw stub DebugTrap, // calls C++ to handle debug event FarJumpIsland, // inserted to connect otherwise out-of-range insns OutOfBoundsExit, // stub jumped to by non-standard asm.js SIMD/Atomics @@ -1087,7 +1087,7 @@ class CodeRange return kind() == ImportJitExit; } bool isTrapExit() const { - return kind() == TrapExit; + return kind() == OldTrapExit; } bool isDebugTrap() const { return kind() == DebugTrap; @@ -1187,12 +1187,12 @@ LookupInSorted(const CodeRangeVector& codeRanges, CodeRange::OffsetInCode target struct BytecodeOffset { static const uint32_t INVALID = -1; - uint32_t bytecodeOffset; + uint32_t offset; - BytecodeOffset() : bytecodeOffset(INVALID) {} - explicit BytecodeOffset(uint32_t bytecodeOffset) : bytecodeOffset(bytecodeOffset) {} + BytecodeOffset() : offset(INVALID) {} + explicit BytecodeOffset(uint32_t offset) : offset(offset) {} - bool isValid() const { return bytecodeOffset != INVALID; } + bool isValid() const { return offset != INVALID; } }; // While the frame-pointer chain allows the stack to be unwound without @@ -1210,7 +1210,7 @@ class CallSiteDesc Func, // pc-relative call to a specific function Dynamic, // dynamic callee called via register Symbolic, // call to a single symbolic callee - TrapExit, // call to a trap exit + OldTrapExit,// call to a trap exit (being removed) EnterFrame, // call to a enter frame handler LeaveFrame, // call to a leave frame handler Breakpoint // call to instruction breakpoint @@ -1333,7 +1333,7 @@ enum class SymbolicAddress HandleExecutionInterrupt, HandleDebugTrap, HandleThrow, - ReportTrap, + OldReportTrap, ReportOutOfBounds, ReportUnalignedAccess, CallImport_Void, From c4c25d2fb094a5e49e6bcdcca8672cb64a4bf931 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 8 Jan 2018 17:53:21 -0600 Subject: [PATCH 15/33] Bug 1428453 - Baldr: remove WasmFrameIter::debugTrapCallsite() (r=yury) MozReview-Commit-ID: AHjWPINanvF --- js/src/wasm/WasmBuiltins.cpp | 23 ++++++++++++++--------- js/src/wasm/WasmFrameIter.cpp | 15 +-------------- js/src/wasm/WasmFrameIter.h | 1 - js/src/wasm/WasmTypes.cpp | 9 +++++++++ js/src/wasm/WasmTypes.h | 1 + 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/js/src/wasm/WasmBuiltins.cpp b/js/src/wasm/WasmBuiltins.cpp index 27b527b2d3ff..5f5aa574950d 100644 --- a/js/src/wasm/WasmBuiltins.cpp +++ b/js/src/wasm/WasmBuiltins.cpp @@ -96,17 +96,24 @@ static bool WasmHandleDebugTrap() { JitActivation* activation = CallingActivation(); - MOZ_ASSERT(activation); JSContext* cx = activation->cx(); + Frame* fp = activation->wasmExitFP(); + Instance* instance = fp->tls->instance; + const Code& code = instance->code(); + MOZ_ASSERT(code.metadata().debugEnabled); - WasmFrameIter frame(activation); - MOZ_ASSERT(frame.debugEnabled()); - const CallSite* site = frame.debugTrapCallsite(); + // The debug trap stub is the innermost frame. It's return address is the + // actual trap site. + const CallSite* site = code.lookupCallSite(fp->returnAddress); MOZ_ASSERT(site); + + // Advance to the actual trapping frame. + fp = fp->callerFP; + DebugFrame* debugFrame = DebugFrame::from(fp); + if (site->kind() == CallSite::EnterFrame) { - if (!frame.instance()->enterFrameTrapsEnabled()) + if (!instance->enterFrameTrapsEnabled()) return true; - DebugFrame* debugFrame = frame.debugFrame(); debugFrame->setIsDebuggee(); debugFrame->observe(cx); // TODO call onEnterFrame @@ -121,15 +128,13 @@ WasmHandleDebugTrap() return status == JSTRAP_CONTINUE; } if (site->kind() == CallSite::LeaveFrame) { - DebugFrame* debugFrame = frame.debugFrame(); debugFrame->updateReturnJSValue(); bool ok = Debugger::onLeaveFrame(cx, debugFrame, nullptr, true); debugFrame->leave(cx); return ok; } - DebugFrame* debugFrame = frame.debugFrame(); - DebugState& debug = frame.instance()->debug(); + DebugState& debug = instance->debug(); MOZ_ASSERT(debug.hasBreakpointTrapAtOffset(site->lineOrBytecode())); if (debug.stepModeEnabled(debugFrame->funcIndex())) { RootedValue result(cx, UndefinedValue()); diff --git a/js/src/wasm/WasmFrameIter.cpp b/js/src/wasm/WasmFrameIter.cpp index da282f9451d5..c7c03eb008a4 100644 --- a/js/src/wasm/WasmFrameIter.cpp +++ b/js/src/wasm/WasmFrameIter.cpp @@ -216,20 +216,7 @@ DebugFrame* WasmFrameIter::debugFrame() const { MOZ_ASSERT(!done()); - MOZ_ASSERT(debugEnabled()); - return reinterpret_cast((uint8_t*)fp_ - DebugFrame::offsetOfFrame()); -} - -const CallSite* -WasmFrameIter::debugTrapCallsite() const -{ - MOZ_ASSERT(!done()); - MOZ_ASSERT(callsite_); - MOZ_ASSERT(debugEnabled()); - MOZ_ASSERT(callsite_->kind() == CallSite::EnterFrame || - callsite_->kind() == CallSite::LeaveFrame || - callsite_->kind() == CallSite::Breakpoint); - return callsite_; + return DebugFrame::from(fp_); } /*****************************************************************************/ diff --git a/js/src/wasm/WasmFrameIter.h b/js/src/wasm/WasmFrameIter.h index 292bc0b5dafc..d4ada44fac32 100644 --- a/js/src/wasm/WasmFrameIter.h +++ b/js/src/wasm/WasmFrameIter.h @@ -91,7 +91,6 @@ class WasmFrameIter void** unwoundAddressOfReturnAddress() const; bool debugEnabled() const; DebugFrame* debugFrame() const; - const CallSite* debugTrapCallsite() const; }; enum class SymbolicAddress; diff --git a/js/src/wasm/WasmTypes.cpp b/js/src/wasm/WasmTypes.cpp index 586580af5b81..54a7c4576549 100644 --- a/js/src/wasm/WasmTypes.cpp +++ b/js/src/wasm/WasmTypes.cpp @@ -562,6 +562,15 @@ wasm::ComputeMappedSize(uint32_t maxSize) #endif // WASM_HUGE_MEMORY +/* static */ DebugFrame* +DebugFrame::from(Frame* fp) +{ + MOZ_ASSERT(fp->tls->instance->code().metadata().debugEnabled); + auto* df = reinterpret_cast((uint8_t*)fp - DebugFrame::offsetOfFrame()); + MOZ_ASSERT(fp->instance() == df->instance()); + return df; +} + void DebugFrame::alignmentStaticAsserts() { diff --git a/js/src/wasm/WasmTypes.h b/js/src/wasm/WasmTypes.h index f2c75861dbaa..619e9179ec42 100644 --- a/js/src/wasm/WasmTypes.h +++ b/js/src/wasm/WasmTypes.h @@ -1879,6 +1879,7 @@ class DebugFrame Frame frame_; public: + static DebugFrame* from(Frame* fp); Frame& frame() { return frame_; } uint32_t funcIndex() const { return funcIndex_; } Instance* instance() const { return frame_.instance(); } From 95733d05bf63d9483d2ca689dced04496047780a Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 8 Jan 2018 17:53:53 -0600 Subject: [PATCH 16/33] Bug 1428453 - Baldr: remove WasmFrameIter::callsite_ (r=bbouvier) MozReview-Commit-ID: LBTtxbqZamP --- js/src/wasm/WasmFrameIter.cpp | 14 ++++++++------ js/src/wasm/WasmFrameIter.h | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/js/src/wasm/WasmFrameIter.cpp b/js/src/wasm/WasmFrameIter.cpp index c7c03eb008a4..b7ad369e05a4 100644 --- a/js/src/wasm/WasmFrameIter.cpp +++ b/js/src/wasm/WasmFrameIter.cpp @@ -35,8 +35,8 @@ using mozilla::Swap; WasmFrameIter::WasmFrameIter(JitActivation* activation, wasm::Frame* fp) : activation_(activation), code_(nullptr), - callsite_(nullptr), codeRange_(nullptr), + lineOrBytecode_(0), fp_(fp ? fp : activation->wasmExitFP()), unwind_(Unwind::False) { @@ -57,6 +57,8 @@ WasmFrameIter::WasmFrameIter(JitActivation* activation, wasm::Frame* fp) codeRange_ = code_->lookupRange(activation->wasmUnwindPC()); MOZ_ASSERT(codeRange_->kind() == CodeRange::Function); + lineOrBytecode_ = codeRange_->funcLineOrBytecode(); + MOZ_ASSERT(!done()); return; } @@ -112,7 +114,6 @@ WasmFrameIter::popFrame() if (!fp_) { code_ = nullptr; codeRange_ = nullptr; - callsite_ = nullptr; if (unwind_ == Unwind::True) { // TODO with bug 1319203, there may be other JIT frames above. @@ -132,8 +133,10 @@ WasmFrameIter::popFrame() codeRange_ = code_->lookupRange(returnAddress); MOZ_ASSERT(codeRange_->kind() == CodeRange::Function); - callsite_ = code_->lookupCallSite(returnAddress); - MOZ_ASSERT(callsite_); + const CallSite* callsite = code_->lookupCallSite(returnAddress); + MOZ_ASSERT(callsite); + + lineOrBytecode_ = callsite->lineOrBytecode(); MOZ_ASSERT(!done()); } @@ -178,8 +181,7 @@ unsigned WasmFrameIter::lineOrBytecode() const { MOZ_ASSERT(!done()); - MOZ_ASSERT_IF(!callsite_, activation_->isWasmInterrupted()); - return callsite_ ? callsite_->lineOrBytecode() : codeRange_->funcLineOrBytecode(); + return lineOrBytecode_; } Instance* diff --git a/js/src/wasm/WasmFrameIter.h b/js/src/wasm/WasmFrameIter.h index d4ada44fac32..7ee57e68bd41 100644 --- a/js/src/wasm/WasmFrameIter.h +++ b/js/src/wasm/WasmFrameIter.h @@ -66,8 +66,8 @@ class WasmFrameIter private: jit::JitActivation* activation_; const Code* code_; - const CallSite* callsite_; const CodeRange* codeRange_; + unsigned lineOrBytecode_; Frame* fp_; Unwind unwind_; void** unwoundAddressOfReturnAddress_; From 68f574e92ce1987a096e256ff9306bfdc481c456 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Mon, 8 Jan 2018 20:25:52 -0500 Subject: [PATCH 17/33] Bug 1426977 P1 Preload the cookie permission to properly block client-side service worker interception. r=mystor --- extensions/cookie/nsPermissionManager.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp index e412975bc9f1..abd81aa068b3 100644 --- a/extensions/cookie/nsPermissionManager.cpp +++ b/extensions/cookie/nsPermissionManager.cpp @@ -126,7 +126,13 @@ static const char* kPreloadPermissions[] = { "beacon", "fetch", "image", - "manifest" + "manifest", + + // This permission is preloaded to support properly blocking service worker + // interception when a user has disabled storage for a specific site. Once + // service worker interception moves to the parent process this should be + // removed. See bug 1428130. + "cookie" }; // A list of permissions that can have a fallback default permission From 223b11ff62e1c369b7b23bc6c523dfd1258de56c Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Mon, 8 Jan 2018 20:25:53 -0500 Subject: [PATCH 18/33] Bug 1426977 P2 Add StorageAllowedForNewWindow() to support docshell service worker checks. r=mystor --- dom/base/nsContentUtils.cpp | 32 ++++++++++++++++++++++++-------- dom/base/nsContentUtils.h | 14 ++++++++++++-- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 437cba722ada..049a3e007676 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -8896,7 +8896,7 @@ nsContentUtils::StorageAllowedForWindow(nsPIDOMWindowInner* aWindow) { if (nsIDocument* document = aWindow->GetExtantDoc()) { nsCOMPtr principal = document->NodePrincipal(); - return InternalStorageAllowedForPrincipal(principal, aWindow); + return InternalStorageAllowedForPrincipal(principal, aWindow, nullptr); } return StorageAccess::eDeny; @@ -8910,17 +8910,30 @@ nsContentUtils::StorageAllowedForDocument(nsIDocument* aDoc) if (nsPIDOMWindowInner* inner = aDoc->GetInnerWindow()) { nsCOMPtr principal = aDoc->NodePrincipal(); - return InternalStorageAllowedForPrincipal(principal, inner); + return InternalStorageAllowedForPrincipal(principal, inner, nullptr); } return StorageAccess::eDeny; } +// static, public +nsContentUtils::StorageAccess +nsContentUtils::StorageAllowedForNewWindow(nsIPrincipal* aPrincipal, + nsIURI* aURI, + nsPIDOMWindowInner* aParent) +{ + MOZ_ASSERT(aPrincipal); + MOZ_ASSERT(aURI); + // parent may be nullptr + + return InternalStorageAllowedForPrincipal(aPrincipal, aParent, aURI); +} + // static, public nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForPrincipal(nsIPrincipal* aPrincipal) { - return InternalStorageAllowedForPrincipal(aPrincipal, nullptr); + return InternalStorageAllowedForPrincipal(aPrincipal, nullptr, nullptr); } // static, private @@ -8979,7 +8992,8 @@ nsContentUtils::GetCookieBehaviorForPrincipal(nsIPrincipal* aPrincipal, // static, private nsContentUtils::StorageAccess nsContentUtils::InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal, - nsPIDOMWindowInner* aWindow) + nsPIDOMWindowInner* aWindow, + nsIURI* aURI) { MOZ_ASSERT(aPrincipal); @@ -9049,9 +9063,11 @@ nsContentUtils::InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal, // affected, which is desireable due to the lack of automated testing for about: // URIs with these preferences set, and the importance of the correct functioning // of these URIs even with custom preferences. - nsCOMPtr uri; - nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri)); - if (NS_SUCCEEDED(rv) && uri) { + nsCOMPtr uri = aURI; + if (!uri) { + Unused << aPrincipal->GetURI(getter_AddRefs(uri)); + } + if (uri) { bool isAbout = false; MOZ_ALWAYS_SUCCEEDS(uri->SchemeIs("about", &isAbout)); if (isAbout) { @@ -9073,7 +9089,7 @@ nsContentUtils::InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal, bool thirdPartyWindow = false; if (NS_SUCCEEDED(thirdPartyUtil->IsThirdPartyWindow( - aWindow->GetOuterWindow(), nullptr, &thirdPartyWindow)) && thirdPartyWindow) { + aWindow->GetOuterWindow(), aURI, &thirdPartyWindow)) && thirdPartyWindow) { // XXX For non-cookie forms of storage, we handle BEHAVIOR_LIMIT_FOREIGN by // simply rejecting the request to use the storage. In the future, if we // change the meaning of BEHAVIOR_LIMIT_FOREIGN to be one which makes sense diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 2b626abbd582..2c0d06f79ea7 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -2961,6 +2961,14 @@ public: */ static StorageAccess StorageAllowedForDocument(nsIDocument* aDoc); + /* + * Checks if storage should be allowed for a new window with the given + * principal, load URI, and parent. + */ + static StorageAccess StorageAllowedForNewWindow(nsIPrincipal* aPrincipal, + nsIURI* aURI, + nsPIDOMWindowInner* aParent); + /* * Checks if storage for the given principal is permitted by the user's * preferences. The caller is assumed to not be a third-party iframe. @@ -3338,13 +3346,15 @@ private: * Checks if storage for a given principal is permitted by the user's * preferences. If aWindow is non-null, its principal must be passed as * aPrincipal, and the third-party iframe and sandboxing status of the window - * are also checked. + * are also checked. If aURI is non-null, then it is used as the comparison + * against aWindow to determine if this is a third-party load. * * Used in the implementation of StorageAllowedForWindow and * StorageAllowedForPrincipal. */ static StorageAccess InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal, - nsPIDOMWindowInner* aWindow); + nsPIDOMWindowInner* aWindow, + nsIURI* aURI); static nsINode* GetCommonAncestorHelper(nsINode* aNode1, nsINode* aNode2); static nsIContent* GetCommonFlattenedTreeAncestorHelper(nsIContent* aContent1, From 11f4db4683db96517a509d990e27f0d85ffe7ae2 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Mon, 8 Jan 2018 20:25:53 -0500 Subject: [PATCH 19/33] Bug 1426977 P3 Use StorageAllowedForNewWindow() in nsDocShell::ServiceWorkerAllowedToControlWindow(). r=mystor --- docshell/base/nsDocShell.cpp | 60 ++++++++++++------------------------ docshell/base/nsDocShell.h | 6 ++-- 2 files changed, 22 insertions(+), 44 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index d03e4cb31f7d..bbd0b4d885ed 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -2835,10 +2835,14 @@ nsDocShell::MaybeCreateInitialClientSource(nsIPrincipal* aPrincipal) return; } + nsCOMPtr uri; + MOZ_ALWAYS_SUCCEEDS( + NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("about:blank"))); + // We're done if there is no parent controller or if this docshell // is not permitted to control for some reason. Maybe controller(parentInner->GetController()); - if (controller.isNothing() || !ServiceWorkerAllowedToControlWindow(nullptr)) { + if (controller.isNothing() || !ServiceWorkerAllowedToControlWindow(principal, uri)) { return; } @@ -14099,51 +14103,26 @@ nsDocShell::CanSetOriginAttributes() } bool -nsDocShell::ServiceWorkerAllowedToControlWindow(nsIURI* aURI) +nsDocShell::ServiceWorkerAllowedToControlWindow(nsIPrincipal* aPrincipal, + nsIURI* aURI) { - // NOTE: Ideally this method would call one of the - // nsContentUtils::StorageAllowed*() methods to determine if the - // interception is allowed. Unfortunately we cannot safely do this - // before the first window loads in the child process because the - // permission manager might not have all its data yet. Therefore, - // we use this somewhat lame alternate implementation here. Once - // interception is moved to the parent process we should switch - // to calling nsContentUtils::StorageAllowed*(). See bug 1428130. + MOZ_ASSERT(aPrincipal); + MOZ_ASSERT(aURI); if (UsePrivateBrowsing() || mSandboxFlags) { return false; } - uint32_t cookieBehavior = nsContentUtils::CookiesBehavior(); - uint32_t lifetimePolicy = nsContentUtils::CookiesLifetimePolicy(); - if (cookieBehavior == nsICookieService::BEHAVIOR_REJECT || - lifetimePolicy == nsICookieService::ACCEPT_SESSION) { - return false; - } - - if (!aURI || cookieBehavior == nsICookieService::BEHAVIOR_ACCEPT) { - return true; - } - nsCOMPtr parent; GetSameTypeParent(getter_AddRefs(parent)); - nsCOMPtr parentWindow = parent ? parent->GetWindow() - : nullptr; - if (parentWindow) { - nsresult rv = NS_OK; - nsCOMPtr thirdPartyUtil = - do_GetService(THIRDPARTYUTIL_CONTRACTID, &rv); - if (thirdPartyUtil) { - bool isThirdPartyURI = true; - rv = thirdPartyUtil->IsThirdPartyWindow(parentWindow, aURI, - &isThirdPartyURI); - if (NS_SUCCEEDED(rv) && isThirdPartyURI) { - return false; - } - } - } + nsPIDOMWindowOuter* parentOuter = parent ? parent->GetWindow() : nullptr; + nsPIDOMWindowInner* parentInner = + parentOuter ? parentOuter->GetCurrentInnerWindow() : nullptr; - return true; + nsContentUtils::StorageAccess storage = + nsContentUtils::StorageAllowedForNewWindow(aPrincipal, aURI, parentInner); + + return storage == nsContentUtils::StorageAccess::eAllow; } nsresult @@ -14370,9 +14349,12 @@ nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNonSubresourceReques return NS_OK; } + nsCOMPtr principal = + BasePrincipal::CreateCodebasePrincipal(aURI, mOriginAttributes); + // For navigations, first check to see if we are allowed to control a // window with the given URL. - if (!ServiceWorkerAllowedToControlWindow(aURI)) { + if (!ServiceWorkerAllowedToControlWindow(principal, aURI)) { return NS_OK; } @@ -14383,8 +14365,6 @@ nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNonSubresourceReques // We're allowed to control a window, so check with the ServiceWorkerManager // for a matching service worker. - nsCOMPtr principal = - BasePrincipal::CreateCodebasePrincipal(aURI, mOriginAttributes); *aShouldIntercept = swm->IsAvailable(principal, aURI); return NS_OK; } diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 22aa38e230e4..de6e1330a623 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -792,10 +792,8 @@ private: // member functions // controlled. The caller must still consult either the parent controller // or the ServiceWorkerManager to determine if a service worker should // actually control the window. - // - // A nullptr URL is considered to be an about:blank window and will not - // trigger 3rd party iframe checks. - bool ServiceWorkerAllowedToControlWindow(nsIURI* aURI); + bool ServiceWorkerAllowedToControlWindow(nsIPrincipal* aPrincipal, + nsIURI* aURI); // Return the ClientInfo for the initial about:blank window, if it exists // or we have speculatively created a ClientSource in From 6b60ca24ef0e31441a653f10d64aa91b6d495986 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Mon, 8 Jan 2018 20:25:53 -0500 Subject: [PATCH 20/33] Bug 1426977 P4 Add mochitest verifying service workers respect per-site cookie permissions. r=mystor --- dom/workers/test/serviceworkers/browser.ini | 2 + .../browser_storage_permission.js | 123 ++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 dom/workers/test/serviceworkers/browser_storage_permission.js diff --git a/dom/workers/test/serviceworkers/browser.ini b/dom/workers/test/serviceworkers/browser.ini index aaf9ef7da8ed..04da81fa2e71 100644 --- a/dom/workers/test/serviceworkers/browser.ini +++ b/dom/workers/test/serviceworkers/browser.ini @@ -9,6 +9,7 @@ support-files = file_userContextId_openWindow.js force_refresh_browser_worker.js empty.html + empty.js server_multie10s_update.sjs [browser_devtools_serviceworker_interception.js] @@ -16,5 +17,6 @@ support-files = [browser_download.js] [browser_multie10s_update.js] skip-if = !e10s || os != "win" # Bug 1404914 +[browser_storage_permission.js] [browser_userContextId_openWindow.js] skip-if = !e10s diff --git a/dom/workers/test/serviceworkers/browser_storage_permission.js b/dom/workers/test/serviceworkers/browser_storage_permission.js new file mode 100644 index 000000000000..28807f564acc --- /dev/null +++ b/dom/workers/test/serviceworkers/browser_storage_permission.js @@ -0,0 +1,123 @@ +"use strict"; + +const { interfaces: Ci } = Components; + +const BASE_URI = "http://mochi.test:8888/browser/dom/workers/test/serviceworkers/"; +const PAGE_URI = BASE_URI + "empty.html"; +const SCOPE = PAGE_URI + "?storage_permission"; +const SW_SCRIPT = BASE_URI + "empty.js"; + + +add_task(async function setup() { + await SpecialPowers.pushPrefEnv({"set": [ + ["dom.serviceWorkers.enabled", true], + ["dom.serviceWorkers.testing.enabled", true], + ]}); + + let tab = BrowserTestUtils.addTab(gBrowser, PAGE_URI); + let browser = gBrowser.getBrowserForTab(tab); + await BrowserTestUtils.browserLoaded(browser); + + await ContentTask.spawn(browser, { script: SW_SCRIPT, scope: SCOPE }, + async function(opts) { + let reg = await content.navigator.serviceWorker.register(opts.script, + { scope: opts.scope }); + let worker = reg.installing || reg.waiting || reg.active; + await new Promise(resolve => { + if (worker.state === "activated") { + resolve(); + return; + } + worker.addEventListener("statechange", function onStateChange() { + if (worker.state === "activated") { + worker.removeEventListener("statechange", onStateChange); + resolve(); + } + }); + }); + } + ); + + await BrowserTestUtils.removeTab(tab); +}); + +add_task(async function test_allow_permission() { + Services.perms.add(Services.io.newURI(PAGE_URI), "cookie", + Ci.nsICookiePermission.ACCESS_ALLOW); + + let tab = BrowserTestUtils.addTab(gBrowser, SCOPE); + let browser = gBrowser.getBrowserForTab(tab); + await BrowserTestUtils.browserLoaded(browser); + + let controller = await ContentTask.spawn(browser, null, async function() { + return content.navigator.serviceWorker.controller; + }); + + ok(!!controller, "page should be controlled with storage allowed"); + + await BrowserTestUtils.removeTab(tab); +}); + +add_task(async function test_deny_permission() { + Services.perms.add(Services.io.newURI(PAGE_URI), "cookie", + Ci.nsICookiePermission.ACCESS_DENY); + + let tab = BrowserTestUtils.addTab(gBrowser, SCOPE); + let browser = gBrowser.getBrowserForTab(tab); + await BrowserTestUtils.browserLoaded(browser); + + let controller = await ContentTask.spawn(browser, null, async function() { + return content.navigator.serviceWorker.controller; + }); + + is(controller, null, "page should be not controlled with storage denied"); + + await BrowserTestUtils.removeTab(tab); + Services.perms.remove(Services.io.newURI(PAGE_URI), "cookie"); +}); + +add_task(async function test_session_permission() { + Services.perms.add(Services.io.newURI(PAGE_URI), "cookie", + Ci.nsICookiePermission.ACCESS_SESSION); + + let tab = BrowserTestUtils.addTab(gBrowser, SCOPE); + let browser = gBrowser.getBrowserForTab(tab); + await BrowserTestUtils.browserLoaded(browser); + + let controller = await ContentTask.spawn(browser, null, async function() { + return content.navigator.serviceWorker.controller; + }); + + is(controller, null, "page should be not controlled with session storage"); + + await BrowserTestUtils.removeTab(tab); + Services.perms.remove(Services.io.newURI(PAGE_URI), "cookie"); +}); + +add_task(async function cleanup() { + Services.perms.remove(Services.io.newURI(PAGE_URI), "cookie"); + + let tab = BrowserTestUtils.addTab(gBrowser, PAGE_URI); + let browser = gBrowser.getBrowserForTab(tab); + await BrowserTestUtils.browserLoaded(browser); + + await ContentTask.spawn(browser, SCOPE, async function(uri) { + let reg = await content.navigator.serviceWorker.getRegistration(uri); + let worker = reg.active; + await reg.unregister(); + await new Promise(resolve => { + if (worker.state === "redundant") { + resolve(); + return; + } + worker.addEventListener("statechange", function onStateChange() { + if (worker.state === "redundant") { + worker.removeEventListener("statechange", onStateChange); + resolve(); + } + }); + }); + }); + + await BrowserTestUtils.removeTab(tab); +}); From 572321a804b3ccc39e04ca0fe23ebf90d13653e2 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Mon, 8 Jan 2018 20:25:53 -0500 Subject: [PATCH 21/33] Bug 1426977 P5 Remove unnused cookie pref getters from nsContentUtils. r=mystor --- dom/base/nsContentUtils.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 2c0d06f79ea7..b5fe9e674ade 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -2913,16 +2913,6 @@ public: static bool IsNonSubresourceRequest(nsIChannel* aChannel); - static uint32_t CookiesBehavior() - { - return sCookiesBehavior; - } - - static uint32_t CookiesLifetimePolicy() - { - return sCookiesLifetimePolicy; - } - // The order of these entries matters, as we use std::min for total ordering // of permissions. Private Browsing is considered to be more limiting // then session scoping From ed36e1377d526bac8dc38daab77f554fd7285204 Mon Sep 17 00:00:00 2001 From: Tom Tung Date: Mon, 8 Jan 2018 11:27:23 +0800 Subject: [PATCH 22/33] Bug 1427978 - P1: Update the wpt tests to expect to reject the cors synthesized response to a same origin request. r=bkelly --HG-- extra : rebase_source : 916544a65fd4a74d1880ae03b08fb54ea747ae75 --- .../service-worker/fetch-response-taint.https.html | 6 ++++++ .../service-worker/worker-interception.https.html | 12 +++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/testing/web-platform/tests/service-workers/service-worker/fetch-response-taint.https.html b/testing/web-platform/tests/service-workers/service-worker/fetch-response-taint.https.html index a6e7f984ea24..8ebee0c07374 100644 --- a/testing/web-platform/tests/service-workers/service-worker/fetch-response-taint.https.html +++ b/testing/web-platform/tests/service-workers/service-worker/fetch-response-taint.https.html @@ -193,6 +193,9 @@ for_each_origin_mode_credentials(function(origin, mode, credentials) { // Fetch to the other origin with same-origin mode should fail. if (origin == OTHER_ORIGIN && mode == 'same-origin') { ng_test(url, mode, credentials); + } else if (origin == BASE_ORIGIN && mode == 'same-origin') { + // Cors type response to a same-origin mode request should fail + ng_test(url, mode, credentials); } else { // The response from the SW should be cors. ok_test(url, mode, credentials, 'cors', 'undefined'); @@ -208,6 +211,9 @@ for_each_origin_mode_credentials(function(origin, mode, credentials) { // Fetch to the other origin with same-origin mode should fail. if (origin == OTHER_ORIGIN && mode == 'same-origin') { ng_test(url, mode, credentials); + } else if (origin == BASE_ORIGIN && mode == 'same-origin') { + // Cors type response to a same-origin mode request should fail + ng_test(url, mode, credentials); } else { // The response from the SW should be cors. ok_test(url, mode, credentials, 'cors', 'username1s'); diff --git a/testing/web-platform/tests/service-workers/service-worker/worker-interception.https.html b/testing/web-platform/tests/service-workers/service-worker/worker-interception.https.html index 3ec66a54b6e1..4f14746d917f 100644 --- a/testing/web-platform/tests/service-workers/service-worker/worker-interception.https.html +++ b/testing/web-platform/tests/service-workers/service-worker/worker-interception.https.html @@ -81,10 +81,16 @@ promise_test(function(t) { }); }) .then(function(data) { - assert_equals(data, 'dummy-worker-script loaded'); + assert_unreached('intercepted cors response to a same-origin mode ' + + 'worker load should fail'); service_worker_unregister_and_done(t, scope); - }); - }, 'Verify worker script intercepted by cors response succeeds'); + }) + .catch(function(e) { + assert_true(true, 'intercepted cors response to a same-origin mode ' + + 'worker load should fail'); + service_worker_unregister_and_done(t, scope); + }); + }, 'Verify worker script intercepted by cors response fails'); promise_test(function(t) { var worker_url = 'resources/dummy-no-cors-worker.js'; From c9bf5a8d878bbd35c225f1a25245f99fd17e0a9e Mon Sep 17 00:00:00 2001 From: Tom Tung Date: Mon, 8 Jan 2018 11:28:34 +0800 Subject: [PATCH 23/33] Bug 1427978 - P2: Remove the ini file to expect the wpt tests succeed by default. r=bkelly --HG-- extra : rebase_source : 6cc0849e2ca892dbc87ec9831764c20b2eea3cc6 --- .../fetch-response-taint.https.html.ini | 20 ------------------- .../worker-interception.https.html.ini | 5 ----- 2 files changed, 25 deletions(-) delete mode 100644 testing/web-platform/meta/service-workers/service-worker/fetch-response-taint.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/service-worker/worker-interception.https.html.ini diff --git a/testing/web-platform/meta/service-workers/service-worker/fetch-response-taint.https.html.ini b/testing/web-platform/meta/service-workers/service-worker/fetch-response-taint.https.html.ini deleted file mode 100644 index de837da4fbec..000000000000 --- a/testing/web-platform/meta/service-workers/service-worker/fetch-response-taint.https.html.ini +++ /dev/null @@ -1,20 +0,0 @@ -[fetch-response-taint.https.html] - type: testharness - [fetching url:"https://web-platform.test:8443/?url=https%3A%2F%2Fwww1.web-platform.test%3A8443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"same-origin" credentials:"omit" should succeed.] - expected: FAIL # issue: https://github.com/whatwg/fetch/issues/629 - - [fetching url:"https://web-platform.test:8443/?url=https%3A%2F%2Fwww1.web-platform.test%3A8443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"same-origin" credentials:"same-origin" should succeed.] - expected: FAIL # issue: https://github.com/whatwg/fetch/issues/629 - - [fetching url:"https://web-platform.test:8443/?url=https%3A%2F%2Fwww1.web-platform.test%3A8443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"same-origin" credentials:"include" should succeed.] - expected: FAIL # issue: https://github.com/whatwg/fetch/issues/629 - - [fetching url:"https://web-platform.test:8443/?url=https%3A%2F%2Fwww1.web-platform.test%3A8443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Fweb-platform.test%3A8443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"same-origin" credentials:"omit" should succeed.] - expected: FAIL # issue: https://github.com/whatwg/fetch/issues/629 - - [fetching url:"https://web-platform.test:8443/?url=https%3A%2F%2Fwww1.web-platform.test%3A8443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Fweb-platform.test%3A8443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"same-origin" credentials:"same-origin" should succeed.] - expected: FAIL # issue: https://github.com/whatwg/fetch/issues/629 - - [fetching url:"https://web-platform.test:8443/?url=https%3A%2F%2Fwww1.web-platform.test%3A8443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Fweb-platform.test%3A8443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"same-origin" credentials:"include" should succeed.] - expected: FAIL # issue: https://github.com/whatwg/fetch/issues/629 - diff --git a/testing/web-platform/meta/service-workers/service-worker/worker-interception.https.html.ini b/testing/web-platform/meta/service-workers/service-worker/worker-interception.https.html.ini deleted file mode 100644 index afc2805ebf47..000000000000 --- a/testing/web-platform/meta/service-workers/service-worker/worker-interception.https.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[worker-interception.https.html] - type: testharness - [Verify worker script intercepted by cors response succeeds] - expected: FAIL # issue: https://github.com/whatwg/fetch/issues/629 - From 9166b5153688428870b2edf639a760c9557105d9 Mon Sep 17 00:00:00 2001 From: Aditya Bharti Date: Tue, 9 Jan 2018 02:16:30 +0530 Subject: [PATCH 24/33] bug 1364043 - Allow C++ to accumulate multiple samples into histograms with one call. r=chutten Added another Telemetry::Accumulate function that takes a histogram id and an array of samples as arguments. As of this patch, adding multiple samples to keyed and categorical histograms is not supported. --HG-- extra : rebase_source : e84c53d23c9d2a6fc07f57b626e76e09c61c3bee --- toolkit/components/telemetry/Telemetry.cpp | 6 + toolkit/components/telemetry/Telemetry.h | 7 ++ .../telemetry/TelemetryHistogram.cpp | 16 +++ .../components/telemetry/TelemetryHistogram.h | 1 + .../telemetry/tests/gtest/TestHistograms.cpp | 111 ++++++++++++++++++ 5 files changed, 141 insertions(+) diff --git a/toolkit/components/telemetry/Telemetry.cpp b/toolkit/components/telemetry/Telemetry.cpp index ccea36c2a6cf..4aaa1152437e 100644 --- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/Telemetry.cpp @@ -1930,6 +1930,12 @@ Accumulate(HistogramID aHistogram, uint32_t aSample) TelemetryHistogram::Accumulate(aHistogram, aSample); } +void +Accumulate(HistogramID aHistogram, const nsTArray& aSamples) +{ + TelemetryHistogram::Accumulate(aHistogram, aSamples); +} + void Accumulate(HistogramID aID, const nsCString& aKey, uint32_t aSample) { diff --git a/toolkit/components/telemetry/Telemetry.h b/toolkit/components/telemetry/Telemetry.h index 452fdfe6c824..1bac7cea926f 100644 --- a/toolkit/components/telemetry/Telemetry.h +++ b/toolkit/components/telemetry/Telemetry.h @@ -58,6 +58,13 @@ void Init(); */ void Accumulate(HistogramID id, uint32_t sample); +/** + * Adds an array of samples to a histogram defined in TelemetryHistograms.h + * @param id - histogram id + * @param samples - values to record. + */ +void Accumulate(HistogramID id, const nsTArray& samples); + /** * Adds sample to a keyed histogram defined in TelemetryHistogramEnums.h * diff --git a/toolkit/components/telemetry/TelemetryHistogram.cpp b/toolkit/components/telemetry/TelemetryHistogram.cpp index c2556a370274..c7eafab61b05 100644 --- a/toolkit/components/telemetry/TelemetryHistogram.cpp +++ b/toolkit/components/telemetry/TelemetryHistogram.cpp @@ -1874,6 +1874,22 @@ TelemetryHistogram::Accumulate(HistogramID aID, internal_Accumulate(aID, aSample); } +void +TelemetryHistogram::Accumulate(HistogramID aID, const nsTArray& aSamples) +{ + if (NS_WARN_IF(!internal_IsHistogramEnumId(aID))) { + MOZ_ASSERT_UNREACHABLE("Histogram usage requires valid ids."); + return; + } + + MOZ_ASSERT(!gHistogramInfos[aID].keyed, "Cannot accumulate into a keyed histogram. No key given."); + + StaticMutexAutoLock locker(gTelemetryHistogramMutex); + for(uint32_t sample: aSamples){ + internal_Accumulate(aID, sample); + } +} + void TelemetryHistogram::Accumulate(HistogramID aID, const nsCString& aKey, uint32_t aSample) diff --git a/toolkit/components/telemetry/TelemetryHistogram.h b/toolkit/components/telemetry/TelemetryHistogram.h index fdc95549dcd7..216e99230c1e 100644 --- a/toolkit/components/telemetry/TelemetryHistogram.h +++ b/toolkit/components/telemetry/TelemetryHistogram.h @@ -36,6 +36,7 @@ void SetHistogramRecordingEnabled(mozilla::Telemetry::HistogramID aID, bool aEna nsresult SetHistogramRecordingEnabled(const nsACString &id, bool aEnabled); void Accumulate(mozilla::Telemetry::HistogramID aHistogram, uint32_t aSample); +void Accumulate(mozilla::Telemetry::HistogramID aHistogram, const nsTArray& aSamples); void Accumulate(mozilla::Telemetry::HistogramID aID, const nsCString& aKey, uint32_t aSample); void Accumulate(const char* name, uint32_t sample); diff --git a/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp b/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp index c7e00025455f..c8135bd1b898 100644 --- a/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp @@ -238,3 +238,114 @@ TEST_F(TelemetryTestFixture, AccumulateKeyedCategoricalHistogram) JS::ToUint32(cx.GetJSContext(), otherValue, &uOtherValue); ASSERT_EQ(uOtherValue, kOtherSampleExpectedValue) << "The other-sample histogram is not returning expected value"; } + +TEST_F(TelemetryTestFixture, AccumulateCountHistogram_MultipleSamples) +{ + nsTArray samples({4,4,4}); + const uint32_t kExpectedSum = 12; + + AutoJSContextWithGlobal cx(mCleanGlobal); + + GetAndClearHistogram(cx.GetJSContext(), mTelemetry, NS_LITERAL_CSTRING("TELEMETRY_TEST_COUNT"), + false); + + // Accumulate in histogram + Telemetry::Accumulate(Telemetry::TELEMETRY_TEST_COUNT, samples); + + // Get a snapshot of all the histograms + JS::RootedValue snapshot(cx.GetJSContext()); + GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_COUNT", &snapshot, false); + + // Get histogram from snapshot + JS::RootedValue histogram(cx.GetJSContext()); + GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_COUNT", snapshot, &histogram); + + // Get "sum" from histogram + JS::RootedValue sum(cx.GetJSContext()); + GetProperty(cx.GetJSContext(), "sum", histogram, &sum); + + // Check that sum matches with aValue + uint32_t uSum = 0; + JS::ToUint32(cx.GetJSContext(), sum, &uSum); + ASSERT_EQ(uSum, kExpectedSum) << "This histogram is not returning expected value"; +} + +TEST_F(TelemetryTestFixture, AccumulateLinearHistogram_MultipleSamples) +{ + nsTArray samples({4,4,4}); + const uint32_t kExpectedCount = 3; + + AutoJSContextWithGlobal cx(mCleanGlobal); + + GetAndClearHistogram(cx.GetJSContext(), mTelemetry, NS_LITERAL_CSTRING("TELEMETRY_TEST_LINEAR"), + false); + + // Accumulate in the histogram + Telemetry::Accumulate(Telemetry::TELEMETRY_TEST_LINEAR, samples); + + // Get a snapshot of all the histograms + JS::RootedValue snapshot(cx.GetJSContext()); + GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_LINEAR", &snapshot, false); + + // Get histogram from snapshot + JS::RootedValue histogram(cx.GetJSContext()); + GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_LINEAR", snapshot, &histogram); + + // Get "counts" array from histogram + JS::RootedValue counts(cx.GetJSContext()); + GetProperty(cx.GetJSContext(), "counts", histogram, &counts); + + // Index 0 is only for values less than 'low'. Values within range start at index 1 + JS::RootedValue count(cx.GetJSContext()); + const uint32_t index = 1; + GetElement(cx.GetJSContext(), index, counts, &count); + + // Check that this count matches with nSamples + uint32_t uCount = 0; + JS::ToUint32(cx.GetJSContext(), count, &uCount); + ASSERT_EQ(uCount, kExpectedCount) << "The histogram did not accumulate the correct number of values"; +} + +TEST_F(TelemetryTestFixture, AccumulateLinearHistogram_DifferentSamples) +{ + nsTArray samples({4, 8, 2147483646}); + + AutoJSContextWithGlobal cx(mCleanGlobal); + + GetAndClearHistogram(cx.GetJSContext(), mTelemetry, NS_LITERAL_CSTRING("TELEMETRY_TEST_LINEAR"), + false); + + // Accumulate in histogram + Telemetry::Accumulate(Telemetry::TELEMETRY_TEST_LINEAR, samples); + + // Get a snapshot of all histograms + JS::RootedValue snapshot(cx.GetJSContext()); + GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_LINEAR", &snapshot, false); + + // Get histogram from snapshot + JS::RootedValue histogram(cx.GetJSContext()); + GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_LINEAR", snapshot, &histogram); + + // Get counts array from histogram + JS::RootedValue counts(cx.GetJSContext()); + GetProperty(cx.GetJSContext(), "counts", histogram, &counts); + + // Get counts in first and last buckets + JS::RootedValue countFirst(cx.GetJSContext()); + JS::RootedValue countLast(cx.GetJSContext()); + const uint32_t firstIndex = 1; + const uint32_t lastIndex = 9; + GetElement(cx.GetJSContext(), firstIndex, counts, &countFirst); + GetElement(cx.GetJSContext(), lastIndex, counts, &countLast); + + // Check that the counts match + uint32_t uCountFirst = 0; + uint32_t uCountLast = 0; + JS::ToUint32(cx.GetJSContext(), countFirst, &uCountFirst); + JS::ToUint32(cx.GetJSContext(), countLast, &uCountLast); + + const uint32_t kExpectedCountFirst = 2; + const uint32_t kExpectedCountLast = 1; + ASSERT_EQ(uCountFirst, kExpectedCountFirst) << "The first bucket did not accumulate the correct number of values"; + ASSERT_EQ(uCountLast, kExpectedCountLast) << "The last bucket did not accumulate the correct number of values"; +} From ad62e674487f143ad9abb6ed35d662d8299306eb Mon Sep 17 00:00:00 2001 From: Andre Alves Garzia Date: Fri, 5 Jan 2018 21:00:58 -0200 Subject: [PATCH 25/33] Bug 1428446 - Add DAT, IPFS, and SSB to the webextension protocol whitelist. r=mixedpuppy --- .../extensions/schemas/extension_protocol_handlers.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolkit/components/extensions/schemas/extension_protocol_handlers.json b/toolkit/components/extensions/schemas/extension_protocol_handlers.json index 2f7c479c0630..8fa20fb598a4 100644 --- a/toolkit/components/extensions/schemas/extension_protocol_handlers.json +++ b/toolkit/components/extensions/schemas/extension_protocol_handlers.json @@ -16,8 +16,8 @@ "choices": [{ "type": "string", "enum": [ - "bitcoin", "geo", "gopher", "im", "irc", "ircs", "magnet", - "mailto", "mms", "news", "nntp", "sip", "sms", "smsto", "ssh", + "bitcoin", "dat", "dweb", "geo", "gopher", "im", "ipfs", "ipns", "irc", "ircs", "magnet", + "mailto", "mms", "news", "nntp", "sip", "sms", "smsto", "ssb", "ssh", "tel", "urn", "webcal", "wtai", "xmpp" ] }, { From 87bb85b91b8a086ef2ec68e15129469ffcc335c7 Mon Sep 17 00:00:00 2001 From: Alphan Chen Date: Fri, 5 Jan 2018 15:12:16 +0800 Subject: [PATCH 26/33] Bug 1421214 - Try GoToAnchor() with unescaped string before using document's charset. r=smaug --- docshell/base/nsDocShell.cpp | 14 ++++++++++++++ dom/base/nsDocument.cpp | 18 ++++++++++++------ .../scroll-to-anchor-name.html | 6 ++++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index bbd0b4d885ed..e73941d589df 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -11359,6 +11359,20 @@ nsDocShell::ScrollToAnchor(bool aCurHasRef, bool aNewHasRef, nsIPresShell::SCROLL_SMOOTH_AUTO); } + if (NS_FAILED(rv)) { + char* str = ToNewCString(aNewHash); + if (!str) { + return NS_ERROR_OUT_OF_MEMORY; + } + nsUnescape(str); + NS_ConvertUTF8toUTF16 utf16Str(str); + if (!utf16Str.IsEmpty()) { + rv = shell->GoToAnchor(utf16Str, scroll, + nsIPresShell::SCROLL_SMOOTH_AUTO); + } + free(str); + } + // Above will fail if the anchor name is not UTF-8. Need to // convert from document charset to unicode. if (NS_FAILED(rv)) { diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 34bd86f751fa..1b98f94341c2 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -10035,10 +10035,7 @@ nsDocument::ScrollToRef() rv = NS_ERROR_FAILURE; } - // If UTF-8 URI failed then try to assume the string as a - // document's charset. if (NS_FAILED(rv)) { - auto encoding = GetDocumentCharacterSet(); char* tmpstr = ToNewCString(mScrollToRef); if (!tmpstr) { return; @@ -10048,10 +10045,19 @@ nsDocument::ScrollToRef() unescapedRef.Assign(tmpstr); free(tmpstr); - rv = encoding->DecodeWithoutBOMHandling(unescapedRef, ref); + NS_ConvertUTF8toUTF16 utf16Str(unescapedRef); + if (!utf16Str.IsEmpty()) { + rv = shell->GoToAnchor(utf16Str, mChangeScrollPosWhenScrollingToRef); + } - if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) { - rv = shell->GoToAnchor(ref, mChangeScrollPosWhenScrollingToRef); + // If UTF-8 URI failed then try to assume the string as a + // document's charset. + if (NS_FAILED(rv)) { + const Encoding* encoding = GetDocumentCharacterSet(); + rv = encoding->DecodeWithoutBOMHandling(unescapedRef, ref); + if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) { + rv = shell->GoToAnchor(ref, mChangeScrollPosWhenScrollingToRef); + } } } if (NS_SUCCEEDED(rv)) { diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/scroll-to-fragid/scroll-to-anchor-name.html b/testing/web-platform/tests/html/browsers/browsing-the-web/scroll-to-fragid/scroll-to-anchor-name.html index 43dbaf9e297b..060aed11e264 100644 --- a/testing/web-platform/tests/html/browsers/browsing-the-web/scroll-to-fragid/scroll-to-anchor-name.html +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/scroll-to-fragid/scroll-to-anchor-name.html @@ -8,6 +8,7 @@
+
diff --git a/dom/webauthn/tests/test_webauthn_authenticator_transports.html b/dom/webauthn/tests/test_webauthn_authenticator_transports.html new file mode 100644 index 000000000000..56a3879c67e9 --- /dev/null +++ b/dom/webauthn/tests/test_webauthn_authenticator_transports.html @@ -0,0 +1,150 @@ + + + + W3C Web Authentication - Authenticator Transports + + + + + + + +

W3C Web Authentication - Authenticator Transports

+ Mozilla Bug 1406467 + + + + + diff --git a/dom/webauthn/u2f-hid-rs/examples/main.rs b/dom/webauthn/u2f-hid-rs/examples/main.rs index 2210d04ad95e..a0904ccd1fef 100644 --- a/dom/webauthn/u2f-hid-rs/examples/main.rs +++ b/dom/webauthn/u2f-hid-rs/examples/main.rs @@ -9,7 +9,7 @@ use crypto::digest::Digest; use crypto::sha2::Sha256; use std::io; use std::sync::mpsc::channel; -use u2fhid::{RegisterFlags, U2FManager}; +use u2fhid::{AuthenticatorTransports, KeyHandle, RegisterFlags, SignFlags, U2FManager}; extern crate log; extern crate env_logger; @@ -66,11 +66,17 @@ fn main() { let register_data = rx.recv().unwrap(); println!("Register result: {}", base64::encode(®ister_data)); println!("Asking a security key to sign now, with the data from the register..."); - let key_handle = u2f_get_key_handle_from_register_response(®ister_data).unwrap(); + let credential = u2f_get_key_handle_from_register_response(®ister_data).unwrap(); + let key_handle = KeyHandle { + credential, + transports: AuthenticatorTransports::empty(), + }; + let flags = SignFlags::empty(); let (tx, rx) = channel(); manager .sign( + flags, 15_000, chall_bytes, app_bytes, diff --git a/dom/webauthn/u2f-hid-rs/src/capi.rs b/dom/webauthn/u2f-hid-rs/src/capi.rs index 69b0c2d9c349..a0fe441e8328 100644 --- a/dom/webauthn/u2f-hid-rs/src/capi.rs +++ b/dom/webauthn/u2f-hid-rs/src/capi.rs @@ -9,7 +9,7 @@ use std::{ptr, slice}; use U2FManager; -type U2FKeyHandles = Vec>; +type U2FKeyHandles = Vec<::KeyHandle>; type U2FResult = HashMap>; type U2FCallback = extern "C" fn(u64, *mut U2FResult); @@ -52,8 +52,12 @@ pub unsafe extern "C" fn rust_u2f_khs_add( khs: *mut U2FKeyHandles, key_handle_ptr: *const u8, key_handle_len: usize, + transports: u8, ) { - (*khs).push(from_raw(key_handle_ptr, key_handle_len)); + (*khs).push(::KeyHandle { + credential: from_raw(key_handle_ptr, key_handle_len), + transports: ::AuthenticatorTransports::from_bits_truncate(transports), + }); } #[no_mangle] @@ -156,6 +160,7 @@ pub unsafe extern "C" fn rust_u2f_mgr_register( #[no_mangle] pub unsafe extern "C" fn rust_u2f_mgr_sign( mgr: *mut U2FManager, + flags: u64, timeout: u64, callback: U2FCallback, challenge_ptr: *const u8, @@ -178,21 +183,29 @@ pub unsafe extern "C" fn rust_u2f_mgr_sign( return 0; } + let flags = ::SignFlags::from_bits_truncate(flags); let challenge = from_raw(challenge_ptr, challenge_len); let application = from_raw(application_ptr, application_len); let key_handles = (*khs).clone(); let tid = new_tid(); - let res = (*mgr).sign(timeout, challenge, application, key_handles, move |rv| { - if let Ok((key_handle, signature)) = rv { - let mut result = U2FResult::new(); - result.insert(RESBUF_ID_KEYHANDLE, key_handle); - result.insert(RESBUF_ID_SIGNATURE, signature); - callback(tid, Box::into_raw(Box::new(result))); - } else { - callback(tid, ptr::null_mut()); - }; - }); + let res = (*mgr).sign( + flags, + timeout, + challenge, + application, + key_handles, + move |rv| { + if let Ok((key_handle, signature)) = rv { + let mut result = U2FResult::new(); + result.insert(RESBUF_ID_KEYHANDLE, key_handle); + result.insert(RESBUF_ID_SIGNATURE, signature); + callback(tid, Box::into_raw(Box::new(result))); + } else { + callback(tid, ptr::null_mut()); + }; + }, + ); if res.is_ok() { tid } else { 0 } } diff --git a/dom/webauthn/u2f-hid-rs/src/lib.rs b/dom/webauthn/u2f-hid-rs/src/lib.rs index db3234fcd304..859a4b17afe6 100644 --- a/dom/webauthn/u2f-hid-rs/src/lib.rs +++ b/dom/webauthn/u2f-hid-rs/src/lib.rs @@ -56,6 +56,24 @@ bitflags! { const REQUIRE_PLATFORM_ATTACHMENT = 4; } } +bitflags! { + pub struct SignFlags: u64 { + const REQUIRE_USER_VERIFICATION = 1; + } +} +bitflags! { + pub struct AuthenticatorTransports: u8 { + const USB = 1; + const NFC = 2; + const BLE = 4; + } +} + +#[derive(Clone)] +pub struct KeyHandle { + pub credential: Vec, + pub transports: AuthenticatorTransports, +} #[cfg(fuzzing)] pub use u2fprotocol::*; diff --git a/dom/webauthn/u2f-hid-rs/src/manager.rs b/dom/webauthn/u2f-hid-rs/src/manager.rs index 502364fd8439..31b834cf2860 100644 --- a/dom/webauthn/u2f-hid-rs/src/manager.rs +++ b/dom/webauthn/u2f-hid-rs/src/manager.rs @@ -17,14 +17,15 @@ enum QueueAction { timeout: u64, challenge: Vec, application: Vec, - key_handles: Vec>, + key_handles: Vec<::KeyHandle>, callback: OnceCallback>, }, Sign { + flags: ::SignFlags, timeout: u64, challenge: Vec, application: Vec, - key_handles: Vec>, + key_handles: Vec<::KeyHandle>, callback: OnceCallback<(Vec, Vec)>, }, Cancel, @@ -64,6 +65,7 @@ impl U2FManager { ); } Ok(QueueAction::Sign { + flags, timeout, challenge, application, @@ -71,7 +73,14 @@ impl U2FManager { callback, }) => { // This must not block, otherwise we can't cancel. - sm.sign(timeout, challenge, application, key_handles, callback); + sm.sign( + flags, + timeout, + challenge, + application, + key_handles, + callback, + ); } Ok(QueueAction::Cancel) => { // Cancelling must block so that we don't start a new @@ -101,7 +110,7 @@ impl U2FManager { timeout: u64, challenge: Vec, application: Vec, - key_handles: Vec>, + key_handles: Vec<::KeyHandle>, callback: F, ) -> io::Result<()> where @@ -116,7 +125,7 @@ impl U2FManager { } for key_handle in &key_handles { - if key_handle.len() > 256 { + if key_handle.credential.len() > 256 { return Err(io::Error::new( io::ErrorKind::InvalidInput, "Key handle too large", @@ -138,10 +147,11 @@ impl U2FManager { pub fn sign( &self, + flags: ::SignFlags, timeout: u64, challenge: Vec, application: Vec, - key_handles: Vec>, + key_handles: Vec<::KeyHandle>, callback: F, ) -> io::Result<()> where @@ -163,7 +173,7 @@ impl U2FManager { } for key_handle in &key_handles { - if key_handle.len() > 256 { + if key_handle.credential.len() > 256 { return Err(io::Error::new( io::ErrorKind::InvalidInput, "Key handle too large", @@ -173,6 +183,7 @@ impl U2FManager { let callback = OnceCallback::new(callback); let action = QueueAction::Sign { + flags, timeout, challenge, application, diff --git a/dom/webauthn/u2f-hid-rs/src/statemachine.rs b/dom/webauthn/u2f-hid-rs/src/statemachine.rs index 5e1b7be27d04..7674a889a386 100644 --- a/dom/webauthn/u2f-hid-rs/src/statemachine.rs +++ b/dom/webauthn/u2f-hid-rs/src/statemachine.rs @@ -10,6 +10,10 @@ use std::time::Duration; use util::{io_err, OnceCallback}; use u2fprotocol::{u2f_init_device, u2f_is_keyhandle_valid, u2f_register, u2f_sign}; +fn is_valid_transport(transports: ::AuthenticatorTransports) -> bool { + transports.is_empty() || transports.contains(::AuthenticatorTransports::USB) +} + #[derive(Default)] pub struct StateMachine { transaction: Option, @@ -26,7 +30,7 @@ impl StateMachine { timeout: u64, challenge: Vec, application: Vec, - key_handles: Vec>, + key_handles: Vec<::KeyHandle>, callback: OnceCallback>, ) { // Abort any prior register/sign calls. @@ -60,8 +64,9 @@ impl StateMachine { // Iterate the exclude list and see if there are any matches. // Abort the state machine if we found a valid key handle. if key_handles.iter().any(|key_handle| { - u2f_is_keyhandle_valid(dev, &challenge, &application, key_handle) - .unwrap_or(false) /* no match on failure */ + is_valid_transport(key_handle.transports) && + u2f_is_keyhandle_valid(dev, &challenge, &application, &key_handle.credential) + .unwrap_or(false) /* no match on failure */ }) { return; @@ -85,10 +90,11 @@ impl StateMachine { pub fn sign( &mut self, + flags: ::SignFlags, timeout: u64, challenge: Vec, application: Vec, - key_handles: Vec>, + key_handles: Vec<::KeyHandle>, callback: OnceCallback<(Vec, Vec)>, ) { // Abort any prior register/sign calls. @@ -108,15 +114,38 @@ impl StateMachine { return; } + // We currently don't support user verification because we can't + // ask tokens whether they do support that. If the flag is set, + // ignore all tokens for now. + // + // Technically, this is a ConstraintError because we shouldn't talk + // to this authenticator in the first place. But the result is the + // same anyway. + if !flags.is_empty() { + return; + } + // Find all matching key handles. let key_handles = key_handles .iter() .filter(|key_handle| { - u2f_is_keyhandle_valid(dev, &challenge, &application, key_handle) + u2f_is_keyhandle_valid(dev, &challenge, &application, &key_handle.credential) .unwrap_or(false) /* no match on failure */ }) .collect::>(); + // Aggregate distinct transports from all given credentials. + let transports = key_handles.iter().fold( + ::AuthenticatorTransports::empty(), + |t, k| t | k.transports, + ); + + // We currently only support USB. If the RP specifies transports + // and doesn't include USB it's probably lying. + if !is_valid_transport(transports) { + return; + } + while alive() { // If the device matches none of the given key handles // then just make it blink with bogus data. @@ -129,8 +158,14 @@ impl StateMachine { } else { // Otherwise, try to sign. for key_handle in &key_handles { - if let Ok(bytes) = u2f_sign(dev, &challenge, &application, key_handle) { - callback.call(Ok((key_handle.to_vec(), bytes))); + if let Ok(bytes) = u2f_sign( + dev, + &challenge, + &application, + &key_handle.credential, + ) + { + callback.call(Ok((key_handle.credential.clone(), bytes))); break; } } diff --git a/dom/webauthn/u2f-hid-rs/src/u2fhid-capi.h b/dom/webauthn/u2f-hid-rs/src/u2fhid-capi.h index a27f7fc1b5be..3dc0bb0847ef 100644 --- a/dom/webauthn/u2f-hid-rs/src/u2fhid-capi.h +++ b/dom/webauthn/u2f-hid-rs/src/u2fhid-capi.h @@ -19,6 +19,10 @@ const uint64_t U2F_FLAG_REQUIRE_RESIDENT_KEY = 1; const uint64_t U2F_FLAG_REQUIRE_USER_VERIFICATION = 2; const uint64_t U2F_FLAG_REQUIRE_PLATFORM_ATTACHMENT = 4; +const uint8_t U2F_AUTHENTICATOR_TRANSPORT_USB = 1; +const uint8_t U2F_AUTHENTICATOR_TRANSPORT_NFC = 2; +const uint8_t U2F_AUTHENTICATOR_TRANSPORT_BLE = 4; + // NOTE: Preconditions // * All rust_u2f_mgr* pointers must refer to pointers which are returned // by rust_u2f_mgr_new, and must be freed with rust_u2f_mgr_free. @@ -56,6 +60,7 @@ uint64_t rust_u2f_mgr_register(rust_u2f_manager* mgr, const rust_u2f_key_handles* khs); uint64_t rust_u2f_mgr_sign(rust_u2f_manager* mgr, + uint64_t flags, uint64_t timeout, rust_u2f_callback, const uint8_t* challenge_ptr, @@ -72,7 +77,8 @@ uint64_t rust_u2f_mgr_cancel(rust_u2f_manager* mgr); rust_u2f_key_handles* rust_u2f_khs_new(); void rust_u2f_khs_add(rust_u2f_key_handles* khs, const uint8_t* key_handle, - size_t key_handle_len); + size_t key_handle_len, + uint8_t transports); /* unsafe */ void rust_u2f_khs_free(rust_u2f_key_handles* khs); diff --git a/dom/webidl/WebAuthentication.webidl b/dom/webidl/WebAuthentication.webidl index 8bf7f49c25b5..51e8d5fbdeba 100644 --- a/dom/webidl/WebAuthentication.webidl +++ b/dom/webidl/WebAuthentication.webidl @@ -4,7 +4,7 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. * * The origin of this IDL file is - * https://www.w3.org/TR/webauthn/ + * https://w3c.github.io/webauthn/ */ /***** Interfaces to Data *****/ @@ -94,6 +94,7 @@ dictionary PublicKeyCredentialRequestOptions { unsigned long timeout; USVString rpId; sequence allowCredentials = []; + UserVerificationRequirement userVerification = "preferred"; // Extensions are not supported yet. // AuthenticationExtensions extensions; // Add in Bug 1406458 }; From d6173b3fbb296d605301f63c5c8a13c0fd96b928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Fri, 5 Jan 2018 21:03:39 +0100 Subject: [PATCH 32/33] Bug 449045 - Drop support for type=timed textboxes. r=enn MozReview-Commit-ID: Ld6foAxCAhW --HG-- extra : rebase_source : 94065ccfb55e8a93322cd5fbbeabcc78b222bf1a --- editor/reftests/xul/emptytextbox-5.xul | 12 ------ editor/reftests/xul/reftest.list | 1 - toolkit/content/widgets/textbox.xml | 56 -------------------------- toolkit/content/xul.css | 4 -- 4 files changed, 73 deletions(-) delete mode 100644 editor/reftests/xul/emptytextbox-5.xul diff --git a/editor/reftests/xul/emptytextbox-5.xul b/editor/reftests/xul/emptytextbox-5.xul deleted file mode 100644 index 6c8c27971ef3..000000000000 --- a/editor/reftests/xul/emptytextbox-5.xul +++ /dev/null @@ -1,12 +0,0 @@ - - - - - -