From 22954acd32e0a91c87bb5da64a3db577894bf370 Mon Sep 17 00:00:00 2001 From: Fedor Date: Mon, 25 Nov 2024 17:24:41 +0200 Subject: [PATCH] 68.14.5 - everything else --- .clang-format-ignore | 3 +- .eslintrc.js | 1 + .flake8 | 2 +- Makefile.in | 93 +- README.md | 23 +- accessible/base/nsCoreUtils.cpp | 2 +- .../mochitest/attributes/test_obj_css.xul | 2 - aclocal.m4 | 6 - browser/actors/moz.build | 2 +- browser/app/macbuild/Contents/MacOS-files.in | 1 - browser/app/module.ver | 2 +- browser/app/moz.build | 4 - browser/app/profile/mypal.js | 23 +- browser/base/content/browser.js | 9 +- browser/base/content/moz.build | 14 +- browser/base/content/tabbrowser.js | 11 +- browser/base/content/test/menubar/browser.ini | 2 + .../test/menubar/browser_window_menu_list.js | 45 + browser/base/content/test/plugins/browser.ini | 4 +- browser/base/content/test/sanitize/head.js | 4 +- browser/base/jar.mn | 6 +- browser/base/moz.build | 4 +- browser/components/BrowserGlue.jsm | 38 +- .../tests/browser/browser.ini | 3 +- .../xpcshell/test_clear_blocked_cookies.js | 10 +- .../test/browser/browser-common.ini | 2 +- .../browser/browser_ext_tabs_insertCSS.js | 93 + .../test_ext_browsingData_cookies_cache.js | 2 +- .../migration/ChromeProfileMigrator.jsm | 2 +- .../components/migration/MSMigrationUtils.jsm | 2 +- .../tests/marionette/test_refresh_firefox.py | 2 +- browser/components/moz.build | 2 +- .../components/preferences/in-content/main.js | 10 +- .../tests/siteData/browser_siteData.js | 8 +- .../sessionstore/ContentRestore.jsm | 4 +- .../sessionstore/SessionCookies.jsm | 2 +- .../test/browser_cookies_privacy.js | 2 +- .../shell/nsWindowsShellService.cpp | 2 + browser/config/mozconfigs/linux32/beta | 2 - browser/config/mozconfigs/linux32/debug | 3 + browser/config/mozconfigs/linux32/devedition | 2 - browser/config/mozconfigs/linux32/nightly | 6 + .../mozconfigs/linux32/profile-generate | 1 - browser/config/mozconfigs/linux32/release | 2 - browser/config/mozconfigs/linux32/valgrind | 2 + browser/config/mozconfigs/linux64/beta | 2 - .../config/mozconfigs/linux64/code-coverage | 2 +- browser/config/mozconfigs/linux64/debug | 3 + .../mozconfigs/linux64/debug-searchfox-clang | 5 +- .../linux64/debug-static-analysis-clang | 4 +- browser/config/mozconfigs/linux64/devedition | 2 - browser/config/mozconfigs/linux64/nightly | 6 + browser/config/mozconfigs/linux64/plain-opt | 20 +- .../mozconfigs/linux64/profile-generate | 3 +- browser/config/mozconfigs/linux64/release | 2 - browser/config/mozconfigs/linux64/tup | 2 +- browser/config/mozconfigs/linux64/valgrind | 3 + .../config/mozconfigs/macosx64/add-on-devel | 2 - browser/config/mozconfigs/macosx64/beta | 2 - .../config/mozconfigs/macosx64/code-coverage | 2 +- .../mozconfigs/macosx64/debug-searchfox | 1 + browser/config/mozconfigs/macosx64/devedition | 4 - .../macosx64/l10n-mozconfig-devedition | 6 +- browser/config/mozconfigs/macosx64/nightly | 3 - browser/config/mozconfigs/macosx64/release | 2 - browser/config/mozconfigs/macosx64/repack | 8 +- browser/config/mozconfigs/whitelist | 5 - browser/config/mozconfigs/win32/beta | 2 - browser/config/mozconfigs/win32/devedition | 2 - browser/config/mozconfigs/win32/mingwclang | 16 +- .../config/mozconfigs/win32/profile-generate | 1 - browser/config/mozconfigs/win32/release | 2 - browser/config/mozconfigs/win64/beta | 2 - browser/config/mozconfigs/win64/code-coverage | 4 +- .../config/mozconfigs/win64/debug-searchfox | 1 + browser/config/mozconfigs/win64/devedition | 2 - browser/config/mozconfigs/win64/mingwclang | 16 +- browser/config/mozconfigs/win64/plain-opt | 16 +- .../config/mozconfigs/win64/profile-generate | 1 - browser/config/mozconfigs/win64/release | 2 - browser/config/version.txt | 2 +- browser/config/version_display.txt | 2 +- browser/confvars.sh | 27 +- browser/installer/Makefile.in | 4 - browser/installer/package-manifest.in | 12 +- browser/installer/windows/nsis/shared.nsh | 1 - browser/l10n-registry.manifest | 1 + browser/modules/moz.build | 12 +- .../modules/test/unit/test_SiteDataManager.js | 8 + browser/moz.build | 7 + browser/themes/shared/browser.inc.css | 2 +- .../shared/incontentprefs/preferences.inc.css | 2 + .../themes/shared/urlbar-searchbar.inc.css | 2 +- browser/themes/windows/browser.css | 2 +- .../browser_screenshots_cropping.js | 13 +- browser/tools/mozscreenshots/moz.build | 4 +- build.gradle | 86 +- build/autoconf/altoptions.m4 | 2 +- build/autoconf/android.m4 | 5 - build/autoconf/clang-plugin.m4 | 8 +- build/autoconf/compiler-opts.m4 | 28 +- build/autoconf/config.status.m4 | 13 - build/autoconf/icu.m4 | 99 - build/autoconf/ios.m4 | 107 - build/autoconf/nspr-build.m4 | 190 - build/autoconf/nspr.m4 | 109 - build/autoconf/nss.m4 | 90 - build/autoconf/zlib.m4 | 54 - .../llvmorg-11-init-4265-g2dcbdba8540.patch | 106 + build/docs/mozinfo.rst | 7 + build/docs/pgo.rst | 17 +- build/docs/test_certificates.rst | 4 +- build/mach_bootstrap.py | 4 + build/macosx/local-mozconfig.common | 26 +- build/merge_profdata.py | 18 - build/moz-automation.mk | 40 +- build/moz.configure/android-ndk.configure | 25 +- build/moz.configure/android-sdk.configure | 2 +- build/moz.configure/arm.configure | 38 +- build/moz.configure/bindgen.configure | 16 +- build/moz.configure/headers.configure | 6 +- build/moz.configure/init.configure | 83 +- build/moz.configure/lto-pgo.configure | 156 +- build/moz.configure/memory.configure | 10 +- build/moz.configure/nspr.configure | 98 + build/moz.configure/old.configure | 425 +- build/moz.configure/pkg.configure | 8 +- build/moz.configure/rust.configure | 9 +- build/moz.configure/toolchain.configure | 260 +- build/moz.configure/util.configure | 18 +- build/moz.configure/warnings.configure | 31 +- build/moz.configure/windows.configure | 44 +- build/mozconfig.automation | 1 + build/mozconfig.cache | 6 +- build/mozconfig.clang-cl | 8 +- build/mozconfig.lld-link | 4 +- build/mozconfig.nasm | 4 +- build/mozconfig.node | 4 +- build/mozconfig.pgo | 7 - build/mozconfig.rust | 10 +- build/mozconfig.stylo | 2 +- build/mozconfig.win-common | 4 +- build/pgo/index.html | 45 +- build/pgo/profileserver.py | 78 +- build/sanitizers/lsan_suppressions.txt | 80 - build/sanitizers/tsan_suppressions.txt | 21 - build/sanitizers/ubsan_suppressions.txt | 15 - build/sparse-profiles/taskgraph | 7 + build/unix/mozconfig.asan | 2 +- build/unix/mozconfig.stdcxx | 8 +- build/unix/mozconfig.tsan | 2 +- build/unix/mozconfig.unix | 41 +- build/valgrind/x86_64-pc-linux-gnu.sup | 4 - build/win32/pgomerge.py | 49 - build/win64/mozconfig.asan | 7 +- caps/nsScriptSecurityManager.cpp | 26 +- caps/nsScriptSecurityManager.h | 6 +- config/MozZipFile.py | 3 +- config/baseconfig.mk | 6 +- config/check_js_msg_encoding.py | 1 + config/check_js_opcode.py | 1 + config/check_macroassembler_style.py | 226 +- config/check_source_count.py | 1 + config/check_spidermonkey_style.py | 2 +- config/check_vanilla_allocations.py | 1 + config/config.mk | 24 +- config/external/ffi/subst_header.py | 1 + config/external/icu/data/genicudata.py | 12 - config/external/icu/data/icu_data.S | 24 + config/external/icu/data/icudata.s | 31 - config/external/icu/data/icudt67l.dat | Bin 14073408 -> 14073728 bytes config/external/icu/data/moz.build | 36 +- config/external/nspr/pr/moz.build | 13 +- config/external/sqlite/moz.build | 22 +- config/make-stl-wrappers.py | 1 + config/make-system-wrappers.py | 1 + config/make-windows-h-wrapper.py | 1 + config/makefiles/debugmake.mk | 1 - config/makefiles/rust.mk | 2 +- config/milestone.txt | 2 +- config/mozunit/mozunit/mozunit.py | 1 + config/nsinstall.py | 1 + config/printconfigsetting.py | 2 + config/printprereleasesuffix.py | 1 + config/pythonpath.py | 2 + config/rebuild_check.py | 2 + config/recurse.mk | 3 +- config/rules.mk | 119 +- config/run_spidermonkey_checks.py | 1 + config/system-headers.mozbuild | 13 +- config/system_header_util.py | 1 + config/tests/test_mozbuild_reading.py | 3 +- config/tests/unit-mozunit.py | 1 + config/tests/unit-nsinstall.py | 1 + config/tests/unit-printprereleasesuffix.py | 1 + config/tests/unitMozZipFile.py | 1 + configure.py | 44 +- .../aboutdebugging/src/actions/runtimes.js | 21 +- .../src/components/sidebar/Sidebar.js | 6 +- devtools/client/framework/test/browser.ini | 1 - .../browser_toolbox_window_reload_target.js | 37 +- .../client/inspector/rules/test/browser.ini | 3 + .../test/browser_rules_pseudo-visited.js | 44 + .../test/browser_rules_pseudo_lock_options.js | 3 + devtools/client/jar.mn | 9 +- .../client/locales/en-US/markers.properties | 2 +- devtools/client/responsive/browser/tunnel.js | 3 - .../images/aboutdebugging-fenix-nightly.svg | 13 - .../themes/images/aboutdebugging-fenix.svg | 12 - .../images/aboutdebugging-firefox-aurora.svg | 4 - .../images/aboutdebugging-firefox-beta.svg | 4 - .../images/aboutdebugging-firefox-logo.svg | 7 - .../images/aboutdebugging-firefox-nightly.svg | 4 - .../images/aboutdebugging-firefox-release.svg | 4 - .../server/actors/animation-type-longhand.js | 1 - devtools/server/actors/breakpoint.js | 3 +- .../server/actors/highlighters/flexbox.js | 5 +- devtools/server/actors/storage.js | 2 +- devtools/server/actors/styles.js | 22 +- devtools/shared/css/constants.js | 9 +- .../shared/css/generated/properties-db.js | 5 + docshell/base/BrowsingContext.h | 1 - docshell/base/moz.build | 6 +- docshell/base/nsDocShell.h | 5 +- docshell/moz.build | 2 +- docshell/test/moz.build | 12 +- editor/libeditor/CompositionTransaction.h | 7 +- editor/libeditor/EditorEventListener.cpp | 2 +- editor/libeditor/HTMLEditor.h | 32 +- editor/libeditor/HTMLTableEditor.cpp | 70 +- editor/libeditor/PlaceholderTransaction.h | 7 +- editor/libeditor/moz.build | 3 + editor/moz.build | 4 +- editor/nsITableEditor.idl | 3 + extensions/auth/nsHttpNegotiateAuth.cpp | 1 + .../permissions/PermissionDelegateHandler.cpp | 1 + .../permissions/nsPermissionManager.cpp | 9 +- extensions/permissions/nsPermissionManager.h | 25 +- .../permissions/test/PermissionTestUtils.jsm | 10 +- .../test/unit/test_permmanager_cleardata.js | 15 +- .../test/unit/test_permmanager_matches.js | 10 +- .../test/unit/test_permmanager_migrate_4-7.js | 1 + ...test_permmanager_migrate_4-7_no_history.js | 1 + .../unit/test_permmanager_migrate_5-7a.js | 2 +- .../unit/test_permmanager_migrate_5-7b.js | 2 +- .../unit/test_permmanager_migrate_6-7a.js | 1 + .../unit/test_permmanager_migrate_6-7b.js | 2 +- .../test/unit/test_permmanager_migrate_7-8.js | 3 +- .../unit/test_permmanager_migrate_9-10.js | 3 +- .../test/unit/test_permmanager_removeall.js | 4 +- .../pref/autoconfig/src/nsAutoConfig.cpp | 1 + .../hunspell/tests/unit/test_hunspell.js | 11 +- .../tests/unit/test_hunspell_unicode_paths.js | 2 - .../tests/mochitest/helper_bug1170484.js | 4 +- .../tests/mochitest/test_bug1170484.html | 1 + .../tests/mochitest/test_bug1272623.html | 5 +- .../tests/test_bug431054.html | 18 +- gfx/2d/2D.h | 82 +- gfx/2d/DrawEventRecorder.cpp | 4 - gfx/2d/Logging.h | 6 + gfx/2d/RecordedEventImpl.h | 6 + gfx/2d/SourceSurfaceCapture.cpp | 33 +- gfx/2d/SourceSurfaceCapture.h | 3 + gfx/2d/SourceSurfaceRawData.cpp | 23 +- gfx/2d/SourceSurfaceRawData.h | 55 +- gfx/2d/Swizzle.cpp | 549 +- gfx/2d/Swizzle.h | 19 + gfx/2d/SwizzleAVX2.cpp | 83 + gfx/2d/SwizzleNEON.cpp | 111 +- gfx/2d/SwizzleSSE2.cpp | 106 +- gfx/2d/SwizzleSSSE3.cpp | 65 + gfx/2d/Types.h | 53 +- gfx/2d/moz.build | 4 + gfx/gl/GLContext.h | 4 +- gfx/gl/SharedSurface.h | 6 +- gfx/ipc/GPUProcessManager.h | 1 + gfx/layers/Compositor.h | 6 - gfx/layers/ImageContainer.h | 4 +- gfx/layers/LayersLogging.cpp | 6 + gfx/layers/SourceSurfaceSharedData.cpp | 18 +- gfx/layers/SourceSurfaceSharedData.h | 9 +- gfx/layers/SourceSurfaceVolatileData.cpp | 17 +- gfx/layers/SourceSurfaceVolatileData.h | 9 +- gfx/layers/apz/src/APZCTreeManager.cpp | 94 +- gfx/layers/apz/src/APZCTreeManager.h | 30 - .../apz/src/AndroidDynamicToolbarAnimator.cpp | 1229 -- .../apz/src/AndroidDynamicToolbarAnimator.h | 309 - gfx/layers/apz/src/AndroidVelocityTracker.cpp | 23 +- gfx/layers/apz/src/AndroidVelocityTracker.h | 6 - gfx/layers/apz/src/AsyncPanZoomController.cpp | 106 +- gfx/layers/apz/src/AsyncPanZoomController.h | 33 +- gfx/layers/apz/src/Axis.cpp | 48 +- gfx/layers/apz/src/Axis.h | 24 +- gfx/layers/apz/src/SimpleVelocityTracker.cpp | 16 - gfx/layers/apz/src/SimpleVelocityTracker.h | 3 - gfx/layers/apz/test/gtest/InputUtils.h | 14 +- gfx/layers/apz/util/APZCCallbackHelper.cpp | 2 +- gfx/layers/basic/BasicCompositor.h | 2 - gfx/layers/client/CompositableClient.cpp | 3 +- gfx/layers/client/TextureClient.cpp | 75 +- .../client/TextureClientRecycleAllocator.cpp | 2 +- .../composite/AsyncCompositionManager.cpp | 34 +- .../composite/LayerManagerComposite.cpp | 100 - gfx/layers/d3d11/CompositorD3D11.h | 11 - gfx/layers/d3d9/CompositorD3D9.h | 11 - gfx/layers/d3d9/TextureD3D9.cpp | 15 +- gfx/layers/ipc/CompositorBridgeChild.cpp | 340 +- gfx/layers/ipc/CompositorBridgeChild.h | 4 +- gfx/layers/ipc/CompositorBridgeParent.cpp | 8 - gfx/layers/ipc/CompositorBridgeParent.h | 7 - gfx/layers/ipc/ImageBridgeChild.cpp | 71 +- gfx/layers/ipc/ImageBridgeChild.h | 15 +- gfx/layers/ipc/PUiCompositorController.ipdl | 3 - gfx/layers/ipc/ShadowLayers.cpp | 6 +- gfx/layers/ipc/ShadowLayers.h | 2 +- gfx/layers/ipc/TextureForwarder.h | 3 +- .../ipc/UiCompositorControllerChild.cpp | 26 +- gfx/layers/ipc/UiCompositorControllerChild.h | 3 - .../ipc/UiCompositorControllerMessageTypes.h | 22 +- .../ipc/UiCompositorControllerParent.cpp | 69 - gfx/layers/ipc/UiCompositorControllerParent.h | 14 - gfx/layers/ipc/VideoBridgeChild.cpp | 12 +- gfx/layers/ipc/VideoBridgeChild.h | 4 +- gfx/layers/moz.build | 4 - gfx/layers/opengl/CompositorOGL.cpp | 13 +- gfx/layers/opengl/CompositorOGL.h | 14 - gfx/layers/wr/WebRenderBridgeParent.h | 12 +- gfx/layers/wr/WebRenderCommandBuilder.cpp | 12 +- gfx/qcms/iccread.c | 27 +- gfx/qcms/qcms.h | 10 + gfx/src/FilterSupport.h | 1 + gfx/src/gfxCrashReporterUtils.cpp | 5 +- gfx/tests/crashtests/766422-1.html | 2 +- gfx/tests/crashtests/766422-2.html | 2 +- gfx/tests/crashtests/914457-1.html | 2 +- gfx/tests/gtest/TestSwizzle.cpp | 107 + gfx/thebes/gfxColor.h | 40 +- gfx/thebes/gfxDWriteFonts.cpp | 2 + gfx/thebes/gfxPlatform.cpp | 69 +- gfx/thebes/gfxPlatform.h | 16 +- gfx/thebes/gfxPlatformGtk.cpp | 223 +- gfx/thebes/gfxPlatformGtk.h | 2 +- gfx/thebes/gfxPlatformMac.cpp | 24 +- gfx/thebes/gfxPlatformMac.h | 2 +- gfx/thebes/gfxTextRun.cpp | 4 +- gfx/thebes/gfxUserFontSet.h | 49 +- gfx/thebes/gfxWindowsPlatform.cpp | 52 +- gfx/thebes/gfxWindowsPlatform.h | 2 +- gfx/thebes/mach_commands.py | 191 + gradle/wrapper/gradle-wrapper.properties | 4 +- image/AnimationFrameBuffer.cpp | 11 +- image/BMPHeaders.h | 15 + image/ClippedImage.cpp | 22 +- image/Decoder.cpp | 46 +- image/Decoder.h | 14 +- image/DownscalingFilter.h | 14 +- image/DynamicImage.cpp | 17 +- image/FrameAnimator.cpp | 108 +- image/FrameAnimator.h | 7 +- image/FrozenImage.cpp | 4 +- image/FrozenImage.h | 2 +- image/IDecodingTask.cpp | 6 +- image/IProgressObserver.h | 4 +- image/Image.cpp | 45 +- image/Image.h | 60 +- image/ImageCacheKey.cpp | 14 +- image/ImageOps.cpp | 8 + image/ImageOps.h | 9 + image/ImageWrapper.cpp | 7 +- image/LookupResult.h | 30 +- image/Orientation.h | 27 +- image/OrientedImage.cpp | 127 +- image/OrientedImage.h | 28 +- image/ProgressTracker.h | 3 +- image/RasterImage.cpp | 652 +- image/RasterImage.h | 164 +- image/RecyclingSourceSurface.h | 15 +- image/SourceBuffer.h | 7 +- image/StreamingLexer.h | 5 +- image/SurfaceCache.cpp | 169 +- image/SurfaceCache.h | 16 +- image/SurfaceFilters.h | 108 +- image/SurfaceFlags.h | 9 +- image/SurfacePipe.cpp | 5 + image/SurfacePipe.h | 62 +- image/SurfacePipeFactory.h | 543 +- image/VectorImage.cpp | 44 +- image/decoders/icon/android/nsIconChannel.cpp | 24 +- image/decoders/icon/gtk/nsIconChannel.cpp | 40 +- image/decoders/icon/mac/nsIconChannel.h | 4 +- image/decoders/icon/mac/nsIconChannelCocoa.mm | 11 +- image/decoders/icon/win/nsIconChannel.h | 4 +- image/decoders/nsBMPDecoder.cpp | 410 +- image/decoders/nsBMPDecoder.h | 63 +- image/decoders/nsGIFDecoder2.cpp | 63 +- image/decoders/nsGIFDecoder2.h | 2 + image/decoders/nsICODecoder.cpp | 25 +- image/decoders/nsICODecoder.h | 2 + image/decoders/nsIconDecoder.cpp | 35 +- image/decoders/nsJPEGDecoder.cpp | 68 +- image/decoders/nsJPEGDecoder.h | 2 - image/decoders/nsPNGDecoder.cpp | 267 +- image/decoders/nsPNGDecoder.h | 8 +- image/decoders/nsWebPDecoder.cpp | 98 +- image/imgFrame.cpp | 67 +- image/imgFrame.h | 26 +- image/imgIContainer.idl | 35 +- image/imgIRequest.idl | 17 +- image/imgLoader.cpp | 70 +- image/imgRequestProxy.cpp | 7 +- image/imgTools.cpp | 8 +- image/test/crashtests/1629490-1-iframe.html | 1 + image/test/crashtests/1629490-1.html | 49 + image/test/crashtests/1634839-1-iframe.html | 1 + image/test/crashtests/1634839-1.html | 51 + image/test/crashtests/1634839-2-iframe.html | 1 + image/test/crashtests/1634839-2.html | 51 + image/test/crashtests/1676172-1-iframe.html | 13 + image/test/crashtests/1676172-1.gif | Bin 0 -> 2439 bytes image/test/crashtests/1676172-1.html | 45 + image/test/crashtests/crashtests.list | 5 + image/test/crashtests/delaytest.html | 30 +- image/test/crashtests/finite-apng.png | Bin 0 -> 5834 bytes image/test/crashtests/out2.gif | Bin 0 -> 24129 bytes image/test/crashtests/rainbow.gif | Bin 0 -> 6171 bytes image/test/fuzzing/TestDecoders.cpp | 81 +- image/test/gtest/Common.cpp | 271 +- image/test/gtest/Common.h | 140 +- .../gtest/TestADAM7InterpolatingFilter.cpp | 22 +- image/test/gtest/TestAnimationFrameBuffer.cpp | 2 +- image/test/gtest/TestBlendAnimationFilter.cpp | 72 +- image/test/gtest/TestDecodeToSurface.cpp | 7 +- image/test/gtest/TestDecoders.cpp | 317 +- image/test/gtest/TestDecodersPerf.cpp | 159 + image/test/gtest/TestDeinterlacingFilter.cpp | 39 +- image/test/gtest/TestDownscalingFilter.cpp | 30 +- .../gtest/TestDownscalingFilterNoSkia.cpp | 6 +- image/test/gtest/TestFrameAnimator.cpp | 10 +- image/test/gtest/TestMetadata.cpp | 6 +- .../test/gtest/TestRemoveFrameRectFilter.cpp | 42 +- .../test/gtest/TestSurfacePipeIntegration.cpp | 54 +- image/test/gtest/TestSurfaceSink.cpp | 540 +- image/test/gtest/TestSwizzleFilter.cpp | 118 + image/test/gtest/downscaled.icon | Bin 40003 -> 40005 bytes image/test/gtest/green.icon | Bin 40002 -> 40004 bytes image/test/gtest/moz.build | 14 + .../test/gtest/perf_cmyk.jpg | Bin 16384 -> 18960 bytes image/test/gtest/perf_gray.jpg | Bin 0 -> 4479 bytes image/test/gtest/perf_gray.png | Bin 0 -> 4472 bytes image/test/gtest/perf_gray_alpha.png | Bin 0 -> 6847 bytes image/test/gtest/perf_srgb.gif | Bin 0 -> 1743 bytes image/test/gtest/perf_srgb.png | Bin 0 -> 2993 bytes image/test/gtest/perf_srgb_alpha.png | Bin 0 -> 3203 bytes .../test/gtest/perf_srgb_alpha_lossless.webp | Bin 0 -> 3134 bytes image/test/gtest/perf_srgb_alpha_lossy.webp | Bin 0 -> 5014 bytes image/test/gtest/perf_srgb_lossless.webp | Bin 0 -> 3134 bytes image/test/gtest/perf_srgb_lossy.webp | Bin 0 -> 4948 bytes .../test/gtest/perf_ycbcr.jpg | Bin 16384 -> 15049 bytes image/test/mochitest/finite-apng.png | Bin 0 -> 5834 bytes image/test/mochitest/mochitest.ini | 3 +- .../mochitest/test_ImageContentLoaded.html | 28 - .../test_discardFinishedAnimatedImage.html | 144 + .../test/mochitest/test_svg_animatedGIF.html | 2 +- .../test/reftest/bmp/bmpsuite/g/reftest.list | 3 +- .../test/reftest/bmp/bmpsuite/q/reftest.list | 9 +- .../reftest/bmp/bmpsuite/q/rgb24prof2.png | Bin 19650 -> 0 bytes .../downscaling/downscale-orient-ref.html | 24 + .../downscaling/downscale-orient-ref.png | Bin 0 -> 146 bytes .../reftest/downscaling/downscale-orient.html | 24 + .../downscaling/image-pre-rotated-90-deg.jpg | Bin 0 -> 6914 bytes image/test/reftest/downscaling/reftest.list | 12 +- .../reftest/pngsuite-background/reftest.list | 16 +- image/test/unit/image1png16x16.jpg | Bin 1051 -> 1050 bytes image/test/unit/image1png64x64.jpg | Bin 4503 -> 4507 bytes image/test/unit/test_imgtools.js | 4 +- .../bug-1636984-alias-append-items-sink.diff | 33 + ...end-item-dayperiod-fractional-seconds.diff | 86 + ...36984-display-name-fractional-seconds.diff | 39 + intl/icu/source/data/locales/root.txt | 11 + intl/icu/source/i18n/dtptngen.cpp | 15 +- intl/l10n/L10nRegistry.jsm | 21 +- intl/l10n/Localization.cpp | 3 + intl/locale/android/OSPreferences_android.cpp | 5 +- intl/strres/nsStringBundle.cpp | 14 + intl/update-icu.sh | 3 + ipc/chromium/src/base/logging.cc | 4 +- ipc/chromium/src/chrome/common/ipc_message.cc | 3 +- ipc/glue/BackgroundImpl.cpp | 5 +- ipc/glue/GeckoChildProcessHost.cpp | 131 +- ipc/glue/GeckoChildProcessHost.h | 3 + ipc/glue/IPCMessageUtils.h | 61 + ipc/glue/IPCStreamSource.cpp | 23 +- ipc/glue/MessageChannel.cpp | 12 +- ipc/glue/TaskFactory.h | 2 +- ipc/ipdl/ipdl/lower.py | 12 +- ipc/mscom/ActivationContext.h | 5 +- ipc/mscom/AgileReference.cpp | 3 +- ipc/mscom/AsyncInvoker.h | 11 +- ipc/mscom/COMPtrHolder.h | 3 +- ipc/mscom/DispatchForwarder.cpp | 6 +- ipc/mscom/Interceptor.cpp | 14 +- ipc/mscom/Interceptor.h | 13 +- ipc/mscom/InterceptorLog.cpp | 11 +- ipc/mscom/MainThreadHandoff.cpp | 11 +- ipc/mscom/MainThreadHandoff.h | 5 +- ipc/mscom/MainThreadInvoker.h | 7 +- ipc/mscom/Registration.cpp | 7 +- ipc/mscom/oop/Factory.h | 15 +- ipc/testshell/XPCShellEnvironment.cpp | 7 +- media/mtransport/nricectx.cpp | 5 +- .../src/media-conduit/VideoConduit.h | 1 + .../WebrtcMediaCodecVP8VideoCodec.cpp | 94 +- .../WebrtcMediaDataEncoderCodec.cpp | 16 +- .../peerconnection/MediaTransportHandler.cpp | 1 + mfbt/ArrayUtils.h | 2 +- mfbt/AtomicBitfields.h | 461 + mfbt/Atomics.h | 5 +- mfbt/BitSet.h | 113 + mfbt/BloomFilter.h | 148 +- mfbt/BufferList.h | 3 +- mfbt/FloatingPoint.h | 56 +- mfbt/HashTable.h | 7 + mfbt/LinuxSignal.h | 38 - mfbt/MacroArgs.h | 6 + mfbt/NullPtr.h | 29 - mfbt/Result.h | 242 +- mfbt/ResultVariant.h | 50 + mfbt/Tainting.h | 272 +- mfbt/TsanOptions.h | 85 + mfbt/Vector.h | 71 +- mfbt/WeakPtr.h | 193 +- mfbt/double-conversion/GIT-INFO | 27 +- .../ToPrecision-exponential.patch | 62 - .../add-mfbt-api-markers.patch | 84 +- .../debug-only-functions.patch | 39 + .../double-conversion/README.md | 5 +- .../double-conversion/bignum-dtoa.cc | 50 +- .../double-conversion/bignum-dtoa.h | 2 +- .../double-conversion/bignum.cc | 587 +- .../double-conversion/bignum.h | 66 +- .../double-conversion/cached-powers.cc | 208 +- .../double-conversion/cached-powers.h | 28 +- .../double-conversion/diy-fp.cc | 57 - .../double-conversion/diy-fp.h | 61 +- .../double-conversion/double-conversion.h | 523 +- .../double-conversion/double-to-string.cc | 436 + .../double-conversion/double-to-string.h | 446 + .../double-conversion/fast-dtoa.cc | 62 +- .../double-conversion/fast-dtoa.h | 2 +- .../double-conversion/fixed-dtoa.cc | 24 +- .../double-conversion/fixed-dtoa.h | 2 +- .../double-conversion/ieee.h | 60 +- ...uble-conversion.cc => string-to-double.cc} | 649 +- .../double-conversion/string-to-double.h | 226 + .../double-conversion/strtod.cc | 122 +- .../double-conversion/strtod.h | 7 +- .../double-conversion/utils.h | 141 +- mfbt/double-conversion/to-fixed-dbl-max.patch | 53 + .../to-fixed-digits-after-point.patch | 22 + mfbt/double-conversion/update.sh | 6 +- .../use-mozilla-assertions.patch | 29 +- mfbt/moz.build | 17 +- mfbt/tests/TestAtomicBitfields.cpp | 187 + mfbt/tests/TestBitSet.cpp | 66 + mfbt/tests/TestBloomFilter.cpp | 42 +- mfbt/tests/TestCheckedInt.cpp | 43 +- mfbt/tests/TestFloatingPoint.cpp | 229 +- mfbt/tests/TestMacroArgs.cpp | 10 +- mfbt/tests/TestResult.cpp | 144 +- mfbt/tests/TestTainting.cpp | 277 + mfbt/tests/TestVector.cpp | 24 + mfbt/tests/TestWeakPtr.cpp | 40 +- mfbt/tests/gtest/TestAlgorithm.cpp | 2 +- mfbt/tests/gtest/TestMainThreadWeakPtr.cpp | 40 + mfbt/tests/gtest/moz.build | 2 + mfbt/tests/moz.build | 165 +- modules/libmar/moz.build | 17 +- modules/libmar/sign/mar_sign.c | 80 +- modules/libmar/sign/nss_secutil.c | 182 +- modules/libmar/sign/nss_secutil.h | 17 +- modules/libmar/src/mar_cmdline.h | 24 +- modules/libmar/src/mar_create.c | 36 +- modules/libmar/src/mar_extract.c | 18 +- modules/libmar/src/mar_private.h | 22 +- modules/libmar/src/mar_read.c | 2 +- modules/libmar/src/moz.build | 19 +- modules/libmar/tests/moz.build | 4 +- modules/libmar/tests/unit/data/cert8.db | Bin 65536 -> 0 bytes modules/libmar/tests/unit/data/cert9.db | Bin 0 -> 36864 bytes modules/libmar/tests/unit/data/key3.db | Bin 24576 -> 0 bytes modules/libmar/tests/unit/data/key4.db | Bin 0 -> 61440 bytes modules/libmar/tool/mar.c | 105 +- modules/libmar/tool/moz.build | 55 +- modules/libmar/verify/cryptox.c | 44 +- modules/libmar/verify/cryptox.h | 198 +- modules/libmar/verify/mar_verify.c | 54 +- modules/libpref/Preferences.cpp | 3 + modules/libpref/Preferences.h | 1 + modules/libpref/docs/index.md | 2 +- modules/libpref/init/StaticPrefList.yaml | 235 +- modules/libpref/init/all.js | 70 +- .../libpref/init/generate_static_pref_list.py | 357 +- modules/libpref/moz.build | 2 + .../test/test_generate_static_pref_list.py | 265 +- moz.build | 10 - moz.configure | 122 +- .../core/platform-linux-android.cpp | 3 +- mozglue/build/AsanOptions.cpp | 108 +- mozglue/build/TsanOptions.cpp | 311 + mozglue/build/UbsanOptions.cpp | 6 +- mozglue/build/moz.build | 5 + mozglue/misc/Printf.cpp | 321 +- mozglue/misc/Printf.h | 6 +- mozglue/misc/interceptor/Arm64.cpp | 2 + mozglue/tests/TestPrintf.cpp | 107 +- mozglue/tests/glibc_printf_tests/COPYING | 7 + mozglue/tests/glibc_printf_tests/COPYING.LIB | 502 + .../tests/glibc_printf_tests/README.MOZILLA | 2 + mozglue/tests/glibc_printf_tests/tfformat.c | 4164 ++++ mozglue/tests/glibc_printf_tests/tiformat.c | 5070 +++++ mozglue/tests/glibc_printf_tests/tllformat.c | 59 + netwerk/base/ArrayBufferInputStream.cpp | 13 +- netwerk/base/CaptivePortalService.cpp | 2 +- netwerk/base/NetworkInfoServiceLinux.cpp | 3 +- netwerk/base/nsIArrayBufferInputStream.idl | 2 +- netwerk/base/nsIOService.h | 1 + netwerk/base/nsIPermissionManager.idl | 5 + netwerk/base/nsIncrementalDownload.cpp | 2 +- netwerk/base/nsNetUtil.cpp | 4 + netwerk/base/nsNetUtil.h | 5 + netwerk/build/components.conf | 30 +- netwerk/build/nsNetModule.cpp | 2 - netwerk/cache/nsApplicationCacheService.cpp | 46 +- netwerk/cache/nsCacheService.cpp | 2 - netwerk/cache2/CacheObserver.cpp | 64 - netwerk/cache2/CacheObserver.h | 1 + netwerk/cache2/CacheStorageService.cpp | 118 +- netwerk/cache2/CacheStorageService.h | 7 + netwerk/cache2/nsICacheStorageService.idl | 8 + netwerk/cookie/CookieServiceChild.cpp | 9 +- netwerk/cookie/moz.build | 73 +- netwerk/cookie/nsCookie.cpp | 28 +- netwerk/cookie/nsCookie.h | 7 +- netwerk/cookie/nsCookieService.cpp | 205 +- netwerk/cookie/nsCookieService.h | 4 +- netwerk/cookie/nsICookie.idl | 4 +- netwerk/cookie/test/unit/test_bug1321912.js | 2 +- netwerk/cookie/test/unit/test_rawSameSite.js | 126 + netwerk/cookie/test/unit/xpcshell.ini | 1 + netwerk/ipc/ChannelEventQueue.cpp | 4 +- netwerk/ipc/NeckoChannelParams.ipdlh | 1 + netwerk/ipc/NeckoChild.cpp | 1 - netwerk/ipc/NeckoCommon.cpp | 15 - netwerk/ipc/NeckoCommon.h | 24 - netwerk/ipc/NeckoParent.cpp | 91 +- netwerk/ipc/moz.build | 1 - netwerk/moz.build | 3 - netwerk/necko-config.h.in | 12 - netwerk/protocol/ftp/FTPChannelChild.cpp | 3 - netwerk/protocol/http/AlternateServices.cpp | 8 +- netwerk/protocol/http/Http2Stream.h | 3 +- netwerk/protocol/http/HttpBaseChannel.cpp | 19 +- netwerk/protocol/http/HttpBaseChannel.h | 11 +- netwerk/protocol/http/HttpChannelChild.cpp | 28 +- netwerk/protocol/http/HttpChannelChild.h | 6 +- netwerk/protocol/http/HttpChannelParent.cpp | 11 +- netwerk/protocol/http/HttpChannelParent.h | 4 + netwerk/protocol/http/PHttpChannel.ipdl | 2 + netwerk/protocol/http/nsHttpChannel.cpp | 12 +- .../protocol/websocket/WebSocketChannel.cpp | 4 +- .../websocket/WebSocketChannelChild.cpp | 3 - netwerk/sctp/datachannel/DataChannel.h | 5 +- netwerk/test/TestCookie.cpp | 14 +- .../file_testloadflags_chromescript.js | 2 +- netwerk/test/mochitests/mochitest.ini | 5 + .../test_arraybufferinputstream_large.html | 45 + netwerk/test/unit/test_bug411952.js | 2 +- netwerk/test/unit/test_bug526789.js | 14 +- netwerk/test/unit/test_bug650522.js | 2 +- netwerk/test/unit/test_bug667087.js | 2 +- .../test/unit/test_cookies_async_failure.js | 2 +- .../test/unit/test_cookies_profile_close.js | 2 +- .../test/unit/test_cookies_sync_failure.js | 2 +- netwerk/test/unit/test_domain_eviction.js | 6 +- netwerk/test/unit/test_eviction.js | 2 +- netwerk/test/unit/test_redirect_history.js | 2 +- .../unit_ipc/test_cookie_header_stripped.js | 2 +- nsprpub/TAG-INFO | 2 +- nsprpub/configure | 2 +- nsprpub/configure.in | 2 +- nsprpub/lib/ds/plds.rc | 2 +- nsprpub/lib/libc/src/plc.rc | 2 +- nsprpub/lib/prstreams/prstrms.rc | 2 +- nsprpub/pr/include/md/_linux.cfg | 51 + nsprpub/pr/include/md/_linux.h | 8 + nsprpub/pr/include/prinit.h | 4 +- nsprpub/pr/include/prlog.h | 4 + nsprpub/pr/src/md/windows/ntio.c | 10 +- nsprpub/pr/src/nspr.rc | 2 +- nsprpub/pr/tests/Makefile.in | 15 +- nsprpub/pr/tests/acceptread.c | 13 +- nsprpub/pr/tests/acceptreademu.c | 13 +- nsprpub/pr/tests/append.c | 4 +- nsprpub/pr/tests/cltsrv.c | 34 +- nsprpub/pr/tests/fdcach.c | 106 +- nsprpub/pr/tests/foreign.c | 3 +- nsprpub/pr/tests/forktest.c | 3 +- nsprpub/pr/tests/fsync.c | 2 +- nsprpub/pr/tests/gethost.c | 2 +- nsprpub/pr/tests/layer.c | 14 +- nsprpub/pr/tests/lazyinit.c | 4 +- nsprpub/pr/tests/multiwait.c | 16 +- nsprpub/pr/tests/nameshm1.c | 17 +- nsprpub/pr/tests/nblayer.c | 14 +- nsprpub/pr/tests/ntioto.c | 14 +- nsprpub/pr/tests/op_filnf.c | 2 +- nsprpub/pr/tests/provider.c | 13 +- nsprpub/pr/tests/runtests.pl | 1 - nsprpub/pr/tests/runtests.sh | 81 +- nsprpub/pr/tests/sel_spd.c | 43 +- nsprpub/pr/tests/sema.c | 15 +- nsprpub/pr/tests/semaerr.c | 15 +- nsprpub/pr/tests/semaerr1.c | 15 +- nsprpub/pr/tests/semaping.c | 17 +- nsprpub/pr/tests/semapong.c | 17 +- nsprpub/pr/tests/socket.c | 6 +- nsprpub/pr/tests/testfile.c | 2 +- nsprpub/pr/tests/thruput.c | 15 +- nsprpub/pr/tests/tmoacc.c | 13 +- nsprpub/pr/tests/tmocon.c | 13 +- nsprpub/pr/tests/vercheck.c | 5 +- nsprpub/pr/tests/writev.c | 13 +- nsprpub/pr/tests/zerolen.c | 8 +- old-configure.in | 487 +- other-licenses/bsdiff/moz.build | 1 + parser/html/javasrc/AttributeName.java | 1415 +- parser/html/nsHtml5AttributeName.cpp | 841 +- parser/html/nsHtml5AttributeName.h | 1 + parser/moz.build | 2 +- parser/xml/moz.build | 2 +- python/moz.build | 3 + python/mozboot/mozboot/android-packages.txt | 2 +- python/mozboot/mozboot/base.py | 2 +- python/mozbuild/mozbuild/action/fat_aar.py | 99 +- .../mozbuild/action/generate_strings_xml.py | 38 - .../action/generate_suggestedsites.py | 159 - .../mozbuild/action/package_fennec_apk.py | 139 - python/mozbuild/mozbuild/artifact_commands.py | 431 + python/mozbuild/mozbuild/artifacts.py | 1 - python/mozbuild/mozbuild/backend/common.py | 18 +- .../mozbuild/backend/configenvironment.py | 19 +- .../mozbuild/backend/recursivemake.py | 91 +- python/mozbuild/mozbuild/backend/tup.py | 8 +- python/mozbuild/mozbuild/base.py | 24 +- python/mozbuild/mozbuild/build_commands.py | 231 + .../mozbuild/code-analysis/mach_commands.py | 2044 ++ .../mozbuild/mozbuild/compilation/warnings.py | 20 +- python/mozbuild/mozbuild/config_status.py | 8 +- .../mozbuild/mozbuild/configure/__init__.py | 14 +- .../mozbuild/mozbuild/configure/constants.py | 1 - python/mozbuild/mozbuild/configure/lint.py | 4 +- .../mozbuild/mozbuild/controller/building.py | 31 +- .../mozbuild/mozbuild/controller/clobber.py | 86 +- python/mozbuild/mozbuild/dotproperties.py | 2 +- python/mozbuild/mozbuild/frontend/context.py | 206 +- python/mozbuild/mozbuild/frontend/data.py | 44 +- python/mozbuild/mozbuild/frontend/emitter.py | 102 +- python/mozbuild/mozbuild/frontend/reader.py | 9 +- python/mozbuild/mozbuild/mach_commands.py | 2650 +-- python/mozbuild/mozbuild/mozconfig.py | 6 + python/mozbuild/mozbuild/mozinfo.py | 2 +- python/mozbuild/mozbuild/repackaging/mar.py | 8 +- .../data/package_fennec_apk/assets/asset.txt | 1 - .../action/data/package_fennec_apk/input1.ap_ | Bin 503 -> 0 bytes .../package_fennec_apk/input1/res/res.txt | 1 - .../package_fennec_apk/input1/resources.arsc | 1 - .../action/data/package_fennec_apk/input2.apk | Bin 1649 -> 0 bytes .../input2/assets/asset.txt | 1 - .../package_fennec_apk/input2/assets/omni.ja | 1 - .../package_fennec_apk/input2/classes.dex | 1 - .../package_fennec_apk/input2/lib/lib.txt | 1 - .../package_fennec_apk/input2/res/res.txt | 1 - .../package_fennec_apk/input2/resources.arsc | 1 - .../package_fennec_apk/input2/root_file.txt | 1 - .../data/package_fennec_apk/lib/lib.txt | 1 - .../action/data/package_fennec_apk/omni.ja | 1 - .../data/package_fennec_apk/root_file.txt | 1 - .../test/action/test_package_fennec_apk.py | 68 - .../mozbuild/mozbuild/test/backend/common.py | 21 - .../test/backend/data/sources/moz.build | 3 + .../test/backend/test_configenvironment.py | 4 +- .../backend/test_partialconfigenvironment.py | 4 - .../test/backend/test_recursivemake.py | 10 +- .../configure/test_toolchain_configure.py | 4 - .../data/wasm-compile-flags/moz.build | 20 + .../frontend/data/wasm-compile-flags/test1.c | 0 .../test/frontend/data/wasm-sources/a.cpp | 0 .../test/frontend/data/wasm-sources/b.cc | 0 .../test/frontend/data/wasm-sources/c.cxx | 0 .../test/frontend/data/wasm-sources/d.c | 0 .../test/frontend/data/wasm-sources/moz.build | 15 + .../mozbuild/test/frontend/test_emitter.py | 49 + python/mozbuild/mozbuild/test/python.ini | 1 - python/mozbuild/mozbuild/test/test_base.py | 35 +- python/mozbuild/mozbuild/util.py | 1 - python/mozbuild/mozpack/executables.py | 9 +- python/mozrelease/mozrelease/versions.py | 2 +- .../mozversioncontrol/__init__.py | 22 + python/mozversioncontrol/test/python.ini | 1 + python/mozversioncontrol/test/test_commit.py | 64 + .../certverifier/NSSCertDBTrustDomain.cpp | 17 +- security/manager/ssl/moz.build | 3 - security/manager/ssl/nsCertOverrideService.h | 3 +- security/manager/ssl/nsClientAuthRemember.h | 7 +- security/manager/ssl/nsNSSIOLayer.cpp | 38 +- .../ssl/tests/unit/test_broken_fips.js | 21 +- .../ssl/tests/unit/test_broken_fips/key3.db | Bin 16384 -> 0 bytes .../ssl/tests/unit/test_broken_fips/key4.db | Bin 0 -> 36864 bytes .../tests/unit/test_broken_fips/pkcs11.txt | 4 + .../unit/test_cert_isBuiltInRoot_reload.js | 9 +- .../test_cert_isBuiltInRoot_reload/cert8.db | Bin 65536 -> 0 bytes .../test_cert_isBuiltInRoot_reload/key3.db | Bin 16384 -> 0 bytes .../ssl/tests/unit/test_sdr_preexisting.js | 164 +- .../tests/unit/test_sdr_preexisting/key3.db | Bin 16384 -> 0 bytes .../tests/unit/test_sdr_preexisting/key4.db | Bin 36864 -> 36864 bytes .../test_sdr_preexisting_with_password.js | 4 +- .../key3.db | Bin 16384 -> 0 bytes .../key4.db | Bin 0 -> 36864 bytes .../unit/test_sdr_upgraded_with_password.js | 148 - .../test_sdr_upgraded_with_password/cert8.db | Bin 65536 -> 0 bytes .../test_sdr_upgraded_with_password/cert9.db | Bin 229376 -> 0 bytes .../test_sdr_upgraded_with_password/key3.db | Bin 16384 -> 0 bytes .../test_sdr_upgraded_with_password/key4.db | Bin 294912 -> 0 bytes .../tests/unit/test_sss_sanitizeOnShutdown.js | 9 + .../tests/unit/tlsserver/lib/TLSServer.cpp | 3 +- security/manager/ssl/tests/unit/xpcshell.ini | 4 +- security/moz.build | 7 +- security/nss/lib/ckfw/builtins/nssckbi.rc | 2 +- .../ckfw/builtins/testlib/nssckbi-testlib.rc | 2 +- security/nss/lib/ckfw/capi/nsscapi.rc | 2 +- security/nss/lib/freebl/freebl.rc | 2 +- security/nss/lib/nss/nss.rc | 2 +- security/nss/lib/smime/smime.rc | 2 +- security/nss/lib/softoken/legacydb/nssdbm.rc | 2 +- security/nss/lib/softoken/softokn.rc | 2 +- security/nss/lib/ssl/ssl.rc | 2 +- security/nss/lib/util/nssutil.rc | 2 +- security/sandbox/common/SandboxSettings.cpp | 6 +- .../sandbox/linux/SandboxBrokerClient.cpp | 1 - security/sandbox/linux/SandboxFilter.cpp | 30 +- security/sandbox/linux/SandboxOpenedFiles.cpp | 7 +- .../sandbox/linux/broker/SandboxBroker.cpp | 8 +- security/sandbox/linux/gtest/TestBroker.cpp | 1 - .../sandbox/linux/launch/SandboxLaunch.cpp | 6 +- .../win/src/sandboxtarget/sandboxTarget.h | 8 +- settings.gradle | 4 - storage/SQLiteMutex.h | 69 +- storage/moz.build | 6 - storage/mozStorageConnection.cpp | 4 - storage/mozStorageService.cpp | 27 - taskcluster/ci/artifact-build/kind.yml | 6 +- taskcluster/ci/beetmover-geckoview/kind.yml | 2 +- taskcluster/ci/build-fat-aar/kind.yml | 125 + taskcluster/ci/build/android-stuff.yml | 9 +- taskcluster/ci/build/android.yml | 741 +- taskcluster/ci/build/kind.yml | 30 +- taskcluster/ci/build/linux.yml | 693 +- taskcluster/ci/build/macosx.yml | 293 +- taskcluster/ci/build/windows-mingw.yml | 92 +- taskcluster/ci/build/windows.yml | 461 +- taskcluster/ci/config.yml | 1 + taskcluster/ci/generate-profile/kind.yml | 84 +- taskcluster/ci/instrumented-build/kind.yml | 158 +- taskcluster/ci/l10n/kind.yml | 72 +- taskcluster/ci/nightly-l10n/kind.yml | 20 +- .../kind.yml | 1 - .../release-partner-repack-repackage/kind.yml | 1 - taskcluster/ci/release-source/kind.yml | 1 - taskcluster/ci/repackage-l10n/kind.yml | 8 +- taskcluster/ci/repackage-msi/kind.yml | 4 +- taskcluster/ci/repackage/kind.yml | 8 +- taskcluster/ci/searchfox/kind.yml | 75 +- taskcluster/ci/source-test/clang.yml | 15 +- taskcluster/ci/source-test/coverity.yml | 13 +- taskcluster/ci/source-test/infer.yml | 19 +- taskcluster/ci/source-test/kind.yml | 1 - taskcluster/ci/spidermonkey/linux.yml | 10 + .../ci/static-analysis-autotest/kind.yml | 37 +- taskcluster/ci/test/talos.yml | 34 - taskcluster/ci/test/test-sets.yml | 2 - taskcluster/ci/toolchain/mingw.yml | 8 - taskcluster/ci/toolchain/misc.yml | 26 + taskcluster/ci/toolchain/sccache.yml | 26 +- taskcluster/ci/valgrind/kind.yml | 18 +- taskcluster/docker/debian-build/Dockerfile | 1 + .../scripts/funsize.py | 13 +- taskcluster/docker/mingw32-build/Dockerfile | 2 +- taskcluster/docker/toolchain-build/Dockerfile | 1 + taskcluster/docs/attributes.rst | 10 + taskcluster/docs/kinds.rst | 16 + taskcluster/docs/parameters.rst | 2 +- taskcluster/mach_commands.py | 5 +- taskcluster/scripts/builder/build-l10n.sh | 2 - taskcluster/scripts/builder/build-linux.sh | 2 - taskcluster/scripts/builder/repackage.sh | 1 - taskcluster/scripts/misc/build-mar-tools.sh | 31 + taskcluster/scripts/misc/build-sccache.sh | 72 +- taskcluster/scripts/misc/build-upx.sh | 3 +- taskcluster/scripts/misc/run-profileserver.sh | 9 +- .../scripts/misc/source-test-clang-setup.sh | 13 +- .../scripts/misc/source-test-common.sh | 20 +- .../scripts/misc/source-test-infer-setup.sh | 10 +- .../scripts/misc/wrench-android-build.sh | 2 +- taskcluster/taskgraph/decision.py | 3 +- .../taskgraph/manifests/fennec_geckoview.yml | 138 +- taskcluster/taskgraph/parameters.py | 206 +- taskcluster/taskgraph/test/test_create.py | 2 +- taskcluster/taskgraph/test/test_decision.py | 19 +- taskcluster/taskgraph/test/test_parameters.py | 61 +- .../transforms/beetmover_geckoview.py | 97 +- taskcluster/taskgraph/transforms/build.py | 34 +- .../taskgraph/transforms/build_fat_aar.py | 69 + .../taskgraph/transforms/build_signing.py | 6 +- .../taskgraph/transforms/job/__init__.py | 2 +- taskcluster/taskgraph/transforms/l10n.py | 12 +- .../transforms/nightly_l10n_signing.py | 6 +- taskcluster/taskgraph/transforms/partials.py | 14 +- .../taskgraph/transforms/partner_signing.py | 6 +- taskcluster/taskgraph/transforms/repackage.py | 64 +- .../taskgraph/transforms/repackage_partner.py | 19 +- .../taskgraph/transforms/run_pgo_profile.py | 7 +- taskcluster/taskgraph/transforms/signing.py | 6 +- .../taskgraph/transforms/use_toolchains.py | 124 - taskcluster/taskgraph/util/attributes.py | 7 +- .../taskgraph/util/declarative_artifacts.py | 53 + .../taskgraph/util/parameterization.py | 4 +- taskcluster/taskgraph/util/scriptworker.py | 77 +- .../taskgraph/util/signed_artifacts.py | 34 +- third_party/sqlite3/src/moz.build | 2 - third_party/sqlite3/src/sqlite.symbols | 1 - third_party/sqlite3/src/sqlite3.c | 17676 ++++++++++------ third_party/sqlite3/src/sqlite3.h | 4364 ++-- toolkit/actors/WebNavigationChild.jsm | 16 +- .../antitracking/AntiTrackingCommon.cpp | 7 + .../browser/browser_referrerDefaultPolicy.js | 34 +- .../browser/browser_urlDecorationStripping.js | 60 +- .../antitracking/test/browser/referrer.sjs | 15 +- .../BackgroundHangMonitor.cpp | 23 +- .../backgroundhangmonitor/HangDetails.h | 11 +- .../ThreadStackHelper.cpp | 15 +- .../components/cleardata/ClearDataService.jsm | 233 +- .../cleardata/ServiceWorkerCleanUp.jsm | 7 + .../cleardata/SiteDataTestUtils.jsm | 2 +- .../cleardata/nsIClearDataService.idl | 5 +- .../cleardata/tests/browser/browser.ini | 1 + .../cleardata/tests/browser/browser_quota.js | 238 + .../cleardata/tests/unit/test_cookies.js | 6 +- .../tests/unit/test_corruptedFile.js | 2 +- .../components/downloads/DownloadPlatform.cpp | 10 +- .../extensions/ExtensionContent.jsm | 21 +- .../extensions/WebExtensionPolicy.h | 3 +- .../extensions/parent/ext-cookies.js | 2 +- .../extensions/test/mochitest/head_cookies.js | 10 +- .../test/mochitest/mochitest-common.ini | 3 +- .../mochitest/test_ext_cookies_expiry.html | 4 +- .../mochitest/test_ext_cookies_incognito.html | 4 +- ...t_ext_adoption_with_private_field_xrays.js | 12 +- .../extensions/webrequest/ChannelWrapper.h | 3 +- .../webrequest/StreamFilterEvents.h | 3 +- .../osfile/NativeOSFileInternals.cpp | 9 +- .../nsParentalControlsServiceAndroid.cpp | 21 +- .../passwordmgr/test/unit/data/key3.db | Bin 16384 -> 0 bytes .../components/passwordmgr/test/unit/head.js | 3 +- toolkit/components/places/History.cpp | 2 +- toolkit/components/places/History.h | 7 - .../places/INativePlacesEventCallback.h | 4 +- .../favicons/expected-favicon-big48.ico.png | Bin 2358 -> 2352 bytes .../printing/content/printPageSetup.xul | 24 +- .../components/printingui/nsPrintProgress.cpp | 1 + .../processsingleton/MainProcessSingleton.jsm | 12 +- toolkit/components/reader/ReaderMode.jsm | 4 +- .../RemoteWebNavigation.jsm | 27 +- .../components/remotebrowserutils/moz.build | 2 +- toolkit/components/statusfilter/moz.build | 2 +- toolkit/components/telemetry/moz.build | 1 - .../nsUrlClassifierStreamUpdater.cpp | 1 + toolkit/content/browser-child.js | 17 - toolkit/content/license.html | 33 - toolkit/content/macWindowMenu.js | 2 +- toolkit/content/moz.build | 8 +- .../browser_bug295977_autoscroll_overflow.js | 2 +- .../content/widgets/browser-custom-element.js | 40 +- toolkit/content/xul.css | 11 +- toolkit/crashreporter/test/unit/xpcshell.ini | 47 +- .../crashreporter/test/unit_ipc/xpcshell.ini | 2 +- toolkit/docs/index.rst | 20 + .../test/unit/test_removeDataFromDomain.js | 2 +- toolkit/l10n-registry.manifest | 1 + toolkit/library/moz.build | 8 - toolkit/modules/AppConstants.jsm | 21 - toolkit/modules/docs/index.rst | 2 +- toolkit/modules/moz.build | 6 +- toolkit/moz.build | 15 +- toolkit/moz.configure | 253 +- toolkit/mozapps/downloads/HelperAppDlg.jsm | 11 +- .../extensions/AddonManagerStartup.cpp | 4 +- .../mozapps/extensions/AddonManagerStartup.h | 2 - .../extensions/test/xpcshell/test_cookies.js | 2 +- .../test/xpinstall/browser_cookies2.js | 2 +- .../test/xpinstall/browser_cookies3.js | 2 +- .../test/xpinstall/browser_cookies4.js | 2 +- toolkit/mozapps/installer/informulate.py | 23 +- toolkit/mozapps/installer/l10n-repack.py | 2 +- toolkit/mozapps/installer/packager.mk | 12 +- toolkit/mozapps/installer/packager.py | 11 - toolkit/mozapps/installer/strip.py | 2 +- toolkit/mozapps/installer/unpack.py | 2 +- toolkit/mozapps/installer/upload-files-APK.mk | 102 - toolkit/mozapps/installer/upload-files.mk | 3 +- toolkit/mozapps/update/tests/moz.build | 2 +- .../mozapps/update/updater/TsanOptions.cpp | 24 + .../mozapps/update/updater/progressui_gtk.cpp | 3 +- .../update/updater/updater-common.build | 7 + toolkit/nss.configure | 15 - toolkit/themes/linux/global/button.css | 6 +- toolkit/themes/osx/global/button.css | 10 +- toolkit/themes/osx/reftests/482681.xul | 22 - toolkit/themes/osx/reftests/reftest.list | 1 - toolkit/themes/shared/global.inc.css | 5 + toolkit/themes/shared/notification.inc.css | 2 +- toolkit/themes/windows/global/button.css | 7 +- .../themes/windows/global/printPageSetup.css | 16 +- toolkit/xre/CmdLineAndEnvUtils.h | 34 +- toolkit/xre/LauncherRegistryInfo.h | 2 +- toolkit/xre/nsAppRunner.cpp | 133 +- toolkit/xre/nsAppStartupNotifier.cpp | 75 +- toolkit/xre/nsEmbedFunctions.cpp | 2 +- toolkit/xre/nsIAppStartupNotifier.h | 1 - toolkit/xre/nsNativeAppSupportWin.h | 18 +- toolkit/xre/nsXREDirProvider.cpp | 27 + toolkit/xre/nsXREDirProvider.h | 1 + .../interface/FuzzingInterfaceStream.h | 28 +- tools/lint/codespell.yml | 1 - .../lib/configs/chrome-test.js | 5 + tools/lint/l10n.yml | 1 - tools/lint/libpref/__init__.py | 1 + tools/lint/py2.yml | 1 - .../profiler/core/platform-linux-android.cpp | 3 +- tools/profiler/gecko/nsIProfiler.idl | 2 +- tools/profiler/gecko/nsProfiler.cpp | 2 +- .../public/BlocksRingBufferGeckoExtensions.h | 15 +- tools/rewriting/ThirdPartyPaths.txt | 2 +- tools/tryselect/mach_commands.py | 14 +- tools/tryselect/push.py | 31 +- tools/tryselect/selectors/chooser/__init__.py | 11 +- tools/tryselect/selectors/coverage.py | 13 +- tools/tryselect/selectors/empty.py | 7 +- tools/tryselect/selectors/fuzzy.py | 13 +- tools/tryselect/selectors/release.py | 8 +- tools/tryselect/selectors/syntax.py | 2 +- tools/tryselect/templates.py | 30 +- tools/tryselect/test/test_again.py | 41 +- tools/tryselect/test/test_empty.t | 15 + .../update-packaging/app.mozbuild | 13 +- tools/update-packaging/make_full_update.sh | 4 + .../make_incremental_update.sh | 4 +- tools/update-packaging/moz.configure | 0 .../android/nsExternalURLHandlerService.cpp | 6 +- .../android/nsOSHelperAppService.cpp | 6 +- .../exthandler/nsExternalHelperAppService.cpp | 33 +- .../exthandler/nsIHelperAppLauncherDialog.idl | 5 +- .../prefetch/OfflineCacheUpdateChild.cpp | 10 - uriloader/prefetch/nsOfflineCacheUpdate.h | 4 +- uriloader/preload/FetchPreloader.h | 6 + uriloader/preload/PreloaderBase.cpp | 8 +- uriloader/preload/PreloaderBase.h | 4 +- widget/EventForwards.h | 11 +- widget/InputData.cpp | 20 +- widget/InputData.h | 4 +- widget/MouseEvents.h | 24 +- widget/android/ANRReporter.cpp | 78 - widget/android/ANRReporter.h | 24 - widget/android/AndroidBridge.cpp | 29 +- widget/android/Telemetry.h | 2 +- widget/android/fennec/MemoryMonitor.h | 26 - widget/android/fennec/ThumbnailHelper.h | 264 - widget/android/fennec/moz.build | 37 - widget/android/jni/Natives.h | 9 +- widget/android/jni/Utils.cpp | 14 - widget/android/jni/Utils.h | 6 - widget/android/moz.build | 2 - widget/android/nsAppShell.cpp | 18 - widget/android/nsClipboard.cpp | 2 +- widget/android/nsWindow.cpp | 20 +- widget/cocoa/nsChildView.mm | 23 +- widget/cocoa/nsCocoaUtils.mm | 6 +- widget/gtk/moz.build | 4 - widget/gtk/mozgtk/mozgtk.c | 1 + widget/gtk/nsGtkKeyUtils.cpp | 25 +- widget/gtk/nsWindow.cpp | 57 +- widget/headless/HeadlessWidget.cpp | 2 +- widget/nsBaseDragService.cpp | 6 +- widget/nsGUIEventIPC.h | 2 +- widget/tests/TestAppShellSteadyState.cpp | 450 - widget/tests/browser/browser.ini | 1 - widget/tests/mochitest.ini | 3 +- widget/tests/moz.build | 18 +- widget/tests/test_actionhint.html | 32 +- .../test_mouse_event_with_control_on_mac.html | 114 + widget/uikit/nsWindow.mm | 2 +- widget/windows/IMMHandler.cpp | 4 +- widget/windows/KeyboardLayout.cpp | 4 +- widget/windows/TSFTextStore.cpp | 12 +- widget/windows/WinHeaderOnlyUtils.h | 132 +- widget/windows/WindowsUIUtils.cpp | 1 + widget/windows/nsWindow.cpp | 91 +- widget/windows/nsWindow.h | 2 +- xpcom/base/ClearOnShutdown.cpp | 22 +- xpcom/base/ClearOnShutdown.h | 71 +- xpcom/base/CycleCollectedJSContext.cpp | 17 +- xpcom/base/CycleCollectedJSRuntime.cpp | 35 +- xpcom/base/CycleCollectedJSRuntime.h | 2 + xpcom/base/LogCommandLineHandler.cpp | 3 +- xpcom/base/moz.build | 1 - xpcom/base/nsCycleCollector.cpp | 21 +- xpcom/base/nsCycleCollectorTraceJSHelpers.cpp | 2 +- xpcom/base/nsDumpUtils.cpp | 2 +- xpcom/base/nsIMemoryReporter.idl | 4 +- xpcom/base/nsMacUtilsImpl.cpp | 8 +- xpcom/base/nsMemoryInfoDumper.cpp | 21 +- xpcom/base/nsMemoryReporterManager.cpp | 10 +- xpcom/base/nsMessageLoop.cpp | 4 +- xpcom/base/nsTWeakRef.h | 157 - xpcom/base/nscore.h | 2 - xpcom/build/IOInterposer.cpp | 137 +- xpcom/build/LateWriteChecks.cpp | 38 +- xpcom/build/MainThreadIOLogger.cpp | 23 +- xpcom/build/NSPRInterposer.cpp | 22 +- xpcom/build/PoisonIOInterposerBase.cpp | 14 +- xpcom/build/PoisonIOInterposerMac.cpp | 38 +- xpcom/build/PoisonIOInterposerWin.cpp | 62 +- xpcom/build/XPCOM.h | 1 - xpcom/build/XPCOMInit.cpp | 49 +- xpcom/build/nsXPCOM.h | 6 +- xpcom/components/ManifestParser.cpp | 3 +- xpcom/components/gen_static_components.py | 2 +- xpcom/components/nsComponentManager.cpp | 32 +- xpcom/components/nsComponentManager.h | 1 - xpcom/ds/AtomArray.h | 2 +- xpcom/ds/StaticAtoms.py | 53 + xpcom/ds/nsAtomTable.cpp | 4 +- xpcom/ds/nsExpirationTracker.h | 22 +- xpcom/ds/nsObserverService.cpp | 11 +- xpcom/idl-parser/xpidl/runtests.py | 45 +- xpcom/idl-parser/xpidl/rust.py | 7 +- xpcom/idl-parser/xpidl/rust_macros.py | 7 +- xpcom/idl-parser/xpidl/xpidl.py | 5 +- xpcom/io/Base64.cpp | 82 +- xpcom/io/Base64.h | 5 + xpcom/io/SpecialSystemDirectory.cpp | 2 +- xpcom/io/SpecialSystemDirectory.h | 3 +- xpcom/io/nsBinaryStream.cpp | 12 +- xpcom/io/nsDirectoryService.cpp | 31 +- xpcom/io/nsDirectoryService.h | 9 +- xpcom/io/nsIBinaryInputStream.idl | 2 +- xpcom/io/nsLocalFileUnix.cpp | 42 +- xpcom/io/nsLocalFileUnix.h | 37 - xpcom/io/nsLocalFileWin.cpp | 4 +- xpcom/io/nsMultiplexInputStream.cpp | 4 +- xpcom/io/nsNativeCharsetUtils.cpp | 2 - xpcom/io/nsStorageStream.cpp | 6 +- xpcom/moz.build | 1 - xpcom/rust/gtest/nsstring/Test.cpp | 15 + xpcom/rust/gtest/nsstring/test.rs | 6 + xpcom/rust/nsstring/src/lib.rs | 17 + xpcom/string/nsLiteralString.h | 14 + xpcom/string/nsStringBuffer.h | 35 +- xpcom/string/nsStringObsolete.cpp | 20 + xpcom/string/nsSubstring.cpp | 29 - xpcom/string/nsTDependentSubstring.cpp | 5 + xpcom/string/nsTDependentSubstring.h | 6 + xpcom/string/nsTLiteralString.h | 24 +- xpcom/string/nsTStringComparator.cpp | 10 + xpcom/string/nsTStringObsolete.cpp | 7 + xpcom/string/nsTStringRepr.h | 30 +- xpcom/string/nsTSubstring.cpp | 73 +- xpcom/string/nsTSubstring.h | 11 +- xpcom/string/nsTSubstringTuple.cpp | 1 + xpcom/string/precompiled_templates.cpp | 59 +- xpcom/tests/TestHarness.h | 4 +- xpcom/tests/gtest/TestAtoms.cpp | 2 +- xpcom/tests/gtest/TestBase64.cpp | 25 + xpcom/tests/gtest/TestDafsa.cpp | 20 +- xpcom/tests/gtest/TestEventTargetQI.cpp | 6 +- xpcom/tests/gtest/TestFile.cpp | 6 +- xpcom/tests/gtest/TestFilePreferencesWin.cpp | 182 +- .../tests/gtest/TestLogCommandLineHandler.cpp | 39 +- xpcom/tests/gtest/TestMruCache.cpp | 6 +- xpcom/tests/gtest/TestObserverService.cpp | 32 +- xpcom/tests/gtest/TestStrings.cpp | 162 +- xpcom/tests/gtest/TestTextFormatter.cpp | 2 +- xpcom/tests/gtest/TestTokenizer.cpp | 97 +- xpcom/tests/gtest/TestUTF.cpp | 16 +- xpcom/tests/windows/TestNtPathToDosPath.cpp | 2 +- xpcom/threads/CPUUsageWatcher.cpp | 2 +- xpcom/threads/CPUUsageWatcher.h | 13 +- xpcom/threads/IdleTaskRunner.cpp | 29 +- xpcom/threads/IdleTaskRunner.h | 40 +- xpcom/threads/ThreadEventQueue.cpp | 1 + xpcom/threads/ThrottledEventQueue.cpp | 6 +- xpcom/threads/moz.build | 1 + xpcom/threads/nsICancelableRunnable.h | 5 +- xpcom/threads/nsIDiscardableRunnable.h | 39 + xpcom/threads/nsThreadManager.cpp | 6 +- xpcom/threads/nsThreadUtils.cpp | 49 +- xpcom/threads/nsThreadUtils.h | 71 +- xpcom/xpcom-private.h.in | 38 - xpfe/appshell/nsContentTreeOwner.cpp | 3 +- 1218 files changed, 49605 insertions(+), 31438 deletions(-) create mode 100644 browser/base/content/test/menubar/browser_window_menu_list.js create mode 100644 browser/l10n-registry.manifest delete mode 100644 build/autoconf/icu.m4 delete mode 100644 build/autoconf/ios.m4 delete mode 100644 build/autoconf/nspr-build.m4 delete mode 100644 build/autoconf/nspr.m4 delete mode 100644 build/autoconf/nss.m4 delete mode 100644 build/autoconf/zlib.m4 create mode 100644 build/build-clang/llvmorg-11-init-4265-g2dcbdba8540.patch delete mode 100644 build/merge_profdata.py create mode 100644 build/moz.configure/nspr.configure delete mode 100644 build/mozconfig.pgo delete mode 100644 build/sanitizers/lsan_suppressions.txt delete mode 100644 build/sanitizers/tsan_suppressions.txt delete mode 100644 build/sanitizers/ubsan_suppressions.txt delete mode 100644 build/win32/pgomerge.py delete mode 100644 config/external/icu/data/genicudata.py create mode 100644 config/external/icu/data/icu_data.S delete mode 100644 config/external/icu/data/icudata.s create mode 100644 devtools/client/inspector/rules/test/browser_rules_pseudo-visited.js delete mode 100644 devtools/client/themes/images/aboutdebugging-fenix-nightly.svg delete mode 100644 devtools/client/themes/images/aboutdebugging-fenix.svg delete mode 100644 devtools/client/themes/images/aboutdebugging-firefox-aurora.svg delete mode 100644 devtools/client/themes/images/aboutdebugging-firefox-beta.svg delete mode 100644 devtools/client/themes/images/aboutdebugging-firefox-logo.svg delete mode 100644 devtools/client/themes/images/aboutdebugging-firefox-nightly.svg delete mode 100644 devtools/client/themes/images/aboutdebugging-firefox-release.svg create mode 100644 gfx/2d/SwizzleAVX2.cpp create mode 100644 gfx/2d/SwizzleSSSE3.cpp delete mode 100644 gfx/layers/apz/src/AndroidDynamicToolbarAnimator.cpp delete mode 100644 gfx/layers/apz/src/AndroidDynamicToolbarAnimator.h create mode 100644 gfx/thebes/mach_commands.py create mode 100644 image/test/crashtests/1629490-1-iframe.html create mode 100644 image/test/crashtests/1629490-1.html create mode 100644 image/test/crashtests/1634839-1-iframe.html create mode 100644 image/test/crashtests/1634839-1.html create mode 100644 image/test/crashtests/1634839-2-iframe.html create mode 100644 image/test/crashtests/1634839-2.html create mode 100644 image/test/crashtests/1676172-1-iframe.html create mode 100644 image/test/crashtests/1676172-1.gif create mode 100644 image/test/crashtests/1676172-1.html create mode 100644 image/test/crashtests/finite-apng.png create mode 100644 image/test/crashtests/out2.gif create mode 100644 image/test/crashtests/rainbow.gif create mode 100644 image/test/gtest/TestDecodersPerf.cpp create mode 100644 image/test/gtest/TestSwizzleFilter.cpp rename security/manager/ssl/tests/unit/test_broken_fips/secmod.db => image/test/gtest/perf_cmyk.jpg (59%) create mode 100644 image/test/gtest/perf_gray.jpg create mode 100644 image/test/gtest/perf_gray.png create mode 100644 image/test/gtest/perf_gray_alpha.png create mode 100644 image/test/gtest/perf_srgb.gif create mode 100644 image/test/gtest/perf_srgb.png create mode 100644 image/test/gtest/perf_srgb_alpha.png create mode 100644 image/test/gtest/perf_srgb_alpha_lossless.webp create mode 100644 image/test/gtest/perf_srgb_alpha_lossy.webp create mode 100644 image/test/gtest/perf_srgb_lossless.webp create mode 100644 image/test/gtest/perf_srgb_lossy.webp rename modules/libmar/tests/unit/data/secmod.db => image/test/gtest/perf_ycbcr.jpg (71%) create mode 100644 image/test/mochitest/finite-apng.png delete mode 100644 image/test/mochitest/test_ImageContentLoaded.html create mode 100644 image/test/mochitest/test_discardFinishedAnimatedImage.html delete mode 100644 image/test/reftest/bmp/bmpsuite/q/rgb24prof2.png create mode 100644 image/test/reftest/downscaling/downscale-orient-ref.html create mode 100644 image/test/reftest/downscaling/downscale-orient-ref.png create mode 100644 image/test/reftest/downscaling/downscale-orient.html create mode 100644 image/test/reftest/downscaling/image-pre-rotated-90-deg.jpg create mode 100644 intl/icu-patches/bug-1636984-alias-append-items-sink.diff create mode 100644 intl/icu-patches/bug-1636984-append-item-dayperiod-fractional-seconds.diff create mode 100644 intl/icu-patches/bug-1636984-display-name-fractional-seconds.diff create mode 100644 mfbt/AtomicBitfields.h create mode 100644 mfbt/BitSet.h delete mode 100644 mfbt/LinuxSignal.h delete mode 100644 mfbt/NullPtr.h create mode 100644 mfbt/ResultVariant.h create mode 100644 mfbt/TsanOptions.h delete mode 100644 mfbt/double-conversion/ToPrecision-exponential.patch create mode 100644 mfbt/double-conversion/debug-only-functions.patch delete mode 100644 mfbt/double-conversion/double-conversion/diy-fp.cc create mode 100644 mfbt/double-conversion/double-conversion/double-to-string.cc create mode 100644 mfbt/double-conversion/double-conversion/double-to-string.h rename mfbt/double-conversion/double-conversion/{double-conversion.cc => string-to-double.cc} (55%) create mode 100644 mfbt/double-conversion/double-conversion/string-to-double.h create mode 100644 mfbt/double-conversion/to-fixed-dbl-max.patch create mode 100644 mfbt/double-conversion/to-fixed-digits-after-point.patch create mode 100644 mfbt/tests/TestAtomicBitfields.cpp create mode 100644 mfbt/tests/TestBitSet.cpp create mode 100644 mfbt/tests/TestTainting.cpp create mode 100644 mfbt/tests/gtest/TestMainThreadWeakPtr.cpp delete mode 100644 modules/libmar/tests/unit/data/cert8.db create mode 100644 modules/libmar/tests/unit/data/cert9.db delete mode 100644 modules/libmar/tests/unit/data/key3.db create mode 100644 modules/libmar/tests/unit/data/key4.db create mode 100644 mozglue/build/TsanOptions.cpp create mode 100644 mozglue/tests/glibc_printf_tests/COPYING create mode 100644 mozglue/tests/glibc_printf_tests/COPYING.LIB create mode 100644 mozglue/tests/glibc_printf_tests/README.MOZILLA create mode 100644 mozglue/tests/glibc_printf_tests/tfformat.c create mode 100644 mozglue/tests/glibc_printf_tests/tiformat.c create mode 100644 mozglue/tests/glibc_printf_tests/tllformat.c create mode 100644 netwerk/cookie/test/unit/test_rawSameSite.js delete mode 100644 netwerk/ipc/NeckoCommon.cpp delete mode 100644 netwerk/necko-config.h.in create mode 100644 netwerk/test/mochitests/test_arraybufferinputstream_large.html delete mode 100644 python/mozbuild/mozbuild/action/generate_strings_xml.py delete mode 100644 python/mozbuild/mozbuild/action/generate_suggestedsites.py delete mode 100644 python/mozbuild/mozbuild/action/package_fennec_apk.py create mode 100644 python/mozbuild/mozbuild/artifact_commands.py create mode 100644 python/mozbuild/mozbuild/build_commands.py create mode 100644 python/mozbuild/mozbuild/code-analysis/mach_commands.py delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/assets/asset.txt delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/input1.ap_ delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/input1/res/res.txt delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/input1/resources.arsc delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/input2.apk delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/input2/assets/asset.txt delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/input2/assets/omni.ja delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/input2/classes.dex delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/input2/lib/lib.txt delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/input2/res/res.txt delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/input2/resources.arsc delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/input2/root_file.txt delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/lib/lib.txt delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/omni.ja delete mode 100644 python/mozbuild/mozbuild/test/action/data/package_fennec_apk/root_file.txt delete mode 100644 python/mozbuild/mozbuild/test/action/test_package_fennec_apk.py create mode 100644 python/mozbuild/mozbuild/test/frontend/data/wasm-compile-flags/moz.build create mode 100644 python/mozbuild/mozbuild/test/frontend/data/wasm-compile-flags/test1.c create mode 100644 python/mozbuild/mozbuild/test/frontend/data/wasm-sources/a.cpp create mode 100644 python/mozbuild/mozbuild/test/frontend/data/wasm-sources/b.cc create mode 100644 python/mozbuild/mozbuild/test/frontend/data/wasm-sources/c.cxx create mode 100644 python/mozbuild/mozbuild/test/frontend/data/wasm-sources/d.c create mode 100644 python/mozbuild/mozbuild/test/frontend/data/wasm-sources/moz.build create mode 100644 python/mozversioncontrol/test/test_commit.py delete mode 100644 security/manager/ssl/tests/unit/test_broken_fips/key3.db create mode 100644 security/manager/ssl/tests/unit/test_broken_fips/key4.db create mode 100644 security/manager/ssl/tests/unit/test_broken_fips/pkcs11.txt delete mode 100644 security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/cert8.db delete mode 100644 security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/key3.db delete mode 100644 security/manager/ssl/tests/unit/test_sdr_preexisting/key3.db delete mode 100644 security/manager/ssl/tests/unit/test_sdr_preexisting_with_password/key3.db create mode 100644 security/manager/ssl/tests/unit/test_sdr_preexisting_with_password/key4.db delete mode 100644 security/manager/ssl/tests/unit/test_sdr_upgraded_with_password.js delete mode 100644 security/manager/ssl/tests/unit/test_sdr_upgraded_with_password/cert8.db delete mode 100644 security/manager/ssl/tests/unit/test_sdr_upgraded_with_password/cert9.db delete mode 100644 security/manager/ssl/tests/unit/test_sdr_upgraded_with_password/key3.db delete mode 100644 security/manager/ssl/tests/unit/test_sdr_upgraded_with_password/key4.db create mode 100644 taskcluster/ci/build-fat-aar/kind.yml create mode 100644 taskcluster/scripts/misc/build-mar-tools.sh create mode 100644 taskcluster/taskgraph/transforms/build_fat_aar.py delete mode 100644 taskcluster/taskgraph/transforms/use_toolchains.py create mode 100644 taskcluster/taskgraph/util/declarative_artifacts.py create mode 100644 toolkit/components/cleardata/tests/browser/browser_quota.js delete mode 100644 toolkit/components/passwordmgr/test/unit/data/key3.db create mode 100644 toolkit/docs/index.rst create mode 100644 toolkit/l10n-registry.manifest delete mode 100644 toolkit/mozapps/installer/upload-files-APK.mk create mode 100644 toolkit/mozapps/update/updater/TsanOptions.cpp delete mode 100644 toolkit/nss.configure delete mode 100644 toolkit/themes/osx/reftests/482681.xul rename config/external/icu/data/icudata_gas.S => tools/update-packaging/app.mozbuild (53%) create mode 100644 tools/update-packaging/moz.configure delete mode 100644 widget/android/ANRReporter.cpp delete mode 100644 widget/android/ANRReporter.h delete mode 100644 widget/android/fennec/MemoryMonitor.h delete mode 100644 widget/android/fennec/ThumbnailHelper.h delete mode 100644 widget/android/fennec/moz.build delete mode 100644 widget/tests/TestAppShellSteadyState.cpp create mode 100644 widget/tests/test_mouse_event_with_control_on_mac.html delete mode 100644 xpcom/base/nsTWeakRef.h create mode 100644 xpcom/threads/nsIDiscardableRunnable.h delete mode 100644 xpcom/xpcom-private.h.in diff --git a/.clang-format-ignore b/.clang-format-ignore index ff9305ff37..154661830f 100644 --- a/.clang-format-ignore +++ b/.clang-format-ignore @@ -133,17 +133,16 @@ media/webrtc/trunk/.* mfbt/double-conversion/double-conversion/.* mfbt/lz4.* mobile/android/geckoview/src/thirdparty/.* -mobile/android/thirdparty/.* modules/brotli/.* modules/fdlibm/.* modules/freetype2/.* modules/libbz2/.* -modules/libmar/.* modules/pdfium/.* modules/woff2/.* modules/xz-embedded/.* modules/zlib/.* mozglue/misc/decimal/.* +mozglue/tests/glibc_printf_tests/.* netwerk/dns/nsIDNKitInterface.h netwerk/sctp/src/.* netwerk/srtp/src/.* diff --git a/.eslintrc.js b/.eslintrc.js index 9e1014bc2e..1353d05a30 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -248,6 +248,7 @@ module.exports = { "dom/security/test/general/**", "dom/security/test/mixedcontentblocker/**", "dom/security/test/sri/**", + "dom/security/test/referrer-policy/**", "dom/serviceworkers/**", "dom/smil/**", "dom/tests/mochitest/**", diff --git a/.flake8 b/.flake8 index 4be43b2322..623eaa46e3 100644 --- a/.flake8 +++ b/.flake8 @@ -83,7 +83,7 @@ exclude = # - http://pep8.readthedocs.io/en/latest/intro.html#configuration ignore = # These should be triaged and either fixed or moved to the list below. - F632, F633, F811, E117, W504, W605, W606, + F633, F811, E117, W504, W605, W606, # These are intentionally disabled (not necessarily for good reason). # F723: syntax error in type comment # text contains quotes which breaks our custom JSON formatter diff --git a/Makefile.in b/Makefile.in index 098abb7d04..900b45a6da 100644 --- a/Makefile.in +++ b/Makefile.in @@ -31,29 +31,26 @@ GARBAGE_DIRS += _javagen _profile staticlib # subdirectories to remove. So we add to GARBAGE_DIRS once here, globally, # for it to have the desired effect. GARBAGE_DIRS += $(RUST_TARGET) -DIST_GARBAGE = config.cache config.log config.status* config-defs.h \ +GARBAGE_DIRS += config.statusd +DIST_GARBAGE = config.cache config.log config.status config-defs.h \ config/autoconf.mk \ mozilla-config.h \ - netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \ + xpcom/xpcom-config.h \ .mozconfig.mk -ifndef MOZ_PROFILE_USE ifneq (mobile/android,$(MOZ_BUILD_APP)) $(MDDEPDIR)/buildid.h.stub $(MDDEPDIR)/source-repo.h.stub: FORCE endif source-repo.h: $(MDDEPDIR)/source-repo.h.stub buildid.h: $(MDDEPDIR)/buildid.h.stub -endif BUILD_BACKEND_FILES := $(addprefix backend.,$(addsuffix Backend,$(BUILD_BACKENDS))) ifndef TEST_MOZBUILD -ifndef MOZ_PROFILE_USE # We need to explicitly put BUILD_BACKEND_FILES here otherwise the rule in # rules.mk doesn't run early enough. $(RUNNABLE_TIERS) binaries:: CLOBBER $(BUILD_BACKEND_FILES) endif -endif ifdef JS_STANDALONE .PHONY: CLOBBER @@ -115,33 +112,17 @@ install-test-files: include $(topsrcdir)/build/moz-automation.mk -# dist and _tests should be purged during cleaning. However, we don't want them -# purged during PGO builds because they contain some auto-generated files. -ifneq ($(filter-out maybe_clobber_profiledbuild,$(MAKECMDGOALS)),) +# dist and _tests should be purged during cleaning. GARBAGE_DIRS += dist _tests -endif # Dummy rule for the cases below where we don't depend on dist/include recurse_pre-export:: -# Windows PGO builds don't perform a clean before the 2nd pass. So, we want -# to preserve content for the 2nd pass on Windows. Everywhere else, we always -# process the install manifests as part of export. # For the binaries rule, not all the install manifests matter, so force only # the interesting ones to be done. -ifdef MOZ_1TIER_PGO -ifndef NO_PROFILE_GUIDED_OPTIMIZE -ifneq ($(OS_ARCH)_$(GNU_CC), WINNT_) recurse_pre-export:: install-manifests binaries:: @$(MAKE) install-manifests install_manifests=dist/include -endif -endif -else # !MOZ_1TIER_PGO (normal build) -recurse_pre-export:: install-manifests -binaries:: - @$(MAKE) install-manifests install_manifests=dist/include -endif # Host binaries are not produced for macOS consumers: that is, there's # no macOS-hosted job to produce them at this time. Therefore we @@ -152,8 +133,21 @@ recurse_artifact: ifdef MOZ_ANDROID_FAT_AAR_ARCHITECTURES recurse_android-fat-aar-artifact: - $(call py_action,fat_aar,$(MOZ_ANDROID_FAT_AAR_ARCHITECTURES) --distdir $(abspath $(DIST)/fat-aar)) -endif # MOZ_ANDROID_FAT_AAR_ARCHITECTURES + $(call py_action,fat_aar,\ + $(addprefix --armeabi-v7a $(MOZ_FETCHES_DIR)/,$(MOZ_ANDROID_FAT_AAR_ARMEABI_V7A)) \ + $(addprefix --arm64-v8a $(MOZ_FETCHES_DIR)/,$(MOZ_ANDROID_FAT_AAR_ARM64_V8A)) \ + $(addprefix --x86 $(MOZ_FETCHES_DIR)/,$(MOZ_ANDROID_FAT_AAR_X86)) \ + $(addprefix --x86-64 $(MOZ_FETCHES_DIR)/,$(MOZ_ANDROID_FAT_AAR_X86_64)) \ + --distdir $(abspath $(DIST)/fat-aar)) +endif + +ifeq ($(MOZ_BUILD_APP),mobile/android) + +recurse_android-stage-package: stage-package + +recurse_android-archive-geckoview: + GRADLE_INVOKED_WITHIN_MACH_BUILD=1 $(topsrcdir)/mach --log-no-times android archive-geckoview +endif ifdef MOZ_WIDGET_TOOLKIT ifdef ENABLE_TESTS @@ -165,37 +159,6 @@ endif default all:: $(call BUILDSTATUS,TIERS $(TIERS) $(if $(MOZ_AUTOMATION),$(MOZ_AUTOMATION_TIERS))) -# PGO build target. -profiledbuild:: - $(call BUILDSTATUS,TIERS pgo_profile_generate pgo_package pgo_profile pgo_clobber pgo_profile_use) - $(call BUILDSTATUS,TIER_START pgo_profile_generate) - $(MAKE) default MOZ_PROFILE_GENERATE=1 MOZ_LTO= - $(call BUILDSTATUS,TIER_FINISH pgo_profile_generate) - $(call BUILDSTATUS,TIER_START pgo_package) - $(MAKE) package - rm -f jarlog/en-US.log - $(call BUILDSTATUS,TIER_FINISH pgo_package) - $(call BUILDSTATUS,TIER_START pgo_profile) - JARLOG_FILE=jarlog/en-US.log $(PYTHON) $(topsrcdir)/build/pgo/profileserver.py - $(call BUILDSTATUS,TIER_FINISH pgo_profile) - $(call BUILDSTATUS,TIER_START pgo_clobber) - $(MAKE) maybe_clobber_profiledbuild - $(call BUILDSTATUS,TIER_FINISH pgo_clobber) - $(call BUILDSTATUS,TIER_START pgo_profile_use) - $(MAKE) default MOZ_PROFILE_USE=1 MOZ_1TIER_PGO=1 - $(call BUILDSTATUS,TIER_FINISH pgo_profile_use) - -# Change default target to PGO build if PGO is enabled. -ifdef MOZ_PGO -ifdef COMPILE_ENVIRONMENT -# If one of these is already set in addition to PGO we are doing a single phase -# of PGO in isolation, so don't override the default target. -ifeq (,$(MOZ_PROFILE_GENERATE)$(MOZ_PROFILE_USE)) -OVERRIDE_DEFAULT_GOAL := profiledbuild -endif -endif -endif - include $(topsrcdir)/config/rules.mk ifdef SCCACHE_VERBOSE_STATS @@ -261,19 +224,6 @@ update-packaging: package-generated-sources: $(call py_action,package_generated_sources,'$(DIST)/$(PKG_PATH)$(GENERATED_SOURCE_FILE_PACKAGE)') -# PGO support, but we can't do this test in client.mk -# No point in clobbering if PGO has been explicitly disabled. -ifdef NO_PROFILE_GUIDED_OPTIMIZE -maybe_clobber_profiledbuild: -else -maybe_clobber_profiledbuild: clean -ifneq (,$(findstring clang,$(CC_TYPE))) - $(LLVM_PROFDATA) merge -o $(DEPTH)/merged.profdata $(DEPTH)/*.profraw -endif -endif # NO_PROFILE_GUIDED_OPTIMIZE - -.PHONY: maybe_clobber_profiledbuild - ifdef JS_STANDALONE # Delegate js-specific rules to js check-%: @@ -289,4 +239,9 @@ config/export: endif +ifdef REBASE_DIR +default all:: + $(REBASE_DIR)\Rebase.Exe -b 61d60000 $(DIST)/bin/mozglue.dll $(DIST)/bin/lgpllibs.dll $(DIST)/bin/nss3.dll $(DIST)/bin/xul.dll $(DIST)/bin/softokn3.dll $(DIST)/bin/freebl3.dll $(DIST)/bin/nssckbi.dll $(DIST)/bin/mozavutil.dll $(DIST)/bin/mozavcodec.dll $(DIST)/bin/libEGL.dll $(DIST)/bin/libGLESv2.dll $(DIST)/bin/qipcap.dll +endif + # There used to be build interdependencies here. They are now in config/recurse.mk diff --git a/README.md b/README.md index 29601686a9..eec0a1f9f4 100644 --- a/README.md +++ b/README.md @@ -5,40 +5,43 @@ A browser for Windows XP based on Firefox 68. ![image](https://user-images.githubusercontent.com/19492771/152347482-f51058cd-2967-4bc5-80fd-5d269c328774.png) -**WARNING** +## WARNING This browser does not run well on winxp SP2 and lower. If you do not want to install SP3, be ready for crashes and blue screens. If you are on SP2 and lower, there is no need to post a screenshot from blue_screen_view. And i suggest to apply postready updates of 2019. Some say that it runs fine on sp2 but it is no accurate data what to do. -**IF YOU GOT A BLUE SCREEN** +## IF YOU GOT A BLUE SCREEN Don't post a screenshot of the blue screen, as the screen isn't useful for troubleshooting. For more data look [#3](https://github.com/Feodor2/Mypal68/issues/3), and please do not make new duplicate reports. Suddenly restart may be also this error depends of the settings -**IF YOU GOT A CRASH BUT WITHOUT BLUE SCREEN** +## IF YOU GOT A CRASH BUT WITHOUT BLUE SCREEN Describe detailed how to reproduces the crash, do not forget to put the link. Do not post pictures of the crash, this is useless and a waste. -If i don't reproduce the crash myself then you may to submit drwatson.log. +Also put your pc specs: cpu, ram and graphics card +If I don't reproduce the crash myself then you may to submit drwatson.log. Drwatson log is usually inside All Users\Application Data\Microsoft\Dr Watson. Minidump also may be usefull. Do not post any irrelevent logs. +An issue without details cosider as invalid. -**IF YOU WANT REPORT A SITE** +## IF YOU WANT REPORT A SITE Report [there](https://github.com/Feodor2/Mypal68/issues/228). Put the actual link to the site -Notice that i never would look to the site which requires the login, including any goolag sites. Please try to find what feature is missig by yourself. -Then report like for site 'x' is missing feature 'y' +Notice that I never would look to the site which requires the login, including any goolag sites. +Please try to find what feature is missig by yourself by checking on newer firefoxes and find first version where it works. +Actually I do not look every site, no time for this. -**YOU MAY DONATE** +## YOU MAY DONATE But only by crypto [Look here](https://github.com/Feodor2/Mypal68/issues/84) -**MY MIRROR PAGES** +## MY MIRROR PAGES -https://codeberg.org/Theodor2/Mypal68 +https://codeberg.org/Theodor2/Mypal68 \ https://notabug.org/Theodor/Mypal68 diff --git a/accessible/base/nsCoreUtils.cpp b/accessible/base/nsCoreUtils.cpp index a16e2b0cd3..67864ef1a5 100644 --- a/accessible/base/nsCoreUtils.cpp +++ b/accessible/base/nsCoreUtils.cpp @@ -122,7 +122,7 @@ void nsCoreUtils::DispatchMouseEvent(EventMessage aMessage, int32_t aX, event.mRefPoint = LayoutDeviceIntPoint(aX, aY); event.mClickCount = 1; - event.mButton = MouseButton::eLeft; + event.mButton = MouseButton::ePrimary; event.mTime = PR_IntervalNow(); event.mInputSource = dom::MouseEvent_Binding::MOZ_SOURCE_UNKNOWN; diff --git a/accessible/tests/mochitest/attributes/test_obj_css.xul b/accessible/tests/mochitest/attributes/test_obj_css.xul index f89d318bf1..e110ac5b67 100644 --- a/accessible/tests/mochitest/attributes/test_obj_css.xul +++ b/accessible/tests/mochitest/attributes/test_obj_css.xul @@ -28,7 +28,6 @@ testCSSAttrs("display_mozstack"); testCSSAttrs("display_mozdeck"); testCSSAttrs("display_mozpopup"); - testCSSAttrs("display_mozgroupbox"); SimpleTest.finish(); } @@ -61,7 +60,6 @@ - diff --git a/aclocal.m4 b/aclocal.m4 index 43b7dbd019..2bc8657ba1 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -7,9 +7,6 @@ builtin(include, build/autoconf/hotfixes.m4)dnl builtin(include, build/autoconf/hooks.m4)dnl builtin(include, build/autoconf/config.status.m4)dnl builtin(include, build/autoconf/toolchain.m4)dnl -builtin(include, build/autoconf/nspr.m4)dnl -builtin(include, build/autoconf/nspr-build.m4)dnl -builtin(include, build/autoconf/nss.m4)dnl builtin(include, build/autoconf/pkg.m4)dnl builtin(include, build/autoconf/codeset.m4)dnl builtin(include, build/autoconf/altoptions.m4)dnl @@ -19,11 +16,8 @@ builtin(include, build/autoconf/compiler-opts.m4)dnl builtin(include, build/autoconf/expandlibs.m4)dnl builtin(include, build/autoconf/arch.m4)dnl builtin(include, build/autoconf/android.m4)dnl -builtin(include, build/autoconf/zlib.m4)dnl -builtin(include, build/autoconf/icu.m4)dnl builtin(include, build/autoconf/clang-plugin.m4)dnl builtin(include, build/autoconf/alloc.m4)dnl -builtin(include, build/autoconf/ios.m4)dnl builtin(include, build/autoconf/sanitize.m4)dnl MOZ_PROG_CHECKMSYS() diff --git a/browser/actors/moz.build b/browser/actors/moz.build index cb871edaf2..5eeec819d0 100644 --- a/browser/actors/moz.build +++ b/browser/actors/moz.build @@ -18,7 +18,7 @@ with Files("PluginChild.jsm"): BUG_COMPONENT = ("Core", "Plug-ins") with Files("WebRTCChild.jsm"): - BUG_COMPONENT = ("Firefox", "Device Permissions") + BUG_COMPONENT = ("Firefox", "Site Permissions") FINAL_TARGET_FILES.actors += [ 'AboutReaderChild.jsm', diff --git a/browser/app/macbuild/Contents/MacOS-files.in b/browser/app/macbuild/Contents/MacOS-files.in index 3dac37a298..c54e3257cc 100644 --- a/browser/app/macbuild/Contents/MacOS-files.in +++ b/browser/app/macbuild/Contents/MacOS-files.in @@ -10,7 +10,6 @@ #if defined(MOZ_ASAN) || defined(MOZ_TSAN) /llvm-symbolizer #endif -/pingsender /pk12util /ssltunnel /webrtc-gtest diff --git a/browser/app/module.ver b/browser/app/module.ver index ae6c35acee..dd26a5855b 100644 --- a/browser/app/module.ver +++ b/browser/app/module.ver @@ -1,4 +1,4 @@ -WIN32_MODULE_COMPANYNAME=Feodor2 +WIN32_MODULE_COMPANYNAME=Theodor2 WIN32_MODULE_COPYRIGHT=©Mypal and Mozilla Developers; available under the MPL 2 license. WIN32_MODULE_PRODUCTVERSION=@MOZ_APP_WINVERSION@ WIN32_MODULE_PRODUCTVERSION_STRING=@MOZ_APP_VERSION@ diff --git a/browser/app/moz.build b/browser/app/moz.build index d4b7921931..739134cb96 100644 --- a/browser/app/moz.build +++ b/browser/app/moz.build @@ -67,7 +67,6 @@ if CONFIG['CC_TYPE'] == 'clang-cl': if CONFIG['OS_ARCH'] == 'WINNT': RCINCLUDE = 'splash.rc' - DEFINES['MOZ_PHOENIX'] = True DIRS += [ # 'winlauncher', ] @@ -118,9 +117,6 @@ if CONFIG['OS_ARCH'] == 'WINNT' and CONFIG['CC_TYPE'] not in ('clang', 'gcc'): DisableStlWrapping() -if CONFIG['MOZ_LINKER']: - OS_LIBS += CONFIG['MOZ_ZLIB_LIBS'] - if CONFIG['HAVE_CLOCK_MONOTONIC']: OS_LIBS += CONFIG['REALTIME_LIBS'] diff --git a/browser/app/profile/mypal.js b/browser/app/profile/mypal.js index 475e918ef5..c9cd32f144 100644 --- a/browser/app/profile/mypal.js +++ b/browser/app/profile/mypal.js @@ -394,7 +394,7 @@ pref("browser.tabs.insertRelatedAfterCurrent", true); // for non-related links. Note that if this is set to true, it will trump // the value of browser.tabs.insertRelatedAfterCurrent. pref("browser.tabs.insertAfterCurrent", false); -pref("browser.tabs.warnOnClose", true); +pref("browser.tabs.warnOnClose", 1); pref("browser.tabs.warnOnCloseOtherTabs", true); pref("browser.tabs.warnOnOpen", true); pref("browser.tabs.maxOpenBeforeWarn", 15); @@ -515,7 +515,6 @@ pref("privacy.history.custom", false); // 5 - Last 5 minutes // 6 - Last 24 hours pref("privacy.sanitize.timeSpan", 1); -pref("privacy.sanitize.sanitizeOnShutdown", false); pref("privacy.sanitize.migrateFx3Prefs", false); @@ -524,12 +523,6 @@ pref("privacy.panicButton.enabled", true); // Time until temporary permissions expire, in ms pref("privacy.temporary_permission_expire_time_ms", 3600000); -// If Accept-Language should be spoofed by en-US -// 0 - will prompt -// 1 - don't spoof -// 2 - spoof -pref("privacy.spoof_english", 0); - pref("network.proxy.share_proxy_settings", false); // use the same proxy settings for all protocols // simple gestures support @@ -660,16 +653,6 @@ pref("plugins.show_infobar", false); pref("plugin.default.state", 1); #endif -// Plugins bundled in XPIs are enabled by default. -pref("plugin.defaultXpi.state", 2); - -// Flash is Click-to-Activate by default on all channels. Disabled for ARM builds. -#if defined(_ARM64_) && defined(XP_WIN) - pref("plugin.state.flash", 0); -#else - pref("plugin.state.flash", 1); -#endif - // Prefer HTML5 video over Flash content, and don't // load plugin instances with no src declared. // These prefs are documented in details on all.js. @@ -1121,7 +1104,7 @@ pref("services.sync.prefs.sync.browser.sessionstore.restore_on_demand", true); pref("services.sync.prefs.sync.browser.startup.homepage", true); pref("services.sync.prefs.sync.browser.startup.page", true); pref("services.sync.prefs.sync.browser.tabs.loadInBackground", true); -pref("services.sync.prefs.sync.browser.tabs.warnOnClose", true); +pref("services.sync.prefs.sync.browser.tabs.warnOnClose", 1); pref("services.sync.prefs.sync.browser.tabs.warnOnOpen", true); pref("services.sync.prefs.sync.browser.taskbar.previews.enable", true); pref("services.sync.prefs.sync.browser.urlbar.matchBuckets", true); @@ -1535,7 +1518,7 @@ pref("dom.ipc.cpows.forbid-unsafe-from-browser", true); // detection). pref("dom.ipc.processHangMonitor", false); -#if defined(NIGHTLY_BUILD) && defined(XP_WIN) +#if defined(XP_WIN) // Allows us to deprioritize the processes of background tabs at an OS level pref("dom.ipc.processPriorityManager.enabled", true); #endif diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index dd049b57c1..3515e8845b 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -1407,13 +1407,14 @@ function _loadURI(browser, uri, params = {}) { } let { - flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE, triggeringPrincipal, referrerInfo, postData, userContextId, csp, } = params || {}; + let loadFlags = params.loadFlags || params.flags || + Ci.nsIWebNavigation.LOAD_FLAGS_NONE; if (!triggeringPrincipal) { throw new Error("Must load with a triggering Principal"); @@ -1429,7 +1430,7 @@ function _loadURI(browser, uri, params = {}) { uri, gMultiProcessBrowser, gFissionBrowser, - flags + loadFlags ); if (uriObject && handleUriInChrome(browser, uriObject)) { // If we've handled the URI in Chrome then just return here. @@ -1448,7 +1449,7 @@ function _loadURI(browser, uri, params = {}) { let loadURIOptions = { triggeringPrincipal, csp, - loadFlags: flags, + loadFlags, referrerInfo, postData, }; @@ -1479,7 +1480,7 @@ function _loadURI(browser, uri, params = {}) { triggeringPrincipal: triggeringPrincipal ? E10SUtils.serializePrincipal(triggeringPrincipal) : null, - flags, + flags: loadFlags, referrerInfo: E10SUtils.serializeReferrerInfo(referrerInfo), remoteType: requiredRemoteType, postData, diff --git a/browser/base/content/moz.build b/browser/base/content/moz.build index e7b50cba30..c48a4327e3 100644 --- a/browser/base/content/moz.build +++ b/browser/base/content/moz.build @@ -51,7 +51,7 @@ with Files("test/performance/browser_appmenu.js"): BUG_COMPONENT = ("Firefox", "Menus") with Files("test/permissions/**"): - BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels") + BUG_COMPONENT = ("Firefox", "Site Permissions") with Files("test/plugins/**"): BUG_COMPONENT = ("Core", "Plug-ins") @@ -60,16 +60,16 @@ with Files("test/popupNotifications/**"): BUG_COMPONENT = ("Toolkit", "Notifications and Alerts") with Files("test/popups/**"): - BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels") + BUG_COMPONENT = ("Firefox", "Site Permissions") with Files("test/referrer/**"): - BUG_COMPONENT = ("Core", "Document Navigation") + BUG_COMPONENT = ("Core", "DOM: Navigation") with Files("test/sanitize/**"): BUG_COMPONENT = ("Toolkit", "Data Sanitization") with Files("test/siteIdentity/**"): - BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels") + BUG_COMPONENT = ("Firefox", "Site Identity") with Files("test/sidebar/**"): BUG_COMPONENT = ("Firefox", "General") @@ -96,7 +96,7 @@ with Files("test/touch/**"): BUG_COMPONENT = ("Firefox", "General") with Files("test/trackingUI/**"): - BUG_COMPONENT = ("Firefox", "Tracking Protection") + BUG_COMPONENT = ("Firefox", "Protections UI") with Files("test/webextensions/**"): BUG_COMPONENT = ("WebExtensions", "Untriaged") @@ -150,7 +150,7 @@ with Files("contentSearch*"): BUG_COMPONENT = ("Firefox", "Search") with Files("hiddenWindow.xul"): - BUG_COMPONENT = ("Firefox", "Device Permissions") + BUG_COMPONENT = ("Firefox", "Site Permissions") with Files("macWindow.inc.xul"): BUG_COMPONENT = ("Firefox", "Shell Integration") @@ -165,4 +165,4 @@ with Files("webext-panels*"): BUG_COMPONENT = ("WebExtensions", "Frontend") with Files("webrtcIndicator*"): - BUG_COMPONENT = ("Firefox", "Device Permissions") + BUG_COMPONENT = ("Firefox", "Site Permissions") diff --git a/browser/base/content/tabbrowser.js b/browser/base/content/tabbrowser.js index 32c057a158..5c81baf8c7 100644 --- a/browser/base/content/tabbrowser.js +++ b/browser/base/content/tabbrowser.js @@ -2938,11 +2938,12 @@ }, warnAboutClosingTabs(tabsToClose, aCloseTabs) { - const pref = - aCloseTabs == this.closingTabsEnum.ALL - ? "browser.tabs.warnOnClose" - : "browser.tabs.warnOnCloseOtherTabs"; - var shouldPrompt = Services.prefs.getBoolPref(pref); + var shouldPrompt; + if (aCloseTabs == this.closingTabsEnum.ALL) { + shouldPrompt = Services.prefs.getIntPref("browser.tabs.warnOnClose") <= tabsToClose; + } else { + shouldPrompt = Services.prefs.getBoolPref("browser.tabs.warnOnCloseOtherTabs"); + } if (!shouldPrompt) { return true; } diff --git a/browser/base/content/test/menubar/browser.ini b/browser/base/content/test/menubar/browser.ini index 5a9e69e25c..0b904f9802 100644 --- a/browser/base/content/test/menubar/browser.ini +++ b/browser/base/content/test/menubar/browser.ini @@ -1,3 +1,5 @@ [DEFAULT] [browser_file_menu_import_wizard.js] +[browser_window_menu_list.js] +skip-if = os != "mac" # Mac only feature diff --git a/browser/base/content/test/menubar/browser_window_menu_list.js b/browser/base/content/test/menubar/browser_window_menu_list.js new file mode 100644 index 0000000000..0e4e64d30f --- /dev/null +++ b/browser/base/content/test/menubar/browser_window_menu_list.js @@ -0,0 +1,45 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_window_menu_list() { + // This title is different depending on the build. For example, it's "Nightly" + // for a local build, "Mozilla Firefox" for an official release build. + const windowTitle = window.document.title; + await checkWindowMenu([windowTitle, "Browser chrome tests"]); + let newWindow = await BrowserTestUtils.openNewBrowserWindow(); + await checkWindowMenu([windowTitle, "Browser chrome tests", windowTitle]); + await BrowserTestUtils.closeWindow(newWindow); +}); + +async function checkWindowMenu(labels) { + let menu = document.querySelector("#windowMenu"); + // We can't toggle menubar items on OSX, so mocking instead. + await new Promise(resolve => { + menu.addEventListener("popupshown", resolve, { once: true }); + menu.dispatchEvent(new MouseEvent("popupshowing")); + menu.dispatchEvent(new MouseEvent("popupshown")); + }); + + let menuitems = [...menu.querySelectorAll("menuseparator ~ menuitem")]; + is(menuitems.length, labels.length, "Correct number of windows in the menu"); + is( + menuitems.map(item => item.label).join(","), + labels.join(","), + "Correct labels on menuitems" + ); + for (let menuitem of menuitems) { + ok( + menuitem instanceof customElements.get("menuitem"), + "sibling is menuitem" + ); + } + + // We can't toggle menubar items on OSX, so mocking instead. + await new Promise(resolve => { + menu.addEventListener("popuphidden", resolve, { once: true }); + menu.dispatchEvent(new MouseEvent("popuphiding")); + menu.dispatchEvent(new MouseEvent("popuphidden")); + }); +} diff --git a/browser/base/content/test/plugins/browser.ini b/browser/base/content/test/plugins/browser.ini index 8b0be6d6fc..df4ccf53dd 100644 --- a/browser/base/content/test/plugins/browser.ini +++ b/browser/base/content/test/plugins/browser.ini @@ -95,8 +95,8 @@ tags = blocklist [browser_globalplugin_crashinfobar.js] skip-if = !crashreporter [browser_pluginCrashCommentAndURL.js] -skip-if = !crashreporter || (processor == 'aarch64' && os == 'win') # aarch64 due to 1538785 +skip-if = !crashreporter [browser_pluginCrashReportNonDeterminism.js] -skip-if = !crashreporter || (processor == 'aarch64' && os == 'win') # aarch64 due to 1538785 +skip-if = !crashreporter [browser_private_clicktoplay.js] [browser_subframe_access_hidden_plugins.js] diff --git a/browser/base/content/test/sanitize/head.js b/browser/base/content/test/sanitize/head.js index 33e243b168..1957fc4c8b 100644 --- a/browser/base/content/test/sanitize/head.js +++ b/browser/base/content/test/sanitize/head.js @@ -49,7 +49,7 @@ function createHostCookie(host, originAttributes) { false, Date.now() + 24000 * 60 * 60, originAttributes, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); } @@ -64,7 +64,7 @@ function createDomainCookie(host, originAttributes) { false, Date.now() + 24000 * 60 * 60, originAttributes, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); } diff --git a/browser/base/jar.mn b/browser/base/jar.mn index d348e68cf3..82ad17648e 100644 --- a/browser/base/jar.mn +++ b/browser/base/jar.mn @@ -25,10 +25,10 @@ browser.jar: content/browser/aboutTabCrashed.xhtml (content/aboutTabCrashed.xhtml) * content/browser/browser.css (content/browser.css) content/browser/browser.js (content/browser.js) -#ifdef MOZ_BROWSER_XHTML -* content/browser/browser.xhtml (content/browser.xhtml) -#else +#ifdef MOZ_BROWSER_XUL * content/browser/browser.xul (content/browser.xul) +#else +* content/browser/browser.xhtml (content/browser.xhtml) #endif content/browser/browser-addons.js (content/browser-addons.js) content/browser/browser-allTabsMenu.js (content/browser-allTabsMenu.js) diff --git a/browser/base/moz.build b/browser/base/moz.build index c9be2976f5..513e703e74 100644 --- a/browser/base/moz.build +++ b/browser/base/moz.build @@ -57,8 +57,8 @@ BROWSER_CHROME_MANIFESTS += [ DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION'] DEFINES['MOZ_APP_VERSION_DISPLAY'] = CONFIG['MOZ_APP_VERSION_DISPLAY'] -if CONFIG['MOZ_BROWSER_XHTML']: - DEFINES['MOZ_BROWSER_XHTML'] = CONFIG['MOZ_BROWSER_XHTML'] +if CONFIG['MOZ_BROWSER_XUL']: + DEFINES['MOZ_BROWSER_XUL'] = CONFIG['MOZ_BROWSER_XUL'] DEFINES['APP_LICENSE_BLOCK'] = '%s/content/overrides/app-license.html' % SRCDIR diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm index 4adf182d09..270202f2a0 100644 --- a/browser/components/BrowserGlue.jsm +++ b/browser/components/BrowserGlue.jsm @@ -426,12 +426,10 @@ XPCOMUtils.defineLazyModuleGetters(this, { Corroborate: "resource://gre/modules/Corroborate.jsm", DateTimePickerParent: "resource://gre/modules/DateTimePickerParent.jsm", ExtensionsUI: "resource:///modules/ExtensionsUI.jsm", - FileSource: "resource://gre/modules/L10nRegistry.jsm", FxAccounts: "resource://gre/modules/FxAccounts.jsm", HomePage: "resource:///modules/HomePage.jsm", HybridContentTelemetry: "resource://gre/modules/HybridContentTelemetry.jsm", Integration: "resource://gre/modules/Integration.jsm", - L10nRegistry: "resource://gre/modules/L10nRegistry.jsm", LiveBookmarkMigrator: "resource:///modules/LiveBookmarkMigrator.jsm", NewTabUtils: "resource://gre/modules/NewTabUtils.jsm", ObjectUtils: "resource://gre/modules/ObjectUtils.jsm", @@ -1046,22 +1044,6 @@ BrowserGlue.prototype = { PdfJs.earlyInit(); } - // Initialize the default l10n resource sources for L10nRegistry. - let locales = Services.locale.packagedLocales; - const greSource = new FileSource( - "toolkit", - locales, - "resource://gre/localization/{locale}/" - ); - L10nRegistry.registerSource(greSource); - - const appSource = new FileSource( - "app", - locales, - "resource://app/localization/{locale}/" - ); - L10nRegistry.registerSource(appSource); - // check if we're in safe mode if (Services.appinfo.inSafeMode) { Services.ww.openWindow( @@ -2009,7 +1991,7 @@ BrowserGlue.prototype = { return; } // Otherwise, we check browser.tabs.warnOnClose - } else if (!Services.prefs.getBoolPref("browser.tabs.warnOnClose")) { + } else if (Services.prefs.getIntPref("browser.tabs.warnOnClose") >= pagecount) { return; } @@ -2563,11 +2545,22 @@ BrowserGlue.prototype = { } }, + _migrateXULStoreForDocument(fromURL, toURL) { + Array.from(Services.xulStore.getIDsEnumerator(fromURL)).forEach((id) => { + Array.from(Services.xulStore.getAttributeEnumerator(fromURL, id)).forEach( + attr => { + let value = Services.xulStore.getValue(fromURL, id, attr); + Services.xulStore.setValue(toURL, id, attr, value); + } + ); + }); + }, + // eslint-disable-next-line complexity _migrateUI: function BG__migrateUI() { // Use an increasing number to keep track of the current migration state. // Completely unrelated to the current Firefox release number. - const UI_VERSION = 81; + const UI_VERSION = 82; const BROWSER_DOCURL = AppConstants.BROWSER_CHROME_URL; let currentUIVersion; @@ -2912,6 +2905,11 @@ BrowserGlue.prototype = { } } + if (currentUIVersion < 82) { + this._migrateXULStoreForDocument("chrome://browser/content/browser.xul", + "chrome://browser/content/browser.xhtml"); + } + // Update the migration version. Services.prefs.setIntPref("browser.migration.version", UI_VERSION); }, diff --git a/browser/components/enterprisepolicies/tests/browser/browser.ini b/browser/components/enterprisepolicies/tests/browser/browser.ini index 0d21a06576..e4593133ed 100644 --- a/browser/components/enterprisepolicies/tests/browser/browser.ini +++ b/browser/components/enterprisepolicies/tests/browser/browser.ini @@ -24,7 +24,8 @@ skip-if = os != 'mac' [browser_policy_cookie_settings.js] [browser_policy_disable_feedback_commands.js] [browser_policy_disable_flash_plugin.js] -skip-if = (processor == 'aarch64' && os == 'win') # aarch64 due to 1538785 +skip-if = (processor == 'aarch64' && os == 'win') +reason = Plugins are not supported on Windows/AArch64 [browser_policy_disable_fxaccounts.js] skip-if = (verify && debug && (os == 'mac')) [browser_policy_disable_masterpassword.js] diff --git a/browser/components/enterprisepolicies/tests/xpcshell/test_clear_blocked_cookies.js b/browser/components/enterprisepolicies/tests/xpcshell/test_clear_blocked_cookies.js index dea9c60433..a4622cbf58 100644 --- a/browser/components/enterprisepolicies/tests/xpcshell/test_clear_blocked_cookies.js +++ b/browser/components/enterprisepolicies/tests/xpcshell/test_clear_blocked_cookies.js @@ -17,7 +17,7 @@ add_task(async function setup() { false, expiry, {}, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); Services.cookies.add( HOSTNAME_DOMAIN, @@ -29,7 +29,7 @@ add_task(async function setup() { false, expiry, {}, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); Services.cookies.add( ORIGIN_DOMAIN, @@ -41,7 +41,7 @@ add_task(async function setup() { false, expiry, {}, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); Services.cookies.add( ORIGIN_DOMAIN, @@ -53,7 +53,7 @@ add_task(async function setup() { false, expiry, {}, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); Services.cookies.add( "example.net", @@ -65,7 +65,7 @@ add_task(async function setup() { false, expiry, {}, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); await setupPolicyEngineWithJson({ policies: { diff --git a/browser/components/extensions/test/browser/browser-common.ini b/browser/components/extensions/test/browser/browser-common.ini index 3743e9e74d..013969259a 100644 --- a/browser/components/extensions/test/browser/browser-common.ini +++ b/browser/components/extensions/test/browser/browser-common.ini @@ -159,7 +159,7 @@ disabled = bug 1438663 [browser_ext_popup_sendMessage.js] [browser_ext_popup_shutdown.js] [browser_ext_port_disconnect_on_crash.js] -skip-if = !e10s || !crashreporter || (processor == 'aarch64' && os == 'win') # the tab's process is killed during the test. Without e10s the parent process would die too, aarch64 due to 1538785 +skip-if = !e10s || !crashreporter # the tab's process is killed during the test. Without e10s the parent process would die too [browser_ext_port_disconnect_on_window_close.js] [browser_ext_runtime_openOptionsPage.js] [browser_ext_runtime_openOptionsPage_uninstall.js] diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_insertCSS.js b/browser/components/extensions/test/browser/browser_ext_tabs_insertCSS.js index a7a7bdf416..d629c5a928 100644 --- a/browser/components/extensions/test/browser/browser_ext_tabs_insertCSS.js +++ b/browser/components/extensions/test/browser/browser_ext_tabs_insertCSS.js @@ -1,5 +1,11 @@ "use strict"; +const { AddonTestUtils } = ChromeUtils.import( + "resource://testing-common/AddonTestUtils.jsm" +); + +AddonTestUtils.initMochitest(this); + add_task(async function testExecuteScript() { let { MessageChannel } = ChromeUtils.import( "resource://gre/modules/MessageChannel.jsm" @@ -223,3 +229,90 @@ add_task(async function testInsertCSS_cleanup() { BrowserTestUtils.removeTab(tab); }); + +// Verify that no removeSheet/removeSheetUsingURIString errors are logged while +// cleaning up css injected using a manifest content script or tabs.insertCSS. +add_task(async function test_csscode_cleanup_on_closed_windows() { + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["http://example.com/*"], + content_scripts: [ + { + matches: ["http://example.com/*"], + css: ["content.css"], + run_at: "document_start", + }, + ], + }, + + files: { + "content.css": "body { min-width: 15px; }", + }, + + async background() { + browser.runtime.onConnect.addListener(port => { + port.onDisconnect.addListener(() => { + browser.test.sendMessage("port-disconnected"); + }); + browser.test.sendMessage("port-connected"); + }); + + await browser.tabs.create({ + url: "http://example.com/", + active: true, + }); + + await browser.tabs.insertCSS({ + code: "body { max-width: 50px; }", + }); + + // Create a port, as a way to detect when the content script has been + // destroyed and any removeSheet error already collected (if it has been + // raised during the content scripts cleanup). + await browser.tabs.executeScript({ + code: `(${function() { + const { maxWidth, minWidth } = window.getComputedStyle(document.body); + browser.test.sendMessage("body-styles", { maxWidth, minWidth }); + browser.runtime.connect(); + }})();`, + }); + }, + }); + + await extension.startup(); + + let { messages } = await AddonTestUtils.promiseConsoleOutput(async () => { + info("Waiting for content scripts to be injected"); + + const { maxWidth, minWidth } = await extension.awaitMessage("body-styles"); + is(maxWidth, "50px", "tabs.insertCSS applied"); + is(minWidth, "15px", "manifest.content_scripts CSS applied"); + + await extension.awaitMessage("port-connected"); + const tab = gBrowser.selectedTab; + + info("Close tab and wait for content script port to be disconnected"); + BrowserTestUtils.removeTab(tab); + await extension.awaitMessage("port-disconnected"); + }); + + // Look for nsIDOMWindowUtils.removeSheet and + // nsIDOMWindowUtils.removeSheetUsingURIString errors. + messages = messages.filter( + m => + m.errorMessage && + m.errorMessage.includes( + "(NS_ERROR_FAILURE) [nsIDOMWindowUtils.removeSheet" + ) + ); + + AddonTestUtils.checkMessages( + messages, + { + forbidden: [/nsIDOMWindowUtils.removeSheet/], + }, + "Expect no remoteSheet errors" + ); + + await extension.unload(); +}); diff --git a/browser/components/extensions/test/xpcshell/test_ext_browsingData_cookies_cache.js b/browser/components/extensions/test/xpcshell/test_ext_browsingData_cookies_cache.js index 1cc6f61e5b..dd43f771b9 100644 --- a/browser/components/extensions/test/xpcshell/test_ext_browsingData_cookies_cache.js +++ b/browser/components/extensions/test/xpcshell/test_ext_browsingData_cookies_cache.js @@ -35,7 +35,7 @@ function addCookie(cookie) { false, Date.now() / 1000 + 10000, {}, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); ok( Services.cookies.cookieExists(cookie.host, cookie.path, cookie.name, {}), diff --git a/browser/components/migration/ChromeProfileMigrator.jsm b/browser/components/migration/ChromeProfileMigrator.jsm index 85592d9761..2f5c406161 100644 --- a/browser/components/migration/ChromeProfileMigrator.jsm +++ b/browser/components/migration/ChromeProfileMigrator.jsm @@ -390,7 +390,7 @@ async function GetCookiesResource(aProfileFolder) { false, parseInt(expiresUtc), {}, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); } catch (e) { Cu.reportError(e); diff --git a/browser/components/migration/MSMigrationUtils.jsm b/browser/components/migration/MSMigrationUtils.jsm index 7444a5af8b..ea1e4d479c 100644 --- a/browser/components/migration/MSMigrationUtils.jsm +++ b/browser/components/migration/MSMigrationUtils.jsm @@ -727,7 +727,7 @@ Cookies.prototype = { false, // session expireTime, {}, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); } }, diff --git a/browser/components/migration/tests/marionette/test_refresh_firefox.py b/browser/components/migration/tests/marionette/test_refresh_firefox.py index acb8fdefcb..89d9de30df 100644 --- a/browser/components/migration/tests/marionette/test_refresh_firefox.py +++ b/browser/components/migration/tests/marionette/test_refresh_firefox.py @@ -142,7 +142,7 @@ class TestFirefoxRefresh(MarionetteTestCase): // Expire in 15 minutes: let expireTime = Math.floor(Date.now() / 1000) + 15 * 60; Services.cookies.add(arguments[0], arguments[1], arguments[2], arguments[3], - true, false, false, expireTime, {}, Ci.nsICookie.SAMESITE_UNSET); + true, false, false, expireTime, {}, Ci.nsICookie.SAMESITE_NONE); """, script_args=(self._cookieHost, self._cookiePath, self._cookieName, self._cookieValue)) def createSession(self): diff --git a/browser/components/moz.build b/browser/components/moz.build index 2cf1f56357..a3227b4d32 100644 --- a/browser/components/moz.build +++ b/browser/components/moz.build @@ -15,7 +15,7 @@ with Files("tests/browser/browser_bug538331.js"): BUG_COMPONENT = ("Toolkit", "Application Update") with Files("tests/browser/browser_contentpermissionprompt.js"): - BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels") + BUG_COMPONENT = ("Firefox", "Site Permissions") with Files("tests/unit/test_distribution.js"): BUG_COMPONENT = ("Firefox", "Distributions") diff --git a/browser/components/preferences/in-content/main.js b/browser/components/preferences/in-content/main.js index 5afa4fc111..33455161dd 100644 --- a/browser/components/preferences/in-content/main.js +++ b/browser/components/preferences/in-content/main.js @@ -117,8 +117,8 @@ Preferences.addAll([ - true if display should switch to a new tab which has been opened from a link, false if display shouldn't switch browser.tabs.warnOnClose - - true if when closing a window with multiple tabs the user is warned and - allowed to cancel the action, false to just close the window + - >0 if when closing a window with multiple tabs the user is warned and + allowed to cancel the action, 0 to just close the window browser.tabs.warnOnOpen - true if the user should be warned if he attempts to open a lot of tabs at once (e.g. a large folder of bookmarks), false otherwise @@ -128,7 +128,7 @@ Preferences.addAll([ { id: "browser.link.open_newwindow", type: "int" }, { id: "browser.tabs.loadInBackground", type: "bool", inverted: true }, - { id: "browser.tabs.warnOnClose", type: "bool" }, + { id: "browser.tabs.warnOnClose", type: "int" }, { id: "browser.tabs.warnOnOpen", type: "bool" }, { id: "browser.sessionstore.restore_on_demand", type: "bool" }, { id: "browser.ctrlTab.recentlyUsedOrder", type: "bool" }, @@ -1038,8 +1038,8 @@ var gMainPane = { * browser.tabs.loadInBackground - bool * True - Whether browser should switch to a new tab opened from a link. * browser.tabs.warnOnClose - bool - * True - If when closing a window with multiple tabs the user is warned and - * allowed to cancel the action, false to just close the window. + * >0 - If when closing a window with multiple tabs the user is warned and + * allowed to cancel the action, 0 to just close the window. * browser.tabs.warnOnOpen - bool * True - Whether the user should be warned when trying to open a lot of * tabs at once (e.g. a large folder of bookmarks), allowing to diff --git a/browser/components/preferences/in-content/tests/siteData/browser_siteData.js b/browser/components/preferences/in-content/tests/siteData/browser_siteData.js index fa60b371ef..2bff34f18d 100644 --- a/browser/components/preferences/in-content/tests/siteData/browser_siteData.js +++ b/browser/components/preferences/in-content/tests/siteData/browser_siteData.js @@ -218,7 +218,7 @@ add_task(async function() { false, Date.now() + 1000 * 60 * 60, {}, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); Services.cookies.add( uri.host, @@ -230,7 +230,7 @@ add_task(async function() { false, Date.now() + 1000 * 60 * 60, {}, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); Services.cookies.add( uri2.host, @@ -242,7 +242,7 @@ add_task(async function() { false, Date.now() + 1000 * 60 * 60, {}, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); // Ensure that private browsing cookies are ignored. @@ -256,7 +256,7 @@ add_task(async function() { false, Date.now() + 1000 * 60 * 60, { privateBrowsingId: 1 }, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); // Get the exact creation date from the cookies (to avoid intermittents diff --git a/browser/components/sessionstore/ContentRestore.jsm b/browser/components/sessionstore/ContentRestore.jsm index a3b0eda77f..e179edb44c 100644 --- a/browser/components/sessionstore/ContentRestore.jsm +++ b/browser/components/sessionstore/ContentRestore.jsm @@ -423,10 +423,10 @@ HistoryListener.prototype = { // new URL that was passed to loadURI(). The new load will cause a // STATE_START notification to be sent and the ProgressListener will then // notify the parent and do the rest. - let flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP; + let loadFlags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP; let loadURIOptions = { triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), - loadFlags: flags, + loadFlags, }; this.webNavigation.loadURI(newURI.spec, loadURIOptions); }, diff --git a/browser/components/sessionstore/SessionCookies.jsm b/browser/components/sessionstore/SessionCookies.jsm index 0ee466561b..c80e17fb15 100644 --- a/browser/components/sessionstore/SessionCookies.jsm +++ b/browser/components/sessionstore/SessionCookies.jsm @@ -79,7 +79,7 @@ var SessionCookiesInternal = { /* isSession = */ true, expiry, cookie.originAttributes || {}, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); } catch (ex) { Cu.reportError( diff --git a/browser/components/sessionstore/test/browser_cookies_privacy.js b/browser/components/sessionstore/test/browser_cookies_privacy.js index 3688aba4c6..d49032de22 100644 --- a/browser/components/sessionstore/test/browser_cookies_privacy.js +++ b/browser/components/sessionstore/test/browser_cookies_privacy.js @@ -15,7 +15,7 @@ function addCookie(scheme, secure = false) { /* isSession = */ true, MAX_EXPIRY, /* originAttributes = */ {}, - Ci.nsICookie.SAMESITE_UNSET + Ci.nsICookie.SAMESITE_NONE ); return cookie; } diff --git a/browser/components/shell/nsWindowsShellService.cpp b/browser/components/shell/nsWindowsShellService.cpp index ac7fbef329..af87953918 100644 --- a/browser/components/shell/nsWindowsShellService.cpp +++ b/browser/components/shell/nsWindowsShellService.cpp @@ -13,6 +13,7 @@ #include "nsIContent.h" #include "nsIImageLoadingContent.h" #include "nsIOutputStream.h" +#include "nsIPrefService.h" #include "nsIStringBundle.h" #include "nsNetUtil.h" #include "nsServiceManagerUtils.h" @@ -27,6 +28,7 @@ #include "nsXULAppAPI.h" #include "mozilla/WindowsVersion.h" #include "mozilla/dom/Element.h" +#include "mozilla/gfx/2D.h" #include "windows.h" #include "shellapi.h" diff --git a/browser/config/mozconfigs/linux32/beta b/browser/config/mozconfigs/linux32/beta index 043e23e9d6..c8aedd4f81 100644 --- a/browser/config/mozconfigs/linux32/beta +++ b/browser/config/mozconfigs/linux32/beta @@ -1,5 +1,3 @@ -export MOZ_PGO=1 - . "$topsrcdir/browser/config/mozconfigs/linux32/common-opt" ac_add_options --enable-official-branding diff --git a/browser/config/mozconfigs/linux32/debug b/browser/config/mozconfigs/linux32/debug index 0ea9942b5d..4a6bbf0b25 100644 --- a/browser/config/mozconfigs/linux32/debug +++ b/browser/config/mozconfigs/linux32/debug @@ -14,6 +14,9 @@ export MOZILLA_OFFICIAL=1 # Package js shell. export MOZ_PACKAGE_JSSHELL=1 +# Keep basic GDB symbols around in debug builds +ac_add_options STRIP_FLAGS=--strip-debug + ac_add_options --with-branding=browser/branding/nightly . "$topsrcdir/build/mozconfig.common.override" diff --git a/browser/config/mozconfigs/linux32/devedition b/browser/config/mozconfigs/linux32/devedition index 51db666f5e..e21f6a0a6f 100644 --- a/browser/config/mozconfigs/linux32/devedition +++ b/browser/config/mozconfigs/linux32/devedition @@ -1,5 +1,3 @@ -export MOZ_PGO=1 - . "$topsrcdir/browser/config/mozconfigs/linux32/common-opt" ac_add_options --with-branding=browser/branding/aurora diff --git a/browser/config/mozconfigs/linux32/nightly b/browser/config/mozconfigs/linux32/nightly index 686266944d..5c1a542260 100644 --- a/browser/config/mozconfigs/linux32/nightly +++ b/browser/config/mozconfigs/linux32/nightly @@ -2,4 +2,10 @@ ac_add_options --with-branding=browser/branding/nightly +# STRIP_FLAGS is only valid for builds that strip; valgrind builds disable stripping +if [ -z "$USE_VALGRIND" ]; then + # Keep basic GDB symbols around in Nightly builds + ac_add_options STRIP_FLAGS=--strip-debug +fi + . "$topsrcdir/build/mozconfig.common.override" diff --git a/browser/config/mozconfigs/linux32/profile-generate b/browser/config/mozconfigs/linux32/profile-generate index bf16ac1f99..9fb7a51970 100644 --- a/browser/config/mozconfigs/linux32/profile-generate +++ b/browser/config/mozconfigs/linux32/profile-generate @@ -1,6 +1,5 @@ . $topsrcdir/browser/config/mozconfigs/linux32/nightly -mk_add_options "export MOZ_AUTOMATION_BUILD_SYMBOLS=0" mk_add_options "export MOZ_AUTOMATION_PACKAGE_TESTS=0" mk_add_options "export MOZ_AUTOMATION_PACKAGE_GENERATED_SOURCES=0" mk_add_options "export MOZ_AUTOMATION_L10N_CHECK=0" diff --git a/browser/config/mozconfigs/linux32/release b/browser/config/mozconfigs/linux32/release index dc3a46d8df..d7ad589810 100644 --- a/browser/config/mozconfigs/linux32/release +++ b/browser/config/mozconfigs/linux32/release @@ -1,8 +1,6 @@ # This make file should be identical to the beta mozconfig, apart from the # safeguard below -export MOZ_PGO=1 - . "$topsrcdir/browser/config/mozconfigs/linux32/common-opt" ac_add_options --enable-official-branding diff --git a/browser/config/mozconfigs/linux32/valgrind b/browser/config/mozconfigs/linux32/valgrind index d335038dea..1b6e1c2225 100644 --- a/browser/config/mozconfigs/linux32/valgrind +++ b/browser/config/mozconfigs/linux32/valgrind @@ -1,3 +1,5 @@ +USE_VALGRIND=1 + . $topsrcdir/browser/config/mozconfigs/linux32/nightly ac_add_options --enable-valgrind diff --git a/browser/config/mozconfigs/linux64/beta b/browser/config/mozconfigs/linux64/beta index c136f06c54..37723c43d4 100644 --- a/browser/config/mozconfigs/linux64/beta +++ b/browser/config/mozconfigs/linux64/beta @@ -1,5 +1,3 @@ -. "$topsrcdir/build/mozconfig.pgo" - . "$topsrcdir/browser/config/mozconfigs/linux64/common-opt" ac_add_options --enable-official-branding diff --git a/browser/config/mozconfigs/linux64/code-coverage b/browser/config/mozconfigs/linux64/code-coverage index b32a5d692e..78c9421d72 100644 --- a/browser/config/mozconfigs/linux64/code-coverage +++ b/browser/config/mozconfigs/linux64/code-coverage @@ -12,6 +12,6 @@ ac_add_options --disable-profiling ac_add_options --disable-warnings-as-errors ac_add_options --enable-coverage -export LDFLAGS="--coverage -L$topsrcdir/clang/lib/clang/8.0.0/lib/linux/" +export LDFLAGS="--coverage -L$MOZ_FETCHES_DIR/clang/lib/clang/8.0.0/lib/linux/" export LIBS="-lclang_rt.profile-x86_64" export RUSTFLAGS="-Ccodegen-units=1 -Zprofile -Zno-landing-pads -Clink-dead-code -Coverflow-checks=off" diff --git a/browser/config/mozconfigs/linux64/debug b/browser/config/mozconfigs/linux64/debug index 8a4b70b489..5f6f2441a1 100644 --- a/browser/config/mozconfigs/linux64/debug +++ b/browser/config/mozconfigs/linux64/debug @@ -14,4 +14,7 @@ export MOZ_PACKAGE_JSSHELL=1 ac_add_options --with-branding=browser/branding/nightly +# Keep basic GDB symbols around in debug builds +ac_add_options STRIP_FLAGS=--strip-debug + . "$topsrcdir/build/mozconfig.common.override" diff --git a/browser/config/mozconfigs/linux64/debug-searchfox-clang b/browser/config/mozconfigs/linux64/debug-searchfox-clang index f7e50e785b..032e0912c0 100644 --- a/browser/config/mozconfigs/linux64/debug-searchfox-clang +++ b/browser/config/mozconfigs/linux64/debug-searchfox-clang @@ -1,6 +1,7 @@ MOZ_AUTOMATION_BUILD_SYMBOLS=0 MOZ_AUTOMATION_PACKAGE_TESTS=0 MOZ_AUTOMATION_L10N_CHECK=0 +MOZ_AUTOMATION_CHECK=0 . "$topsrcdir/build/unix/mozconfig.unix" @@ -9,8 +10,8 @@ ac_add_options --enable-debug . $topsrcdir/build/mozconfig.stylo # Use Clang as specified in manifest -export CC="$topsrcdir/clang/bin/clang" -export CXX="$topsrcdir/clang/bin/clang++" +export CC="$MOZ_FETCHES_DIR/clang/bin/clang" +export CXX="$MOZ_FETCHES_DIR/clang/bin/clang++" # Save rust analysis (this requires unlocking the unstable features, # which is done in the taskcluster task definition via RUSTC_BOOTSTRAP) diff --git a/browser/config/mozconfigs/linux64/debug-static-analysis-clang b/browser/config/mozconfigs/linux64/debug-static-analysis-clang index 0dba5a939c..2b4a162dcb 100644 --- a/browser/config/mozconfigs/linux64/debug-static-analysis-clang +++ b/browser/config/mozconfigs/linux64/debug-static-analysis-clang @@ -9,8 +9,8 @@ ac_add_options --enable-debug . $topsrcdir/build/mozconfig.stylo # Use Clang as specified in manifest -export CC="$topsrcdir/clang/bin/clang" -export CXX="$topsrcdir/clang/bin/clang++" +export CC="$MOZ_FETCHES_DIR/clang/bin/clang" +export CXX="$MOZ_FETCHES_DIR/clang/bin/clang++" # Add the static checker ac_add_options --enable-clang-plugin diff --git a/browser/config/mozconfigs/linux64/devedition b/browser/config/mozconfigs/linux64/devedition index d0839205e2..63995ced77 100644 --- a/browser/config/mozconfigs/linux64/devedition +++ b/browser/config/mozconfigs/linux64/devedition @@ -1,5 +1,3 @@ -export MOZ_PGO=1 - . "$topsrcdir/browser/config/mozconfigs/linux64/common-opt" ac_add_options --with-branding=browser/branding/aurora diff --git a/browser/config/mozconfigs/linux64/nightly b/browser/config/mozconfigs/linux64/nightly index 15090cc01c..fa54d10f4f 100644 --- a/browser/config/mozconfigs/linux64/nightly +++ b/browser/config/mozconfigs/linux64/nightly @@ -2,4 +2,10 @@ ac_add_options --with-branding=browser/branding/nightly +# STRIP_FLAGS is only valid for builds that strip; valgrind builds disable stripping +if [ -z "$USE_VALGRIND" ]; then + # Keep basic GDB symbols around in Nightly builds + ac_add_options STRIP_FLAGS=--strip-debug +fi + . "$topsrcdir/build/mozconfig.common.override" diff --git a/browser/config/mozconfigs/linux64/plain-opt b/browser/config/mozconfigs/linux64/plain-opt index 92c10af2fa..a7c5c78f28 100644 --- a/browser/config/mozconfigs/linux64/plain-opt +++ b/browser/config/mozconfigs/linux64/plain-opt @@ -1,14 +1,14 @@ export TOOLTOOL_DIR="$topsrcdir" -export LLVM_CONFIG="${TOOLTOOL_DIR}/clang/bin/llvm-config" +export LLVM_CONFIG="${MOZ_FETCHES_DIR}/clang/bin/llvm-config" -CARGO="${TOOLTOOL_DIR}/rustc/bin/cargo" -RUSTC="${TOOLTOOL_DIR}/rustc/bin/rustc" -RUSTDOC="${TOOLTOOL_DIR}/rustc/bin/rustdoc" -RUSTFMT="${TOOLTOOL_DIR}/rustc/bin/rustfmt" -CBINDGEN="${TOOLTOOL_DIR}/cbindgen/cbindgen" +CARGO="${MOZ_FETCHES_DIR}/rustc/bin/cargo" +RUSTC="${MOZ_FETCHES_DIR}/rustc/bin/rustc" +RUSTDOC="${MOZ_FETCHES_DIR}/rustc/bin/rustdoc" +RUSTFMT="${MOZ_FETCHES_DIR}/rustc/bin/rustfmt" +CBINDGEN="${MOZ_FETCHES_DIR}/cbindgen/cbindgen" -export NODEJS="${TOOLTOOL_DIR}/node/bin/node" -NASM="${TOOLTOOL_DIR}/nasm/nasm" +export NODEJS="${MOZ_FETCHES_DIR}/node/bin/node" +NASM="${MOZ_FETCHES_DIR}/nasm/nasm" -CC="${TOOLTOOL_DIR}/clang/bin/clang" -CXX="${TOOLTOOL_DIR}/clang/bin/clang++" +CC="${MOZ_FETCHES_DIR}/clang/bin/clang" +CXX="${MOZ_FETCHES_DIR}/clang/bin/clang++" diff --git a/browser/config/mozconfigs/linux64/profile-generate b/browser/config/mozconfigs/linux64/profile-generate index eedfd74a5e..5542f8e478 100644 --- a/browser/config/mozconfigs/linux64/profile-generate +++ b/browser/config/mozconfigs/linux64/profile-generate @@ -1,6 +1,5 @@ -. $topsrcdir/browser/config/mozconfigs/linux64/beta +. $topsrcdir/browser/config/mozconfigs/linux64/nightly -mk_add_options "export MOZ_AUTOMATION_BUILD_SYMBOLS=0" mk_add_options "export MOZ_AUTOMATION_PACKAGE_TESTS=0" mk_add_options "export MOZ_AUTOMATION_PACKAGE_GENERATED_SOURCES=0" mk_add_options "export MOZ_AUTOMATION_L10N_CHECK=0" diff --git a/browser/config/mozconfigs/linux64/release b/browser/config/mozconfigs/linux64/release index 5b4328c779..ab09eef653 100644 --- a/browser/config/mozconfigs/linux64/release +++ b/browser/config/mozconfigs/linux64/release @@ -1,8 +1,6 @@ # This make file should be identical to the beta mozconfig, apart from the # safeguard below -. "$topsrcdir/build/mozconfig.pgo" - . "$topsrcdir/browser/config/mozconfigs/linux64/common-opt" ac_add_options --enable-official-branding diff --git a/browser/config/mozconfigs/linux64/tup b/browser/config/mozconfigs/linux64/tup index 9cdbf6844b..2f76b1f7f4 100644 --- a/browser/config/mozconfigs/linux64/tup +++ b/browser/config/mozconfigs/linux64/tup @@ -6,7 +6,7 @@ MOZ_AUTOMATION_UPLOAD=0 MOZ_AUTOMATION_UPLOAD_SYMBOLS=0 TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir} -export TUP=${TOOLTOOL_DIR}/tup/tup +export TUP=${MOZ_FETCHES_DIR}/tup/tup . "$topsrcdir/browser/config/mozconfigs/linux64/common-opt" . "$topsrcdir/build/mozconfig.common.override" diff --git a/browser/config/mozconfigs/linux64/valgrind b/browser/config/mozconfigs/linux64/valgrind index 1ca6b62095..ac9908da95 100644 --- a/browser/config/mozconfigs/linux64/valgrind +++ b/browser/config/mozconfigs/linux64/valgrind @@ -1,3 +1,6 @@ +MOZ_AUTOMATION_CHECK=0 +USE_VALGRIND=1 + . $topsrcdir/browser/config/mozconfigs/linux64/nightly ac_add_options --enable-valgrind diff --git a/browser/config/mozconfigs/macosx64/add-on-devel b/browser/config/mozconfigs/macosx64/add-on-devel index 58739c204e..410c8637ad 100644 --- a/browser/config/mozconfigs/macosx64/add-on-devel +++ b/browser/config/mozconfigs/macosx64/add-on-devel @@ -1,7 +1,5 @@ . $topsrcdir/browser/config/mozconfigs/macosx64/nightly -unset MOZ_LTO - ac_add_options --with-branding=browser/branding/unofficial ac_add_options --enable-update-channel=default diff --git a/browser/config/mozconfigs/macosx64/beta b/browser/config/mozconfigs/macosx64/beta index a4d89d8bf4..232750daa4 100644 --- a/browser/config/mozconfigs/macosx64/beta +++ b/browser/config/mozconfigs/macosx64/beta @@ -2,6 +2,4 @@ ac_add_options --enable-official-branding -export MOZ_LTO=cross - . "$topsrcdir/build/mozconfig.common.override" diff --git a/browser/config/mozconfigs/macosx64/code-coverage b/browser/config/mozconfigs/macosx64/code-coverage index c525272071..62c5336eb6 100644 --- a/browser/config/mozconfigs/macosx64/code-coverage +++ b/browser/config/mozconfigs/macosx64/code-coverage @@ -8,6 +8,6 @@ ac_add_options --disable-sandbox ac_add_options --disable-warnings-as-errors ac_add_options --enable-coverage -export LDFLAGS="-coverage -L$topsrcdir/clang/lib/clang/8.0.0/lib/darwin/" +export LDFLAGS="-coverage -L$MOZ_FETCHES_DIR/clang/lib/clang/8.0.0/lib/darwin/" export LIBS="-lclang_rt.profile_osx" export RUSTFLAGS="-Ccodegen-units=1 -Zprofile -Zno-landing-pads -Clink-dead-code -Coverflow-checks=off" diff --git a/browser/config/mozconfigs/macosx64/debug-searchfox b/browser/config/mozconfigs/macosx64/debug-searchfox index d3207eacc0..0fa9df329d 100644 --- a/browser/config/mozconfigs/macosx64/debug-searchfox +++ b/browser/config/mozconfigs/macosx64/debug-searchfox @@ -1,6 +1,7 @@ MOZ_AUTOMATION_BUILD_SYMBOLS=0 MOZ_AUTOMATION_PACKAGE_TESTS=0 MOZ_AUTOMATION_L10N_CHECK=0 +MOZ_AUTOMATION_CHECK=0 . $topsrcdir/build/macosx/mozconfig.common diff --git a/browser/config/mozconfigs/macosx64/devedition b/browser/config/mozconfigs/macosx64/devedition index bb59121d9a..db700db10d 100644 --- a/browser/config/mozconfigs/macosx64/devedition +++ b/browser/config/mozconfigs/macosx64/devedition @@ -1,9 +1,5 @@ . "$topsrcdir/browser/config/mozconfigs/macosx64/common-opt" -ac_add_options --disable-install-strip - -export MOZ_LTO=cross - ac_add_options --enable-instruments # Cross-compiled builds fail when dtrace is enabled diff --git a/browser/config/mozconfigs/macosx64/l10n-mozconfig-devedition b/browser/config/mozconfigs/macosx64/l10n-mozconfig-devedition index a13d6dee7c..bd64063747 100644 --- a/browser/config/mozconfigs/macosx64/l10n-mozconfig-devedition +++ b/browser/config/mozconfigs/macosx64/l10n-mozconfig-devedition @@ -4,9 +4,9 @@ if test `uname -s` = "Linux"; then # We need to indicate the target for cross builds ac_add_options --target=x86_64-apple-darwin - export MKFSHFS=$topsrcdir/hfsplus-tools/newfs_hfs - export DMG_TOOL=$topsrcdir/dmg/dmg - export HFS_TOOL=$topsrcdir/dmg/hfsplus + export MKFSHFS=$MOZ_FETCHES_DIR/hfsplus-tools/newfs_hfs + export DMG_TOOL=$MOZ_FETCHES_DIR/dmg/dmg + export HFS_TOOL=$MOZ_FETCHES_DIR/dmg/hfsplus fi ac_add_options --with-l10n-base=../../l10n diff --git a/browser/config/mozconfigs/macosx64/nightly b/browser/config/mozconfigs/macosx64/nightly index 0c5b2adbc7..95cd36fe9e 100644 --- a/browser/config/mozconfigs/macosx64/nightly +++ b/browser/config/mozconfigs/macosx64/nightly @@ -1,6 +1,5 @@ . "$topsrcdir/browser/config/mozconfigs/macosx64/common-opt" -ac_add_options --disable-install-strip ac_add_options --enable-instruments # Cross-compiled builds fail when dtrace is enabled @@ -8,8 +7,6 @@ if test `uname -s` != Linux; then ac_add_options --enable-dtrace fi -export MOZ_LTO=cross - ac_add_options --with-branding=browser/branding/nightly . "$topsrcdir/build/mozconfig.common.override" diff --git a/browser/config/mozconfigs/macosx64/release b/browser/config/mozconfigs/macosx64/release index 2439d7131c..840e9afd24 100644 --- a/browser/config/mozconfigs/macosx64/release +++ b/browser/config/mozconfigs/macosx64/release @@ -5,8 +5,6 @@ ac_add_options --enable-official-branding -export MOZ_LTO=cross - # safeguard against someone forgetting to re-set EARLY_BETA_OR_EARLIER in # defines.sh during the beta cycle export BUILDING_RELEASE=1 diff --git a/browser/config/mozconfigs/macosx64/repack b/browser/config/mozconfigs/macosx64/repack index 9974c70bb5..c18e14b895 100644 --- a/browser/config/mozconfigs/macosx64/repack +++ b/browser/config/mozconfigs/macosx64/repack @@ -1,8 +1,8 @@ # This mozconfig is responsible merely for getting the cross tools setup # for repacking a .tar into a .dmg as returned from signing. -export MKFSHFS=$topsrcdir/hfsplus-tools/newfs_hfs -export DMG_TOOL=$topsrcdir/dmg/dmg -export HFS_TOOL=$topsrcdir/dmg/hfsplus -export NODEJS=$topsrcdir/node/bin/node +export MKFSHFS=$MOZ_FETCHES_DIR/hfsplus-tools/newfs_hfs +export DMG_TOOL=$MOZ_FETCHES_DIR/dmg/dmg +export HFS_TOOL=$MOZ_FETCHES_DIR/dmg/hfsplus +export NODEJS=$MOZ_FETCHES_DIR/node/bin/node ac_add_options --disable-compile-environment diff --git a/browser/config/mozconfigs/whitelist b/browser/config/mozconfigs/whitelist index 5e4295ab33..f073b8a45b 100644 --- a/browser/config/mozconfigs/whitelist +++ b/browser/config/mozconfigs/whitelist @@ -13,7 +13,6 @@ for platform in all_platforms: ] whitelist['nightly']['macosx64'] += [ - 'ac_add_options --disable-install-strip', 'ac_add_options --enable-instruments', 'ac_add_options --enable-dtrace', 'if test `uname -s` != Linux; then', @@ -30,16 +29,12 @@ for platform in all_platforms: 'ac_add_options --enable-official-branding', 'export BUILDING_RELEASE=1', ] -whitelist['release']['win32'] += ['export MOZ_PGO=1'] -whitelist['release']['win64'] += ['export MOZ_PGO=1'] whitelist['release']['linux32'] += [ 'export MOZILLA_OFFICIAL=1', - 'export MOZ_PGO=1', ] whitelist['release']['linux64'] += [ 'export MOZILLA_OFFICIAL=1', - '. "$topsrcdir/build/mozconfig.pgo"', ] if __name__ == '__main__': diff --git a/browser/config/mozconfigs/win32/beta b/browser/config/mozconfigs/win32/beta index b7b4dfdd4a..767c514cd6 100644 --- a/browser/config/mozconfigs/win32/beta +++ b/browser/config/mozconfigs/win32/beta @@ -1,5 +1,3 @@ -export MOZ_PGO=1 - . "$topsrcdir/build/mozconfig.win-common" . "$topsrcdir/browser/config/mozconfigs/win32/common-opt" diff --git a/browser/config/mozconfigs/win32/devedition b/browser/config/mozconfigs/win32/devedition index 9cddb0b4d9..62ee0921e6 100644 --- a/browser/config/mozconfigs/win32/devedition +++ b/browser/config/mozconfigs/win32/devedition @@ -1,5 +1,3 @@ -export MOZ_PGO=1 - . "$topsrcdir/build/mozconfig.win-common" . "$topsrcdir/browser/config/mozconfigs/win32/common-opt" diff --git a/browser/config/mozconfigs/win32/mingwclang b/browser/config/mozconfigs/win32/mingwclang index 5ce6fffa09..15e31aeb2d 100644 --- a/browser/config/mozconfigs/win32/mingwclang +++ b/browser/config/mozconfigs/win32/mingwclang @@ -42,24 +42,24 @@ ac_add_options --disable-webrtc # Bug 1393901 ac_add_options --disable-geckodriver # Bug 1489320 # Find our toolchain -HOST_CC="$TOOLTOOL_DIR/clang/bin/clang" -HOST_CXX="$TOOLTOOL_DIR/clang/bin/clang++" -CC="$TOOLTOOL_DIR/clang/bin/i686-w64-mingw32-clang" -CXX="$TOOLTOOL_DIR/clang/bin/i686-w64-mingw32-clang++" +HOST_CC="$MOZ_FETCHES_DIR/clang/bin/clang" +HOST_CXX="$MOZ_FETCHES_DIR/clang/bin/clang++" +CC="$MOZ_FETCHES_DIR/clang/bin/i686-w64-mingw32-clang" +CXX="$MOZ_FETCHES_DIR/clang/bin/i686-w64-mingw32-clang++" ac_add_options --with-clang-path="$CC" -ac_add_options --with-libclang-path="$TOOLTOOL_DIR/clang/lib" +ac_add_options --with-libclang-path="$MOZ_FETCHES_DIR/clang/lib" CXXFLAGS="-fms-extensions" AR=llvm-ar RANLIB=llvm-ranlib # For Stylo -BINDGEN_CFLAGS="-I$TOOLTOOL_DIR/clang/i686-w64-mingw32/include/c++/v1 -I$TOOLTOOL_DIR/clang/i686-w64-mingw32/include" +BINDGEN_CFLAGS="-I$MOZ_FETCHES_DIR/clang/i686-w64-mingw32/include/c++/v1 -I$MOZ_FETCHES_DIR/clang/i686-w64-mingw32/include" # We want to make sure we use binutils and other binaries in the tooltool # package. -mk_add_options "export PATH=$TOOLTOOL_DIR/clang/bin:$TOOLTOOL_DIR/mingw32/bin:$TOOLTOOL_DIR/wine/bin:$TOOLTOOL_DIR/upx/bin:$TOOLTOOL_DIR/fxc2/bin:$PATH" +mk_add_options "export PATH=$MOZ_FETCHES_DIR/clang/bin:$MOZ_FETCHES_DIR/mingw32/bin:$MOZ_FETCHES_DIR/wine/bin:$MOZ_FETCHES_DIR/upx/bin:$MOZ_FETCHES_DIR/fxc2/bin:$PATH" -LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$TOOLTOOL_DIR/mingw32/lib64:$TOOLTOOL_DIR/clang/lib +LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$MOZ_FETCHES_DIR/mingw32/lib64:$MOZ_FETCHES_DIR/clang/lib mk_add_options "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH" # Do not include the visual studio related mozconfigs of course diff --git a/browser/config/mozconfigs/win32/profile-generate b/browser/config/mozconfigs/win32/profile-generate index a02d0b5b8e..1177bb8b31 100644 --- a/browser/config/mozconfigs/win32/profile-generate +++ b/browser/config/mozconfigs/win32/profile-generate @@ -1,6 +1,5 @@ . $topsrcdir/browser/config/mozconfigs/win32/nightly -mk_add_options "export MOZ_AUTOMATION_BUILD_SYMBOLS=0" mk_add_options "export MOZ_AUTOMATION_PACKAGE_TESTS=0" mk_add_options "export MOZ_AUTOMATION_PACKAGE_GENERATED_SOURCES=0" mk_add_options "export MOZ_AUTOMATION_L10N_CHECK=0" diff --git a/browser/config/mozconfigs/win32/release b/browser/config/mozconfigs/win32/release index e692069321..a8fca41487 100644 --- a/browser/config/mozconfigs/win32/release +++ b/browser/config/mozconfigs/win32/release @@ -1,8 +1,6 @@ # This make file should be identical to the beta mozconfig, apart from the # safeguard below -export MOZ_PGO=1 - . "$topsrcdir/build/mozconfig.win-common" . "$topsrcdir/browser/config/mozconfigs/win32/common-opt" diff --git a/browser/config/mozconfigs/win64/beta b/browser/config/mozconfigs/win64/beta index b31df28773..ab3613c373 100644 --- a/browser/config/mozconfigs/win64/beta +++ b/browser/config/mozconfigs/win64/beta @@ -1,5 +1,3 @@ -export MOZ_PGO=1 - . "$topsrcdir/build/mozconfig.win-common" . "$topsrcdir/browser/config/mozconfigs/win64/common-win64" . "$topsrcdir/browser/config/mozconfigs/win64/common-opt" diff --git a/browser/config/mozconfigs/win64/code-coverage b/browser/config/mozconfigs/win64/code-coverage index 9812417bb9..6ec078c555 100644 --- a/browser/config/mozconfigs/win64/code-coverage +++ b/browser/config/mozconfigs/win64/code-coverage @@ -18,8 +18,8 @@ export MOZILLA_OFFICIAL=1 # Package js shell. export MOZ_PACKAGE_JSSHELL=1 -if [ -d "$topsrcdir/clang" ]; then - CLANG_LIB_DIR="$(cd $topsrcdir/clang/lib/clang/* && cd lib/windows && pwd)" +if [ -d "$MOZ_FETCHES_DIR/clang" ]; then + CLANG_LIB_DIR="$(cd $MOZ_FETCHES_DIR/clang/lib/clang/* && cd lib/windows && pwd)" export LIB=$LIB:$CLANG_LIB_DIR export LDFLAGS="clang_rt.profile-x86_64.lib" diff --git a/browser/config/mozconfigs/win64/debug-searchfox b/browser/config/mozconfigs/win64/debug-searchfox index c121359700..2a13adca90 100644 --- a/browser/config/mozconfigs/win64/debug-searchfox +++ b/browser/config/mozconfigs/win64/debug-searchfox @@ -1,6 +1,7 @@ MOZ_AUTOMATION_BUILD_SYMBOLS=0 MOZ_AUTOMATION_PACKAGE_TESTS=0 MOZ_AUTOMATION_L10N_CHECK=0 +MOZ_AUTOMATION_CHECK=0 . "$topsrcdir/build/mozconfig.win-common" . "$topsrcdir/browser/config/mozconfigs/common" diff --git a/browser/config/mozconfigs/win64/devedition b/browser/config/mozconfigs/win64/devedition index 54b3fd90d3..a55a17b45a 100644 --- a/browser/config/mozconfigs/win64/devedition +++ b/browser/config/mozconfigs/win64/devedition @@ -1,5 +1,3 @@ -export MOZ_PGO=1 - . "$topsrcdir/build/mozconfig.win-common" . "$topsrcdir/browser/config/mozconfigs/win64/common-win64" . "$topsrcdir/browser/config/mozconfigs/win64/common-opt" diff --git a/browser/config/mozconfigs/win64/mingwclang b/browser/config/mozconfigs/win64/mingwclang index 18cf2c516d..b8bedc5dfd 100644 --- a/browser/config/mozconfigs/win64/mingwclang +++ b/browser/config/mozconfigs/win64/mingwclang @@ -41,24 +41,24 @@ ac_add_options --disable-webrtc # Bug 1393901 ac_add_options --disable-geckodriver # Bug 1489320 # Find our toolchain -HOST_CC="$TOOLTOOL_DIR/clang/bin/clang" -HOST_CXX="$TOOLTOOL_DIR/clang/bin/clang++" -CC="$TOOLTOOL_DIR/clang/bin/x86_64-w64-mingw32-clang" -CXX="$TOOLTOOL_DIR/clang/bin/x86_64-w64-mingw32-clang++" +HOST_CC="$MOZ_FETCHES_DIR/clang/bin/clang" +HOST_CXX="$MOZ_FETCHES_DIR/clang/bin/clang++" +CC="$MOZ_FETCHES_DIR/clang/bin/x86_64-w64-mingw32-clang" +CXX="$MOZ_FETCHES_DIR/clang/bin/x86_64-w64-mingw32-clang++" ac_add_options --with-clang-path="$CC" -ac_add_options --with-libclang-path="$TOOLTOOL_DIR/clang/lib" +ac_add_options --with-libclang-path="$MOZ_FETCHES_DIR/clang/lib" CXXFLAGS="-fms-extensions" AR=llvm-ar RANLIB=llvm-ranlib # For Stylo -BINDGEN_CFLAGS="-I$TOOLTOOL_DIR/clang/x86_64-w64-mingw32/include/c++/v1 -I$TOOLTOOL_DIR/clang/x86_64-w64-mingw32/include" +BINDGEN_CFLAGS="-I$MOZ_FETCHES_DIR/clang/x86_64-w64-mingw32/include/c++/v1 -I$MOZ_FETCHES_DIR/clang/x86_64-w64-mingw32/include" # We want to make sure we use binutils and other binaries in the tooltool # package. -mk_add_options "export PATH=$TOOLTOOL_DIR/clang/bin:$TOOLTOOL_DIR/mingw32/bin:$TOOLTOOL_DIR/wine/bin:$TOOLTOOL_DIR/upx/bin:$TOOLTOOL_DIR/fxc2/bin:$PATH" +mk_add_options "export PATH=$MOZ_FETCHES_DIR/clang/bin:$MOZ_FETCHES_DIR/mingw32/bin:$MOZ_FETCHES_DIR/wine/bin:$MOZ_FETCHES_DIR/upx/bin:$MOZ_FETCHES_DIR/fxc2/bin:$PATH" -LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$TOOLTOOL_DIR/mingw32/lib64:$TOOLTOOL_DIR/clang/lib +LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$MOZ_FETCHES_DIR/mingw32/lib64:$MOZ_FETCHES_DIR/clang/lib mk_add_options "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH" # Do not include the visual studio related mozconfigs of course diff --git a/browser/config/mozconfigs/win64/plain-opt b/browser/config/mozconfigs/win64/plain-opt index 7753e4687d..e1dd4148db 100644 --- a/browser/config/mozconfigs/win64/plain-opt +++ b/browser/config/mozconfigs/win64/plain-opt @@ -1,15 +1,15 @@ TOOLTOOL_DIR=${topsrcdir} export MAKECAB=$TOOLTOOL_DIR/makecab.exe -export LLVM_CONFIG="${TOOLTOOL_DIR}/clang/bin/llvm-config" +export LLVM_CONFIG="${MOZ_FETCHES_DIR}/clang/bin/llvm-config" -RUSTC="${TOOLTOOL_DIR}/rustc/bin/rustc" -CARGO="${TOOLTOOL_DIR}/rustc/bin/cargo" -RUSTDOC="${TOOLTOOL_DIR}/rustc/bin/rustdoc" -RUSTFMT="${TOOLTOOL_DIR}/rustc/bin/rustfmt" -CBINDGEN="${TOOLTOOL_DIR}/cbindgen/cbindgen" +RUSTC="${MOZ_FETCHES_DIR}/rustc/bin/rustc" +CARGO="${MOZ_FETCHES_DIR}/rustc/bin/cargo" +RUSTDOC="${MOZ_FETCHES_DIR}/rustc/bin/rustdoc" +RUSTFMT="${MOZ_FETCHES_DIR}/rustc/bin/rustfmt" +CBINDGEN="${MOZ_FETCHES_DIR}/cbindgen/cbindgen" -NASM="${TOOLTOOL_DIR}/nasm/nasm.exe" -NODEJS="${TOOLTOOL_DIR}/node/node.exe" +NASM="${MOZ_FETCHES_DIR}/nasm/nasm.exe" +NODEJS="${MOZ_FETCHES_DIR}/node/node.exe" ac_add_options --target=x86_64-pc-mingw32 diff --git a/browser/config/mozconfigs/win64/profile-generate b/browser/config/mozconfigs/win64/profile-generate index 6b9ad0795f..00a69c6ff7 100644 --- a/browser/config/mozconfigs/win64/profile-generate +++ b/browser/config/mozconfigs/win64/profile-generate @@ -1,6 +1,5 @@ . $topsrcdir/browser/config/mozconfigs/win64/nightly -mk_add_options "export MOZ_AUTOMATION_BUILD_SYMBOLS=0" mk_add_options "export MOZ_AUTOMATION_PACKAGE_TESTS=0" mk_add_options "export MOZ_AUTOMATION_PACKAGE_GENERATED_SOURCES=0" mk_add_options "export MOZ_AUTOMATION_L10N_CHECK=0" diff --git a/browser/config/mozconfigs/win64/release b/browser/config/mozconfigs/win64/release index 952fc7b55f..df6e68bef1 100644 --- a/browser/config/mozconfigs/win64/release +++ b/browser/config/mozconfigs/win64/release @@ -1,8 +1,6 @@ # This make file should be identical to the beta mozconfig, apart from the # safeguard below -export MOZ_PGO=1 - . "$topsrcdir/build/mozconfig.win-common" . "$topsrcdir/browser/config/mozconfigs/win64/common-win64" . "$topsrcdir/browser/config/mozconfigs/win64/common-opt" diff --git a/browser/config/version.txt b/browser/config/version.txt index 51b911d778..dfd2c37c92 100644 --- a/browser/config/version.txt +++ b/browser/config/version.txt @@ -1 +1 @@ -68.14.4 +68.14.5 diff --git a/browser/config/version_display.txt b/browser/config/version_display.txt index a43ba26b40..a772a330bf 100644 --- a/browser/config/version_display.txt +++ b/browser/config/version_display.txt @@ -1 +1 @@ -68.14.4b +68.14.5b diff --git a/browser/confvars.sh b/browser/confvars.sh index ac3f19f720..b9bd7f1ff5 100644 --- a/browser/confvars.sh +++ b/browser/confvars.sh @@ -3,10 +3,8 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MOZ_APP_BASENAME=Mypal MOZ_APP_VENDOR=Theodor2 MOZ_UPDATER=1 -MOZ_PHOENIX=1 if test "$OS_ARCH" = "WINNT"; then if ! test "$HAVE_64BIT_BUILD"; then @@ -28,13 +26,10 @@ if test "$OS_ARCH" = "WINNT"; then fi fi -# Enable building ./signmar and running libmar signature tests -MOZ_ENABLE_SIGNMAR=1 - -if [ "${MOZ_BROWSER_XHTML}" = "1" ]; then - BROWSER_CHROME_URL=chrome://browser/content/browser.xhtml -else +if [ "${MOZ_BROWSER_XUL}" = "1" ]; then BROWSER_CHROME_URL=chrome://browser/content/browser.xul +else + BROWSER_CHROME_URL=chrome://browser/content/browser.xhtml fi # MOZ_APP_DISPLAYNAME will be set by branding/configure.sh @@ -45,22 +40,6 @@ fi # For the mozilla-aurora repository, use "aurora". MOZ_BRANDING_DIRECTORY=browser/branding/unofficial MOZ_APP_ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384} -# ACCEPTED_MAR_CHANNEL_IDS should usually be the same as the value MAR_CHANNEL_ID. -# If more than one ID is needed, then you should use a comma separated list -# of values. -# The MAR_CHANNEL_ID must not contain the following 3 characters: ",\t " -if test "$MOZ_UPDATE_CHANNEL" = "aurora"; then - ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-aurora - MAR_CHANNEL_ID=firefox-mozilla-aurora -else - ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-esr - MAR_CHANNEL_ID=firefox-mozilla-esr -fi -# ASan reporter builds should have different channel ids -if [ "${MOZ_ASAN_REPORTER}" = "1" ]; then - ACCEPTED_MAR_CHANNEL_IDS="${ACCEPTED_MAR_CHANNEL_IDS}-asan" - MAR_CHANNEL_ID="${MAR_CHANNEL_ID}-asan" -fi MOZ_PROFILE_MIGRATOR=1 diff --git a/browser/installer/Makefile.in b/browser/installer/Makefile.in index 8b99eed27e..e8af11801e 100644 --- a/browser/installer/Makefile.in +++ b/browser/installer/Makefile.in @@ -48,10 +48,6 @@ ifdef MOZ_SYSTEM_NSS DEFINES += -DMOZ_SYSTEM_NSS=1 endif -ifdef NSS_DISABLE_DBM -DEFINES += -DNSS_DISABLE_DBM=1 -endif - ifdef MOZ_ARTIFACT_BUILDS DEFINES += -DMOZ_ARTIFACT_BUILDS=1 endif diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 6bb9ad958f..968ed5f410 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -136,11 +136,9 @@ @RESPATH@/update-settings.ini #endif @RESPATH@/platform.ini -#ifndef MOZ_SYSTEM_SQLITE #ifndef MOZ_FOLD_LIBS @BINPATH@/@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@ #endif -#endif @BINPATH@/@DLL_PREFIX@lgpllibs@DLL_SUFFIX@ #ifdef MOZ_FFVPX @BINPATH@/@DLL_PREFIX@mozavutil@DLL_SUFFIX@ @@ -185,6 +183,9 @@ @RESPATH@/components/Push.manifest +@RESPATH@/components/l10n-registry.manifest +@RESPATH@/browser/components/l10n-registry.manifest + ; CDP remote agent #ifdef ENABLE_REMOTE_AGENT @RESPATH@/chrome/remote@JAREXT@ @@ -354,9 +355,6 @@ #endif @BINPATH@/@DLL_PREFIX@nss3@DLL_SUFFIX@ @BINPATH@/@DLL_PREFIX@nssckbi@DLL_SUFFIX@ -#ifndef NSS_DISABLE_DBM -@BINPATH@/@DLL_PREFIX@nssdbm3@DLL_SUFFIX@ -#endif #ifndef MOZ_FOLD_LIBS @BINPATH@/@DLL_PREFIX@nssutil3@DLL_SUFFIX@ @BINPATH@/@DLL_PREFIX@smime3@DLL_SUFFIX@ @@ -417,10 +415,6 @@ bin/libfreebl_32int64_3.so #endif #endif -; [ Ping Sender ] -; -@BINPATH@/pingsender@BIN_SUFFIX@ - ; Shutdown Terminator @RESPATH@/components/terminator.manifest diff --git a/browser/installer/windows/nsis/shared.nsh b/browser/installer/windows/nsis/shared.nsh index cd9be47ad0..39c26ee662 100644 --- a/browser/installer/windows/nsis/shared.nsh +++ b/browser/installer/windows/nsis/shared.nsh @@ -1351,7 +1351,6 @@ Push "xpcom.dll" Push "crashreporter.exe" Push "minidump-analyzer.exe" - Push "pingsender.exe" Push "updater.exe" Push "${FileMainEXE}" !macroend diff --git a/browser/l10n-registry.manifest b/browser/l10n-registry.manifest new file mode 100644 index 0000000000..6b02008b80 --- /dev/null +++ b/browser/l10n-registry.manifest @@ -0,0 +1 @@ +category l10n-registry 5-browser resource://app/localization/{locale}/ diff --git a/browser/modules/moz.build b/browser/modules/moz.build index 51bb857bfe..73ee46593b 100644 --- a/browser/modules/moz.build +++ b/browser/modules/moz.build @@ -12,10 +12,10 @@ with Files("test/browser/*ContentSearch*"): BUG_COMPONENT = ("Firefox", "Search") with Files("test/browser/*PermissionUI*"): - BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels") + BUG_COMPONENT = ("Firefox", "Site Permissions") with Files("test/browser/*SitePermissions*"): - BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels") + BUG_COMPONENT = ("Firefox", "Site Permissions") with Files("test/browser/browser_UnsubmittedCrashHandler.js"): BUG_COMPONENT = ("Toolkit", "Crash Reporting") @@ -33,7 +33,7 @@ with Files("test/unit/test_LaterRun.js"): BUG_COMPONENT = ("Firefox", "Tours") with Files("test/unit/test_SitePermissions.js"): - BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels") + BUG_COMPONENT = ("Firefox", "Site Permissions") with Files("AboutNewTab.jsm"): BUG_COMPONENT = ("Firefox", "New Tab Page") @@ -75,7 +75,7 @@ with Files("OpenInTabsUtils.jsm"): BUG_COMPONENT = ("Firefox", "Tabbed Browser") with Files("PermissionUI.jsm"): - BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels") + BUG_COMPONENT = ("Firefox", "Site Permissions") with Files("ProcessHangMonitor.jsm"): BUG_COMPONENT = ("Core", "DOM: Content Processes") @@ -93,7 +93,7 @@ with Files("SiteDataManager.jsm"): BUG_COMPONENT = ("Firefox", "Preferences") with Files("SitePermissions.jsm"): - BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels") + BUG_COMPONENT = ("Firefox", "Site Permissions") with Files("TabsList.jsm"): BUG_COMPONENT = ("Firefox", "Tabbed Browser") @@ -114,7 +114,7 @@ with Files("WindowsPreviewPerTab.jsm"): BUG_COMPONENT = ("Core", "Widget: Win32") with Files("webrtcUI.jsm"): - BUG_COMPONENT = ("Firefox", "Device Permissions") + BUG_COMPONENT = ("Firefox", "Site Permissions") with Files("ZoomUI.jsm"): BUG_COMPONENT = ("Firefox", "Toolbars and Customization") diff --git a/browser/modules/test/unit/test_SiteDataManager.js b/browser/modules/test/unit/test_SiteDataManager.js index 9d4d2e3d84..5e2ec254b0 100644 --- a/browser/modules/test/unit/test_SiteDataManager.js +++ b/browser/modules/test/unit/test_SiteDataManager.js @@ -5,6 +5,7 @@ const EXAMPLE_ORIGIN = "https://www.example.com"; const EXAMPLE_ORIGIN_2 = "https://example.org"; +const EXAMPLE_ORIGIN_3 = "http://localhost:8000"; const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); const { SiteDataManager } = ChromeUtils.import( @@ -130,11 +131,18 @@ add_task(async function testRemove() { SiteDataTestUtils.addToCookies(EXAMPLE_ORIGIN_2, "foo", "bar"); await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN_2, 2048); await SiteDataTestUtils.persist(EXAMPLE_ORIGIN_2); + await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN_3, 2048); await SiteDataManager.updateSites(); let sites = await SiteDataManager.getSites(); + Assert.equal(sites.length, 3, "Has three sites."); + + await SiteDataManager.remove(["localhost"]); + + sites = await SiteDataManager.getSites(); + Assert.equal(sites.length, 2, "Has two sites."); await SiteDataManager.remove(["www.example.com"]); diff --git a/browser/moz.build b/browser/moz.build index b841379a5a..589245afec 100644 --- a/browser/moz.build +++ b/browser/moz.build @@ -9,6 +9,10 @@ SPHINX_TREES['browser'] = 'docs' with Files('docs/**'): SCHEDULES.exclusive = ['docs'] +EXTRA_COMPONENTS += [ + 'l10n-registry.manifest', +] + DIRS += [ 'actors', 'base', @@ -92,3 +96,6 @@ with Files("installer/**"): with Files("tools/**"): BUG_COMPONENT = ("Firefox", "General") + +with Files('l10n-registry.manifest'): + BUG_COMPONENT = ('Core', 'Localization') diff --git a/browser/themes/shared/browser.inc.css b/browser/themes/shared/browser.inc.css index e7336465d7..d5c467d01d 100644 --- a/browser/themes/shared/browser.inc.css +++ b/browser/themes/shared/browser.inc.css @@ -54,7 +54,7 @@ /* Bookmark toolbar */ #PersonalToolbar { - overflow: -moz-hidden-unscrollable; + overflow: clip; max-height: 4em; padding: 0 6px 2px; } diff --git a/browser/themes/shared/incontentprefs/preferences.inc.css b/browser/themes/shared/incontentprefs/preferences.inc.css index 126cdbb4db..46c1d1e66b 100644 --- a/browser/themes/shared/incontentprefs/preferences.inc.css +++ b/browser/themes/shared/incontentprefs/preferences.inc.css @@ -535,6 +535,8 @@ button > hbox > label { background: none !important; min-width: 0; min-height: auto; + padding-inline: 0; + margin-inline: 0 8px; } .dialogFrame { diff --git a/browser/themes/shared/urlbar-searchbar.inc.css b/browser/themes/shared/urlbar-searchbar.inc.css index f5fbd9ae91..989a13e2be 100644 --- a/browser/themes/shared/urlbar-searchbar.inc.css +++ b/browser/themes/shared/urlbar-searchbar.inc.css @@ -36,7 +36,7 @@ margin: 3px 5px; min-height: 30px; cursor: default; - overflow: -moz-hidden-unscrollable; + overflow: clip; } #urlbar:hover, diff --git a/browser/themes/windows/browser.css b/browser/themes/windows/browser.css index 972c88a1ac..498be2c626 100644 --- a/browser/themes/windows/browser.css +++ b/browser/themes/windows/browser.css @@ -255,7 +255,7 @@ /* Need to constrain the box shadow fade to avoid overlapping layers, see bug 886281. */ #main-window[tabsintitlebar]:not([sizemode=fullscreen]) #navigator-toolbox:not(:-moz-lwtheme) { - overflow: -moz-hidden-unscrollable; + overflow: clip; } #main-window[tabsintitlebar][sizemode="normal"] > #navigator-toolbox:-moz-lwtheme { diff --git a/browser/tools/mozscreenshots/browser_screenshots_cropping.js b/browser/tools/mozscreenshots/browser_screenshots_cropping.js index 45a6264af4..e80e46765c 100644 --- a/browser/tools/mozscreenshots/browser_screenshots_cropping.js +++ b/browser/tools/mozscreenshots/browser_screenshots_cropping.js @@ -53,7 +53,18 @@ async function compareImages(window, expected, test) { "The test and expected images must be the same size" ); - return window.windowUtils.compareCanvases(expectedCanvas, testCanvas, {}); + var maxDifference = {}; + var differences = window.windowUtils.compareCanvases( + expectedCanvas, + testCanvas, + maxDifference + ); + + // Fuzz for minor differences that can be caused by the encoder. + if (maxDifference.value > 1) { + return differences; + } + return 0; } async function cropAndCompare(window, src, expected, test, region, subregions) { diff --git a/browser/tools/mozscreenshots/moz.build b/browser/tools/mozscreenshots/moz.build index 459fc86679..89287ca92e 100644 --- a/browser/tools/mozscreenshots/moz.build +++ b/browser/tools/mozscreenshots/moz.build @@ -6,13 +6,13 @@ with Files("**"): BUG_COMPONENT = ("Firefox", "General") with Files("controlCenter/**"): - BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels") + BUG_COMPONENT = ("Firefox", "Site Identity") with Files("devtools/**"): BUG_COMPONENT = ("DevTools", "General") with Files("permissionPrompts/**"): - BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels") + BUG_COMPONENT = ("Firefox", "Site Permissions") with Files("preferences/**"): BUG_COMPONENT = ("Firefox", "Preferences") diff --git a/build.gradle b/build.gradle index 8b91888b5d..7498b81160 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,6 @@ allprojects { ANDROID_PACKAGE_NAME: mozconfig.substs.ANDROID_PACKAGE_NAME, ANDROID_TARGET_SDK: mozconfig.substs.ANDROID_TARGET_SDK, MOZ_ANDROID_MIN_SDK_VERSION: mozconfig.substs.MOZ_ANDROID_MIN_SDK_VERSION, - MOZ_ANDROID_SHARED_ID: "${mozconfig.substs.ANDROID_PACKAGE_NAME}.sharedID", ] } @@ -71,7 +70,7 @@ buildscript { } } - ext.kotlin_version = '1.2.41' + ext.kotlin_version = '1.3.41' ext.support_library_version = '28.0.0' ext.jacoco_version = '0.8.1' ext.lifecycle_library_version = '1.1.1' @@ -83,8 +82,8 @@ buildscript { } dependencies { - classpath 'org.mozilla.apilint:apilint:0.2.1' - classpath 'com.android.tools.build:gradle:3.1.4' + classpath 'org.mozilla.apilint:apilint:0.2.6' + classpath 'com.android.tools.build:gradle:3.4.2' classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.2' classpath 'org.apache.commons:commons-exec:1.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" @@ -157,26 +156,6 @@ class MachExec extends Exec { } } -task machBuildGeneratedAndroidCodeAndResources(type: MachExec) { - onlyIf rootProject.ext.geckoBinariesOnlyIf - - workingDir "${topsrcdir}" - - commandLine mozconfig.substs.PYTHON - args "${topsrcdir}/mach" - args 'build' - args 'mobile/android/base/generated_android_code_and_resources' - - // Add `-v` if we're running under `--info` (or `--debug`). - if (project.logger.isEnabled(LogLevel.INFO)) { - args '-v' - } - - // `path` is like `:machBuildGeneratedAndroidCodeAndResources`. - standardOutput = new TaggedLogOutputStream("${path}>", logger) - errorOutput = standardOutput -} - // Why |mach build mobile/android/base/...| and |mach build faster|? |mach // build faster| generates dependentlibs.list, which in turn depends on compiled // code. That causes a circular dependency between Java compilation/JNI wrapper @@ -250,43 +229,21 @@ createMachStagePackageTask("machStagePackageForGeckoview").with { afterEvaluate { subprojects { project -> - if (project.name != 'thirdparty') { - tasks.withType(JavaCompile) { - // Add compiler args for all code except third-party code. - options.compilerArgs += [ - // Turn on all warnings, except... - "-Xlint:all", - // Deprecation, because we do use deprecated API for compatibility. - "-Xlint:-deprecation", - // Serial, because we don't use Java serialization. - "-Xlint:-serial", - // Classfile, because javac has a bug with MethodParameters attributes - // with Java 7. https://bugs.openjdk.java.net/browse/JDK-8190452 - "-Xlint:-classfile", - // Turn all remaining warnings into errors, - // unless marked by @SuppressWarnings. - "-Werror"] - } - if (project.name == 'app') { - tasks.withType(JavaCompile) { - // Turn off classfile warnings because upon updating to play services 15.0.0 - // a warning is being thrown from play-services-base which fails the build - // (com/google/android/gms/common/api/GoogleApiClient.class): - // warning: Cannot find annotation method 'value()' in type 'GuardedBy': - // class file for javax.annotation.concurrent.GuardedBy not found - options.compilerArgs += ["-Xlint:-classfile"] - } - } - } - - if (!hasProperty('android')) { - return - } - android.applicationVariants.all { - preBuild.dependsOn rootProject.machBuildGeneratedAndroidCodeAndResources - } - android.libraryVariants.all { - preBuild.dependsOn rootProject.machBuildGeneratedAndroidCodeAndResources + tasks.withType(JavaCompile) { + // Add compiler args for all code except third-party code. + options.compilerArgs += [ + // Turn on all warnings, except... + "-Xlint:all", + // Deprecation, because we do use deprecated API for compatibility. + "-Xlint:-deprecation", + // Serial, because we don't use Java serialization. + "-Xlint:-serial", + // Classfile, because javac has a bug with MethodParameters attributes + // with Java 7. https://bugs.openjdk.java.net/browse/JDK-8190452 + "-Xlint:-classfile", + // Turn all remaining warnings into errors, + // unless marked by @SuppressWarnings. + "-Werror"] } } } @@ -318,12 +275,5 @@ idea { excludeDirs += files(file(topobjdir).listFiles()) excludeDirs -= file("${topobjdir}/gradle") } - - if (!mozconfig.substs.MOZ_INSTALL_TRACKING) { - excludeDirs += file("${topsrcdir}/mobile/android/thirdparty/com/adjust") - } } } - -task wrapper(type: Wrapper) { -} diff --git a/build/autoconf/altoptions.m4 b/build/autoconf/altoptions.m4 index b6e365bdcb..ac016f4b91 100644 --- a/build/autoconf/altoptions.m4 +++ b/build/autoconf/altoptions.m4 @@ -73,5 +73,5 @@ define(MOZ_ARG_HEADER, [# $1]) dnl MOZ_READ_MYCONFIG() - Read in 'myconfig.sh' file AC_DEFUN([MOZ_READ_MOZCONFIG], [AC_REQUIRE([AC_INIT_BINSH])dnl -. ./old-configure.vars +. $OLD_CONFIGURE_VARS ]) diff --git a/build/autoconf/android.m4 b/build/autoconf/android.m4 index 6bba60e448..425def2023 100644 --- a/build/autoconf/android.m4 +++ b/build/autoconf/android.m4 @@ -23,11 +23,6 @@ case "$target" in ASFLAGS="$directory_include_args -DANDROID $ASFLAGS" LDFLAGS="-L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform $LDFLAGS" - ANDROID_PLATFORM="${android_platform}" - - AC_DEFINE(ANDROID) - AC_SUBST(ANDROID_PLATFORM) - ;; esac diff --git a/build/autoconf/clang-plugin.m4 b/build/autoconf/clang-plugin.m4 index a1e7b71edd..419ebf962c 100644 --- a/build/autoconf/clang-plugin.m4 +++ b/build/autoconf/clang-plugin.m4 @@ -175,16 +175,12 @@ if test -n "$ENABLE_MOZSEARCH_PLUGIN"; then AC_MSG_ERROR([Can't use mozsearch plugin without --enable-clang-plugin.]) fi - dnl We use this construct rather than $_objdir to avoid getting /js/src in the - dnl path when compiling JS code. - OBJDIR="$(dirname $(dirname $(dirname $CLANG_PLUGIN)))" - CLANG_PLUGIN_FLAGS="$CLANG_PLUGIN_FLAGS -Xclang -add-plugin -Xclang mozsearch-index" dnl Parameters are: srcdir, outdir (path where output JSON is stored), objdir. CLANG_PLUGIN_FLAGS="$CLANG_PLUGIN_FLAGS -Xclang -plugin-arg-mozsearch-index -Xclang $_topsrcdir" - CLANG_PLUGIN_FLAGS="$CLANG_PLUGIN_FLAGS -Xclang -plugin-arg-mozsearch-index -Xclang $OBJDIR/mozsearch_index" - CLANG_PLUGIN_FLAGS="$CLANG_PLUGIN_FLAGS -Xclang -plugin-arg-mozsearch-index -Xclang $OBJDIR" + CLANG_PLUGIN_FLAGS="$CLANG_PLUGIN_FLAGS -Xclang -plugin-arg-mozsearch-index -Xclang $_objdir/mozsearch_index" + CLANG_PLUGIN_FLAGS="$CLANG_PLUGIN_FLAGS -Xclang -plugin-arg-mozsearch-index -Xclang $_objdir" AC_DEFINE(MOZ_MOZSEARCH_PLUGIN) fi diff --git a/build/autoconf/compiler-opts.m4 b/build/autoconf/compiler-opts.m4 index 2ef0353ea5..15677cef2f 100644 --- a/build/autoconf/compiler-opts.m4 +++ b/build/autoconf/compiler-opts.m4 @@ -11,11 +11,6 @@ dnl the user the option of enabling it. dnl ============================================================================ AC_DEFUN([MOZ_RTTI], [ -MOZ_ARG_ENABLE_BOOL(cpp-rtti, -[ --enable-cpp-rtti Enable C++ RTTI ], -[ _MOZ_USE_RTTI=1 ], -[ _MOZ_USE_RTTI= ]) - if test -z "$_MOZ_USE_RTTI"; then if test "$GNU_CC"; then CXXFLAGS="$CXXFLAGS -fno-rtti" @@ -42,15 +37,6 @@ fi AC_SUBST(MOZ_NO_DEBUG_RTL) -MOZ_DEBUG_ENABLE_DEFS="DEBUG" -MOZ_ARG_WITH_STRING(debug-label, -[ --with-debug-label=LABELS - Define DEBUG_ for each comma-separated - value given.], -[ for option in `echo $withval | sed 's/,/ /g'`; do - MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS DEBUG_${option}" -done]) - if test -n "$MOZ_DEBUG"; then if test -n "$COMPILE_ENVIRONMENT"; then AC_MSG_CHECKING([for valid debug flags]) @@ -66,14 +52,7 @@ if test -n "$MOZ_DEBUG"; then fi CFLAGS=$_SAVE_CFLAGS fi - - MOZ_DEBUG_DEFINES="$MOZ_DEBUG_ENABLE_DEFS" -else - MOZ_DEBUG_DEFINES="NDEBUG TRIMMED" fi - -AC_SUBST_LIST(MOZ_DEBUG_DEFINES) - ]) dnl A high level macro for selecting compiler options. @@ -105,11 +84,6 @@ dnl ======================================================== dnl = Identical Code Folding dnl ======================================================== -MOZ_ARG_DISABLE_BOOL(icf, -[ --disable-icf Disable Identical Code Folding], - MOZ_DISABLE_ICF=1, - MOZ_DISABLE_ICF= ) - if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -z "$MOZ_DISABLE_ICF" -a -z "$DEVELOPER_OPTIONS"; then AC_CACHE_CHECK([whether the linker supports Identical Code Folding], LD_SUPPORTS_ICF, @@ -141,7 +115,7 @@ dnl ======================================================== dnl = Automatically remove dead symbols dnl ======================================================== -if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -z "$DEVELOPER_OPTIONS"; then +if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -z "$DEVELOPER_OPTIONS" -a -z "$MOZ_PROFILE_GENERATE"; then if test -n "$MOZ_DEBUG_FLAGS"; then dnl See bug 670659 AC_CACHE_CHECK([whether removing dead symbols breaks debugging], diff --git a/build/autoconf/config.status.m4 b/build/autoconf/config.status.m4 index 8e2b4d98d3..9be939b2b5 100644 --- a/build/autoconf/config.status.m4 +++ b/build/autoconf/config.status.m4 @@ -149,19 +149,6 @@ done cat >> $CONFIG_STATUS <<\EOF ] -dnl List of AC_DEFINEs that aren't to be exposed in ALLDEFINES -non_global_defines = [ -EOF - -if test -n "$_NON_GLOBAL_ACDEFINES"; then - for var in $_NON_GLOBAL_ACDEFINES; do - echo " '$var'," >> $CONFIG_STATUS - done -fi - -cat >> $CONFIG_STATUS <= 67.1) - CFLAGS="$CFLAGS $MOZ_ICU_CFLAGS" - CXXFLAGS="$CXXFLAGS $MOZ_ICU_CFLAGS" - AC_DEFINE(MOZ_SYSTEM_ICU) -fi - -AC_SUBST(MOZ_SYSTEM_ICU) - -MOZ_ARG_WITH_STRING(intl-api, -[ --with-intl-api, --without-intl-api - Determine the status of the ECMAScript Internationalization API. The first - (or lack of any of these) builds and exposes the API. The second doesn't - build ICU at all.], - _INTL_API=$withval) - -JS_HAS_INTL_API= -case "$_INTL_API" in -no) - ;; -yes) - JS_HAS_INTL_API=1 - ;; -*) - AC_MSG_ERROR([Invalid value passed to --with-intl-api: $_INTL_API]) - ;; -esac - -if test -n "$JS_HAS_INTL_API"; then - USE_ICU=1 -fi - -if test -n "$JS_HAS_INTL_API"; then - AC_DEFINE(JS_HAS_INTL_API) -fi - -dnl Settings for the implementation of the ECMAScript Internationalization API -if test -n "$USE_ICU"; then - icudir="$_topsrcdir/intl/icu/source" - if test ! -d "$icudir"; then - icudir="$_topsrcdir/../../intl/icu/source" - if test ! -d "$icudir"; then - AC_MSG_ERROR([Cannot find the ICU directory]) - fi - fi - - version=`sed -n 's/^[[[:space:]]]*#[[:space:]]*define[[:space:]][[:space:]]*U_ICU_VERSION_MAJOR_NUM[[:space:]][[:space:]]*\([0-9][0-9]*\)[[:space:]]*$/\1/p' "$icudir/common/unicode/uvernum.h"` - if test x"$version" = x; then - AC_MSG_ERROR([cannot determine icu version number from uvernum.h header file $lineno]) - fi - MOZ_ICU_VERSION="$version" - - # TODO: the l is actually endian-dependent - # We could make this set as 'l' or 'b' for little or big, respectively, - # but we'd need to check in a big-endian version of the file. - ICU_DATA_FILE="icudt${version}l.dat" -fi - -AC_SUBST(MOZ_ICU_VERSION) -AC_SUBST(JS_HAS_INTL_API) -AC_SUBST(USE_ICU) -AC_SUBST(ICU_DATA_FILE) - -if test -n "$USE_ICU"; then - dnl Source files that use ICU should have control over which parts of the ICU - dnl namespace they want to use. - AC_DEFINE(U_USING_ICU_NAMESPACE,0) - - if test -z "$MOZ_SYSTEM_ICU"; then - case "$OS_TARGET:$CPU_ARCH" in - WINNT:aarch64) - dnl we use non-yasm, non-GNU as solutions here. - ;; - *) - if test -z "$YASM" -a -z "$GNU_AS" -a "$COMPILE_ENVIRONMENT"; then - AC_MSG_ERROR([Building ICU requires either yasm or a GNU assembler. If you do not have either of those available for this platform you must use --without-intl-api]) - fi - ;; - esac - dnl We build ICU as a static library. - AC_DEFINE(U_STATIC_IMPLEMENTATION) - fi -fi -]) diff --git a/build/autoconf/ios.m4 b/build/autoconf/ios.m4 deleted file mode 100644 index eb4f3ec5c8..0000000000 --- a/build/autoconf/ios.m4 +++ /dev/null @@ -1,107 +0,0 @@ -dnl This Source Code Form is subject to the terms of the Mozilla Public -dnl License, v. 2.0. If a copy of the MPL was not distributed with this -dnl file, You can obtain one at http://mozilla.org/MPL/2.0/. - -AC_DEFUN([MOZ_IOS_PATH_PROG], -[ -changequote({,}) -_prog_name=ifelse($2, {}, `echo $1 | tr "[:upper:]" "[:lower:]"`, $2) -changequote([,]) -AC_CACHE_CHECK([for $_prog_name in iOS SDK], -ac_cv_ios_path_$1, -[ -_path=`xcrun --sdk $ios_sdk --find $_prog_name 2>/dev/null` -_res=$? -if test $_res -ne 0; then - AC_MSG_ERROR([Could not find '$_prog_name' in the iOS SDK]) -fi -ac_cv_ios_path_$1=$_path -]) -$1="${ac_cv_ios_path_$1}$3" -]) - -AC_DEFUN([MOZ_IOS_SDK], -[ - -MOZ_ARG_WITH_STRING(ios-sdk, -[ --with-ios-sdk=TYPE - Type of iOS SDK to use (iphonesimulator, iphoneos) - and optionally version (like iphoneos8.2)], - ios_sdk=$withval) - -MOZ_ARG_ENABLE_STRING(ios-target, - [ --enable-ios-target=VER (default=8.0) - Set the minimum iOS version needed at runtime], - [_IOS_TARGET=$enableval]) -_IOS_TARGET_DEFAULT=8.0 - -case "$target" in -arm*-apple-darwin*) - if test -z "$ios_sdk" -o "$ios_sdk" = "yes"; then - ios_sdk=iphoneos - fi - case "$ios_sdk" in - iphoneos*) - ios_target_arg="-miphoneos-version-min" - ;; - *) - AC_MSG_ERROR([Only 'iphoneos' SDKs are valid when targeting iOS device, don't know what to do with '$ios_sdk'.]) - ;; - esac - ;; -*-apple-darwin*) - ios_target_arg="-mios-simulator-version-min" - case "$ios_sdk" in - # Empty SDK is okay, this might be an OS X desktop build. - ""|iphonesimulator*) - ;; - # Default to iphonesimulator - yes) - ios_sdk=iphonesimulator - ;; - *) - AC_MSG_ERROR([Only 'iphonesimulator' SDKs are valid when targeting iOS simulator.]) - ;; - esac - ;; -esac - - -if test -n "$ios_sdk"; then - if test -z "$_IOS_TARGET"; then - _IOS_TARGET=$_IOS_TARGET_DEFAULT - ios_target_arg="${ios_target_arg}=${_IOS_TARGET}" - fi - # Ensure that xcrun knows where this SDK is. - ios_sdk_path=`xcrun --sdk $ios_sdk --show-sdk-path 2>/dev/null` - _ret=$? - if test $_ret -ne 0; then - AC_MSG_ERROR([iOS SDK '$ios_sdk' could not be found.]) - fi - MOZ_IOS=1 - export HOST_CC=clang - export HOST_CXX=clang++ - # Add isysroot, arch, and ios target arguments - case "$target_cpu" in - arm*) - ARGS="-arch armv7" - ;; - *) - # Unfortunately simulator builds need this. - export CROSS_COMPILE=1 - ;; - esac - ARGS=" $ARGS -isysroot $ios_sdk_path $ios_target_arg" - # Now find our tools - MOZ_IOS_PATH_PROG(CC, clang, $ARGS) - MOZ_IOS_PATH_PROG(CXX, clang++, $ARGS) - export CPP="$CC -E" - MOZ_IOS_PATH_PROG(AR) - MOZ_IOS_PATH_PROG(AS, as, $ARGS) - MOZ_IOS_PATH_PROG(OTOOL) - MOZ_IOS_PATH_PROG(STRIP) - export PKG_CONFIG_PATH=${ios_sdk_path}/usr/lib/pkgconfig/ -fi - -AC_SUBST(MOZ_IOS) -]) diff --git a/build/autoconf/nspr-build.m4 b/build/autoconf/nspr-build.m4 deleted file mode 100644 index ab9747639a..0000000000 --- a/build/autoconf/nspr-build.m4 +++ /dev/null @@ -1,190 +0,0 @@ -dnl This Source Code Form is subject to the terms of the Mozilla Public -dnl License, v. 2.0. If a copy of the MPL was not distributed with this -dnl file, You can obtain one at http://mozilla.org/MPL/2.0/. - -AC_DEFUN([MOZ_CONFIG_NSPR], [ - -ifelse([$1],,define(CONFIGURING_JS,yes)) - -dnl Possible ways this can be called: -dnl from toplevel configure: -dnl JS_STANDALONE= MOZ_BUILD_APP!=js -dnl from js/src/configure invoked by toplevel configure: -dnl JS_STANDALONE= MOZ_BUILD_APP=js -dnl from standalone js/src/configure: -dnl JS_STANDALONE=1 MOZ_BUILD_APP=js - -dnl ======================================================== -dnl = Find the right NSPR to use. -dnl ======================================================== -MOZ_ARG_WITH_STRING(nspr-cflags, -[ --with-nspr-cflags=FLAGS - Pass FLAGS to CC when building code that uses NSPR. - Use this when there's no accurate nspr-config - script available. This is the case when building - SpiderMonkey as part of the Mozilla tree: the - top-level configure script computes NSPR flags - that accomodate the quirks of that environment.], - NSPR_CFLAGS=$withval) -MOZ_ARG_WITH_STRING(nspr-libs, -[ --with-nspr-libs=LIBS Pass LIBS to LD when linking code that uses NSPR. - See --with-nspr-cflags for more details.], - NSPR_LIBS=$withval) - -ifdef([CONFIGURING_JS],[ - MOZ_ARG_ENABLE_BOOL(nspr-build, -[ --enable-nspr-build Build NSPR from source tree], - MOZ_BUILD_NSPR=1, - MOZ_BUILD_NSPR=) -]) - -if test "$MOZ_BUILD_APP" != js || test -n "$JS_STANDALONE"; then - _IS_OUTER_CONFIGURE=1 -fi - -MOZ_ARG_WITH_BOOL(system-nspr, -[ --with-system-nspr Use an NSPR that is already built and installed. - Use the 'nspr-config' script in the current path, - or look for the script in the directories given with - --with-nspr-exec-prefix or --with-nspr-prefix. - (Those flags are only checked if you specify - --with-system-nspr.)], - _USE_SYSTEM_NSPR=1 ) - -JS_WITHOUT_NSPR=unset -ifdef([CONFIGURING_JS],[ - if test -n "$JS_STANDALONE"; then - if test -z "$_HAS_NSPR"; then - JS_WITHOUT_NSPR_DEFAULT=1 - fi - fi -]) - -dnl Pass at most one of -dnl --with-system-nspr -dnl --with-nspr-cflags/libs -dnl --enable-nspr-build - -AC_MSG_CHECKING([NSPR selection]) -nspr_opts= -which_nspr=default -if test -n "$_USE_SYSTEM_NSPR"; then - nspr_opts="x$nspr_opts" - which_nspr="system" -fi -if test -n "$NSPR_CFLAGS" -o -n "$NSPR_LIBS"; then - nspr_opts="x$nspr_opts" - which_nspr="command-line" -fi -if test -n "$MOZ_BUILD_NSPR"; then - nspr_opts="x$nspr_opts" - which_nspr="source-tree" -fi -if test "$JS_WITHOUT_NSPR" = unset; then - JS_WITHOUT_NSPR= -else - nspr_opts="x$nspr_opts" - which_nspr="without-nspr" -fi - -if test -z "$nspr_opts"; then - if test "$MOZ_BUILD_APP" != js; then - dnl Toplevel configure defaults to using nsprpub from the source tree - MOZ_BUILD_NSPR=1 - which_nspr="source-tree" - else - dnl JS configure defaults to no NSPR, falling back to nsprpub. - JS_WITHOUT_NSPR="$JS_WITHOUT_NSPR_DEFAULT" - if test -z "$JS_WITHOUT_NSPR"; then - MOZ_BUILD_NSPR=1 - which_nspr="source-tree" - else - which_nspr="without-nspr" - fi - fi -fi - -if test -z "$nspr_opts" || test "$nspr_opts" = x; then - AC_MSG_RESULT($which_nspr) -else - AC_MSG_ERROR([only one way of using NSPR may be selected. See 'configure --help'.]) -fi - -AC_SUBST(MOZ_BUILD_NSPR) - -if test "$MOZ_BUILD_APP" = js; then - if test "$JS_WITHOUT_NSPR" = 1; then - AC_DEFINE(JS_WITHOUT_NSPR) - fi - AC_SUBST(JS_WITHOUT_NSPR) -fi - -# A (sub)configure invoked by the toplevel configure will always receive -# --with-nspr-libs on the command line. It will never need to figure out -# anything itself. -if test -n "$_IS_OUTER_CONFIGURE"; then - -if test -n "$_USE_SYSTEM_NSPR"; then - AM_PATH_NSPR($NSPR_MINVER, [MOZ_SYSTEM_NSPR=1], [AC_MSG_ERROR([you do not have NSPR installed or your version is older than $NSPR_MINVER.])]) -fi - -if test -n "$MOZ_SYSTEM_NSPR" -o -n "$NSPR_CFLAGS" -o -n "$NSPR_LIBS"; then - _SAVE_CFLAGS=$CFLAGS - CFLAGS="$CFLAGS $NSPR_CFLAGS" - AC_TRY_COMPILE([#include "prtypes.h"], - [#ifndef PR_STATIC_ASSERT - #error PR_STATIC_ASSERT not defined or requires including prtypes.h - #endif], - , - AC_MSG_ERROR([system NSPR does not support PR_STATIC_ASSERT or including prtypes.h does not provide it])) - AC_TRY_COMPILE([#include "prtypes.h"], - [#ifndef PR_UINT64 - #error PR_UINT64 not defined or requires including prtypes.h - #endif], - , - AC_MSG_ERROR([system NSPR does not support PR_UINT64 or including prtypes.h does not provide it])) - CFLAGS=$_SAVE_CFLAGS - NSPR_INCLUDE_DIR=`echo ${NSPR_CFLAGS} | sed -e 's/.*-I\([[^ ]]*\).*/\1/'` - NSPR_LIB_DIR=`echo ${NSPR_LIBS} | sed -e 's/.*-L\([[^ ]]*\).*/\1/'` -elif test -z "$JS_WITHOUT_NSPR"; then - NSPR_INCLUDE_DIR="${DIST}/include/nspr" - NSPR_CFLAGS="-I${NSPR_INCLUDE_DIR}" - if test -n "$GNU_CC"; then - if test -n "$MOZ_FOLD_LIBS"; then - NSPR_LIB_DIR=${DIST}/lib - else - NSPR_LIB_DIR=${DIST}/bin - fi - NSPR_LIBS="-L${NSPR_LIB_DIR} -lnspr${NSPR_VERSION} -lplc${NSPR_VERSION} -lplds${NSPR_VERSION}" - else - # NSS needs actual static libs to link to, and this is where they are. - NSPR_LIBS="${DIST}/lib/nspr${NSPR_VERSION}.lib ${DIST}/lib/plc${NSPR_VERSION}.lib ${DIST}/lib/plds${NSPR_VERSION}.lib " - NSPR_LIB_DIR="${DIST}/lib" - fi -fi - -AC_SUBST_LIST(NSPR_CFLAGS) -AC_SUBST(NSPR_INCLUDE_DIR) -AC_SUBST(NSPR_LIB_DIR) - -PKGCONF_REQUIRES_PRIVATE="Requires.private: nspr" -if test -n "$MOZ_SYSTEM_NSPR"; then - _SAVE_CFLAGS=$CFLAGS - CFLAGS="$CFLAGS $NSPR_CFLAGS" - AC_TRY_COMPILE([#include "prlog.h"], - [#ifndef PR_STATIC_ASSERT - #error PR_STATIC_ASSERT not defined - #endif], - , - AC_MSG_ERROR([system NSPR does not support PR_STATIC_ASSERT])) - CFLAGS=$_SAVE_CFLAGS - # piggy back on $MOZ_SYSTEM_NSPR to set a variable for the nspr check for js.pc - PKGCONF_REQUIRES_PRIVATE="Requires.private: nspr >= $NSPR_MINVER" -elif test -n "$JS_WITHOUT_NSPR"; then - PKGCONF_REQUIRES_PRIVATE= -fi -AC_SUBST([PKGCONF_REQUIRES_PRIVATE]) - -fi # _IS_OUTER_CONFIGURE - -]) diff --git a/build/autoconf/nspr.m4 b/build/autoconf/nspr.m4 deleted file mode 100644 index afd27bfdef..0000000000 --- a/build/autoconf/nspr.m4 +++ /dev/null @@ -1,109 +0,0 @@ -# Configure paths for NSPR -# Public domain - Chris Seawood 2001-04-05 -# Based upon gtk.m4 (also PD) by Owen Taylor - -dnl AM_PATH_NSPR([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) -dnl Test for NSPR, and define NSPR_CFLAGS and NSPR_LIBS -dnl -dnl If the nspr-config script is available, use it to find the -dnl appropriate CFLAGS and LIBS, and to check for the required -dnl version, and run ACTION-IF-FOUND. -dnl -dnl Otherwise, if NO_NSPR_CONFIG_SYSTEM_VERSION is set, we use it, -dnl NO_NSPR_CONFIG_SYSTEM_CFLAGS, and NO_NSPR_CONFIG_SYSTEM_LIBS to -dnl provide default values, and run ACTION-IF-FOUND. (Some systems -dnl ship NSPR without nspr-config, but can glean the appropriate flags -dnl and version.) -dnl -dnl Otherwise, run ACTION-IF-NOT-FOUND. -AC_DEFUN([AM_PATH_NSPR], -[dnl - -AC_ARG_WITH(nspr-prefix, - [ --with-nspr-prefix=PFX Prefix where NSPR is installed], - nspr_config_prefix="$withval", - nspr_config_prefix="") - -AC_ARG_WITH(nspr-exec-prefix, - [ --with-nspr-exec-prefix=PFX - Exec prefix where NSPR is installed], - nspr_config_exec_prefix="$withval", - nspr_config_exec_prefix="") - - if test -n "$nspr_config_exec_prefix"; then - nspr_config_args="$nspr_config_args --exec-prefix=$nspr_config_exec_prefix" - if test -z "$NSPR_CONFIG"; then - NSPR_CONFIG=$nspr_config_exec_prefix/bin/nspr-config - fi - fi - if test -n "$nspr_config_prefix"; then - nspr_config_args="$nspr_config_args --prefix=$nspr_config_prefix" - if test -z "$NSPR_CONFIG"; then - NSPR_CONFIG=$nspr_config_prefix/bin/nspr-config - fi - fi - - unset ac_cv_path_NSPR_CONFIG - AC_PATH_PROG(NSPR_CONFIG, nspr-config, no) - min_nspr_version=ifelse([$1], ,4.0.0,$1) - AC_MSG_CHECKING(for NSPR - version >= $min_nspr_version) - - no_nspr="" - if test "$NSPR_CONFIG" != "no"; then - NSPR_CFLAGS=`$NSPR_CONFIG $nspr_config_args --cflags` - NSPR_LIBS=`$NSPR_CONFIG $nspr_config_args --libs` - NSPR_VERSION_STRING=`$NSPR_CONFIG $nspr_config_args --version` - elif test -n "${NO_NSPR_CONFIG_SYSTEM_VERSION}"; then - NSPR_CFLAGS="${NO_NSPR_CONFIG_SYSTEM_CFLAGS}" - NSPR_LIBS="${NO_NSPR_CONFIG_SYSTEM_LDFLAGS}" - NSPR_VERSION_STRING="$NO_NSPR_CONFIG_SYSTEM_VERSION" - else - no_nspr="yes" - fi - - if test -z "$no_nspr"; then - nspr_config_major_version=`echo $NSPR_VERSION_STRING | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.\([[0-9]]*\)\)\{0,1\}/\1/'` - nspr_config_minor_version=`echo $NSPR_VERSION_STRING | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.\([[0-9]]*\)\)\{0,1\}/\2/'` - nspr_config_micro_version=`echo $NSPR_VERSION_STRING | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.\([[0-9]]*\)\)\{0,1\}/\4/'` - if test -z "$nspr_config_micro_version"; then - nspr_config_micro_version="0" - fi - - min_nspr_major_version=`echo $min_nspr_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.\([[0-9]]*\)\)\{0,1\}/\1/'` - min_nspr_minor_version=`echo $min_nspr_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.\([[0-9]]*\)\)\{0,1\}/\2/'` - min_nspr_micro_version=`echo $min_nspr_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.\([[0-9]]*\)\)\{0,1\}/\4/'` - if test -z "$min_nspr_micro_version"; then - min_nspr_micro_version="0" - fi - - if test "$nspr_config_major_version" -ne "$min_nspr_major_version"; then - no_nspr="yes" - elif test "$nspr_config_major_version" -eq "$min_nspr_major_version" && - test "$nspr_config_minor_version" -lt "$min_nspr_minor_version"; then - no_nspr="yes" - elif test "$nspr_config_major_version" -eq "$min_nspr_major_version" && - test "$nspr_config_minor_version" -eq "$min_nspr_minor_version" && - test "$nspr_config_micro_version" -lt "$min_nspr_micro_version"; then - no_nspr="yes" - fi - fi - - if test -z "$no_nspr"; then - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - AC_MSG_RESULT(no) - ifelse([$3], , :, [$3]) - fi - - - AC_SUBST_LIST(NSPR_CFLAGS) - AC_SUBST_LIST(NSPR_LIBS) - -]) diff --git a/build/autoconf/nss.m4 b/build/autoconf/nss.m4 deleted file mode 100644 index 7924b16060..0000000000 --- a/build/autoconf/nss.m4 +++ /dev/null @@ -1,90 +0,0 @@ -# Configure paths for NSS -# Public domain - Chris Seawood 2001-04-05 -# Based upon gtk.m4 (also PD) by Owen Taylor - -dnl AM_PATH_NSS([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) -dnl Test for NSS, and define NSS_CFLAGS and NSS_LIBS -AC_DEFUN([AM_PATH_NSS], -[dnl - -AC_ARG_WITH(nss-prefix, - [ --with-nss-prefix=PFX Prefix where NSS is installed], - nss_config_prefix="$withval", - nss_config_prefix="") - -AC_ARG_WITH(nss-exec-prefix, - [ --with-nss-exec-prefix=PFX - Exec prefix where NSS is installed], - nss_config_exec_prefix="$withval", - nss_config_exec_prefix="") - - if test -n "$nss_config_exec_prefix"; then - nss_config_args="$nss_config_args --exec-prefix=$nss_config_exec_prefix" - if test -z "$NSS_CONFIG"; then - NSS_CONFIG=$nss_config_exec_prefix/bin/nss-config - fi - fi - if test -n "$nss_config_prefix"; then - nss_config_args="$nss_config_args --prefix=$nss_config_prefix" - if test -z "$NSS_CONFIG"; then - NSS_CONFIG=$nss_config_prefix/bin/nss-config - fi - fi - - unset ac_cv_path_NSS_CONFIG - AC_PATH_PROG(NSS_CONFIG, nss-config, no) - min_nss_version=ifelse([$1], ,3.0.0,$1) - AC_MSG_CHECKING(for NSS - version >= $min_nss_version) - - no_nss="" - if test "$NSS_CONFIG" = "no"; then - no_nss="yes" - else - NSS_CFLAGS=`$NSS_CONFIG $nss_config_args --cflags` - NSS_LIBS=`$NSS_CONFIG $nss_config_args --libs` - - nss_config_major_version=`$NSS_CONFIG $nss_config_args --version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.\([[0-9]]*\)\)\{0,1\}/\1/'` - nss_config_minor_version=`$NSS_CONFIG $nss_config_args --version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.\([[0-9]]*\)\)\{0,1\}/\2/'` - nss_config_micro_version=`$NSS_CONFIG $nss_config_args --version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.\([[0-9]]*\)\)\{0,1\}/\4/'` - if test -z "$nss_config_micro_version"; then - nss_config_micro_version="0" - fi - - min_nss_major_version=`echo $min_nss_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.\([[0-9]]*\)\)\{0,1\}/\1/'` - min_nss_minor_version=`echo $min_nss_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.\([[0-9]]*\)\)\{0,1\}/\2/'` - min_nss_micro_version=`echo $min_nss_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.\([[0-9]]*\)\)\{0,1\}/\4/'` - if test -z "$min_nss_micro_version"; then - min_nss_micro_version="0" - fi - - if test "$nss_config_major_version" -lt "$min_nss_major_version"; then - no_nss="yes" - elif test "$nss_config_major_version" -eq "$min_nss_major_version" && - test "$nss_config_minor_version" -lt "$min_nss_minor_version"; then - no_nss="yes" - elif test "$nss_config_major_version" -eq "$min_nss_major_version" && - test "$nss_config_minor_version" -eq "$min_nss_minor_version" && - test "$nss_config_micro_version" -lt "$min_nss_micro_version"; then - no_nss="yes" - fi - fi - - if test -z "$no_nss"; then - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - AC_MSG_RESULT(no) - ifelse([$3], , :, [$3]) - fi - - - AC_SUBST_LIST(NSS_CFLAGS) - AC_SUBST_LIST(NSS_LIBS) - -]) diff --git a/build/autoconf/zlib.m4 b/build/autoconf/zlib.m4 deleted file mode 100644 index 49a2ccc8bf..0000000000 --- a/build/autoconf/zlib.m4 +++ /dev/null @@ -1,54 +0,0 @@ -dnl This Source Code Form is subject to the terms of the Mozilla Public -dnl License, v. 2.0. If a copy of the MPL was not distributed with this -dnl file, You can obtain one at http://mozilla.org/MPL/2.0/. - -dnl Usage: MOZ_ZLIB_CHECK([version]) - -AC_DEFUN([MOZ_ZLIB_CHECK], -[ - -MOZZLIB=$1 - -MOZ_ARG_WITH_STRING(system-zlib, -[ --with-system-zlib[=PFX] - Use system libz [installed at prefix PFX]], - ZLIB_DIR=$withval) - -if test -z "$MOZ_ZLIB_LIBS$MOZ_ZLIB_CFLAGS$SKIP_LIBRARY_CHECKS"; then - _SAVE_CFLAGS=$CFLAGS - _SAVE_LDFLAGS=$LDFLAGS - _SAVE_LIBS=$LIBS - - if test -n "${ZLIB_DIR}" -a "${ZLIB_DIR}" != "yes"; then - MOZ_ZLIB_CFLAGS="-I${ZLIB_DIR}/include" - MOZ_ZLIB_LIBS="-L${ZLIB_DIR}/lib" - CFLAGS="$MOZ_ZLIB_CFLAGS $CFLAGS" - LDFLAGS="$MOZ_ZLIB_LIBS $LDFLAGS" - fi - if test -z "$ZLIB_DIR" -o "$ZLIB_DIR" = no; then - MOZ_SYSTEM_ZLIB= - else - AC_CHECK_LIB(z, gzread, [MOZ_SYSTEM_ZLIB=1 MOZ_ZLIB_LIBS="$MOZ_ZLIB_LIBS -lz"], - [MOZ_SYSTEM_ZLIB=]) - if test "$MOZ_SYSTEM_ZLIB" = 1; then - MOZZLIBNUM=`echo $MOZZLIB | awk -F. changequote(<<, >>)'{printf "0x%x\n", (((<<$>>1 * 16 + <<$>>2) * 16) + <<$>>3) * 16 + <<$>>4}'changequote([, ])` - AC_TRY_COMPILE([ #include - #include - #include ], - [ #if ZLIB_VERNUM < $MOZZLIBNUM - #error "Insufficient zlib version ($MOZZLIBNUM required)." - #endif ], - MOZ_SYSTEM_ZLIB=1, - AC_MSG_ERROR([Insufficient zlib version for --with-system-zlib ($MOZZLIB required)])) - fi - fi - CFLAGS=$_SAVE_CFLAGS - LDFLAGS=$_SAVE_LDFLAGS - LIBS=$_SAVE_LIBS -fi - -AC_SUBST_LIST(MOZ_ZLIB_CFLAGS) -AC_SUBST_LIST(MOZ_ZLIB_LIBS) -AC_SUBST(MOZ_SYSTEM_ZLIB) - -]) diff --git a/build/build-clang/llvmorg-11-init-4265-g2dcbdba8540.patch b/build/build-clang/llvmorg-11-init-4265-g2dcbdba8540.patch new file mode 100644 index 0000000000..66432bccf4 --- /dev/null +++ b/build/build-clang/llvmorg-11-init-4265-g2dcbdba8540.patch @@ -0,0 +1,106 @@ +diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc +index 9a184c79798..733decfe52c 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc ++++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc +@@ -1021,7 +1021,7 @@ TSAN_INTERCEPTOR(int, pthread_create, + + TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) { + SCOPED_INTERCEPTOR_RAW(pthread_join, th, ret); +- int tid = ThreadTid(thr, pc, (uptr)th); ++ int tid = ThreadConsumeTid(thr, pc, (uptr)th); + ThreadIgnoreBegin(thr, pc); + int res = BLOCK_REAL(pthread_join)(th, ret); + ThreadIgnoreEnd(thr, pc); +@@ -1034,8 +1034,8 @@ TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) { + DEFINE_REAL_PTHREAD_FUNCTIONS + + TSAN_INTERCEPTOR(int, pthread_detach, void *th) { +- SCOPED_TSAN_INTERCEPTOR(pthread_detach, th); +- int tid = ThreadTid(thr, pc, (uptr)th); ++ SCOPED_INTERCEPTOR_RAW(pthread_detach, th); ++ int tid = ThreadConsumeTid(thr, pc, (uptr)th); + int res = REAL(pthread_detach)(th); + if (res == 0) { + ThreadDetach(thr, pc, tid); +@@ -1055,8 +1055,8 @@ TSAN_INTERCEPTOR(void, pthread_exit, void *retval) { + + #if SANITIZER_LINUX + TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) { +- SCOPED_TSAN_INTERCEPTOR(pthread_tryjoin_np, th, ret); +- int tid = ThreadTid(thr, pc, (uptr)th); ++ SCOPED_INTERCEPTOR_RAW(pthread_tryjoin_np, th, ret); ++ int tid = ThreadConsumeTid(thr, pc, (uptr)th); + ThreadIgnoreBegin(thr, pc); + int res = REAL(pthread_tryjoin_np)(th, ret); + ThreadIgnoreEnd(thr, pc); +@@ -1069,8 +1069,8 @@ TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) { + + TSAN_INTERCEPTOR(int, pthread_timedjoin_np, void *th, void **ret, + const struct timespec *abstime) { +- SCOPED_TSAN_INTERCEPTOR(pthread_timedjoin_np, th, ret, abstime); +- int tid = ThreadTid(thr, pc, (uptr)th); ++ SCOPED_INTERCEPTOR_RAW(pthread_timedjoin_np, th, ret, abstime); ++ int tid = ThreadConsumeTid(thr, pc, (uptr)th); + ThreadIgnoreBegin(thr, pc); + int res = BLOCK_REAL(pthread_timedjoin_np)(th, ret, abstime); + ThreadIgnoreEnd(thr, pc); +diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h +index 3a8231bda9a..30e144fbd00 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h ++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h +@@ -772,7 +772,7 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached); + void ThreadStart(ThreadState *thr, int tid, tid_t os_id, + ThreadType thread_type); + void ThreadFinish(ThreadState *thr); +-int ThreadTid(ThreadState *thr, uptr pc, uptr uid); ++int ThreadConsumeTid(ThreadState *thr, uptr pc, uptr uid); + void ThreadJoin(ThreadState *thr, uptr pc, int tid); + void ThreadDetach(ThreadState *thr, uptr pc, int tid); + void ThreadFinalize(ThreadState *thr); +diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc +index fd95cfed4f5..13e457bd770 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc ++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc +@@ -285,19 +285,34 @@ void ThreadFinish(ThreadState *thr) { + ctx->thread_registry->FinishThread(thr->tid); + } + +-static bool FindThreadByUid(ThreadContextBase *tctx, void *arg) { +- uptr uid = (uptr)arg; +- if (tctx->user_id == uid && tctx->status != ThreadStatusInvalid) { ++struct ConsumeThreadContext { ++ uptr uid; ++ ThreadContextBase* tctx; ++}; ++ ++static bool ConsumeThreadByUid(ThreadContextBase *tctx, void *arg) { ++ ConsumeThreadContext *findCtx = (ConsumeThreadContext*)arg; ++ if (tctx->user_id == findCtx->uid && tctx->status != ThreadStatusInvalid) { ++ if (findCtx->tctx) { ++ // Ensure that user_id is unique. If it's not the case we are screwed. ++ // Something went wrong before, but now there is no way to recover. ++ // Returning a wrong thread is not an option, it may lead to very hard ++ // to debug false positives (e.g. if we join a wrong thread). ++ Report("ThreadSanitizer: dup thread with used id 0x%zx\n", findCtx->uid); ++ Die(); ++ } ++ findCtx->tctx = tctx; + tctx->user_id = 0; +- return true; + } + return false; + } + +-int ThreadTid(ThreadState *thr, uptr pc, uptr uid) { +- int res = ctx->thread_registry->FindThread(FindThreadByUid, (void*)uid); +- DPrintf("#%d: ThreadTid uid=%zu tid=%d\n", thr->tid, uid, res); +- return res; ++int ThreadConsumeTid(ThreadState *thr, uptr pc, uptr uid) { ++ ConsumeThreadContext findCtx = {uid, nullptr}; ++ ctx->thread_registry->FindThread(ConsumeThreadByUid, &findCtx); ++ int tid = findCtx.tctx ? findCtx.tctx->tid : ThreadRegistry::kUnknownTid; ++ DPrintf("#%d: ThreadTid uid=%zu tid=%d\n", thr->tid, uid, tid); ++ return tid; + } + + void ThreadJoin(ThreadState *thr, uptr pc, int tid) { diff --git a/build/docs/mozinfo.rst b/build/docs/mozinfo.rst index 709ae87804..795ee3c219 100644 --- a/build/docs/mozinfo.rst +++ b/build/docs/mozinfo.rst @@ -167,3 +167,10 @@ topsrcdir The path to the source directory the build came from. Always defined. + +webrender + Whether or not WebRender is enabled as the Gecko compositor. + + Values are ``true`` and ``false``. + + Always defined. diff --git a/build/docs/pgo.rst b/build/docs/pgo.rst index ed714f8344..722056c727 100644 --- a/build/docs/pgo.rst +++ b/build/docs/pgo.rst @@ -23,17 +23,6 @@ Then:: This is roughly equivalent to:: -#. Perform a build with *MOZ_PROFILE_GENERATE=1* -#. Performing a run of the instrumented binaries -#. $ make maybe_clobber_profiledbuild -#. Perform a build with *MOZ_PROFILE_USE=1* - -Differences between toolchains -============================== - -There are some implementation differences depending on the compiler -toolchain being used. - -The *maybe_clobber_profiledbuild* step gets its name because of a -difference. On Windows, this step merely moves some *.pgc* files around. -Using GCC or Clang, it is equivalent to a *make clean*. +#. Perform a build with *--enable-profile-generate* in $topobjdir/instrumented +#. Perform a run of the instrumented binaries with build/pgo/profileserver.py +#. Perform a build with *--enable-profile-use* in $topobjdir diff --git a/build/docs/test_certificates.rst b/build/docs/test_certificates.rst index 32ab89fd62..c8394f7785 100644 --- a/build/docs/test_certificates.rst +++ b/build/docs/test_certificates.rst @@ -1,8 +1,8 @@ .. _test_certificates: -============== +=============================== Adding Certificates for Testing -============== +=============================== Sometimes we need to write tests for scenarios that require custom client, server or certificate authority (CA) certificates. For that purpose, you can generate such certificates using ``build/pgo/genpgocert.py``. diff --git a/build/mach_bootstrap.py b/build/mach_bootstrap.py index aa94db31cc..d3e5d21183 100644 --- a/build/mach_bootstrap.py +++ b/build/mach_bootstrap.py @@ -36,6 +36,7 @@ MACH_MODULES = [ 'build/valgrind/mach_commands.py', 'devtools/shared/css/generated/mach_commands.py', 'dom/bindings/mach_commands.py', + 'gfx/thebes/mach_commands.py', 'layout/tools/reftest/mach_commands.py', 'python/mach_commands.py', 'python/safety/mach_commands.py', @@ -43,7 +44,10 @@ MACH_MODULES = [ 'python/mach/mach/commands/settings.py', 'python/mozboot/mozboot/mach_commands.py', 'python/mozbuild/mozbuild/mach_commands.py', + 'python/mozbuild/mozbuild/artifact_commands.py', + 'python/mozbuild/mozbuild/build_commands.py', 'python/mozbuild/mozbuild/backend/mach_commands.py', + 'python/mozbuild/mozbuild/code-analysis/mach_commands.py', 'python/mozbuild/mozbuild/compilation/codecomplete.py', 'python/mozbuild/mozbuild/frontend/mach_commands.py', 'python/mozrelease/mozrelease/mach_commands.py', diff --git a/build/macosx/local-mozconfig.common b/build/macosx/local-mozconfig.common index be87140169..fbcc9171be 100644 --- a/build/macosx/local-mozconfig.common +++ b/build/macosx/local-mozconfig.common @@ -4,26 +4,16 @@ . "$topsrcdir/build/mozconfig.common" -if [ -d "$topsrcdir/clang" ]; then +if [ -d "$MOZ_FETCHES_DIR/clang" ]; then # mozilla-central based build - export CC=$topsrcdir/clang/bin/clang - export CXX=$topsrcdir/clang/bin/clang++ - export LLVMCONFIG=$topsrcdir/clang/bin/llvm-config - export DSYMUTIL=$topsrcdir/clang/bin/llvm-dsymutil + export CC=$MOZ_FETCHES_DIR/clang/bin/clang + export CXX=$MOZ_FETCHES_DIR/clang/bin/clang++ + export LLVMCONFIG=$MOZ_FETCHES_DIR/clang/bin/llvm-config + export DSYMUTIL=$MOZ_FETCHES_DIR/clang/bin/llvm-dsymutil # Use an updated linker. - ldflags="-B$topsrcdir/cctools/bin" - export AR=$topsrcdir/cctools/bin/ar - export RANLIB=$topsrcdir/cctools/bin/ranlib -elif [ -d "$topsrcdir/../clang" ]; then - # comm-central based build - export CC=$topsrcdir/../clang/bin/clang - export CXX=$topsrcdir/../clang/bin/clang++ - export LLVMCONFIG=$topsrcdir/../clang/bin/llvm-config - export DSYMUTIL=$topsrcdir/../clang/bin/llvm-dsymutil - # Use an updated linker. - ldflags="-B$topsrcdir/../cctools/bin" - export AR=$topsrcdir/../cctools/bin/ar - export RANLIB=$topsrcdir/../cctools/bin/ranlib + ldflags="-B$MOZ_FETCHES_DIR/cctools/bin" + export AR=$MOZ_FETCHES_DIR/cctools/bin/ar + export RANLIB=$MOZ_FETCHES_DIR/cctools/bin/ranlib fi # Ensure the updated linker doesn't generate things our older build tools diff --git a/build/merge_profdata.py b/build/merge_profdata.py deleted file mode 100644 index cf6a80ee82..0000000000 --- a/build/merge_profdata.py +++ /dev/null @@ -1,18 +0,0 @@ -# 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/. - -import glob -import subprocess -import sys -import buildconfig - - -def main(_, profile_dir): - profraw_files = glob.glob(profile_dir + '/*.profraw') - if not profraw_files: - print('Could not find any profraw files in ' + profile_dir) - sys.exit(1) - - subprocess.check_call([buildconfig.substs['LLVM_PROFDATA'], 'merge', - '-o', 'merged.profdata'] + profraw_files) diff --git a/build/moz-automation.mk b/build/moz-automation.mk index f6504b318c..22cd2320a8 100644 --- a/build/moz-automation.mk +++ b/build/moz-automation.mk @@ -8,6 +8,26 @@ ifndef ENABLE_TESTS MOZ_AUTOMATION_PACKAGE_TESTS = 0 endif +ifdef CROSS_COMPILE +# Narrow the definition of cross compilation to not include win32 builds +# on win64 and linux32 builds on linux64. +ifeq ($(HOST_OS_ARCH),$(OS_TARGET)) +ifneq (,$(filter x86%,$(CPU_ARCH))) +FUZZY_CROSS_COMPILE = +else +FUZZY_CROSS_COMPILE = 1 +endif +else +FUZZY_CROSS_COMPILE = 1 +endif +endif + +# Don't run make check when cross compiling, when doing artifact builds +# or when building instrumented builds for PGO. +ifneq (,$(USE_ARTIFACT)$(FUZZY_CROSS_COMPILE)$(MOZ_PROFILE_GENERATE)) +MOZ_AUTOMATION_CHECK := 0 +endif + ifneq (,$(filter automation/%,$(MAKECMDGOALS))) ifeq (4.0,$(firstword $(sort 4.0 $(MAKE_VERSION)))) MAKEFLAGS += --output-sync=target @@ -33,6 +53,7 @@ tier_MOZ_AUTOMATION_PACKAGE_TESTS = package-tests tier_MOZ_AUTOMATION_PACKAGE_GENERATED_SOURCES = package-generated-sources tier_MOZ_AUTOMATION_UPLOAD_SYMBOLS = uploadsymbols tier_MOZ_AUTOMATION_UPLOAD = upload +tier_MOZ_AUTOMATION_CHECK = check # Automation build steps. Everything in MOZ_AUTOMATION_TIERS also gets used in # TIERS for mach display. As such, the MOZ_AUTOMATION_TIERS are roughly sorted @@ -46,18 +67,22 @@ moz_automation_symbols = \ MOZ_AUTOMATION_PACKAGE_GENERATED_SOURCES \ MOZ_AUTOMATION_L10N_CHECK \ MOZ_AUTOMATION_UPLOAD \ + MOZ_AUTOMATION_CHECK \ $(NULL) MOZ_AUTOMATION_TIERS := $(foreach sym,$(moz_automation_symbols),$(if $(filter 1,$($(sym))),$(tier_$(sym)))) # Dependencies between automation build steps -automation/uploadsymbols: automation/buildsymbols +automation-start/uploadsymbols: automation/buildsymbols -automation/l10n-check: automation/package +automation-start/l10n-check: automation/package -automation/upload: automation/package -automation/upload: automation/package-tests -automation/upload: automation/buildsymbols -automation/upload: automation/package-generated-sources +automation-start/upload: automation/package +automation-start/upload: automation/package-tests +automation-start/upload: automation/buildsymbols +automation-start/upload: automation/package-generated-sources + +# Run the check tier after everything else. +automation-start/check: $(addprefix automation/,$(filter-out check,$(MOZ_AUTOMATION_TIERS))) automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS)) @echo Automation steps completed. @@ -65,6 +90,9 @@ automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS)) # Note: We have to force -j1 here, at least until bug 1036563 is fixed. AUTOMATION_EXTRA_CMDLINE-l10n-check = -j1 +# Run as many tests as possible, even in case of one of them failing. +AUTOMATION_EXTRA_CMDLINE-check = --keep-going + # The commands only run if the corresponding MOZ_AUTOMATION_* variable is # enabled. This means, for example, if we enable MOZ_AUTOMATION_UPLOAD, then # 'buildsymbols' will only run if MOZ_AUTOMATION_BUILD_SYMBOLS is also set. diff --git a/build/moz.configure/android-ndk.configure b/build/moz.configure/android-ndk.configure index 175445b24b..c7a40a878a 100644 --- a/build/moz.configure/android-ndk.configure +++ b/build/moz.configure/android-ndk.configure @@ -12,12 +12,12 @@ def default_android_ndk_root(mozbuild_state_path, _): return path -js_option('--with-android-ndk', nargs=1, - default=default_android_ndk_root, - help='location where the Android NDK can be found{|}') +option('--with-android-ndk', nargs=1, + default=default_android_ndk_root, + help='location where the Android NDK can be found{|}') -js_option('--with-android-toolchain', nargs=1, - help='location of the Android toolchain') +option('--with-android-toolchain', nargs=1, + help='location of the Android toolchain') option('--with-android-googlevr-sdk', nargs=1, help='location of the Android GoogleVR SDK') @@ -31,10 +31,10 @@ def min_android_version(target): return '16' -js_option('--with-android-version', - nargs=1, - help='android platform version{|}', - default=min_android_version) +option('--with-android-version', + nargs=1, + help='android platform version{|}', + default=min_android_version) @depends('--with-android-version', min_android_version) @@ -156,6 +156,7 @@ def android_platform(target, android_version, ndk): add_old_configure_assignment('android_platform', android_platform) +set_config('ANDROID_PLATFORM', android_platform) @depends(android_platform, ndk, target) @@ -256,9 +257,9 @@ def android_toolchain_prefix_base(target): return target.toolchain -js_option(env='STLPORT_CPPFLAGS', - nargs=1, - help='Options compiler should pass for standard C++ library') +option(env='STLPORT_CPPFLAGS', + nargs=1, + help='Options compiler should pass for standard C++ library') @depends('STLPORT_CPPFLAGS', ndk) diff --git a/build/moz.configure/android-sdk.configure b/build/moz.configure/android-sdk.configure index 342976b347..3aafacf46d 100644 --- a/build/moz.configure/android-sdk.configure +++ b/build/moz.configure/android-sdk.configure @@ -39,7 +39,7 @@ def android_sdk_root(value): @depends('--help') def android_sdk_version(_): - return namespace(build_tools_versions=['27.0.3'], target_sdk_version='28') + return namespace(build_tools_versions=['28.0.3'], target_sdk_version='28') @depends(android_sdk_root, android_sdk_version) diff --git a/build/moz.configure/arm.configure b/build/moz.configure/arm.configure index 0022916bda..0b8025d758 100644 --- a/build/moz.configure/arm.configure +++ b/build/moz.configure/arm.configure @@ -24,10 +24,10 @@ def arm_option_defaults(os, _): # default is always returned. The lint is fooled by this file being # conditional. If it weren't conditional, the lint wouldn't ask for '{|}' to # be there. -js_option('--with-arch', nargs=1, - default=arm_option_defaults.arch, - help='{Use specific CPU features (-march=type). Resets thumb, fpu, ' - 'float-abi, etc. defaults when set|}') +option('--with-arch', nargs=1, + default=arm_option_defaults.arch, + help='{Use specific CPU features (-march=type). Resets thumb, fpu, ' + 'float-abi, etc. defaults when set|}') @depends('--with-arch') @@ -38,9 +38,9 @@ def arch_option(value): return [] -js_option('--with-thumb', choices=('yes', 'no', 'toolchain-default'), - default=arm_option_defaults.thumb, - nargs='?', help='{Use Thumb instruction set (-mthumb)|}') +option('--with-thumb', choices=('yes', 'no', 'toolchain-default'), + default=arm_option_defaults.thumb, + nargs='?', help='{Use Thumb instruction set (-mthumb)|}') def normalize_arm_option(value): @@ -65,9 +65,9 @@ def thumb_option(value): return [] -js_option('--with-thumb-interwork', choices=('yes', 'no', 'toolchain-default'), - default='toolchain-default', - nargs='?', help='Use Thumb/ARM instuctions interwork (-mthumb-interwork)') +option('--with-thumb-interwork', choices=('yes', 'no', 'toolchain-default'), + default='toolchain-default', + nargs='?', help='Use Thumb/ARM instuctions interwork (-mthumb-interwork)') @depends('--with-thumb-interwork') @@ -80,9 +80,9 @@ def thumb_interwork_option(value): return [] -js_option('--with-fpu', nargs=1, - default=arm_option_defaults.fpu, - help='{Use specific FPU type (-mfpu=type)|}') +option('--with-fpu', nargs=1, + default=arm_option_defaults.fpu, + help='{Use specific FPU type (-mfpu=type)|}') @depends('--with-fpu') @@ -93,9 +93,9 @@ def fpu_option(value): return [] -js_option('--with-float-abi', nargs=1, - default=arm_option_defaults.float_abi, - help='{Use specific arm float ABI (-mfloat-abi=type)|}') +option('--with-float-abi', nargs=1, + default=arm_option_defaults.float_abi, + help='{Use specific arm float ABI (-mfloat-abi=type)|}') @depends('--with-float-abi') @@ -106,9 +106,9 @@ def float_abi_option(value): return [] -js_option('--with-soft-float', choices=('yes', 'no', 'toolchain-default'), - default='toolchain-default', - nargs='?', help='Use soft float library (-msoft-float)') +option('--with-soft-float', choices=('yes', 'no', 'toolchain-default'), + default='toolchain-default', + nargs='?', help='Use soft float library (-msoft-float)') @depends('--with-soft-float') diff --git a/build/moz.configure/bindgen.configure b/build/moz.configure/bindgen.configure index 5ed59dd797..5bf3479820 100644 --- a/build/moz.configure/bindgen.configure +++ b/build/moz.configure/bindgen.configure @@ -60,16 +60,16 @@ def cbindgen(cbindgen_override, toolchain_search_path): set_config('CBINDGEN', cbindgen) # Bindgen can use rustfmt to format Rust file, but it's not required. -js_option(env='RUSTFMT', nargs=1, help='Path to the rustfmt program') +option(env='RUSTFMT', nargs=1, help='Path to the rustfmt program') rustfmt = check_prog('RUSTFMT', ['rustfmt'], paths=toolchain_search_path, input='RUSTFMT', allow_missing=True) -js_option('--with-libclang-path', nargs=1, - help='Absolute path to a directory containing Clang/LLVM libraries for bindgen (version 3.9.x or above)') -js_option('--with-clang-path', nargs=1, - help='Absolute path to a Clang binary for bindgen (version 3.9.x or above)') +option('--with-libclang-path', nargs=1, + help='Absolute path to a directory containing Clang/LLVM libraries for bindgen (version 3.9.x or above)') +option('--with-clang-path', nargs=1, + help='Absolute path to a Clang binary for bindgen (version 3.9.x or above)') @depends('--with-clang-path', c_compiler, cxx_compiler, toolchain_search_path, @@ -278,9 +278,9 @@ def basic_bindgen_cflags(target, is_unix, compiler_info, android_cflags, return args + (clang_flags or []) -js_option(env='BINDGEN_CFLAGS', - nargs=1, - help='Options bindgen should pass to the C/C++ parser') +option(env='BINDGEN_CFLAGS', + nargs=1, + help='Options bindgen should pass to the C/C++ parser') @depends(basic_bindgen_cflags, 'BINDGEN_CFLAGS') diff --git a/build/moz.configure/headers.configure b/build/moz.configure/headers.configure index eda75ee9a8..b11fb09fa7 100644 --- a/build/moz.configure/headers.configure +++ b/build/moz.configure/headers.configure @@ -66,9 +66,9 @@ check_headers( have_perf_event_h = check_header('linux/perf_event.h', when=building_linux) -js_option('--with-linux-headers', - help='location where the Linux kernel headers can be found', - nargs=1) +option('--with-linux-headers', + help='location where the Linux kernel headers can be found', + nargs=1) passed_linux_header_flags = depends_if( '--with-linux-headers')(lambda v: ['-I%s' % v[0]]) diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure index fcfa4a47fd..a9a8eab4a4 100644 --- a/build/moz.configure/init.configure +++ b/build/moz.configure/init.configure @@ -112,15 +112,12 @@ def check_build_environment(help, dist): set_config('TOPSRCDIR', check_build_environment.topsrcdir) set_config('TOPOBJDIR', check_build_environment.topobjdir) -set_config('MOZ_BUILD_ROOT', check_build_environment.topobjdir) set_config('DIST', check_build_environment.dist) add_old_configure_assignment( '_topsrcdir', check_build_environment.topsrcdir) add_old_configure_assignment( '_objdir', check_build_environment.topobjdir) -add_old_configure_assignment( - 'MOZ_BUILD_ROOT', check_build_environment.topobjdir) add_old_configure_assignment( 'DIST', check_build_environment.dist) @@ -670,9 +667,6 @@ def split_triplet(triplet, allow_unknown=False): elif os.startswith('darwin'): canonical_kernel = 'Darwin' canonical_os = 'OSX' - elif os.startswith('ios'): - canonical_kernel = 'Darwin' - canonical_os = 'iOS' elif os.startswith('dragonfly'): canonical_os = canonical_kernel = 'DragonFly' elif os.startswith('freebsd'): @@ -916,26 +910,16 @@ set_config('HOST_MAJOR_VERSION', host_os_kernel_major_version) @depends(host) -def host_for_old_configure(host): +def host_for_sub_configure(host): return '--host=%s' % host.alias -add_old_configure_arg(host_for_old_configure) - - @depends(target) -def target_for_old_configure(target): +def target_for_sub_configure(target): target_alias = target.alias - # old-configure does plenty of tests against $target and $target_os - # and expects darwin for iOS, so make it happy. - if target.os == 'iOS': - target_alias = target_alias.replace('-ios', '-darwin') return '--target=%s' % target_alias -add_old_configure_arg(target_for_old_configure) - - # These variables are for compatibility with the current moz.builds and # old-configure. Eventually, we'll want to canonicalize better. @depends(target) @@ -1018,15 +1002,6 @@ def target_is_darwin(target): set_define('XP_DARWIN', target_is_darwin) -@depends(target) -def target_is_ios(target): - if target.kernel == 'Darwin' and target.os == 'iOS': - return True - - -set_define('XP_IOS', target_is_ios) - - @depends(target) def target_is_osx(target): if target.kernel == 'Darwin' and target.os == 'OSX': @@ -1045,6 +1020,15 @@ def target_is_linux(target): set_define('XP_LINUX', target_is_linux) +@depends(target) +def target_is_android(target): + if target.os == 'Android': + return True + + +set_define('ANDROID', target_is_android) + + @depends(target) def target_is_openbsd(target): if target.kernel == 'OpenBSD': @@ -1107,23 +1091,8 @@ set_define('MOZ_BUILD_APP', build_project) add_old_configure_assignment('MOZ_BUILD_APP', build_project) -# This is temporary until js/src/configure and configure are merged. -# Use instead of option() in js/moz.configure and more generally, for -# options that are shared between configure and js/src/configure. -@template -def js_option(*args, **kwargs): - opt = option(*args, **kwargs) - - @depends(opt.option, build_project, when=kwargs.get('when')) - def js_option(value, build_project): - if build_project != 'js': - return value.format(opt.option) - - add_old_configure_arg(js_option) - - -js_option(env='MOZILLA_OFFICIAL', - help='Build an official release') +option(env='MOZILLA_OFFICIAL', + help='Build an official release') @depends('MOZILLA_OFFICIAL') @@ -1268,9 +1237,9 @@ set_define('MOZ_UPDATE_CHANNEL', update_channel) add_old_configure_assignment('MOZ_UPDATE_CHANNEL', update_channel) -js_option(env='MOZBUILD_STATE_PATH', nargs=1, - help='Path to a persistent state directory for the build system ' - 'and related tools') +option(env='MOZBUILD_STATE_PATH', nargs=1, + help='Path to a persistent state directory for the build system ' + 'and related tools') @depends('MOZBUILD_STATE_PATH', '--help') @@ -1314,7 +1283,25 @@ def project_flag(env=None, set_for_old_configure=False, # milestone.is_nightly corresponds to cases NIGHTLY_BUILD is set. - @depends(milestone) def enabled_in_nightly(milestone): return milestone.is_nightly + +# Branding +# ============================================================== +option('--with-app-basename', env='MOZ_APP_BASENAME', nargs=1, + help='Typically stays consistent for multiple branded versions of a ' + 'given application (e.g. Aurora and Firefox both use "Firefox"), but ' + 'may vary for full rebrandings (e.g. Iceweasel). Used for ' + 'application.ini\'s "Name" field, which controls profile location in ' + 'the absence of a "Profile" field (see below), and various system ' + 'integration hooks (Unix remoting, Windows MessageWindow name, etc.') + +@depends('--with-app-basename', target_is_android) +def moz_app_basename(value, target_is_android): + if value: + return value[0] + return 'Mypal' + +set_config('MOZ_APP_BASENAME', moz_app_basename, + when=depends(build_project)(lambda p: p != 'js')) diff --git a/build/moz.configure/lto-pgo.configure b/build/moz.configure/lto-pgo.configure index 29e857126b..19f869a5eb 100644 --- a/build/moz.configure/lto-pgo.configure +++ b/build/moz.configure/lto-pgo.configure @@ -4,14 +4,71 @@ # PGO # ============================================================== -@depends(c_compiler, check_build_environment, target) -@imports('multiprocessing') -@imports(_from='__builtin__', _import='min') -def pgo_flags(compiler, build_env, target): +llvm_profdata = check_prog('LLVM_PROFDATA', ['llvm-profdata'], + allow_missing=True, + paths=toolchain_search_path) + +option('--enable-profile-generate', + env='MOZ_PROFILE_GENERATE', + nargs='?', + choices=('cross',), + help='Build a PGO instrumented binary') + +imply_option('MOZ_PGO', + depends_if('--enable-profile-generate')(lambda _: True)) + +set_config('MOZ_PROFILE_GENERATE', + depends_if('--enable-profile-generate')(lambda _: True)) + +set_define('MOZ_PROFILE_GENERATE', + depends_if('--enable-profile-generate')(lambda _: True)) + +add_old_configure_assignment('MOZ_PROFILE_GENERATE', 1, + when='--enable-profile-generate') + +option('--enable-profile-use', + env='MOZ_PROFILE_USE', + nargs='?', + choices=('cross',), + help='Use a generated profile during the build') + +option('--with-pgo-profile-path', + help='Path to the directory with unmerged profile data to use during the build', + nargs=1) + +imply_option('MOZ_PGO', + depends_if('--enable-profile-use')(lambda _: True)) + +set_config('MOZ_PROFILE_USE', + depends_if('--enable-profile-use')(lambda _: True)) + + +@depends('--with-pgo-profile-path', '--enable-profile-use', llvm_profdata, check_build_environment) +@imports('os') +def pgo_profile_path(path, pgo_use, profdata, build_env): topobjdir = build_env.topobjdir if topobjdir.endswith('/js/src'): topobjdir = topobjdir[:-7] + if not path: + return os.path.join(topobjdir, 'instrumented', 'merged.profdata') + if path and not pgo_use: + die('Pass --enable-profile-use to use --with-pgo-profile-path.') + if path and not profdata: + die('LLVM_PROFDATA must be set to process the pgo profile.') + if not os.path.isfile(path[0]): + die('Argument to --with-pgo-profile-path must be a file.') + if not os.path.isabs(path[0]): + die('Argument to --with-pgo-profile-path must be an absolute path.') + return path[0] + + +set_config('PGO_PROFILE_PATH', pgo_profile_path) + +@depends(c_compiler, target, pgo_profile_path) +@imports('multiprocessing') +@imports(_from='__builtin__', _import='min') +def pgo_flags(compiler, target, profdata): if compiler.type == 'gcc': return namespace( gen_cflags=['-fprofile-generate'], @@ -22,7 +79,6 @@ def pgo_flags(compiler, build_env, target): ) if compiler.type in ('clang-cl', 'clang'): - profdata = os.path.join(topobjdir, 'merged.profdata') prefix = '' if compiler.type == 'clang-cl': prefix = '/clang:' @@ -51,61 +107,6 @@ set_config('PROFILE_GEN_LDFLAGS', pgo_flags.gen_ldflags) set_config('PROFILE_USE_CFLAGS', pgo_flags.use_cflags) set_config('PROFILE_USE_LDFLAGS', pgo_flags.use_ldflags) -llvm_profdata = check_prog('LLVM_PROFDATA', ['llvm-profdata'], - allow_missing=True, - paths=toolchain_search_path) - -js_option('--enable-profile-generate', - nargs='?', - choices=('cross',), - help='Build a PGO instrumented binary') - -imply_option('MOZ_PGO', - depends_if('--enable-profile-generate')(lambda _: True)) - -set_config('MOZ_PROFILE_GENERATE', - depends_if('--enable-profile-generate')(lambda _: True)) - -set_define('MOZ_PROFILE_GENERATE', - depends_if('--enable-profile-generate')(lambda _: True)) - -js_option('--enable-profile-use', - nargs='?', - choices=('cross',), - help='Use a generated profile during the build') - -js_option('--with-pgo-profile-path', - help='Path to the directory with unmerged profile data to use during the build', - nargs=1) - -js_option('--enable-cross-pgo', - help='Enable PGO on Rust code') - -imply_option('MOZ_PGO', - depends_if('--enable-profile-use')(lambda _: True)) - -set_config('MOZ_PROFILE_USE', - depends_if('--enable-profile-use')(lambda _: True)) - - -@depends('--with-pgo-profile-path', '--enable-profile-use', llvm_profdata) -@imports('os') -def pgo_profile_path(path, pgo_use, profdata): - if not path: - return - if path and not pgo_use: - die('Pass --enable-profile-use to use --with-pgo-profile-path.') - if path and not profdata: - die('LLVM_PROFDATA must be set to process the pgo profile.') - if not os.path.isdir(path[0]): - die('Argument to --with-pgo-profile-path must be a directory.') - if not os.path.isabs(path[0]): - die('Argument to --with-pgo-profile-path must be an absolute path.') - return path[0] - - -set_config('PGO_PROFILE_PATH', pgo_profile_path) - option('--with-pgo-jarlog', help='Use the provided jarlog file when packaging during a profile-use ' 'build', @@ -147,27 +148,31 @@ set_config('MOZ_PGO_RUST', moz_pgo_rust) # LTO # ============================================================== -js_option('--enable-lto', - env='MOZ_LTO', - nargs='?', - choices=('full', 'thin', 'cross'), - help='Enable LTO') +option('--enable-lto', + env='MOZ_LTO', + nargs='?', + choices=('full', 'thin', 'cross'), + help='Enable LTO') -js_option(env='MOZ_LD64_KNOWN_GOOD', - nargs=1, - help='Indicate that ld64 is free of symbol aliasing bugs.') +option(env='MOZ_LD64_KNOWN_GOOD', + nargs=1, + help='Indicate that ld64 is free of symbol aliasing bugs.') imply_option('MOZ_LD64_KNOWN_GOOD', depends_if('MOZ_AUTOMATION')(lambda _: True)) -@depends('--enable-lto', c_compiler, 'MOZ_LD64_KNOWN_GOOD', target) +@depends('--enable-lto', c_compiler, 'MOZ_LD64_KNOWN_GOOD', target, '--enable-profile-generate') @imports('multiprocessing') -def lto(value, c_compiler, ld64_known_good, target): +def lto(value, c_compiler, ld64_known_good, target, instrumented_build): cflags = [] ldflags = [] enabled = None rust_lto = False if value: + if instrumented_build: + log.warning('Disabling LTO because --enable-profile-generate is specified') + return + enabled = True # `cross` implies `thin`, but with Rust code participating in LTO # as well. Make that a little more explicit. @@ -233,6 +238,17 @@ def lto(value, c_compiler, ld64_known_good, target): ldflags.append("-flto=%s" % num_cores) ldflags.append("-flifetime-dse=1") + # Tell LTO not to inline functions above a certain size, to mitigate + # binary size growth while still getting good performance. + # (For hot functions, PGO will put a multiplier on this limit.) + if target.os == 'WINNT': + ldflags.append('-mllvm:-import-instr-limit=10'); + elif target.os == 'OSX': + # Until OSX gets PGO, too small of a limit will cause slowdowns. + ldflags.append('-Wl,-mllvm,-import-instr-limit=40'); + elif c_compiler.type == 'clang': + ldflags.append('-Wl,-plugin-opt=-import-instr-limit=10'); + return namespace( enabled=enabled, cflags=cflags, diff --git a/build/moz.configure/memory.configure b/build/moz.configure/memory.configure index e408f71552..0fcfc59bef 100644 --- a/build/moz.configure/memory.configure +++ b/build/moz.configure/memory.configure @@ -8,8 +8,8 @@ def jemalloc_default(target): return target.kernel in ('Darwin', 'Linux', 'WINNT') -js_option('--enable-jemalloc', env='MOZ_MEMORY', default=jemalloc_default, - help='{Replace|Do not replace} memory allocator with jemalloc') +option('--enable-jemalloc', env='MOZ_MEMORY', default=jemalloc_default, + help='{Replace|Do not replace} memory allocator with jemalloc') set_config('MOZ_MEMORY', True, when='--enable-jemalloc') @@ -25,9 +25,9 @@ def replace_malloc_default(milestone, build_project): return True -js_option('--enable-replace-malloc', default=replace_malloc_default, - when='--enable-jemalloc', - help='{Enable|Disable} ability to dynamically replace the malloc implementation') +option('--enable-replace-malloc', default=replace_malloc_default, + when='--enable-jemalloc', + help='{Enable|Disable} ability to dynamically replace the malloc implementation') set_config('MOZ_REPLACE_MALLOC', True, when='--enable-replace-malloc') diff --git a/build/moz.configure/nspr.configure b/build/moz.configure/nspr.configure new file mode 100644 index 0000000000..c9d9f8e144 --- /dev/null +++ b/build/moz.configure/nspr.configure @@ -0,0 +1,98 @@ +# 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/. + +# Top-level configure defaults to building NSPR from source. Standalone JS +# doesn't. +option('--enable-nspr-build', when=js_standalone, + help='{Build|Do not build} NSPR from source tree') + +@depends('--enable-nspr-build', when=js_standalone) +def enable_nspr_build(enable): + if enable: + return enable + +option('--with-system-nspr', help='Use system NSPR') + +@depends(enable_nspr_build, '--with-system-nspr', js_standalone) +def build_nspr(nspr_build, system_nspr, js_standalone): + if nspr_build is not None and nspr_build.origin != 'default': + if nspr_build and system_nspr: + die('Cannot use both --enable-nspr-build and --with-system-nspr') + if js_standalone: + return nspr_build + return not system_nspr + +set_config('MOZ_BUILD_NSPR', True, when=build_nspr) +set_config('MOZ_SYSTEM_NSPR', True, when='--with-system-nspr') + +@depends(build_nspr, '--with-system-nspr', js_standalone) +def js_without_nspr(build_nspr, system_nspr, js_standalone): + if js_standalone: + return not build_nspr and not system_nspr + +set_config('JS_WITHOUT_NSPR', True, when=js_without_nspr) +set_define('JS_WITHOUT_NSPR', True, when=js_without_nspr) + +@depends(js_standalone) +def nspr_minver(js_standalone): + if js_standalone: + return 'nspr >= 4.10' + return 'nspr >= 4.25' + +nspr_pkg = pkg_check_modules('NSPR', nspr_minver, when='--with-system-nspr') + +@depends_if(nspr_pkg) +def nspr_pkg(nspr_pkg): + def extract(prefix, list): + for item in list: + if item.startswith(prefix): + return item[len(prefix):] + return '' + + include_dir = extract('-I', nspr_pkg.cflags) + lib_dir = extract('-L', nspr_pkg.libs) + return namespace( + cflags=nspr_pkg.cflags, + include_dir=include_dir, + libs=nspr_pkg.libs, + lib_dir=lib_dir, + ) + +@depends(nspr_minver, when='--with-system-nspr') +def pkgconf_requires_private(nspr_minver): + return 'Requires.private: %s' % nspr_minver + +set_config('PKGCONF_REQUIRES_PRIVATE', pkgconf_requires_private) + +# pkg_check_modules takes care of NSPR_CFLAGS and NSPR_LIBS when using --with-system-nspr. +@depends(check_build_environment, c_compiler, fold_libs, when=build_nspr) +def nspr_config(build_env, c_compiler, fold_libs): + libs = ['nspr4', 'plc4', 'plds4'] + if c_compiler.type == 'clang-cl': + lib_dir = os.path.join(build_env.dist, 'lib') + libs = [os.path.join(lib_dir, '%s.lib' % lib) for lib in libs] + else: + lib_dir = os.path.join(build_env.dist, 'lib' if fold_libs else 'bin') + libs = ['-L%s' % lib_dir] + ['-l%s' % lib for lib in libs] + + include_dir = os.path.join(build_env.dist, 'include', 'nspr') + return namespace( + cflags=['-I%s' % include_dir], + include_dir=include_dir, + libs=libs, + lib_dir=lib_dir, + ) + +set_config('NSPR_CFLAGS', nspr_config.cflags, when=nspr_config) +set_config('NSPR_LIBS', nspr_config.libs, when=nspr_config) + +set_config('NSPR_INCLUDE_DIR', nspr_config.include_dir, when=nspr_config) +set_config('NSPR_LIB_DIR', nspr_config.lib_dir, when=nspr_config) +set_config('NSPR_INCLUDE_DIR', nspr_pkg.include_dir, when=nspr_pkg) +set_config('NSPR_LIB_DIR', nspr_pkg.lib_dir, when=nspr_pkg) + +add_old_configure_assignment('NSPR_CFLAGS', nspr_config.cflags, when=nspr_config) +add_old_configure_assignment('NSPR_LIBS', nspr_config.libs, when=nspr_config) +add_old_configure_assignment('NSPR_CFLAGS', nspr_pkg.cflags, when=nspr_pkg) +add_old_configure_assignment('NSPR_LIBS', nspr_pkg.libs, when=nspr_pkg) diff --git a/build/moz.configure/old.configure b/build/moz.configure/old.configure index 930cbd362d..5b5020edc5 100644 --- a/build/moz.configure/old.configure +++ b/build/moz.configure/old.configure @@ -23,10 +23,19 @@ def autoconf(mozconfig, autoconf): make_extra = mozconfig['make_extra'] if make_extra: for assignment in make_extra: - m = re.match('(?:export\s+)?AUTOCONF\s*:?=\s*(.+)$', + m = re.match(r'(?:export\s+)?AUTOCONF\s*:?=\s*(.+)$', assignment) if m: mozconfig_autoconf = m.group(1) + # Check whether we've exported any known-broken variables. + m = re.match(r'(?:export\s+)?(?:CC|CXX)\s*:?=\s*(?:.+)$', + assignment) + if m: + die('Setting the value of CC or CXX with "mk_add_options" ' + 'can cause the build to fail unexpectedly. Please ' + 'change your mozconfig to instead use ' + '"ac_add_options", e.g. ac_add_options ' + 'CC=my-custom-cc".') autoconf = autoconf[0] if autoconf else None @@ -74,20 +83,8 @@ def prepare_mozconfig(mozconfig): return items -@depends('OLD_CONFIGURE', prepare_mozconfig, autoconf, check_build_environment, - shell, old_configure_assignments, build_project) -@imports(_from='__builtin__', _import='open') -@imports(_from='__builtin__', _import='print') -@imports(_from='__builtin__', _import='sorted') -@imports('glob') -@imports('itertools') -@imports('subprocess') -# Import getmtime without overwriting the sandbox os.path. -@imports(_from='os.path', _import='getmtime') -@imports(_from='os.path', _import='exists') -@imports(_from='mozbuild.shellutil', _import='quote') -def prepare_configure(old_configure, mozconfig, autoconf, build_env, shell, - old_configure_assignments, build_project): +@depends('OLD_CONFIGURE', build_project) +def old_configure(old_configure, build_project): # os.path.abspath in the sandbox will ensure forward slashes on Windows, # which is actually necessary because this path actually ends up literally # as $0, and backslashes there breaks autoconf's detection of the source @@ -98,39 +95,15 @@ def prepare_configure(old_configure, mozconfig, autoconf, build_env, shell, if not old_configure_dir.endswith('/js/src'): old_configure = os.path.join(old_configure_dir, 'js', 'src', os.path.basename(old_configure)) + return old_configure - refresh = True - if exists(old_configure): - mtime = getmtime(old_configure) - aclocal = os.path.join(build_env.topsrcdir, 'build', 'autoconf', - '*.m4') - for input in itertools.chain( - (old_configure + '.in', - os.path.join(os.path.dirname(old_configure), 'aclocal.m4')), - glob.iglob(aclocal), - ): - if getmtime(input) > mtime: - break - else: - refresh = False - if refresh: - log.info('Refreshing %s with %s', old_configure, autoconf) - script = subprocess.check_output([ - shell, autoconf, - '--localdir=%s' % os.path.dirname(old_configure), - old_configure + '.in']) - if not script: - die('Generated old-configure is empty! Check that your autoconf 2.13 program works!') - - # Make old-configure append to config.log, where we put our own log. - # This could be done with a m4 macro, but it's way easier this way - script = script.replace('>./config.log', '>>${CONFIG_LOG=./config.log}') - - with open(old_configure, 'wb') as fh: - fh.write(script) - - cmd = [shell, old_configure] +@depends(prepare_mozconfig, old_configure_assignments, autoconf) +@imports(_from='__builtin__', _import='open') +@imports(_from='__builtin__', _import='print') +@imports(_from='__builtin__', _import='sorted') +@imports(_from='mozbuild.shellutil', _import='quote') +def prepare_configure(mozconfig, old_configure_assignments, autoconf): with encoded_open('old-configure.vars', 'w') as out: log.debug('Injecting the following to old-configure:') @@ -156,8 +129,6 @@ def prepare_configure(old_configure, mozconfig, autoconf, build_env, shell, for k, v in old_configure_assignments: inject('%s=%s' % (k, quote(v))) - return cmd - @template def old_configure_options(*options): @@ -168,50 +139,27 @@ def old_configure_options(*options): def all_options(): return list(options) - return depends(extra_old_configure_args, all_options, *options) + return depends(host_for_sub_configure, target_for_sub_configure, all_options, *options) @old_configure_options( '--cache-file', '--datadir', - '--enable-content-sandbox', - '--enable-cookies', - '--enable-cpp-rtti', '--enable-crashreporter', '--enable-dbus', '--enable-debug-js-modules', - '--enable-directshow', - '--enable-dtrace', '--enable-dump-painting', '--enable-extensions', - '--enable-feeds', - '--enable-gconf', - '--enable-icf', - '--enable-install-strip', - '--enable-ios-target', - '--enable-libjpeg-turbo', '--enable-libproxy', - '--enable-llvm-hacks', '--enable-logrefcnt', - '--enable-mobile-optimize', '--enable-necko-wifi', '--enable-negotiateauth', - '--enable-nfc', - '--enable-nspr-build', '--enable-official-branding', '--enable-parental-controls', - '--enable-pref-extensions', - '--enable-readline', '--enable-sandbox', - '--enable-signmar', - '--enable-startup-notification', - '--enable-startupcache', - '--enable-strip', - '--enable-synth-pico', '--enable-system-cairo', '--enable-system-extension-dirs', '--enable-system-pixman', - '--enable-system-sqlite', '--enable-universalchardet', '--enable-updater', '--enable-webrender', @@ -223,40 +171,16 @@ def old_configure_options(*options): '--with-android-distribution-directory', '--with-android-max-sdk', '--with-android-min-sdk', - '--with-app-basename', - '--with-app-name', '--with-branding', - '--with-cross-lib', - '--with-debug-label', '--with-distribution-id', - '--with-doc-include-dirs', - '--with-doc-input-dirs', - '--with-doc-output-dir', - '--with-intl-api', - '--with-ios-sdk', - '--with-jitreport-granularity', '--with-macbundlename-prefix', - '--with-nspr-cflags', - '--with-nspr-exec-prefix', - '--with-nspr-libs', - '--with-nspr-prefix', - '--with-nss-exec-prefix', - '--with-nss-prefix', - '--with-qemu-exe', - '--with-sixgill', - '--with-system-bz2', - '--with-system-icu', '--with-system-libevent', - '--with-system-nspr', - '--with-system-nss', '--with-system-png', - '--with-system-zlib', - '--with-unify-dist', '--with-user-appdir', '--x-includes', '--x-libraries', ) -def prepare_configure_options(extra_old_configure_args, all_options, *options): +def prepare_configure_options(host, target, all_options, *options): # old-configure only supports the options listed in @old_configure_options # so we don't need to pass it every single option we've been passed. Only # the ones that are not supported by python configure need to. @@ -264,148 +188,183 @@ def prepare_configure_options(extra_old_configure_args, all_options, *options): value.format(name) for name, value in zip(all_options, options) if value.origin != 'default' - ] + ] + [host, target] - extra_env = {} + return namespace(options=options, all_options=all_options) - # We also pass it the options from js/moz.configure so that it can pass - # them down to js/src/configure. Note this list is empty when running - # js/src/configure, in which case we don't need to pass those options - # to old-configure since old-configure doesn't handle them anyways. - if extra_old_configure_args: - for arg in extra_old_configure_args: - if arg.startswith('-'): - options.append(arg) + +@template +def old_configure_for(old_configure_path, extra_env=None): + if extra_env is None: + extra_env = dependable(None) + + @depends(prepare_configure, prepare_configure_options, altered_path, extra_env, + check_build_environment, old_configure_path, 'MOZILLABUILD', autoconf, shell) + @imports(_from='__builtin__', _import='compile') + @imports(_from='__builtin__', _import='open') + @imports(_from='__builtin__', _import='OSError') + @imports('glob') + @imports('itertools') + @imports('logging') + @imports('os') + @imports('subprocess') + @imports('sys') + @imports('types') + @imports(_from='mozbuild.shellutil', _import='quote') + @imports(_from='mozbuild.shellutil', _import='split') + @imports(_from='mozbuild.util', _import='encode') + @imports(_from='tempfile', _import='NamedTemporaryFile') + @imports(_from='subprocess', _import='CalledProcessError') + def old_configure(prepare_configure, prepare_configure_options, altered_path, extra_env, + build_env, old_configure, mozillabuild, autoconf, shell): + # Use prepare_configure to make lint happy + prepare_configure + refresh = True + if os.path.exists(old_configure): + mtime = os.path.getmtime(old_configure) + aclocal = os.path.join(build_env.topsrcdir, 'build', 'autoconf', + '*.m4') + for input in itertools.chain( + (old_configure + '.in', + os.path.join(os.path.dirname(old_configure), 'aclocal.m4')), + glob.iglob(aclocal), + ): + if os.path.getmtime(input) > mtime: + break else: - k, v = arg.split('=', 1) - extra_env[k] = v + refresh = False - return namespace(options=options, extra_env=extra_env, all_options=all_options) + if refresh: + log.info('Refreshing %s with %s', old_configure, autoconf) + + try: + script = subprocess.check_output([ + shell, autoconf, + '--localdir=%s' % os.path.dirname(old_configure), + old_configure + '.in']) + except CalledProcessError as exc: + # Autoconf on win32 may break due to a bad $PATH. Let the user know + # their $PATH is suspect. + if mozillabuild: + mozillabuild_path = normsep(mozillabuild[0]) + sh_path = normsep(find_program('sh')) + if mozillabuild_path not in sh_path: + log.warning("The '{}msys/bin' directory is not first in $PATH. " + "This may cause autoconf to fail. ($PATH is currently " + "set to: {})".format(mozillabuild_path, os.environ[ + 'PATH'])) + die('autoconf exited with return code {}'.format(exc.returncode)) + + if not script: + die('Generated old-configure is empty! Check that your autoconf 2.13 program works!') + + # Make old-configure append to config.log, where we put our own log. + # This could be done with a m4 macro, but it's way easier this way + script = script.replace('>./config.log', '>>${CONFIG_LOG=./config.log}') + + with NamedTemporaryFile(mode='wb', prefix=os.path.basename(old_configure), + dir=os.path.dirname(old_configure), delete=False) as fh: + fh.write(script) + + try: + os.rename(fh.name, old_configure) + except OSError: + try: + # Likely the file already existed (on Windows). Retry after removing it. + os.remove(old_configure) + os.rename(fh.name, old_configure) + except OSError as e: + die('Failed re-creating old-configure: %s' % e.message) + + cmd = [shell, old_configure] + prepare_configure_options.options + + env = dict(os.environ) + + # For debugging purpose, in case it's not what we'd expect. + log.debug('Running %s', quote(*cmd)) + + # Our logging goes to config.log, the same file old.configure uses. + # We can't share the handle on the file, so close it. + logger = logging.getLogger('moz.configure') + config_log = None + for handler in logger.handlers: + if isinstance(handler, logging.FileHandler): + config_log = handler + config_log.close() + logger.removeHandler(config_log) + env['CONFIG_LOG'] = config_log.baseFilename + log_size = os.path.getsize(config_log.baseFilename) + break + + if altered_path: + env['PATH'] = altered_path + + if extra_env: + env.update(extra_env) + + env['OLD_CONFIGURE_VARS'] = os.path.join(build_env.topobjdir, 'old-configure.vars') + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + env=encode(env)) + while True: + line = proc.stdout.readline() + if not line: + break + log.info(line.rstrip()) + + ret = proc.wait() + if ret: + with log.queue_debug(): + if config_log: + with encoded_open(config_log.baseFilename, 'r') as fh: + fh.seek(log_size) + for line in fh: + log.debug(line.rstrip()) + log.error('old-configure failed') + sys.exit(ret) + + if config_log: + # Create a new handler in append mode + handler = logging.FileHandler(config_log.baseFilename, mode='a', delay=True) + handler.setFormatter(config_log.formatter) + logger.addHandler(handler) + + raw_config = { + 'split': split, + 'unique_list': unique_list, + } + with encoded_open('config.data', 'r') as fh: + code = compile(fh.read(), 'config.data', 'exec') + # Every variation of the exec() function I tried led to: + # SyntaxError: unqualified exec is not allowed in function 'main' it + # contains a nested function with free variables + exec code in raw_config # noqa + + # Ensure all the flags known to old-configure appear in the + # @old_configure_options above. + all_options = set(prepare_configure_options.all_options) + for flag in raw_config['flags']: + if flag not in all_options: + die('Missing option in `@old_configure_options` in %s: %s', + __file__, flag) + + # If the code execution above fails, we want to keep the file around for + # debugging. + os.remove('config.data') + + return namespace(**{ + c: [ + (k[1:-1], v[1:-1] if isinstance(v, types.StringTypes) else v) + for k, v in raw_config[c] + ] + for c in ('substs', 'defines') + }) + + return old_configure -@depends(prepare_configure, prepare_configure_options, altered_path) -@imports(_from='__builtin__', _import='compile') -@imports(_from='__builtin__', _import='open') -@imports('logging') -@imports('os') -@imports('subprocess') -@imports('sys') -@imports('types') -@imports(_from='mozbuild.shellutil', _import='quote') -@imports(_from='mozbuild.shellutil', _import='split') -@imports(_from='mozbuild.util', _import='encode') -def old_configure(prepare_configure, prepare_configure_options, altered_path): - cmd = prepare_configure + prepare_configure_options.options - extra_env = prepare_configure_options.extra_env - - env = dict(os.environ) - if extra_env: - env.update(extra_env) - - # For debugging purpose, in case it's not what we'd expect. - log.debug('Running %s', quote(*cmd)) - if extra_env: - log.debug('with extra environment: %s', - ' '.join('%s=%s' % pair for pair in extra_env.iteritems())) - - # Our logging goes to config.log, the same file old.configure uses. - # We can't share the handle on the file, so close it. - logger = logging.getLogger('moz.configure') - config_log = None - for handler in logger.handlers: - if isinstance(handler, logging.FileHandler): - config_log = handler - config_log.close() - logger.removeHandler(config_log) - env['CONFIG_LOG'] = config_log.baseFilename - log_size = os.path.getsize(config_log.baseFilename) - break - - if altered_path: - env['PATH'] = altered_path - - proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - env=encode(env)) - while True: - line = proc.stdout.readline() - if not line: - break - log.info(line.rstrip()) - - ret = proc.wait() - if ret: - with log.queue_debug(): - if config_log: - with encoded_open(config_log.baseFilename, 'r') as fh: - fh.seek(log_size) - for line in fh: - log.debug(line.rstrip()) - log.error('old-configure failed') - sys.exit(ret) - - if config_log: - # Create a new handler in append mode - handler = logging.FileHandler(config_log.baseFilename, mode='a', delay=True) - handler.setFormatter(config_log.formatter) - logger.addHandler(handler) - - raw_config = { - 'split': split, - 'unique_list': unique_list, - } - with encoded_open('config.data', 'r') as fh: - code = compile(fh.read(), 'config.data', 'exec') - # Every variation of the exec() function I tried led to: - # SyntaxError: unqualified exec is not allowed in function 'main' it - # contains a nested function with free variables - exec code in raw_config # noqa - - # Ensure all the flags known to old-configure appear in the - # @old_configure_options above. - all_options = set(prepare_configure_options.all_options) - for flag in raw_config['flags']: - if flag not in all_options: - die('Missing option in `@old_configure_options` in %s: %s', - __file__, flag) - - # If the code execution above fails, we want to keep the file around for - # debugging. - os.remove('config.data') - - for c in ('substs', 'defines'): - raw_config[c] = [ - (k[1:-1], v[1:-1] if isinstance(v, types.StringTypes) else v) - for k, v in raw_config[c] - ] - - return raw_config - - -# set_config is only available in the global namespace, not directly in -# @depends functions, but we do need to enumerate the result of -# old_configure, so we cheat. -@imports('__sandbox__') -def set_old_configure_config(name, value): - __sandbox__.set_config_impl(name, value) - -# Same as set_old_configure_config, but for set_define. - - -@imports('__sandbox__') -def set_old_configure_define(name, value): - __sandbox__.set_define_impl(name, value) - - -@depends(old_configure) -def post_old_configure(raw_config): - for k, v in raw_config['substs']: - set_old_configure_config(k, v) - - for k, v in dict(raw_config['defines']).iteritems(): - set_old_configure_define(k, v) - - set_old_configure_config('non_global_defines', - raw_config['non_global_defines']) +old_configure = old_configure_for(old_configure) +set_config('OLD_CONFIGURE_SUBSTS', old_configure.substs) +set_config('OLD_CONFIGURE_DEFINES', old_configure.defines) # Assuming no other option is declared after this function, handle the diff --git a/build/moz.configure/pkg.configure b/build/moz.configure/pkg.configure index 3a28c3a07b..d779043439 100644 --- a/build/moz.configure/pkg.configure +++ b/build/moz.configure/pkg.configure @@ -14,7 +14,6 @@ pkg_config = check_prog('PKG_CONFIG', pkg_config, allow_missing=True) @depends_if(pkg_config) @checking('for pkg-config version') -@imports('subprocess') def pkg_config_version(pkg_config): return Version(check_cmd_output(pkg_config, '--version').rstrip()) @@ -34,7 +33,7 @@ def pkg_config_version(pkg_config): @template def pkg_check_modules(var, package_desc, when=always, - allow_missing=False): + allow_missing=False, config=True): if isinstance(package_desc, (tuple, list)): package_desc = ' '.join(package_desc) package_desc = dependable(package_desc) @@ -95,7 +94,8 @@ def pkg_check_modules(var, package_desc, when=always, def pkg_info(cflags, libs): return namespace(cflags=cflags, libs=libs) - set_config('%s_CFLAGS' % var, pkg_cflags) - set_config('%s_LIBS' % var, pkg_libs) + if config: + set_config('%s_CFLAGS' % var, pkg_cflags) + set_config('%s_LIBS' % var, pkg_libs) return pkg_info diff --git a/build/moz.configure/rust.configure b/build/moz.configure/rust.configure index a129f9a20b..654ebe4d87 100644 --- a/build/moz.configure/rust.configure +++ b/build/moz.configure/rust.configure @@ -5,8 +5,8 @@ # Rust is required by `rust_compiler` below. We allow_missing here # to propagate failures to the better error message there. -js_option(env='RUSTC', nargs=1, help='Path to the rust compiler') -js_option(env='CARGO', nargs=1, help='Path to the Cargo package manager') +option(env='RUSTC', nargs=1, help='Path to the rust compiler') +option(env='CARGO', nargs=1, help='Path to the Cargo package manager') rustc = check_prog('_RUSTC', ['rustc'], what='rustc', paths=toolchain_search_path, input='RUSTC', @@ -104,7 +104,7 @@ def rust_compiler(rustc_info, cargo_info, build_project): if build_project == 'tools/crashreporter': rustc_min_version = Version('1.31.0') else: - rustc_min_version = Version('1.35.0') + rustc_min_version = Version('1.36.0') cargo_min_version = rustc_min_version version = rustc_info.version @@ -188,7 +188,6 @@ def rust_triple_alias(host_or_target, host_or_target_c_compiler): rust_supported_targets, arm_target, when=rust_compiler) @checking('for rust %s triplet' % host_or_target_str) @imports('os') - @imports('subprocess') @imports(_from='mozbuild.configure.util', _import='LineIO') @imports(_from='mozbuild.shellutil', _import='quote') @imports(_from='tempfile', _import='mkstemp') @@ -381,7 +380,7 @@ set_config('RUST_HOST_TARGET', rust_host_triple) set_config('RUSTC_COMMIT', depends(rustc_info)(lambda i: i.commit)) # Rustdoc is required by Rust tests below. -js_option(env='RUSTDOC', nargs=1, help='Path to the rustdoc program') +option(env='RUSTDOC', nargs=1, help='Path to the rustdoc program') rustdoc = check_prog('RUSTDOC', ['rustdoc'], paths=toolchain_search_path, input='RUSTDOC', allow_missing=True) diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure index f1f975764c..2c2a313155 100644 --- a/build/moz.configure/toolchain.configure +++ b/build/moz.configure/toolchain.configure @@ -5,10 +5,10 @@ imply_option('--enable-release', mozilla_official) imply_option('--enable-release', depends_if('MOZ_AUTOMATION')(lambda x: True)) -js_option('--enable-release', - default=milestone.is_release_or_beta, - help='{Build|Do not build} with more conservative, release ' - 'engineering-oriented options.{ This may slow down builds.|}') +option('--enable-release', + default=milestone.is_release_or_beta, + help='{Build|Do not build} with more conservative, release ' + 'engineering-oriented options.{ This may slow down builds.|}') @depends('--enable-release') @@ -23,9 +23,9 @@ set_config('DEVELOPER_OPTIONS', developer_options) # Code optimization # ============================================================== -js_option('--disable-optimize', - nargs='?', - help='Disable optimizations via compiler flags') +option('--disable-optimize', + nargs='?', + help='Disable optimizations via compiler flags') @depends('--enable-optimize', '--help') @@ -131,7 +131,7 @@ def host_is_osx(host): with only_when(host_is_osx | target_is_osx): # MacOS SDK # ========= - js_option('--with-macos-sdk', env='MACOS_SDK_DIR', nargs=1, + option('--with-macos-sdk', env='MACOS_SDK_DIR', nargs=1, help='Location of platform SDK to use') @depends('--with-macos-sdk', host) @@ -202,62 +202,13 @@ with only_when(target_is_osx): set_config('MACOS_PRIVATE_FRAMEWORKS_DIR', macos_private_frameworks) -with only_when(host_is_osx): - # Xcode state - # =========== - js_option('--disable-xcode-checks', - help='Do not check that Xcode is installed and properly configured') - - - @depends(host, '--disable-xcode-checks') - def xcode_path(host, xcode_checks): - if host.kernel != 'Darwin' or not xcode_checks: - return - - # xcode-select -p prints the path to the installed Xcode. It - # should exit 0 and return non-empty result if Xcode is installed. - - def bad_xcode_select(): - die('Could not find installed Xcode; install Xcode from the App ' - 'Store, run it once to perform initial configuration, and then ' - 'try again; in the rare case you wish to build without Xcode ' - 'installed, add the --disable-xcode-checks configure flag') - - xcode_path = check_cmd_output('xcode-select', '--print-path', - onerror=bad_xcode_select).strip() - - if not xcode_path: - bad_xcode_select() - - # Now look for the Command Line Tools. - def no_cltools(): - die('Could not find installed Xcode Command Line Tools; ' - 'run `xcode-select --install` and follow the instructions ' - 'to install them then try again; if you wish to build without ' - 'Xcode Command Line Tools installed, ' - 'add the --disable-xcode-checks configure flag') - - check_cmd_output('pkgutil', '--pkg-info', - 'com.apple.pkg.CLTools_Executables', - onerror=no_cltools) - - return xcode_path - - - set_config('XCODE_PATH', xcode_path) - - # Compiler wrappers # ============================================================== -# Normally, we'd use js_option and automatically have those variables -# propagated to js/src, but things are complicated by possible additional -# wrappers in CC/CXX, and by other subconfigures that do not handle those -# options and do need CC/CXX altered. option('--with-compiler-wrapper', env='COMPILER_WRAPPER', nargs=1, help='Enable compiling with wrappers such as distcc and ccache') -js_option('--with-ccache', env='CCACHE', nargs='?', - help='Enable compiling with ccache') +option('--with-ccache', env='CCACHE', nargs='?', + help='Enable compiling with ccache') @depends_if('--with-ccache') @@ -271,9 +222,9 @@ def ccache(value): ccache = check_prog('CCACHE', progs=(), input=ccache) -js_option(env='CCACHE_PREFIX', - nargs=1, - help='Compiler prefix to use when using ccache') +option(env='CCACHE_PREFIX', + nargs=1, + help='Compiler prefix to use when using ccache') ccache_prefix = depends_if('CCACHE_PREFIX')(lambda prefix: prefix[0]) set_config('CCACHE_PREFIX', ccache_prefix) @@ -295,6 +246,33 @@ def using_ccache(ccache, ccache_is_sccache): def using_sccache(ccache, ccache_is_sccache): return ccache and ccache_is_sccache +option(env='RUSTC_WRAPPER', nargs=1, + help='Wrap rust compilation with given tool') + +@depends(ccache, ccache_is_sccache, 'RUSTC_WRAPPER') +@imports(_from='textwrap', _import='dedent') +@imports('os') +def check_sccache_version(ccache, ccache_is_sccache, rustc_wrapper): + sccache_min_version = Version('0.2.13') + + def check_version(path): + out = check_cmd_output(path, '--version') + version = Version(out.rstrip().split()[-1]) + if version < sccache_min_version: + die(dedent('''\ + sccache %s or later is required. sccache in use at %s has + version %s. + + Please upgrade or acquire a new version with |./mach bootstrap|. + '''), sccache_min_version, path, version) + + if ccache and ccache_is_sccache: + check_version(ccache) + + if (rustc_wrapper and + (os.path.splitext(os.path.basename(rustc_wrapper[0]))[0].lower() == + 'sccache')): + check_version(rustc_wrapper[0]) set_config('MOZ_USING_CCACHE', using_ccache) set_config('MOZ_USING_SCCACHE', using_sccache) @@ -356,8 +334,8 @@ set_config('MOZ_HAZARD', hazard_analysis) # Cross-compilation related things. # ============================================================== -js_option('--with-toolchain-prefix', env='TOOLCHAIN_PREFIX', nargs=1, - help='Prefix for the target toolchain') +option('--with-toolchain-prefix', env='TOOLCHAIN_PREFIX', nargs=1, + help='Prefix for the target toolchain') @depends('--with-toolchain-prefix', target, cross_compiling) @@ -631,9 +609,9 @@ def host_is_windows(host): return True -js_option('--with-visual-studio-version', nargs=1, - choices=('2017',), when=host_is_windows, - help='Select a specific Visual Studio version to use') +option('--with-visual-studio-version', nargs=1, + choices=('2017',), when=host_is_windows, + help='Select a specific Visual Studio version to use') @depends('--with-visual-studio-version', when=host_is_windows) @@ -642,8 +620,8 @@ def vs_major_version(value): return {'2017': 15}[value[0]] -js_option(env='VC_PATH', nargs=1, when=host_is_windows, - help='Path to the Microsoft Visual C/C++ compiler') +option(env='VC_PATH', nargs=1, when=host_is_windows, + help='Path to the Microsoft Visual C/C++ compiler') @depends(host, vs_major_version, check_build_environment, 'VC_PATH', @@ -881,12 +859,12 @@ def default_cxx_compilers(c_compiler, other_c_compiler=None, other_cxx_compiler= @template -def provided_program(env_var): +def provided_program(env_var, when=None): '''Template handling cases where a program can be specified either as a path or as a path with applicable arguments. ''' - @depends_if(env_var) + @depends_if(env_var, when=when) @imports(_from='itertools', _import='takewhile') @imports(_from='mozbuild.shellutil', _import='split', _as='shell_split') def provided(cmd): @@ -1256,9 +1234,9 @@ option(env='MOZ_DEBUG_FLAGS', imply_option('--enable-debug-symbols', depends_if('--enable-debug')(lambda v: v)) -js_option('--disable-debug-symbols', - nargs='?', - help='Disable debug symbols using the given compiler flags') +option('--disable-debug-symbols', + nargs='?', + help='Disable debug symbols using the given compiler flags') set_config('MOZ_DEBUG_SYMBOLS', depends_if('--enable-debug-symbols')(lambda _: True)) @@ -1420,12 +1398,12 @@ set_config('PREPROCESS_OPTION', preprocess_option) # We only want to include windows.configure when we are compiling on -# Windows, for Windows. +# Windows, or for Windows. @depends(target, host) def is_windows(target, host): - return host.kernel == 'WINNT' and target.kernel == 'WINNT' + return host.kernel == 'WINNT' or target.kernel == 'WINNT' include('windows.configure', when=is_windows) @@ -1433,7 +1411,7 @@ include('windows.configure', when=is_windows) # ASAN # ============================================================== -js_option('--enable-address-sanitizer', help='Enable Address Sanitizer') +option('--enable-address-sanitizer', help='Enable Address Sanitizer') @depends(when='--enable-address-sanitizer') @@ -1446,7 +1424,7 @@ add_old_configure_assignment('MOZ_ASAN', asan) # MSAN # ============================================================== -js_option('--enable-memory-sanitizer', help='Enable Memory Sanitizer') +option('--enable-memory-sanitizer', help='Enable Memory Sanitizer') @depends(when='--enable-memory-sanitizer') @@ -1459,7 +1437,7 @@ add_old_configure_assignment('MOZ_MSAN', msan) # TSAN # ============================================================== -js_option('--enable-thread-sanitizer', help='Enable Thread Sanitizer') +option('--enable-thread-sanitizer', help='Enable Thread Sanitizer') @depends(when='--enable-thread-sanitizer') @@ -1472,9 +1450,9 @@ add_old_configure_assignment('MOZ_TSAN', tsan) # UBSAN # ============================================================== -js_option('--enable-undefined-sanitizer', - nargs='*', - help='Enable UndefinedBehavior Sanitizer') +option('--enable-undefined-sanitizer', + nargs='*', + help='Enable UndefinedBehavior Sanitizer') @depends_if('--enable-undefined-sanitizer') def ubsan(options): @@ -1491,8 +1469,8 @@ def ubsan(options): add_old_configure_assignment('MOZ_UBSAN_CHECKS', ubsan) -js_option('--enable-signed-overflow-sanitizer', - help='Enable UndefinedBehavior Sanitizer (Signed Integer Overflow Parts)') +option('--enable-signed-overflow-sanitizer', + help='Enable UndefinedBehavior Sanitizer (Signed Integer Overflow Parts)') @depends(when='--enable-signed-overflow-sanitizer') @@ -1503,8 +1481,8 @@ def ub_signed_overflow_san(): add_old_configure_assignment('MOZ_SIGNED_OVERFLOW_SANITIZE', ub_signed_overflow_san) -js_option('--enable-unsigned-overflow-sanitizer', - help='Enable UndefinedBehavior Sanitizer (Unsigned Integer Overflow Parts)') +option('--enable-unsigned-overflow-sanitizer', + help='Enable UndefinedBehavior Sanitizer (Unsigned Integer Overflow Parts)') @depends(when='--enable-unsigned-overflow-sanitizer') @@ -1609,10 +1587,10 @@ def security_hardening_cflags(hardening_flag, asan, optimize, c_compiler, target ) -add_old_configure_assignment('MOZ_HARDENING_CFLAGS', security_hardening_cflags.flags) -add_old_configure_assignment('MOZ_HARDENING_LDFLAGS', security_hardening_cflags.ldflags) -add_old_configure_assignment('MOZ_HARDENING_CFLAGS_JS', security_hardening_cflags.js_flags) -add_old_configure_assignment('MOZ_HARDENING_LDFLAGS_JS', security_hardening_cflags.js_ldflags) +set_config('MOZ_HARDENING_CFLAGS', security_hardening_cflags.flags) +set_config('MOZ_HARDENING_LDFLAGS', security_hardening_cflags.ldflags) +set_config('MOZ_HARDENING_CFLAGS_JS', security_hardening_cflags.js_flags) +set_config('MOZ_HARDENING_LDFLAGS_JS', security_hardening_cflags.js_ldflags) # Frame pointers @@ -1638,8 +1616,8 @@ def frame_pointer_default(optimize, debug, target, msan, asan, ubsan): (target.os == 'WINNT' and target.cpu in ('x86', 'aarch64'))) -js_option('--enable-frame-pointers', default=frame_pointer_default, - help='{Enable|Disable} frame pointers') +option('--enable-frame-pointers', default=frame_pointer_default, + help='{Enable|Disable} frame pointers') @depends('--enable-frame-pointers', frame_pointer_flags) @@ -1722,24 +1700,11 @@ set_config('HAVE_YASM', have_yasm) add_old_configure_assignment('YASM', have_yasm) -# clang-cl integrated assembler support -# ============================================================== -@depends(target) -def clangcl_asflags(target): - asflags = None - if target.os == 'WINNT' and target.cpu == 'aarch64': - asflags = ['--target=aarch64-windows-msvc'] - return asflags - - -set_config('CLANGCL_ASFLAGS', clangcl_asflags) - - # Code Coverage # ============================================================== -js_option('--enable-coverage', env='MOZ_CODE_COVERAGE', - help='Enable code coverage') +option('--enable-coverage', env='MOZ_CODE_COVERAGE', + help='Enable code coverage') @depends('--enable-coverage') @@ -1798,9 +1763,9 @@ set_config('RUSTFLAGS', depends('RUSTFLAGS')(lambda flags: flags)) # Rust compiler flags # ============================================================== -js_option(env='RUSTC_OPT_LEVEL', - nargs=1, - help='Rust compiler optimization level (-C opt-level=%s)') +option(env='RUSTC_OPT_LEVEL', + nargs=1, + help='Rust compiler optimization level (-C opt-level=%s)') # --enable-release kicks in full optimizations. imply_option('RUSTC_OPT_LEVEL', '2', when='--enable-release') @@ -1861,13 +1826,15 @@ def rust_compile_flags(opt_level, debug_rust, debug_symbols, frame_pointers): # Rust incremental compilation # ============================================================== -js_option('--disable-cargo-incremental', - help='Disable incremental rust compilation.') + +option('--disable-cargo-incremental', + help='Disable incremental rust compilation.') @depends(rustc_opt_level, debug_rust, 'MOZ_AUTOMATION', code_coverage, - '--disable-cargo-incremental') + '--disable-cargo-incremental', using_sccache, 'RUSTC_WRAPPER') +@imports('os') def cargo_incremental(opt_level, debug_rust, automation, code_coverage, - enabled): + enabled, using_sccache, rustc_wrapper): """Return a value for the CARGO_INCREMENTAL environment variable.""" if not enabled: @@ -1884,6 +1851,15 @@ def cargo_incremental(opt_level, debug_rust, automation, code_coverage, if code_coverage: return '0' + # Incremental compilation doesn't work as well as it should, and if we're + # using sccache, it's better to use sccache than incremental compilation. + if not using_sccache and rustc_wrapper: + rustc_wrapper = os.path.basename(rustc_wrapper[0]) + if os.path.splitext(rustc_wrapper)[0].lower() == 'sccache': + using_sccache = True + if using_sccache: + return '0' + # Incremental compilation is automatically turned on for debug builds, so # we don't need to do anything special here. if debug_rust: @@ -1920,9 +1896,25 @@ option('--enable-gold', imply_option('--enable-linker', 'gold', when='--enable-gold') -js_option('--enable-linker', nargs=1, - help='Select the linker {bfd, gold, ld64, lld, lld-*}', - when=is_linker_option_enabled) +@depends(target, developer_options) +def enable_linker_default(target, developer_options): + # x86-64 gold has bugs in how it lays out .note.* sections. See bug 1573820. + # lld is faster, so prefer that for developer builds. + if target.os == 'Android' and target.cpu == 'x86_64': + return 'lld' if developer_options else 'bfd' + + +option('--enable-linker', nargs=1, + help='Select the linker {bfd, gold, ld64, lld, lld-*}{|}', + default=enable_linker_default, + when=is_linker_option_enabled) + + +# No-op to enable depending on --enable-linker from default_elfhack in +# toolkit/moz.configure. +@depends('--enable-linker', when=is_linker_option_enabled) +def enable_linker(linker): + return linker @depends('--enable-linker', c_compiler, developer_options, '--enable-gold', @@ -2064,14 +2056,14 @@ add_old_configure_assignment('GCC_USE_GNU_LD', gcc_use_gnu_ld) # Assembler detection # ============================================================== -js_option(env='AS', nargs=1, help='Path to the assembler') +option(env='AS', nargs=1, help='Path to the assembler') @depends(target, c_compiler) def as_info(target, c_compiler): if c_compiler.type == 'clang-cl': ml = { - 'x86': 'ml', - 'x86_64': 'ml64', + 'x86': 'ml.exe', + 'x86_64': 'ml64.exe', 'aarch64': 'armasm64.exe', }.get(target.cpu) return namespace( @@ -2166,14 +2158,14 @@ set_config('ASOUTOPTION', as_outoption) # clang plugin handling # ============================================================== -js_option('--enable-clang-plugin', env='ENABLE_CLANG_PLUGIN', - help="Enable building with the mozilla clang plugin") +option('--enable-clang-plugin', env='ENABLE_CLANG_PLUGIN', + help="Enable building with the Clang plugin (gecko specific static analyzers)") add_old_configure_assignment('ENABLE_CLANG_PLUGIN', depends_if('--enable-clang-plugin')(lambda _: True)) -js_option('--enable-mozsearch-plugin', env='ENABLE_MOZSEARCH_PLUGIN', - help="Enable building with the mozsearch indexer plugin") +option('--enable-mozsearch-plugin', env='ENABLE_MOZSEARCH_PLUGIN', + help="Enable building with the mozsearch indexer plugin") add_old_configure_assignment('ENABLE_MOZSEARCH_PLUGIN', depends_if('--enable-mozsearch-plugin')(lambda _: True)) @@ -2181,8 +2173,8 @@ add_old_configure_assignment('ENABLE_MOZSEARCH_PLUGIN', # Libstdc++ compatibility hacks # ============================================================== # -js_option('--enable-stdcxx-compat', env='MOZ_STDCXX_COMPAT', - help='Enable compatibility with older libstdc++') +option('--enable-stdcxx-compat', env='MOZ_STDCXX_COMPAT', + help='Enable compatibility with older libstdc++') @template @@ -2219,7 +2211,7 @@ add_gcc_flag( # Support various fuzzing options # ============================================================== -js_option('--enable-fuzzing', help='Enable fuzzing support') +option('--enable-fuzzing', help='Enable fuzzing support') @depends('--enable-fuzzing') def enable_fuzzing(value): @@ -2343,12 +2335,13 @@ def rc_names(c_compiler, toolchain_prefix): return ('rc',) -check_prog('RC', rc_names, paths=sdk_bin_path) +check_prog('RC', rc_names, paths=sdk_bin_path, when=target_is_windows) -@depends(link, toolchain_prefix) -def ar_config(link, toolchain_prefix): - if link: # if LINKER is set, it's either for lld-link or link +@depends(link, toolchain_prefix, c_compiler) +def ar_config(link, toolchain_prefix, c_compiler): + if c_compiler.type == 'clang-cl' and link: + # if LINKER is set, it's either for lld-link or link if 'lld-link' in link: return namespace( names=('llvm-lib',), @@ -2371,3 +2364,8 @@ ar = check_prog('AR', ar_config.names, paths=toolchain_search_path) add_old_configure_assignment('AR', ar) set_config('AR_FLAGS', ar_config.flags) + + +option('--enable-cpp-rtti', help='Enable C++ RTTI') + +add_old_configure_assignment('_MOZ_USE_RTTI', '1', when='--enable-cpp-rtti') diff --git a/build/moz.configure/util.configure b/build/moz.configure/util.configure index 47480bbc3c..7047baef34 100644 --- a/build/moz.configure/util.configure +++ b/build/moz.configure/util.configure @@ -214,7 +214,6 @@ def find_program(file, paths=None): @imports('os') -@imports('subprocess') @imports(_from='mozbuild.configure.util', _import='LineIO') @imports(_from='tempfile', _import='mkstemp') def try_invoke_compiler(compiler, language, source, flags=None, onerror=None): @@ -421,7 +420,9 @@ def dependable(obj): return obj if isfunction(obj): return depends(when=True)(obj) - return depends(when=True)(lambda: obj) + # Depend on --help to make lint happy if the dependable is used as an input + # to an option(). + return depends('--help', when=True)(lambda _: obj) always = dependable(True) @@ -470,11 +471,6 @@ def old_configure_assignments(): return [] -@dependable -def extra_old_configure_args(): - return [] - - @template def add_old_configure_assignment(var, value, when=None): var = dependable(var) @@ -493,11 +489,3 @@ def add_old_configure_assignment(var, value, when=None): if isinstance(value, (list, tuple)): value = quote(*value) assignments.append((var, str(value))) - - -@template -def add_old_configure_arg(arg): - @depends(extra_old_configure_args, arg) - def add_arg(args, arg): - if arg: - args.append(arg) diff --git a/build/moz.configure/warnings.configure b/build/moz.configure/warnings.configure index 3ccd1f7294..1f39ac1f54 100644 --- a/build/moz.configure/warnings.configure +++ b/build/moz.configure/warnings.configure @@ -2,13 +2,9 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -js_option('--enable-warnings-as-errors', env='MOZ_ENABLE_WARNINGS_AS_ERRORS', - default=depends('MOZ_AUTOMATION')(lambda x: bool(x)), - help='{Enable|Disable} treating warnings as errors') - -add_old_configure_assignment( - 'MOZ_ENABLE_WARNINGS_AS_ERRORS', - depends('--enable-warnings-as-errors')(lambda x: bool(x))) +option('--enable-warnings-as-errors', env='MOZ_ENABLE_WARNINGS_AS_ERRORS', + default=depends('MOZ_AUTOMATION')(lambda x: bool(x)), + help='{Enable|Disable} treating warnings as errors') @depends('--enable-warnings-as-errors') @@ -24,6 +20,22 @@ def rust_warning_flags(warnings_as_errors): return flags +c_warning_flag = dependable('-Werror') + + +@depends('--enable-warnings-as-errors', c_warning_flag) +def warnings_as_errors(warnings_as_errors, c_warning_flag): + if not warnings_as_errors: + return '' + + return c_warning_flag + +set_config('WARNINGS_AS_ERRORS', warnings_as_errors) +# We have a peculiar setup in old-configure.in where some compilation tests +# depend on enabling warnings-as-errors even if it's disabled for Firefox +# compilation. We therefore need this assignment. +add_old_configure_assignment('WARNINGS_AS_ERRORS', c_warning_flag) + # GCC/Clang warnings: # https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html @@ -200,6 +212,11 @@ check_and_add_gcc_warning('-Wno-noexcept-type', cxx_compiler, when=depends(build_project) (lambda build_project: build_project == 'js')) +# Disable broken missing-braces warning on old clang versions +check_and_add_gcc_warning( + '-Wno-missing-braces', + when=depends(c_compiler)(lambda c: c.type == 'clang' and c.version < '6.0')) + # Please keep these last in this file add_old_configure_assignment('_WARNINGS_CFLAGS', warnings_flags.cflags) diff --git a/build/moz.configure/windows.configure b/build/moz.configure/windows.configure index f7a19c7c89..46122bcf54 100644 --- a/build/moz.configure/windows.configure +++ b/build/moz.configure/windows.configure @@ -23,10 +23,11 @@ def valid_windows_version(value): option(env='WINDOWSSDKDIR', nargs=1, - help='Directory containing the Windows SDK') + help='Directory containing the Windows SDK', + when=host_is_windows) -@depends('WINDOWSSDKDIR', host) +@depends('WINDOWSSDKDIR', host, when=host_is_windows) def windows_sdk_dir(value, host): if value: return value @@ -92,7 +93,8 @@ def valid_windows_sdk_dir_result(value): return '0x%04x in %s' % (value.version, quote(value.path)) -@depends(c_compiler, windows_sdk_dir, valid_windows_version, 'WINDOWSSDKDIR') +@depends(c_compiler, windows_sdk_dir, valid_windows_version, 'WINDOWSSDKDIR', + when=host_is_windows) @checking('for Windows SDK', valid_windows_sdk_dir_result) @imports(_from='__builtin__', _import='sorted') @imports(_from='__builtin__', _import='Exception') @@ -161,7 +163,7 @@ def valid_ucrt_sdk_dir_result(value): return '%s in %s' % (value.version, quote(value.path)) -@depends(windows_sdk_dir, 'WINDOWSSDKDIR') +@depends(windows_sdk_dir, 'WINDOWSSDKDIR', when=host_is_windows) @checking('for Universal CRT SDK', valid_ucrt_sdk_dir_result) @imports('os') @imports(_from='__builtin__', _import='sorted') @@ -234,10 +236,10 @@ def valid_ucrt_sdk_dir(windows_sdk_dir, windows_sdk_dir_env): ) -@depends(c_compiler, toolchain_search_path) +@depends(c_compiler, host_c_compiler, toolchain_search_path) @imports('os') -def vc_path(c_compiler, toolchain_search_path): - if c_compiler.type != 'clang-cl': +def vc_path(c_compiler, host_c_compiler, toolchain_search_path): + if c_compiler.type != 'clang-cl' and host_c_compiler.type != 'clang-cl': return # In clang-cl builds, we need the headers and libraries from an MSVC installation. @@ -273,6 +275,8 @@ def dia_sdk_dir(vc_path, dia_sdk_path): # get_vc_paths works with, since 'DIA SDK' is relative to that. path = os.path.normpath(os.path.join( vc_path, r'..\..\..\..\DIA SDK')) + else: + return if os.path.exists(os.path.join(path, 'include', 'dia2.h')): return path @@ -383,7 +387,7 @@ def lib_path_for(host_or_target): return lib_path -@depends(lib_path_for(target)) +@depends_if(lib_path_for(target)) @imports('os') def lib_path(libs): # Set in the environment for old-configure @@ -397,13 +401,13 @@ set_config('LIB', lib_path) lib_path_for_host = lib_path_for(host) -@depends(lib_path_for_host) +@depends_if(lib_path_for_host) @imports(_from='mozbuild.shellutil', _import='quote') def host_linker_libpaths(libs): return ['-LIBPATH:%s' % quote(l) for l in libs] -@depends(lib_path_for_host) +@depends_if(lib_path_for_host) @imports(_from='mozbuild.shellutil', _import='quote') def host_linker_libpaths_bat(libs): # .bat files need a different style of quoting. Batch quoting is actually @@ -419,7 +423,11 @@ set_config('HOST_LINKER_LIBPATHS', host_linker_libpaths) set_config('HOST_LINKER_LIBPATHS_BAT', host_linker_libpaths_bat) -option(env='MT', nargs=1, help='Path to the Microsoft Manifest Tool') +# The when is technically wrong and should be removed and the code that +# @depends on the option will need to be adapted when actual support for +# clang-cl cross-builds emerge. +option(env='MT', nargs=1, help='Path to the Microsoft Manifest Tool', + when=host_is_windows) @depends(valid_windows_sdk_dir, valid_ucrt_sdk_dir) @@ -448,12 +456,12 @@ def sdk_bin_path(valid_windows_sdk_dir, valid_ucrt_sdk_dir): mt = check_prog('MT', ('mt.exe',), input='MT', - paths=sdk_bin_path) + paths=sdk_bin_path, when=host_is_windows) # Check that MT is not something unexpected like "magnetic tape manipulation # utility". -@depends(mt) +@depends_if(mt) @checking('whether MT is really Microsoft Manifest Tool', lambda x: bool(x)) @imports('subprocess') def valid_mt(path): @@ -470,17 +478,17 @@ def valid_mt(path): set_config('MSMANIFEST_TOOL', depends(valid_mt)(lambda x: bool(x))) -js_option(env='LINKER', nargs=1, help='Path to the linker') +option(env='LINKER', nargs=1, when=target_is_windows, help='Path to the linker') link = check_prog('LINKER', ('lld-link',), input='LINKER', - paths=toolchain_search_path) + when=target_is_windows, paths=toolchain_search_path) -js_option(env='HOST_LINKER', nargs=1, help='Path to the host linker') +option(env='HOST_LINKER', nargs=1, when=host_is_windows, help='Path to the host linker') host_link = check_prog('HOST_LINKER', ('lld-link',), input='HOST_LINKER', - paths=host_toolchain_search_path) + when=host_is_windows, paths=host_toolchain_search_path) add_old_configure_assignment('LINKER', link) -check_prog('MAKECAB', ('makecab.exe',)) +check_prog('MAKECAB', ('makecab.exe',), when=host_is_windows) diff --git a/build/mozconfig.automation b/build/mozconfig.automation index 293aa4d7ac..70d5960d1b 100644 --- a/build/mozconfig.automation +++ b/build/mozconfig.automation @@ -15,5 +15,6 @@ mk_add_options "export MOZ_AUTOMATION_PACKAGE=${MOZ_AUTOMATION_PACKAGE-1}" mk_add_options "export MOZ_AUTOMATION_PACKAGE_TESTS=${MOZ_AUTOMATION_PACKAGE_TESTS-1}" mk_add_options "export MOZ_AUTOMATION_PACKAGE_GENERATED_SOURCES=${MOZ_AUTOMATION_PACKAGE_GENERATED_SOURCES-1}" mk_add_options "export MOZ_AUTOMATION_UPLOAD=${MOZ_AUTOMATION_UPLOAD-1}" +mk_add_options "export MOZ_AUTOMATION_CHECK=${MOZ_AUTOMATION_CHECK-1}" export MOZ_AUTOMATION_MOZCONFIG=1 diff --git a/build/mozconfig.cache b/build/mozconfig.cache index fbea916672..4f944ba593 100644 --- a/build/mozconfig.cache +++ b/build/mozconfig.cache @@ -5,7 +5,7 @@ # Setup for build cache # builds where buildprops didn't have the data (eg: taskcluster) and without sccache disabled: -if test -z "$bucket" -a -z "$SCCACHE_DISABLE" -a -z "$MOZ_PGO"; then +if test -z "$bucket" -a -z "$SCCACHE_DISABLE"; then # prevent rerun if az is set, or wget is not available if test -z "$availability_zone" -a -x "$(command -v wget)"; then @@ -60,7 +60,7 @@ if test -n "$bucket"; then # instruct sccache to fetch the credentials from the Auth service's awsS3Credentials endpoint, via the Taskcluster proxy. mk_add_options "export AWS_IAM_CREDENTIALS_URL=http://taskcluster/auth/v1/aws/s3/read-write/${bucket}/?format=iam-role-compat" fi - export CCACHE="$topsrcdir/sccache2/sccache" + export CCACHE="$MOZ_FETCHES_DIR/sccache/sccache" export SCCACHE_VERBOSE_STATS=1 - mk_add_options MOZBUILD_MANAGE_SCCACHE_DAEMON=${topsrcdir}/sccache2/sccache + mk_add_options MOZBUILD_MANAGE_SCCACHE_DAEMON=${MOZ_FETCHES_DIR}/sccache/sccache fi diff --git a/build/mozconfig.clang-cl b/build/mozconfig.clang-cl index efaec52e1d..cfc7a2a8fc 100644 --- a/build/mozconfig.clang-cl +++ b/build/mozconfig.clang-cl @@ -1,9 +1,9 @@ -if test -d "$topsrcdir/clang/bin"; then - CLANG_DIR=`cd "$topsrcdir/clang/bin" ; pwd` +if test -d "$MOZ_FETCHES_DIR/clang/bin"; then + CLANG_DIR=`cd "$MOZ_FETCHES_DIR/clang/bin" ; pwd` export PATH="${CLANG_DIR}:${PATH}" - if $(cd $topsrcdir/clang/lib/clang/* && test -d lib/windows); then - CLANG_LIB_DIR="$(cd $topsrcdir/clang/lib/clang/* && cd lib/windows && pwd)" + if $(cd $MOZ_FETCHES_DIR/clang/lib/clang/* && test -d lib/windows); then + CLANG_LIB_DIR="$(cd $MOZ_FETCHES_DIR/clang/lib/clang/* && cd lib/windows && pwd)" export LIB=$LIB:$CLANG_LIB_DIR fi fi diff --git a/build/mozconfig.lld-link b/build/mozconfig.lld-link index 56f0878ec5..89f91930e7 100644 --- a/build/mozconfig.lld-link +++ b/build/mozconfig.lld-link @@ -1,5 +1,5 @@ -if test -d "$topsrcdir/clang/bin"; then - CLANG_DIR=`cd "$topsrcdir/clang/bin" ; pwd` +if test -d "$MOZ_FETCHES_DIR/clang/bin"; then + CLANG_DIR=`cd "$MOZ_FETCHES_DIR/clang/bin" ; pwd` export PATH="${CLANG_DIR}:${PATH}" fi diff --git a/build/mozconfig.nasm b/build/mozconfig.nasm index d1933e479a..055ec6cb7b 100644 --- a/build/mozconfig.nasm +++ b/build/mozconfig.nasm @@ -4,9 +4,9 @@ case "$(uname -s)" in MINGW*) - export NASM=$topsrcdir/nasm/nasm.exe + export NASM=$MOZ_FETCHES_DIR/nasm/nasm.exe ;; *) - export NASM=$topsrcdir/nasm/nasm + export NASM=$MOZ_FETCHES_DIR/nasm/nasm ;; esac diff --git a/build/mozconfig.node b/build/mozconfig.node index 399cf1e1c4..8a29161ece 100644 --- a/build/mozconfig.node +++ b/build/mozconfig.node @@ -4,9 +4,9 @@ case "$(uname -s)" in MINGW*) - export NODEJS=$topsrcdir/node/node.exe + export NODEJS=$MOZ_FETCHES_DIR/node/node.exe ;; *) - export NODEJS=$topsrcdir/node/bin/node + export NODEJS=$MOZ_FETCHES_DIR/node/bin/node ;; esac diff --git a/build/mozconfig.pgo b/build/mozconfig.pgo deleted file mode 100644 index 41444f7445..0000000000 --- a/build/mozconfig.pgo +++ /dev/null @@ -1,7 +0,0 @@ -case "$PERFHERDER_EXTRA_OPTIONS" in -base-toolchains*) - ;; -*) - export MOZ_PGO=1 - ;; -esac diff --git a/build/mozconfig.rust b/build/mozconfig.rust index 240c10fb1e..d12787f112 100644 --- a/build/mozconfig.rust +++ b/build/mozconfig.rust @@ -3,10 +3,10 @@ TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir} # Tell configure to use the tooltool rustc. -RUSTC="$TOOLTOOL_DIR/rustc/bin/rustc" -CARGO="$TOOLTOOL_DIR/rustc/bin/cargo" -RUSTDOC="$TOOLTOOL_DIR/rustc/bin/rustdoc" -RUSTFMT="$TOOLTOOL_DIR/rustc/bin/rustfmt" -CBINDGEN="$TOOLTOOL_DIR/cbindgen/cbindgen" +RUSTC="$MOZ_FETCHES_DIR/rustc/bin/rustc" +CARGO="$MOZ_FETCHES_DIR/rustc/bin/cargo" +RUSTDOC="$MOZ_FETCHES_DIR/rustc/bin/rustdoc" +RUSTFMT="$MOZ_FETCHES_DIR/rustc/bin/rustfmt" +CBINDGEN="$MOZ_FETCHES_DIR/cbindgen/cbindgen" ac_add_options --enable-rust-simd diff --git a/build/mozconfig.stylo b/build/mozconfig.stylo index 79384471e2..b8233a078b 100644 --- a/build/mozconfig.stylo +++ b/build/mozconfig.stylo @@ -1,2 +1,2 @@ # Tell the build system where to find llvm-config for builds on automation. -export LLVM_CONFIG="${TOOLTOOL_DIR:-$topsrcdir}/clang/bin/llvm-config" +export LLVM_CONFIG="${MOZ_FETCHES_DIR}/clang/bin/llvm-config" diff --git a/build/mozconfig.win-common b/build/mozconfig.win-common index 257b077c4f..17ede0d48c 100644 --- a/build/mozconfig.win-common +++ b/build/mozconfig.win-common @@ -6,10 +6,10 @@ TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir} export MAKECAB=$TOOLTOOL_DIR/makecab.exe if [ -z "$USE_ARTIFACT" ]; then - if [ -n "$MOZ_PGO_PROFILE_USE" ]; then + if [ -n "$TASKCLUSTER_PGO_PROFILE_USE" ]; then export MOZ_LTO=cross ac_add_options --enable-profile-use ac_add_options --with-pgo-jarlog="${WORKSPACE}/fetches/en-US.log" - ac_add_options --with-pgo-profile-path="${WORKSPACE}/fetches" + ac_add_options --with-pgo-profile-path="${WORKSPACE}/fetches/merged.profdata" fi fi diff --git a/build/pgo/index.html b/build/pgo/index.html index 12389a93a5..d61f5cbcad 100644 --- a/build/pgo/index.html +++ b/build/pgo/index.html @@ -7,11 +7,10 @@ var list = [ - "js-input/webkit/PerformanceTests/Speedometer/index.html", - "blueprint/sample.html", + "blueprint/elements.html", "blueprint/forms.html", "blueprint/grid.html", - "blueprint/elements.html", + "blueprint/sample.html", "js-input/3d-thingy.html", "js-input/crypto-otp.html", "js-input/sunspider/3d-cube.html", @@ -40,6 +39,37 @@ "js-input/sunspider/string-tagcloud.html", "js-input/sunspider/string-unpack-code.html", "js-input/sunspider/string-validate-input.html", + "talos/tests/perf-reftest-singletons/abspos-reflow-1.html", + "talos/tests/perf-reftest-singletons/bidi-resolution-1.html", + "talos/tests/perf-reftest-singletons/bloom-basic-2.html", + "talos/tests/perf-reftest-singletons/bloom-basic.html", + "talos/tests/perf-reftest-singletons/coalesce-1.html", + "talos/tests/perf-reftest-singletons/coalesce-2.html", + "talos/tests/perf-reftest-singletons/display-none-1.html", + "talos/tests/perf-reftest-singletons/external-string-pass.html", + "talos/tests/perf-reftest-singletons/getElementById-1.html", + "talos/tests/perf-reftest-singletons/id-getter-1.html", + "talos/tests/perf-reftest-singletons/id-getter-2.html", + "talos/tests/perf-reftest-singletons/id-getter-3.html", + "talos/tests/perf-reftest-singletons/id-getter-4.html", + "talos/tests/perf-reftest-singletons/id-getter-5.html", + "talos/tests/perf-reftest-singletons/id-getter-6.html", + "talos/tests/perf-reftest-singletons/id-getter-7.html", + "talos/tests/perf-reftest-singletons/inline-style-cache-1.html", + "talos/tests/perf-reftest-singletons/link-style-cache-1.html", + "talos/tests/perf-reftest-singletons/nth-index-1.html", + "talos/tests/perf-reftest-singletons/nth-index-2.html", + "talos/tests/perf-reftest-singletons/only-children-1.html", + "talos/tests/perf-reftest-singletons/parent-basic-singleton.html", + "talos/tests/perf-reftest-singletons/scrollbar-styles-1.html", + "talos/tests/perf-reftest-singletons/slow-selector-1.html", + "talos/tests/perf-reftest-singletons/slow-selector-2.html", + "talos/tests/perf-reftest-singletons/style-attr-1.html", + "talos/tests/perf-reftest-singletons/style-sharing-style-attr.html", + "talos/tests/perf-reftest-singletons/style-sharing.html", + "talos/tests/perf-reftest-singletons/tiny-traversal-singleton.html", + "talos/tests/perf-reftest-singletons/window-named-property-get.html", + "webkit/PerformanceTests/Speedometer/index.html", ]; var defaultInterval = 2000; var idx = 0; @@ -51,11 +81,16 @@ }; function loadURL() { var interval = defaultInterval; - if (idx == 0) { + var testURL = list[idx++]; + if (testURL.includes("webkit")) { interval = 90000; } w.close(); - w = window.open(list[idx++]); + w = window.open(testURL); + + // Prevent the perf-reftest-singletons from calling alert() + w.tpRecordTime = function() { }; + if (idx < list.length) { window.setTimeout(loadURL, interval); } else { diff --git a/build/pgo/profileserver.py b/build/pgo/profileserver.py index aacec93a8b..bb98209ab6 100644 --- a/build/pgo/profileserver.py +++ b/build/pgo/profileserver.py @@ -7,8 +7,10 @@ import json import os import sys +import glob +import subprocess -from buildconfig import substs +import mozcrash from mozbuild.base import MozbuildObject from mozfile import TemporaryDirectory from mozhttpd import MozHttpd @@ -20,10 +22,38 @@ from six import string_types PORT = 8888 PATH_MAPPINGS = { - '/js-input/webkit/PerformanceTests': 'third_party/webkit/PerformanceTests', + '/webkit/PerformanceTests': 'third_party/webkit/PerformanceTests', + # It is tempting to map to `testing/talos/talos/tests` instead, to avoid + # writing `tests/` in every path, but we can't do that because some files + # refer to scripts located in `../..`. + '/talos': 'testing/talos/talos', } +def get_crashreports(directory, name=None): + rc = 0 + upload_path = os.environ.get('UPLOAD_PATH') + if upload_path: + # For automation, log the minidumps with stackwalk and get them moved to + # the artifacts directory. + fetches_dir = os.environ.get('MOZ_FETCHES_DIR') + if not fetches_dir: + raise Exception("Unable to process minidump in automation because " + "$MOZ_FETCHES_DIR is not set in the environment") + stackwalk_binary = os.path.join(fetches_dir, 'minidump_stackwalk', 'minidump_stackwalk') + if sys.platform == 'win32': + stackwalk_binary += '.exe' + minidump_path = os.path.join(directory, "minidumps") + rc = mozcrash.check_for_crashes( + minidump_path, + symbols_path=fetches_dir, + stackwalk_binary=stackwalk_binary, + dump_save_path=upload_path, + test_name=name, + ) + return rc + + if __name__ == '__main__': cli = CLI() debug_args, interactive = cli.debugger_arguments() @@ -50,6 +80,10 @@ if __name__ == '__main__': port=PORT, options='primary,privileged') + old_profraw_files = glob.glob('*.profraw') + for f in old_profraw_files: + os.remove(f) + with TemporaryDirectory() as profilePath: # TODO: refactor this into mozprofile profile_data_dir = os.path.join(build.topsrcdir, 'testing', 'profiles') @@ -92,17 +126,6 @@ if __name__ == '__main__': # Ensure different pids write to different files env["LLVM_PROFILE_FILE"] = "default_%p_random_%m.profraw" - # For VC12+, make sure we can find the right bitness of pgort1x0.dll - if not substs.get('HAVE_64BIT_BUILD'): - for e in ('VS140COMNTOOLS', 'VS120COMNTOOLS'): - if e not in env: - continue - - vcdir = os.path.abspath(os.path.join(env[e], '../../VC/bin')) - if os.path.exists(vcdir): - env['PATH'] = '%s;%s' % (vcdir, env['PATH']) - break - # Write to an output file if we're running in automation process_args = {} if 'UPLOAD_PATH' in env: @@ -125,12 +148,15 @@ if __name__ == '__main__': with open(logfile) as f: print(f.read()) httpd.stop() + get_crashreports(profilePath, name='Profile initialization') sys.exit(ret) jarlog = os.getenv("JARLOG_FILE") if jarlog: env["MOZ_JAR_LOG_FILE"] = os.path.abspath(jarlog) print("jarlog: %s" % env["MOZ_JAR_LOG_FILE"]) + if os.path.exists(jarlog): + os.remove(jarlog) if 'UPLOAD_PATH' in env: process_args['logfile'] = os.path.join(env['UPLOAD_PATH'], 'profile-run-2.log') @@ -150,4 +176,30 @@ if __name__ == '__main__': print("Firefox output (%s):" % logfile) with open(logfile) as f: print(f.read()) + get_crashreports(profilePath, name='Profiling run') sys.exit(ret) + + # Try to move the crash reports to the artifacts even if Firefox appears + # to exit successfully, in case there's a crash that doesn't set the + # return code to non-zero for some reason. + if get_crashreports(profilePath, name='Firefox exited successfully?') != 0: + print("Firefox exited successfully, but produced a crashreport") + sys.exit(1) + + llvm_profdata = env.get('LLVM_PROFDATA') + if llvm_profdata: + profraw_files = glob.glob('*.profraw') + if not profraw_files: + print('Could not find profraw files in the current directory: %s' % os.getcwd()) + sys.exit(1) + merge_cmd = [ + llvm_profdata, + 'merge', + '-o', + 'merged.profdata', + ] + profraw_files + rc = subprocess.call(merge_cmd) + if rc != 0: + print('INFRA-ERROR: Failed to merge profile data. Corrupt profile?') + # exit with TBPL_RETRY + sys.exit(4) diff --git a/build/sanitizers/lsan_suppressions.txt b/build/sanitizers/lsan_suppressions.txt deleted file mode 100644 index 2ee52d926c..0000000000 --- a/build/sanitizers/lsan_suppressions.txt +++ /dev/null @@ -1,80 +0,0 @@ -### !!! Please do not add suppressions for new leaks in Gecko code, unless they are intentional !!! - -### -### Some of these leak in every test run. -### - -# LSan runs with a shallow stack depth and no debug symbols, so some small intentional -# leaks in system libraries show up with this. You do not want this enabled -# when running locally with a deep stack, as it can catch too much. -leak:libc.so - -# nsComponentManagerImpl intentionally leaks factory entries, and probably some other stuff. -leak:nsComponentManagerImpl -# These two variants are needed when fast unwind is disabled and stack depth is limited. -leak:mozJSComponentLoader::LoadModule -leak:nsNativeModuleLoader::LoadModule - -# Bug 981220 - Pixman fails to free TLS memory. -leak:pixman_implementation_lookup_composite - -# Bug 987918 - Font shutdown leaks when CLEANUP_MEMORY is not enabled. -leak:libfontconfig.so -leak:GI___strdup -# The symbol is really __GI___strdup, but if you have the leading _, it doesn't suppress it. - -# Bug 1078015 - If the process terminates during a PR_Sleep, LSAN detects a leak -leak:PR_Sleep - -# Bug 1363976 - Stylo holds some global data alive forever. -leak:style::global_style_data - -### -### Many leaks only affect some test suites. The suite annotations are not checked. -### - -# Bug 979928 - WebRTC leaks in different mochitest suites. -leak:NR_reg_init -# nr_reg_local_init should be redundant with NR_reg_init, but on Aurora -# we get fewer stack frames for some reason. -leak:nr_reg_local_init -leak:r_log_register -leak:nr_reg_set - -# This is a one-time leak in mochitest-bc, so it is probably okay to ignore. -leak:GlobalPrinters::InitializeGlobalPrinters -leak:nsPSPrinterList::GetPrinterList - -# Bug 1028456 - Various NSPR fd-related leaks in different mochitest suites. -leak:_PR_Getfd - -# Bug 1028483 - The XML parser sometimes leaks an object. Mostly happens in toolkit/components/thumbnails. -leak:processInternalEntity - -# Bug 1187421 - NSS does not always free the error stack in different mochitest suites. -leak:nss_ClearErrorStack - -### -### Leaks with system libraries in their stacks. These show up across a number of tests. -### Better symbols and disabling fast stackwalking may help diagnose these. -### - -leak:libcairo.so -leak:libdl.so -leak:libdricore.so -leak:libdricore9.2.1.so -leak:libGL.so -leak:libglib-2.0.so -leak:libglsl.so -leak:libp11-kit.so -leak:libpixman-1.so -leak:libpulse.so -# lubpulsecommon 1.1 is Ubuntu 12.04 -leak:libpulsecommon-1.1.so -# lubpulsecommon 1.1 is Ubuntu 16.04 -leak:libpulsecommon-8.0.so -leak:libresolv.so -leak:libstdc++.so -leak:libXrandr.so -leak:pthread_setspecific_internal -leak:swrast_dri.so diff --git a/build/sanitizers/tsan_suppressions.txt b/build/sanitizers/tsan_suppressions.txt deleted file mode 100644 index 3ea562e67c..0000000000 --- a/build/sanitizers/tsan_suppressions.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Bug 931149 -race:DoImageDataComplete - -# Bug 939786 -race:_pt_root - -# Bug 939788 -# Tracked by http://code.google.com/p/thread-sanitizer/issues/detail?id=40 -race:ELMCreationDetector - -# Bug 939790 -race:xpcom/components/nsComponentManager.h - -# Bug 939807 -race:ComputeUTCTime - -# Bug 939805 -race:g_variant_type_info_get - -# Bug 844759 -race:js::gc::ArenaLists::allocateFromArenaInline diff --git a/build/sanitizers/ubsan_suppressions.txt b/build/sanitizers/ubsan_suppressions.txt deleted file mode 100644 index 0d4c7becbd..0000000000 --- a/build/sanitizers/ubsan_suppressions.txt +++ /dev/null @@ -1,15 +0,0 @@ -# This list contains runtime suppression entries for any issues reported -# by UndefinedBehaviorSanitizer (UBSan). Unlike the compile-time blacklists, -# this list allows us to blacklist source code files and functions only for -# specific checks performed by UBSan. -# -# Example: -# -# signed-integer-overflow:file-with-known-overflow.cpp -# alignment:function_doing_unaligned_access -# vptr:shared_object_with_vptr_failures.so -# -# Since runtime suppressions are much more expensive than compile-time -# blacklisting, this list should not be used for frequent issues but rather -# only for sporadic warnings that have already been checked and confirmed -# to not be bugs. diff --git a/build/sparse-profiles/taskgraph b/build/sparse-profiles/taskgraph index 9a9d70ac9b..3df3d0b0b5 100644 --- a/build/sparse-profiles/taskgraph +++ b/build/sparse-profiles/taskgraph @@ -56,3 +56,10 @@ path:.cron.yml # for the wrench-deps toolchain task path:gfx/wr/Cargo.lock + +# for the mar-tools toolchain task +path:mfbt/ +path:modules/libmar/ +path:other-licenses/bsdiff/ +path:other-licenses/nsis/Contrib/CityHash/cityhash/ +path:toolkit/mozapps/update/updater diff --git a/build/unix/mozconfig.asan b/build/unix/mozconfig.asan index 16e7f8a08b..803f0275f8 100644 --- a/build/unix/mozconfig.asan +++ b/build/unix/mozconfig.asan @@ -2,7 +2,7 @@ MOZ_AUTOMATION_L10N_CHECK=0 . "$topsrcdir/build/unix/mozconfig.unix" -export LLVM_SYMBOLIZER="$topsrcdir/clang/bin/llvm-symbolizer" +export LLVM_SYMBOLIZER="$MOZ_FETCHES_DIR/clang/bin/llvm-symbolizer" # # Enable ASan specific code and build workarounds ac_add_options --enable-address-sanitizer diff --git a/build/unix/mozconfig.stdcxx b/build/unix/mozconfig.stdcxx index f86457c531..b1bb4e27db 100644 --- a/build/unix/mozconfig.stdcxx +++ b/build/unix/mozconfig.stdcxx @@ -6,14 +6,14 @@ TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir} # Depending whether GCC was built on a RedHat-based or a Debian-based system, # the directory containing 32-bits libraries can be either (respectively) # lib or lib32. The directory for 64-bits libraries is always lib64. -if [ -f "$TOOLTOOL_DIR/gcc/lib64/libstdc++.so" ]; then +if [ -f "$MOZ_FETCHES_DIR/gcc/lib64/libstdc++.so" ]; then # We put both 32-bits and 64-bits library path in LD_LIBRARY_PATH: ld.so # will prefer the files in the 32-bits path when loading 32-bits executables, # and the files in the 64-bits path when loading 64-bits executables. # We also put both possible 32-bits library paths. - LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$TOOLTOOL_DIR/gcc/lib64:$TOOLTOOL_DIR/gcc/lib32:$TOOLTOOL_DIR/gcc/lib -elif [ -f "$TOOLTOOL_DIR/clang/lib/libstdc++.so" ]; then - LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$TOOLTOOL_DIR/clang/lib:$TOOLTOOL_DIR/clang/lib32 + LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$MOZ_FETCHES_DIR/gcc/lib64:$MOZ_FETCHES_DIR/gcc/lib32:$MOZ_FETCHES_DIR/gcc/lib +elif [ -f "$MOZ_FETCHES_DIR/clang/lib/libstdc++.so" ]; then + LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$MOZ_FETCHES_DIR/clang/lib:$MOZ_FETCHES_DIR/clang/lib32 fi mk_add_options "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH" diff --git a/build/unix/mozconfig.tsan b/build/unix/mozconfig.tsan index 4f7faf443d..8fe913e15e 100644 --- a/build/unix/mozconfig.tsan +++ b/build/unix/mozconfig.tsan @@ -2,7 +2,7 @@ MOZ_AUTOMATION_L10N_CHECK=0 . "$topsrcdir/build/unix/mozconfig.unix" -export LLVM_SYMBOLIZER="$topsrcdir/clang/bin/llvm-symbolizer" +export LLVM_SYMBOLIZER="$MOZ_FETCHES_DIR/clang/bin/llvm-symbolizer" # Enable TSan specific code and build workarounds ac_add_options --enable-thread-sanitizer diff --git a/build/unix/mozconfig.unix b/build/unix/mozconfig.unix index ea860819ee..51753cf420 100644 --- a/build/unix/mozconfig.unix +++ b/build/unix/mozconfig.unix @@ -3,17 +3,22 @@ TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir} if [ -n "$FORCE_GCC" ]; then - CC="$TOOLTOOL_DIR/gcc/bin/gcc" - CXX="$TOOLTOOL_DIR/gcc/bin/g++" + CC="$MOZ_FETCHES_DIR/gcc/bin/gcc" + CXX="$MOZ_FETCHES_DIR/gcc/bin/g++" # We want to make sure we use binutils and other binaries in the tooltool # package. - mk_add_options "export PATH=$TOOLTOOL_DIR/gcc/bin:$PATH" - ac_add_options --with-clang-path=$TOOLTOOL_DIR/clang/bin/clang + mk_add_options "export PATH=$MOZ_FETCHES_DIR/gcc/bin:$PATH" + ac_add_options --with-clang-path=$MOZ_FETCHES_DIR/clang/bin/clang else - CC="$TOOLTOOL_DIR/clang/bin/clang" - CXX="$TOOLTOOL_DIR/clang/bin/clang++" - export ENABLE_CLANG_PLUGIN=1 + CC="$MOZ_FETCHES_DIR/clang/bin/clang" + CXX="$MOZ_FETCHES_DIR/clang/bin/clang++" + + # For some builds we don't want to have Clang based static-analysis activated + if [ -z "$DISABLE_CLANG_PLUGIN" ]; then + export ENABLE_CLANG_PLUGIN=1 + fi + case "$PERFHERDER_EXTRA_OPTIONS" in base-toolchains*) # Clang versions < 7.0 don't support the -fcrash-diagnostics-dir flag. @@ -24,22 +29,20 @@ else ;; esac - if [ -n "$MOZ_PGO" ]; then - if [ -z "$USE_ARTIFACT" ]; then + if [ -z "$USE_ARTIFACT" ]; then + if [ -n "$TASKCLUSTER_PGO_PROFILE_USE" ]; then export MOZ_LTO=cross - if [ -n "$MOZ_PGO_PROFILE_USE" ]; then - ac_add_options --enable-profile-use=cross - ac_add_options --with-pgo-jarlog=/builds/worker/fetches/en-US.log - ac_add_options --with-pgo-profile-path=/builds/worker/fetches - fi + ac_add_options --enable-profile-use=cross + ac_add_options --with-pgo-jarlog=/builds/worker/fetches/en-US.log + ac_add_options --with-pgo-profile-path=/builds/worker/fetches/merged.profdata + export LLVM_PROFDATA="$MOZ_FETCHES_DIR/clang/bin/llvm-profdata" + export AR="$MOZ_FETCHES_DIR/clang/bin/llvm-ar" + export NM="$MOZ_FETCHES_DIR/clang/bin/llvm-nm" + export RANLIB="$MOZ_FETCHES_DIR/clang/bin/llvm-ranlib" fi - export LLVM_PROFDATA="$TOOLTOOL_DIR/clang/bin/llvm-profdata" - export AR="$topsrcdir/clang/bin/llvm-ar" - export NM="$topsrcdir/clang/bin/llvm-nm" - export RANLIB="$topsrcdir/clang/bin/llvm-ranlib" fi - mk_add_options "export PATH=$TOOLTOOL_DIR/binutils/bin:$PATH" + mk_add_options "export PATH=$MOZ_FETCHES_DIR/binutils/bin:$PATH" fi . "$topsrcdir/build/unix/mozconfig.stdcxx" diff --git a/build/valgrind/x86_64-pc-linux-gnu.sup b/build/valgrind/x86_64-pc-linux-gnu.sup index 8a05c49a77..c400d66028 100644 --- a/build/valgrind/x86_64-pc-linux-gnu.sup +++ b/build/valgrind/x86_64-pc-linux-gnu.sup @@ -47,7 +47,6 @@ fun:FcDirCacheWrite fun:FcDirCacheScan fun:FcConfigAddDirList - fun:FcConfigAppFontAddDir ... } { @@ -58,7 +57,6 @@ fun:FcDirScanConfig fun:FcDirCacheScan fun:FcConfigAddDirList - fun:FcConfigAppFontAddDir ... } { @@ -70,7 +68,6 @@ fun:FcDirScanConfig fun:FcDirCacheScan fun:FcConfigAddDirList - fun:FcConfigAppFontAddDir ... } { @@ -82,7 +79,6 @@ obj:/usr/lib/x86_64-linux-gnu/libfontconfig.so.1.5.0 fun:FcDirCacheScan fun:FcConfigAddDirList - fun:FcConfigAppFontAddDir ... } # Leaks due to either Gtk+3 or cairo, but Gecko is not directly involved with diff --git a/build/win32/pgomerge.py b/build/win32/pgomerge.py deleted file mode 100644 index 754a2f6b3a..0000000000 --- a/build/win32/pgomerge.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/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/. - -# Usage: pgomerge.py -# Gathers .pgc files from dist/bin and merges them into -# $PWD/$basename.pgd using pgomgr, then deletes them. -# No errors if any of these files don't exist. - -import sys -import os -import os.path -import subprocess -if not sys.platform == "win32": - raise Exception("This script was only meant for Windows.") - - -def MergePGOFiles(basename, pgddir, pgcdir): - """Merge pgc files produced from an instrumented binary - into the pgd file for the second pass of profile-guided optimization - with MSVC. |basename| is the name of the DLL or EXE without the - extension. |pgddir| is the path that contains .pgd - (should be the objdir it was built in). |pgcdir| is the path - containing basename!N.pgc files, which is probably dist/bin. - Calls pgomgr to merge each pgc file into the pgd, then deletes - the pgc files.""" - if not os.path.isdir(pgddir) or not os.path.isdir(pgcdir): - return - pgdfile = os.path.abspath(os.path.join(pgddir, basename + ".pgd")) - if not os.path.isfile(pgdfile): - return - for file in os.listdir(pgcdir): - if file.startswith(basename+"!") and file.endswith(".pgc"): - try: - pgcfile = os.path.normpath(os.path.join(pgcdir, file)) - subprocess.call(['pgomgr', '-merge', - pgcfile, - pgdfile]) - os.remove(pgcfile) - except OSError: - pass - - -if __name__ == '__main__': - if len(sys.argv) != 3: - print >>sys.stderr, "Usage: pgomerge.py " - sys.exit(1) - MergePGOFiles(sys.argv[1], os.getcwd(), sys.argv[2]) diff --git a/build/win64/mozconfig.asan b/build/win64/mozconfig.asan index c0872d2908..f2b568de80 100644 --- a/build/win64/mozconfig.asan +++ b/build/win64/mozconfig.asan @@ -1,13 +1,13 @@ . "$topsrcdir/browser/config/mozconfigs/win64/common-win64" -if [ -d "$topsrcdir/clang" ]; then - CLANG_LIB_DIR="$(cd $topsrcdir/clang/lib/clang/* && cd lib/windows && pwd)" +if [ -d "$MOZ_FETCHES_DIR/clang" ]; then + CLANG_LIB_DIR="$(cd $MOZ_FETCHES_DIR/clang/lib/clang/* && cd lib/windows && pwd)" export LIB=$LIB:$CLANG_LIB_DIR export LDFLAGS="clang_rt.asan_dynamic-x86_64.lib clang_rt.asan_dynamic_runtime_thunk-x86_64.lib" export MOZ_COPY_PDBS=1 - export LLVM_SYMBOLIZER="$topsrcdir/clang/bin/llvm-symbolizer.exe" + export LLVM_SYMBOLIZER="$MOZ_FETCHES_DIR/clang/bin/llvm-symbolizer.exe" export MOZ_CLANG_RT_ASAN_LIB_PATH="${CLANG_LIB_DIR}/clang_rt.asan_dynamic-x86_64.dll" fi @@ -16,7 +16,6 @@ ac_add_options --enable-address-sanitizer # Mandatory options required for ASan builds ac_add_options --enable-debug-symbols -ac_add_options --disable-install-strip ac_add_options --disable-jemalloc ac_add_options --disable-crashreporter ac_add_options --disable-profiling diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index 349d6aa875..0b3258cabb 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -70,7 +70,6 @@ using namespace mozilla; using namespace mozilla::dom; nsIIOService* nsScriptSecurityManager::sIOService = nullptr; -JSContext* nsScriptSecurityManager::sContext = nullptr; bool nsScriptSecurityManager::sStrictFileOriginPolicy = true; namespace { @@ -1330,22 +1329,29 @@ nsresult nsScriptSecurityManager::Init() { mSystemPrincipal = system; + return NS_OK; +} + +void nsScriptSecurityManager::InitJSCallbacks(JSContext* aCx) { //-- Register security check callback in the JS engine // Currently this is used to control access to function.caller - sContext = danger::GetJSContext(); static const JSSecurityCallbacks securityCallbacks = { ContentSecurityPolicyPermitsJSAction, JSPrincipalsSubsume, }; - MOZ_ASSERT(!JS_GetSecurityCallbacks(sContext)); - JS_SetSecurityCallbacks(sContext, &securityCallbacks); - JS_InitDestroyPrincipalsCallback(sContext, nsJSPrincipals::Destroy); + MOZ_ASSERT(!JS_GetSecurityCallbacks(aCx)); + JS_SetSecurityCallbacks(aCx, &securityCallbacks); + JS_InitDestroyPrincipalsCallback(aCx, nsJSPrincipals::Destroy); - JS_SetTrustedPrincipals(sContext, system); + JS_SetTrustedPrincipals(aCx, BasePrincipal::Cast(mSystemPrincipal)); +} - return NS_OK; +/* static */ +void nsScriptSecurityManager::ClearJSCallbacks(JSContext* aCx) { + JS_SetSecurityCallbacks(aCx, nullptr); + JS_SetTrustedPrincipals(aCx, nullptr); } static StaticRefPtr gScriptSecMan; @@ -1363,12 +1369,6 @@ nsScriptSecurityManager::~nsScriptSecurityManager(void) { } void nsScriptSecurityManager::Shutdown() { - if (sContext) { - JS_SetSecurityCallbacks(sContext, nullptr); - JS_SetTrustedPrincipals(sContext, nullptr); - sContext = nullptr; - } - NS_IF_RELEASE(sIOService); BundleHelper::Shutdown(); } diff --git a/caps/nsScriptSecurityManager.h b/caps/nsScriptSecurityManager.h index 0ceb3491a5..98af9d551f 100644 --- a/caps/nsScriptSecurityManager.h +++ b/caps/nsScriptSecurityManager.h @@ -49,6 +49,11 @@ class nsScriptSecurityManager final : public nsIScriptSecurityManager { // Invoked exactly once, by XPConnect. static void InitStatics(); + void InitJSCallbacks(JSContext* aCx); + + // This has to be static because it is called after gScriptSecMan is cleared. + static void ClearJSCallbacks(JSContext* aCx); + static already_AddRefed SystemPrincipalSingletonConstructor(); @@ -119,7 +124,6 @@ class nsScriptSecurityManager final : public nsIScriptSecurityManager { static nsIIOService* sIOService; static nsIStringBundle* sStrBundle; - static JSContext* sContext; }; #endif // nsScriptSecurityManager_h__ diff --git a/config/MozZipFile.py b/config/MozZipFile.py index d483614355..f8dc5cc7e4 100644 --- a/config/MozZipFile.py +++ b/config/MozZipFile.py @@ -2,6 +2,7 @@ # 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/. +from __future__ import absolute_import import os import time import zipfile @@ -47,7 +48,7 @@ class ZipFile(zipfile.ZipFile): date_time=time.localtime(time.time())) zinfo.compress_type = self.compression # Add some standard UNIX file access permissions (-rw-r--r--). - zinfo.external_attr = (0x81a4 & 0xFFFF) << 16L + zinfo.external_attr = (0x81a4 & 0xFFFF) << 16 else: zinfo = zinfo_or_arcname diff --git a/config/baseconfig.mk b/config/baseconfig.mk index 30582a6f05..532ccab776 100644 --- a/config/baseconfig.mk +++ b/config/baseconfig.mk @@ -43,7 +43,7 @@ ifndef INCLUDED_AUTOCONF_MK default:: else # All possible tiers -ALL_TIERS := artifact win32-artifact android-fat-aar-artifact pre-export export rust compile misc libs tools check +ALL_TIERS := artifact win32-artifact android-fat-aar-artifact pre-export export rust compile misc libs android-stage-package android-archive-geckoview tools check # All tiers that may be used manually via `mach build $tier` RUNNABLE_TIERS := $(ALL_TIERS) @@ -54,6 +54,10 @@ RUNNABLE_TIERS := $(filter-out win32-artifact,$(RUNNABLE_TIERS)) ifndef MOZ_ANDROID_FAT_AAR_ARCHITECTURES RUNNABLE_TIERS := $(filter-out android-fat-aar-artifact,$(RUNNABLE_TIERS)) endif +ifneq ($(MOZ_BUILD_APP),mobile/android) +RUNNABLE_TIERS := $(filter-out android-stage-package,$(RUNNABLE_TIERS)) +RUNNABLE_TIERS := $(filter-out android-archive-geckoview,$(RUNNABLE_TIERS)) +endif # All tiers that run automatically on `mach build` TIERS := $(filter-out check,$(RUNNABLE_TIERS)) diff --git a/config/check_js_msg_encoding.py b/config/check_js_msg_encoding.py index f875b4332d..35129964a4 100644 --- a/config/check_js_msg_encoding.py +++ b/config/check_js_msg_encoding.py @@ -8,6 +8,7 @@ # JSErrorFormatString.format member should be in ASCII encoding. # ---------------------------------------------------------------------------- +from __future__ import absolute_import from __future__ import print_function import os diff --git a/config/check_js_opcode.py b/config/check_js_opcode.py index e38acfc0e3..c6fd1b0336 100644 --- a/config/check_js_opcode.py +++ b/config/check_js_opcode.py @@ -6,6 +6,7 @@ # This script checks bytecode documentation in js/src/vm/Opcodes.h # ---------------------------------------------------------------------------- +from __future__ import absolute_import from __future__ import print_function import os diff --git a/config/check_macroassembler_style.py b/config/check_macroassembler_style.py index 1970f3a2e4..8d74014810 100644 --- a/config/check_macroassembler_style.py +++ b/config/check_macroassembler_style.py @@ -19,6 +19,7 @@ # proper methods annotations. # ---------------------------------------------------------------------------- +from __future__ import absolute_import from __future__ import print_function import difflib @@ -26,56 +27,56 @@ import os import re import sys -architecture_independent = set(['generic']) -all_unsupported_architectures_names = set(['mips32', 'mips64', 'mips_shared']) -all_architecture_names = set(['x86', 'x64', 'arm', 'arm64']) -all_shared_architecture_names = set(['x86_shared', 'arm', 'arm64']) +architecture_independent = set(["generic"]) +all_unsupported_architectures_names = set(["mips32", "mips64", "mips_shared"]) +all_architecture_names = set(["x86", "x64", "arm", "arm64"]) +all_shared_architecture_names = set(["x86_shared", "arm", "arm64"]) reBeforeArg = "(?<=[(,\s])" reArgType = "(?P[\w\s:*&]+)" reArgName = "(?P\s\w+)" reArgDefault = "(?P(?:\s=[^,)]+)?)" reAfterArg = "(?=[,)])" -reMatchArg = re.compile(reBeforeArg + reArgType + - reArgName + reArgDefault + reAfterArg) +reMatchArg = re.compile(reBeforeArg + reArgType + reArgName + reArgDefault + reAfterArg) def get_normalized_signatures(signature, fileAnnot=None): # Remove static - signature = signature.replace('static', '') + signature = signature.replace("static", "") # Remove semicolon. - signature = signature.replace(';', ' ') + signature = signature.replace(";", " ") # Normalize spaces. - signature = re.sub(r'\s+', ' ', signature).strip() + signature = re.sub(r"\s+", " ", signature).strip() # Remove new-line induced spaces after opening braces. - signature = re.sub(r'\(\s+', '(', signature).strip() + signature = re.sub(r"\(\s+", "(", signature).strip() # Match arguments, and keep only the type. - signature = reMatchArg.sub('\g', signature) + signature = reMatchArg.sub("\g", signature) # Remove class name - signature = signature.replace('MacroAssembler::', '') + signature = signature.replace("MacroAssembler::", "") # Extract list of architectures - archs = ['generic'] + archs = ["generic"] if fileAnnot: - archs = [fileAnnot['arch']] + archs = [fileAnnot["arch"]] - if 'DEFINED_ON(' in signature: + if "DEFINED_ON(" in signature: archs = re.sub( - r'.*DEFINED_ON\((?P[^()]*)\).*', '\g', signature).split(',') + r".*DEFINED_ON\((?P[^()]*)\).*", "\g", signature + ).split(",") archs = [a.strip() for a in archs] - signature = re.sub(r'\s+DEFINED_ON\([^()]*\)', '', signature) + signature = re.sub(r"\s+DEFINED_ON\([^()]*\)", "", signature) - elif 'PER_ARCH' in signature: + elif "PER_ARCH" in signature: archs = all_architecture_names - signature = re.sub(r'\s+PER_ARCH', '', signature) + signature = re.sub(r"\s+PER_ARCH", "", signature) - elif 'PER_SHARED_ARCH' in signature: + elif "PER_SHARED_ARCH" in signature: archs = all_shared_architecture_names - signature = re.sub(r'\s+PER_SHARED_ARCH', '', signature) + signature = re.sub(r"\s+PER_SHARED_ARCH", "", signature) - elif 'OOL_IN_HEADER' in signature: - assert archs == ['generic'] - signature = re.sub(r'\s+OOL_IN_HEADER', '', signature) + elif "OOL_IN_HEADER" in signature: + assert archs == ["generic"] + signature = re.sub(r"\s+OOL_IN_HEADER", "", signature) else: # No signature annotation, the list of architectures remains unchanged. @@ -84,58 +85,55 @@ def get_normalized_signatures(signature, fileAnnot=None): # Extract inline annotation inline = False if fileAnnot: - inline = fileAnnot['inline'] + inline = fileAnnot["inline"] - if 'inline ' in signature: - signature = re.sub(r'inline\s+', '', signature) + if "inline " in signature: + signature = re.sub(r"inline\s+", "", signature) inline = True - inlinePrefx = '' + inlinePrefx = "" if inline: - inlinePrefx = 'inline ' - signatures = [ - {'arch': a, 'sig': inlinePrefx + signature} - for a in archs - ] + inlinePrefx = "inline " + signatures = [{"arch": a, "sig": inlinePrefx + signature} for a in archs] return signatures -file_suffixes = set([ - a.replace('_', '-') for a in - all_architecture_names.union(all_shared_architecture_names) - .union(all_unsupported_architectures_names) -]) +file_suffixes = set( + [ + a.replace("_", "-") + for a in all_architecture_names.union(all_shared_architecture_names).union( + all_unsupported_architectures_names + ) + ] +) def get_file_annotation(filename): origFilename = filename - filename = filename.split('/')[-1] + filename = filename.split("/")[-1] inline = False - if filename.endswith('.cpp'): - filename = filename[:-len('.cpp')] - elif filename.endswith('-inl.h'): + if filename.endswith(".cpp"): + filename = filename[: -len(".cpp")] + elif filename.endswith("-inl.h"): inline = True - filename = filename[:-len('-inl.h')] - elif filename.endswith('.h'): + filename = filename[: -len("-inl.h")] + elif filename.endswith(".h"): # This allows the definitions block in MacroAssembler.h to be # style-checked. inline = True - filename = filename[:-len('.h')] + filename = filename[: -len(".h")] else: - raise Exception('unknown file name', origFilename) + raise Exception("unknown file name", origFilename) - arch = 'generic' + arch = "generic" for suffix in file_suffixes: - if filename == 'MacroAssembler-' + suffix: + if filename == "MacroAssembler-" + suffix: arch = suffix break - return { - 'inline': inline, - 'arch': arch.replace('-', '_') - } + return {"inline": inline, "arch": arch.replace("-", "_")} def get_macroassembler_definitions(filename): @@ -145,46 +143,45 @@ def get_macroassembler_definitions(filename): return [] style_section = False - lines = '' + lines = "" signatures = [] with open(filename) as f: for line in f: - if '//{{{ check_macroassembler_style' in line: + if "//{{{ check_macroassembler_style" in line: if style_section: - raise 'check_macroassembler_style section already opened.' + raise "check_macroassembler_style section already opened." style_section = True braces_depth = 0 - elif '//}}} check_macroassembler_style' in line: + elif "//}}} check_macroassembler_style" in line: style_section = False if not style_section: continue # Ignore preprocessor directives. - if line.startswith('#'): + if line.startswith("#"): continue # Remove comments from the processed line. - line = re.sub(r'//.*', '', line) + line = re.sub(r"//.*", "", line) # Locate and count curly braces. - open_curly_brace = line.find('{') + open_curly_brace = line.find("{") was_braces_depth = braces_depth - braces_depth = braces_depth + line.count('{') - line.count('}') + braces_depth = braces_depth + line.count("{") - line.count("}") # Raise an error if the check_macroassembler_style macro is used # across namespaces / classes scopes. if braces_depth < 0: - raise 'check_macroassembler_style annotations are not well scoped.' + raise "check_macroassembler_style annotations are not well scoped." # If the current line contains an opening curly brace, check if # this line combines with the previous one can be identified as a # MacroAssembler function signature. if open_curly_brace != -1 and was_braces_depth == 0: lines = lines + line[:open_curly_brace] - if 'MacroAssembler::' in lines: - signatures.extend( - get_normalized_signatures(lines, fileAnnot)) - lines = '' + if "MacroAssembler::" in lines: + signatures.extend(get_normalized_signatures(lines, fileAnnot)) + lines = "" continue # We do not aggregate any lines if we are scanning lines which are @@ -192,15 +189,15 @@ def get_macroassembler_definitions(filename): if braces_depth > 0: continue if was_braces_depth != 0: - line = line[line.rfind('}') + 1:] + line = line[line.rfind("}") + 1 :] # This logic is used to remove template instantiation, static # variable definitions and function declaration from the next # function definition. - last_semi_colon = line.rfind(';') + last_semi_colon = line.rfind(";") if last_semi_colon != -1: - lines = '' - line = line[last_semi_colon + 1:] + lines = "" + line = line[last_semi_colon + 1 :] # Aggregate lines of non-braced text, which corresponds to the space # where we are expecting to find function definitions. @@ -211,49 +208,49 @@ def get_macroassembler_definitions(filename): def get_macroassembler_declaration(filename): style_section = False - lines = '' + lines = "" signatures = [] with open(filename) as f: for line in f: - if '//{{{ check_macroassembler_decl_style' in line: + if "//{{{ check_macroassembler_decl_style" in line: style_section = True - elif '//}}} check_macroassembler_decl_style' in line: + elif "//}}} check_macroassembler_decl_style" in line: style_section = False if not style_section: continue # Ignore preprocessor directives. - if line.startswith('#'): + if line.startswith("#"): continue - line = re.sub(r'//.*', '', line) - if len(line.strip()) == 0 or 'public:' in line or 'private:' in line: - lines = '' + line = re.sub(r"//.*", "", line) + if len(line.strip()) == 0 or "public:" in line or "private:" in line: + lines = "" continue lines = lines + line # Continue until we have a complete declaration - if ';' not in lines: + if ";" not in lines: continue # Skip member declarations: which are lines ending with a # semi-colon without any list of arguments. - if ')' not in lines: - lines = '' + if ")" not in lines: + lines = "" continue signatures.extend(get_normalized_signatures(lines)) - lines = '' + lines = "" return signatures def append_signatures(d, sigs): for s in sigs: - if s['sig'] not in d: - d[s['sig']] = [] - d[s['sig']].append(s['arch']) + if s["sig"] not in d: + d[s["sig"]] = [] + d[s["sig"]].append(s["arch"]) return d @@ -263,65 +260,66 @@ def generate_file_content(signatures): archs = set(sorted(signatures[s])) archs -= all_unsupported_architectures_names if len(archs.symmetric_difference(architecture_independent)) == 0: - output.append(s + ';\n') - if s.startswith('inline'): + output.append(s + ";\n") + if s.startswith("inline"): # TODO, bug 1432600: This is mistaken for OOL_IN_HEADER # functions. (Such annotation is already removed by the time # this function sees the signature here.) - output.append(' is defined in MacroAssembler-inl.h\n') + output.append(" is defined in MacroAssembler-inl.h\n") else: - output.append(' is defined in MacroAssembler.cpp\n') + output.append(" is defined in MacroAssembler.cpp\n") else: if len(archs.symmetric_difference(all_architecture_names)) == 0: - output.append(s + ' PER_ARCH;\n') + output.append(s + " PER_ARCH;\n") elif len(archs.symmetric_difference(all_shared_architecture_names)) == 0: - output.append(s + ' PER_SHARED_ARCH;\n') + output.append(s + " PER_SHARED_ARCH;\n") else: - output.append( - s + ' DEFINED_ON(' + ', '.join(sorted(archs)) + ');\n') + output.append(s + " DEFINED_ON(" + ", ".join(sorted(archs)) + ");\n") for a in sorted(archs): - a = a.replace('_', '-') - masm = '%s/MacroAssembler-%s' % (a, a) - if s.startswith('inline'): - output.append(' is defined in %s-inl.h\n' % masm) + a = a.replace("_", "-") + masm = "%s/MacroAssembler-%s" % (a, a) + if s.startswith("inline"): + output.append(" is defined in %s-inl.h\n" % masm) else: - output.append(' is defined in %s.cpp\n' % masm) + output.append(" is defined in %s.cpp\n" % masm) return output def check_style(): # We read from the header file the signature of each function. - decls = dict() # type: dict(signature => ['x86', 'x64']) + decls = dict() # type: dict(signature => ['x86', 'x64']) # We infer from each file the signature of each MacroAssembler function. - defs = dict() # type: dict(signature => ['x86', 'x64']) + defs = dict() # type: dict(signature => ['x86', 'x64']) - root_dir = os.path.join('js', 'src', 'jit') + root_dir = os.path.join("js", "src", "jit") for dirpath, dirnames, filenames in os.walk(root_dir): for filename in filenames: - if 'MacroAssembler' not in filename: + if "MacroAssembler" not in filename: continue - filepath = os.path.join(dirpath, filename).replace('\\', '/') + filepath = os.path.join(dirpath, filename).replace("\\", "/") - if filepath.endswith('MacroAssembler.h'): + if filepath.endswith("MacroAssembler.h"): decls = append_signatures( - decls, get_macroassembler_declaration(filepath)) - defs = append_signatures( - defs, get_macroassembler_definitions(filepath)) + decls, get_macroassembler_declaration(filepath) + ) + defs = append_signatures(defs, get_macroassembler_definitions(filepath)) if not decls or not defs: raise Exception("Did not find any definitions or declarations") # Compare declarations and definitions output. - difflines = difflib.unified_diff(generate_file_content(decls), - generate_file_content(defs), - fromfile='check_macroassembler_style.py declared syntax', - tofile='check_macroassembler_style.py found definitions') + difflines = difflib.unified_diff( + generate_file_content(decls), + generate_file_content(defs), + fromfile="check_macroassembler_style.py declared syntax", + tofile="check_macroassembler_style.py found definitions", + ) ok = True for diffline in difflines: ok = False - print(diffline, end='') + print(diffline, end="") return ok @@ -330,12 +328,14 @@ def main(): ok = check_style() if ok: - print('TEST-PASS | check_macroassembler_style.py | ok') + print("TEST-PASS | check_macroassembler_style.py | ok") else: - print('TEST-UNEXPECTED-FAIL | check_macroassembler_style.py | actual output does not match expected output; diff is above') # noqa: E501 + print( + "TEST-UNEXPECTED-FAIL | check_macroassembler_style.py | actual output does not match expected output; diff is above" # noqa: E501 + ) sys.exit(0 if ok else 1) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/config/check_source_count.py b/config/check_source_count.py index 1c86b2d16b..df87c0689f 100644 --- a/config/check_source_count.py +++ b/config/check_source_count.py @@ -9,6 +9,7 @@ # not, an error message is printed, quoting ERROR_LOCATION, which should # probably be the filename and line number of the erroneous call to # check_source_count.py. +from __future__ import absolute_import from __future__ import print_function import sys import re diff --git a/config/check_spidermonkey_style.py b/config/check_spidermonkey_style.py index a609677dcd..2321847052 100644 --- a/config/check_spidermonkey_style.py +++ b/config/check_spidermonkey_style.py @@ -34,7 +34,7 @@ # isolation, but don't try to do any order checking between such blocks. # ---------------------------------------------------------------------------- -from __future__ import print_function +from __future__ import absolute_import, print_function import difflib import os diff --git a/config/check_vanilla_allocations.py b/config/check_vanilla_allocations.py index f6089df439..c1ebbf36b3 100644 --- a/config/check_vanilla_allocations.py +++ b/config/check_vanilla_allocations.py @@ -37,6 +37,7 @@ # mismatched alloc/free checking. # ---------------------------------------------------------------------------- +from __future__ import absolute_import from __future__ import print_function import argparse diff --git a/config/config.mk b/config/config.mk index c2918f9773..3660ffb38f 100644 --- a/config/config.mk +++ b/config/config.mk @@ -195,6 +195,10 @@ HOST_CXXFLAGS = $(COMPUTED_HOST_CXXFLAGS) $(_HOST_DEPEND_CFLAGS) HOST_C_LDFLAGS = $(COMPUTED_HOST_C_LDFLAGS) HOST_CXX_LDFLAGS = $(COMPUTED_HOST_CXX_LDFLAGS) +WASM_CFLAGS = $(COMPUTED_WASM_CFLAGS) $(PGO_CFLAGS) $(_DEPEND_CFLAGS) $(MK_COMPILE_DEFINES) +WASM_CXXFLAGS = $(COMPUTED_WASM_CXXFLAGS) $(PGO_CFLAGS) $(_DEPEND_CFLAGS) $(MK_COMPILE_DEFINES) +WASM_LDFLAGS = $(COMPUTED_WASM_LDFLAGS) + ifdef MOZ_LTO ifeq (Darwin,$(OS_TARGET)) # When linking on macOS, debug info is not linked along with the final binary, @@ -230,6 +234,9 @@ color_flags_vars := \ COMPILE_CMFLAGS \ COMPILE_CMMFLAGS \ LDFLAGS \ + WASM_LDFLAGS \ + WASM_CFLAGS \ + WASM_CXXFLAGS \ $(NULL) ifdef MACH_STDOUT_ISATTY @@ -428,23 +435,6 @@ endif # ! WINNT # this file OBJ_SUFFIX := $(_OBJ_SUFFIX) -OBJS_VAR_SUFFIX := OBJS - -# PGO builds with GCC and clang-cl build objects with instrumentation in -# a first pass, then objects optimized, without instrumentation, in a -# second pass. If we overwrite the objects from the first pass with -# those from the second, we end up not getting instrumentation data for -# better optimization on incremental builds. As a consequence, we use a -# different object suffix for the first pass. -ifdef MOZ_PROFILE_GENERATE -ifneq (,$(GNU_CC)$(CLANG_CL)) -OBJS_VAR_SUFFIX := PGO_OBJS -ifndef NO_PROFILE_GUIDED_OPTIMIZE -OBJ_SUFFIX := i_o -endif -endif -endif - PLY_INCLUDE = -I$(MOZILLA_DIR)/other-licenses/ply # Enable verbose logs when not using `make -s` diff --git a/config/external/ffi/subst_header.py b/config/external/ffi/subst_header.py index eb2a4921c6..48eb080a01 100644 --- a/config/external/ffi/subst_header.py +++ b/config/external/ffi/subst_header.py @@ -2,6 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distibuted with this # file, You can obtain one at http://mozilla.og/MPL/2.0/. +from __future__ import absolute_import import sys import buildconfig from mozbuild.preprocessor import Preprocessor diff --git a/config/external/icu/data/genicudata.py b/config/external/icu/data/genicudata.py deleted file mode 100644 index c94ebfd2f5..0000000000 --- a/config/external/icu/data/genicudata.py +++ /dev/null @@ -1,12 +0,0 @@ -# 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/. - - -def main(output, data_file, data_symbol): - output.write(''' AREA |.rdata|,ALIGN=4,DATA,READONLY - EXPORT |{data_symbol}|[DATA] -|{data_symbol}| - INCBIN {data_file} - END -'''.format(data_file=data_file, data_symbol=data_symbol)) diff --git a/config/external/icu/data/icu_data.S b/config/external/icu/data/icu_data.S new file mode 100644 index 0000000000..95e2e359f9 --- /dev/null +++ b/config/external/icu/data/icu_data.S @@ -0,0 +1,24 @@ +/* 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/. */ + +#if defined(_WIN32) && defined(__i386__) +// Mark the object as SAFESEH-enabled. +.def @feat.00; +.scl 3; +.type 0; +.endef +.global @feat.00 +.set @feat.00, 1 +#endif + +.global ICU_DATA_SYMBOL +#ifdef __APPLE__ +.data +.const +#else +.section .rodata +#endif +.balign 16 +ICU_DATA_SYMBOL: + .incbin ICU_DATA_FILE diff --git a/config/external/icu/data/icudata.s b/config/external/icu/data/icudata.s deleted file mode 100644 index a740f3260b..0000000000 --- a/config/external/icu/data/icudata.s +++ /dev/null @@ -1,31 +0,0 @@ -;; 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/. - -%ifdef PREFIX - %define DATA_SYMBOL _ %+ ICU_DATA_SYMBOL -%else - %define DATA_SYMBOL ICU_DATA_SYMBOL -%endif - -%ifidn __OUTPUT_FORMAT__,elf - %define FORMAT_ELF 1 -%elifidn __OUTPUT_FORMAT__,elf32 - %define FORMAT_ELF 1 -%elifidn __OUTPUT_FORMAT__,elf64 - %define FORMAT_ELF 1 -%else - %define FORMAT_ELF 0 -%endif - -%if FORMAT_ELF - global DATA_SYMBOL:data hidden - ; This is needed for ELF, otherwise the GNU linker assumes the stack is executable by default. - [SECTION .note.GNU-stack noalloc noexec nowrite progbits] -%else - global DATA_SYMBOL -%endif - -SECTION .rodata align=16 -DATA_SYMBOL: - incbin ICU_DATA_FILE diff --git a/config/external/icu/data/icudt67l.dat b/config/external/icu/data/icudt67l.dat index b537282f7a6c35a487d539949eef4b5f56082eea..9bfd05117feddd63abfeaf51a67012cf2402d9b9 100644 GIT binary patch delta 649921 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%0A(Uf!=j&uPH@YCBaq)Q1vdSBA{rjo8U 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

*4s82lPkZ$$Cmdk8@_8(|6!MkD_gP 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

jivX@3wa;F}6)-}CC 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 delta 649933 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 dB "" # 3.2b4 > " 3.2 Beta 4" # 3.2b4pre > "" +from __future__ import absolute_import from __future__ import print_function import sys diff --git a/config/pythonpath.py b/config/pythonpath.py index b02cd44243..9c7878727d 100644 --- a/config/pythonpath.py +++ b/config/pythonpath.py @@ -2,6 +2,8 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import absolute_import +from __future__ import print_function """ Run a python script, adding extra directories to the python path. """ diff --git a/config/rebuild_check.py b/config/rebuild_check.py index ba17f7444a..c957bebcde 100644 --- a/config/rebuild_check.py +++ b/config/rebuild_check.py @@ -2,6 +2,8 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import absolute_import +from __future__ import print_function import os import errno diff --git a/config/recurse.mk b/config/recurse.mk index d45af11a48..cfac86fbcf 100644 --- a/config/recurse.mk +++ b/config/recurse.mk @@ -171,8 +171,7 @@ accessible/xpcom/export: xpcom/xpidl/export widget/android/bindings/export: mobile/android/base/export # The widget JNI wrapper generator code needs to build the GeckoView -# and Fennec source code in order to find JNI wrapper annotations. -widget/android/fennec/export: mobile/android/base/export +# source code in order to find JNI wrapper annotations. widget/android/export: mobile/android/base/export # .xpt generation needs the xpidl lex/yacc files diff --git a/config/rules.mk b/config/rules.mk index e266a1a298..3634114e21 100644 --- a/config/rules.mk +++ b/config/rules.mk @@ -175,20 +175,22 @@ endif ifdef COMPILE_ENVIRONMENT ifndef TARGETS -TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(HOST_SHARED_LIBRARY) +TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(HOST_SHARED_LIBRARY) $(WASM_LIBRARY) endif COBJS = $(notdir $(CSRCS:.c=.$(OBJ_SUFFIX))) +CWASMOBJS = $(notdir $(WASM_CSRCS:.c=.$(WASM_OBJ_SUFFIX))) SOBJS = $(notdir $(SSRCS:.S=.$(OBJ_SUFFIX))) # CPPSRCS can have different extensions (eg: .cpp, .cc) CPPOBJS = $(notdir $(addsuffix .$(OBJ_SUFFIX),$(basename $(CPPSRCS)))) +CPPWASMOBJS = $(notdir $(addsuffix .$(WASM_OBJ_SUFFIX),$(basename $(WASM_CPPSRCS)))) CMOBJS = $(notdir $(CMSRCS:.m=.$(OBJ_SUFFIX))) CMMOBJS = $(notdir $(CMMSRCS:.mm=.$(OBJ_SUFFIX))) # ASFILES can have different extensions (.s, .asm) ASOBJS = $(notdir $(addsuffix .$(OBJ_SUFFIX),$(basename $(ASFILES)))) RS_STATICLIB_CRATE_OBJ = $(addprefix lib,$(notdir $(RS_STATICLIB_CRATE_SRC:.rs=.$(LIB_SUFFIX)))) ifndef OBJS -_OBJS = $(COBJS) $(SOBJS) $(CPPOBJS) $(CMOBJS) $(CMMOBJS) $(ASOBJS) +_OBJS = $(COBJS) $(SOBJS) $(CPPOBJS) $(CMOBJS) $(CMMOBJS) $(ASOBJS) $(CWASMOBJS) $(CPPWASMOBJS) OBJS = $(strip $(_OBJS)) endif @@ -211,8 +213,11 @@ SIMPLE_PROGRAMS := HOST_SHARED_LIBRARY := HOST_PROGRAM := HOST_SIMPLE_PROGRAMS := +WASM_LIBRARY := endif +WASM_ARCHIVE = $(addsuffix .$(WASM_OBJ_SUFFIX),$(WASM_LIBRARY)) + ALL_TRASH = \ $(GARBAGE) $(TARGETS) $(OBJS) $(PROGOBJS) LOGS TAGS a.out \ $(filter-out $(ASFILES),$(OBJS:.$(OBJ_SUFFIX)=.s)) $(OBJS:.$(OBJ_SUFFIX)=.ii) \ @@ -224,7 +229,7 @@ ALL_TRASH = \ $(PROGRAM:$(BIN_SUFFIX)=.exp) $(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=.exp) \ $(PROGRAM:$(BIN_SUFFIX)=.lib) $(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=.lib) \ $(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=.$(OBJ_SUFFIX)) \ - $(wildcard gts_tmp_*) $(LIBRARY:%.a=.%.timestamp) + $(WASM_ARCHIVE) $(wildcard gts_tmp_*) $(LIBRARY:%.a=.%.timestamp) ALL_TRASH_DIRS = \ $(GARBAGE_DIRS) /no-such-file @@ -299,11 +304,7 @@ endif ifeq ($(OS_ARCH),Darwin) ifdef SHARED_LIBRARY -ifdef MOZ_IOS -_LOADER_PATH := @rpath -else _LOADER_PATH := @executable_path -endif EXTRA_DSO_LDOPTS += -dynamiclib -install_name $(_LOADER_PATH)/$(SHARED_LIBRARY) -compatibility_version 1 -current_version 1 -single_module endif endif @@ -403,13 +404,11 @@ GLOBAL_DEPS += Makefile $(addprefix $(DEPTH)/config/,$(INCLUDED_AUTOCONF_MK)) $( ############################################## ifdef COMPILE_ENVIRONMENT -OBJ_TARGETS = $(OBJS) $(PROGOBJS) $(HOST_OBJS) $(HOST_PROGOBJS) - compile:: host target host:: $(HOST_OBJS) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(HOST_RUST_PROGRAMS) $(HOST_RUST_LIBRARY_FILE) $(HOST_SHARED_LIBRARY) -target:: $(filter-out $(MOZBUILD_NON_DEFAULT_TARGETS),$(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(RUST_LIBRARY_FILE) $(RUST_PROGRAMS)) +target:: $(filter-out $(MOZBUILD_NON_DEFAULT_TARGETS),$(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(RUST_LIBRARY_FILE) $(RUST_PROGRAMS) $(WASM_LIBRARY)) ifndef LIBRARY ifdef OBJS @@ -425,64 +424,6 @@ syms:: include $(MOZILLA_DIR)/config/makefiles/target_binaries.mk endif -############################################## -ifneq (1,$(NO_PROFILE_GUIDED_OPTIMIZE)) -ifdef MOZ_1TIER_PGO -ifeq ($(OS_ARCH)_$(GNU_CC), WINNT_) -# When building with PGO, we have to make sure to re-link -# in the MOZ_PROFILE_USE phase if we linked in the -# MOZ_PROFILE_GENERATE phase. We'll touch this pgo.relink -# file in the link rule in the GENERATE phase to indicate -# that we need a relink. -ifdef SHARED_LIBRARY -$(SHARED_LIBRARY): pgo.relink -endif -ifdef PROGRAM -$(PROGRAM): pgo.relink -endif - -# In the second pass, we need to merge the pgc files into the pgd file. -# The compiler would do this for us automatically if they were in the right -# place, but they're in dist/bin. -ifneq (,$(SHARED_LIBRARY)$(PROGRAM)) -export:: -ifdef PROGRAM - $(PYTHON) $(MOZILLA_DIR)/build/win32/pgomerge.py \ - $(PROGRAM:$(BIN_SUFFIX)=) $(DIST)/bin -endif -ifdef SHARED_LIBRARY - $(PYTHON) $(MOZILLA_DIR)/build/win32/pgomerge.py \ - $(patsubst $(DLL_PREFIX)%$(DLL_SUFFIX),%,$(SHARED_LIBRARY)) $(DIST)/bin -endif -endif # SHARED_LIBRARY || PROGRAM -endif # WINNT_ -endif # MOZ_PROFILE_USE -ifdef MOZ_PROFILE_GENERATE -# Clean up profiling data during PROFILE_GENERATE phase -export:: -ifeq ($(OS_ARCH)_$(GNU_CC), WINNT_) - $(foreach pgd,$(wildcard *.pgd),pgomgr -clear $(pgd);) -else -ifdef GNU_CC - -$(RM) *.gcda -endif -endif -endif - -ifneq (,$(MOZ_PROFILE_GENERATE)$(MOZ_PROFILE_USE)) -ifneq (,$(filter target,$(MAKECMDGOALS))) -ifdef GNU_CC -# Force rebuilding libraries and programs in both passes because each -# pass uses different object files. -$(PROGRAM) $(SHARED_LIBRARY) $(LIBRARY): FORCE -endif -endif -endif - -endif # NO_PROFILE_GUIDED_OPTIMIZE - -############################################## - clean clobber realclean clobber_all:: -$(RM) $(ALL_TRASH) -$(RM) -r $(ALL_TRASH_DIRS) @@ -514,7 +455,7 @@ $(PROGRAM): $(PROGOBJS) $(STATIC_LIBS) $(EXTRA_DEPS) $(RESFILE) $(GLOBAL_DEPS) $ $(REPORT_BUILD) @$(RM) $@.manifest ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH)) - $(LINKER) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) -IMPLIB:$(basename $(@F)).lib $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_PROGRAM_LDFLAGS) $($(notdir $@)_$(OBJS_VAR_SUFFIX)) $(RESFILE) $(STATIC_LIBS) $(SHARED_LIBS) $(OS_LIBS) + $(LINKER) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) -IMPLIB:$(basename $(@F)).lib $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_PROGRAM_LDFLAGS) $($(notdir $@)_OBJS) $(RESFILE) $(STATIC_LIBS) $(SHARED_LIBS) $(OS_LIBS) ifdef MSMANIFEST_TOOL @if test -f $@.manifest; then \ if test -f '$(srcdir)/$@.manifest'; then \ @@ -529,13 +470,8 @@ ifdef MSMANIFEST_TOOL $(MT) -NOLOGO -MANIFEST '$(win_srcdir)/$@.manifest' -OUTPUTRESOURCE:$@\;1; \ fi endif # MSVC with manifest tool -ifdef MOZ_PROFILE_GENERATE -# touch it a few seconds into the future to work around FAT's -# 2-second granularity - touch -t `date +%Y%m%d%H%M.%S -d 'now+5seconds'` pgo.relink -endif else # !WINNT || GNU_CC - $(call EXPAND_CC_OR_CXX,$@) -o $@ $(COMPUTED_CXX_LDFLAGS) $(PGO_CFLAGS) $($(notdir $@)_$(OBJS_VAR_SUFFIX)) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(STATIC_LIBS) $(MOZ_PROGRAM_LDFLAGS) $(SHARED_LIBS) $(OS_LIBS) + $(call EXPAND_CC_OR_CXX,$@) -o $@ $(COMPUTED_CXX_LDFLAGS) $(PGO_CFLAGS) $($(notdir $@)_OBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(STATIC_LIBS) $(MOZ_PROGRAM_LDFLAGS) $(SHARED_LIBS) $(OS_LIBS) $(call py_action,check_binary,--target $@) endif # WINNT && !GNU_CC @@ -586,7 +522,7 @@ endif $(SIMPLE_PROGRAMS): %$(BIN_SUFFIX): %.$(OBJ_SUFFIX) $(STATIC_LIBS) $(EXTRA_DEPS) $(GLOBAL_DEPS) $(REPORT_BUILD) ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH)) - $(LINKER) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $($@_$(OBJS_VAR_SUFFIX)) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_PROGRAM_LDFLAGS) $(STATIC_LIBS) $(SHARED_LIBS) $(OS_LIBS) + $(LINKER) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $($@_OBJS) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_PROGRAM_LDFLAGS) $(STATIC_LIBS) $(SHARED_LIBS) $(OS_LIBS) ifdef MSMANIFEST_TOOL @if test -f $@.manifest; then \ $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \ @@ -596,7 +532,7 @@ ifdef MSMANIFEST_TOOL fi endif # MSVC with manifest tool else - $(call EXPAND_CC_OR_CXX,$@) $(COMPUTED_CXX_LDFLAGS) $(PGO_CFLAGS) -o $@ $($@_$(OBJS_VAR_SUFFIX)) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(STATIC_LIBS) $(MOZ_PROGRAM_LDFLAGS) $(SHARED_LIBS) $(OS_LIBS) + $(call EXPAND_CC_OR_CXX,$@) $(COMPUTED_CXX_LDFLAGS) $(PGO_CFLAGS) -o $@ $($@_OBJS) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(STATIC_LIBS) $(MOZ_PROGRAM_LDFLAGS) $(SHARED_LIBS) $(OS_LIBS) $(call py_action,check_binary,--target $@) endif # WINNT && !GNU_CC @@ -625,7 +561,16 @@ endif $(LIBRARY): $(OBJS) $(STATIC_LIBS) $(EXTRA_DEPS) $(GLOBAL_DEPS) $(REPORT_BUILD) $(RM) $(REAL_LIBRARY) - $(AR) $(AR_FLAGS) $($@_$(OBJS_VAR_SUFFIX)) + $(AR) $(AR_FLAGS) $($@_OBJS) + +$(WASM_ARCHIVE): $(CWASMOBJS) $(CPPWASMOBJS) $(STATIC_LIBS) $(EXTRA_DEPS) $(GLOBAL_DEPS) + $(REPORT_BUILD_VERBOSE) + $(RM) $(WASM_LIBRARY).$(WASM_OBJ_SUFFIX) + $(WASM_CXX) $(OUTOPTION)$@ -Wl,--export-all $(WASM_LDFLAGS) $(CWASMOBJS) $(CPPWASMOBJS) +$(WASM_LIBRARY): $(WASM_LIBRARY).$(WASM_OBJ_SUFFIX) + $(REPORT_BUILD) + $(RM) $(WASM_LIBRARY) + $(LUCETC) --bindings $(topsrcdir)/third_party/rust/lucet-wasi/bindings.json $(WASM_LIBRARY).$(WASM_OBJ_SUFFIX) --opt-level 2 -o $(WASM_LIBRARY) ifeq ($(OS_ARCH),WINNT) # Import libraries are created by the rules creating shared libraries. @@ -657,7 +602,7 @@ $(SHARED_LIBRARY): $(OBJS) $(RESFILE) $(STATIC_LIBS) $(EXTRA_DEPS) $(GLOBAL_DEPS ifndef INCREMENTAL_LINKER $(RM) $@ endif - $(MKSHLIB) $($@_$(OBJS_VAR_SUFFIX)) $(RESFILE) $(LDFLAGS) $(STATIC_LIBS) $(SHARED_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS) + $(MKSHLIB) $($@_OBJS) $(RESFILE) $(LDFLAGS) $(STATIC_LIBS) $(SHARED_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS) $(call py_action,check_binary,--target $@) ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH)) @@ -677,9 +622,6 @@ ifdef EMBED_MANIFEST_AT fi endif # EMBED_MANIFEST_AT endif # MSVC with manifest tool -ifdef MOZ_PROFILE_GENERATE - touch -t `date +%Y%m%d%H%M.%S -d 'now+5seconds'` pgo.relink -endif endif # WINNT && !GCC chmod +x $@ ifdef ENABLE_STRIP @@ -696,6 +638,7 @@ $(basename $3$(notdir $1)).$2: $1 $$(call mkdir_deps,$$(MDDEPDIR)) endef $(foreach f,$(CSRCS) $(SSRCS) $(CPPSRCS) $(CMSRCS) $(CMMSRCS) $(ASFILES),$(eval $(call src_objdep,$(f),$(OBJ_SUFFIX)))) $(foreach f,$(HOST_CSRCS) $(HOST_CPPSRCS) $(HOST_CMSRCS) $(HOST_CMMSRCS),$(eval $(call src_objdep,$(f),$(_OBJ_SUFFIX),host_))) +$(foreach f,$(WASM_CSRCS) $(WASM_CPPSRCS),$(eval $(call src_objdep,$(f),wasm))) # The Rust compiler only outputs library objects, and so we need different # mangling to generate dependency rules for it. @@ -727,6 +670,10 @@ $(COBJS): $(REPORT_BUILD_VERBOSE) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $($(notdir $<)_FLAGS) $< +$(CWASMOBJS): + $(REPORT_BUILD_VERBOSE) + $(WASM_CC) $(OUTOPTION)$@ -c $(WASM_CFLAGS) $($(notdir $<)_FLAGS) $< + ifdef ASFILES # The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept # a '-c' flag. @@ -743,11 +690,9 @@ ifdef MOZ_CRASHREPORTER endif endef -ifndef MOZ_PROFILE_GENERATE ifneq (,$(filter $(DIST)/bin%,$(FINAL_TARGET))) DUMP_SYMS_TARGETS := $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) endif -endif ifdef MOZ_AUTOMATION ifeq (,$(filter 1,$(MOZ_AUTOMATION_BUILD_SYMBOLS))) @@ -785,6 +730,11 @@ $(CPPOBJS): $(call BUILDSTATUS,OBJECT_FILE $@) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $< +$(CPPWASMOBJS): + $(REPORT_BUILD_VERBOSE) + $(call BUILDSTATUS,OBJECT_FILE $@) + $(WASM_CXX) $(OUTOPTION)$@ -c $(WASM_CXXFLAGS) $($(notdir $<)_FLAGS) $< + $(CMMOBJS): $(REPORT_BUILD_VERBOSE) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $($(notdir $<)_FLAGS) $< @@ -1273,6 +1223,7 @@ FREEZE_VARIABLES = \ EXPORTS \ DIRS \ LIBRARY \ + WASM_LIBRARY \ MODULE \ $(NULL) diff --git a/config/run_spidermonkey_checks.py b/config/run_spidermonkey_checks.py index 1aed5ce913..9323fdf126 100644 --- a/config/run_spidermonkey_checks.py +++ b/config/run_spidermonkey_checks.py @@ -2,6 +2,7 @@ # 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/. +from __future__ import absolute_import import buildconfig import subprocess import sys diff --git a/config/system-headers.mozbuild b/config/system-headers.mozbuild index 9a00f9cde5..154d5119b5 100644 --- a/config/system-headers.mozbuild +++ b/config/system-headers.mozbuild @@ -1266,16 +1266,6 @@ if CONFIG['MOZ_SYSTEM_ZLIB']: 'zlib.h', ] -if CONFIG['MOZ_ENABLE_STARTUP_NOTIFICATION']: - system_headers += [ - 'libsn/sn-common.h', - 'libsn/sn.h', - 'libsn/sn-launchee.h', - 'libsn/sn-launcher.h', - 'libsn/sn-monitor.h', - 'libsn/sn-util.h', - ] - if CONFIG['MOZ_SYSTEM_LIBEVENT']: system_headers += [ 'event2/event_compat.h', @@ -1359,3 +1349,6 @@ if CONFIG['OS_TARGET'] == 'Linux' and CONFIG['CPU_ARCH'].startswith('mips'): system_headers += [ 'sys/cachectl.h', ] + +if CONFIG['MOZ_APP_SYSTEM_HEADERS']: + include("../" + CONFIG['MOZ_BUILD_APP'] + "/app-system-headers.mozbuild") diff --git a/config/system_header_util.py b/config/system_header_util.py index 6e7b30318f..a623c48ad4 100644 --- a/config/system_header_util.py +++ b/config/system_header_util.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import import os diff --git a/config/tests/test_mozbuild_reading.py b/config/tests/test_mozbuild_reading.py index b95d3e3fc2..6bacf5d799 100644 --- a/config/tests/test_mozbuild_reading.py +++ b/config/tests/test_mozbuild_reading.py @@ -2,6 +2,7 @@ # 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/. +from __future__ import absolute_import from __future__ import unicode_literals import os @@ -77,7 +78,7 @@ class TestMozbuildReading(unittest.TestCase): try: config = mb.config_environment except Exception as e: - if e.message == 'config.status not available. Run configure.': + if str(e) == 'config.status not available. Run configure.': raise unittest.SkipTest('failing without config.status') raise diff --git a/config/tests/unit-mozunit.py b/config/tests/unit-mozunit.py index c217373732..90fd2bc705 100644 --- a/config/tests/unit-mozunit.py +++ b/config/tests/unit-mozunit.py @@ -2,6 +2,7 @@ # 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/. +from __future__ import absolute_import import os from mozunit import main, MockedOpen import unittest diff --git a/config/tests/unit-nsinstall.py b/config/tests/unit-nsinstall.py index cf3db6e18e..172d68a291 100644 --- a/config/tests/unit-nsinstall.py +++ b/config/tests/unit-nsinstall.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import import unittest import os diff --git a/config/tests/unit-printprereleasesuffix.py b/config/tests/unit-printprereleasesuffix.py index ba76ce68c7..4a2382ece0 100644 --- a/config/tests/unit-printprereleasesuffix.py +++ b/config/tests/unit-printprereleasesuffix.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import import unittest import mozunit diff --git a/config/tests/unitMozZipFile.py b/config/tests/unitMozZipFile.py index ecfb69ad95..e1765a2ab3 100644 --- a/config/tests/unitMozZipFile.py +++ b/config/tests/unitMozZipFile.py @@ -2,6 +2,7 @@ # 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/. +from __future__ import absolute_import import unittest import shutil diff --git a/configure.py b/configure.py index 5c83a7d0a7..4bb9e1349b 100644 --- a/configure.py +++ b/configure.py @@ -5,6 +5,7 @@ from __future__ import absolute_import, print_function, unicode_literals import codecs +import errno import itertools import logging import os @@ -40,10 +41,35 @@ def main(argv): if sandbox._help: return 0 + logging.getLogger('moz.configure').info('Creating config.status') + + old_js_configure_substs = config.pop('OLD_JS_CONFIGURE_SUBSTS', None) + old_js_configure_defines = config.pop('OLD_JS_CONFIGURE_DEFINES', None) + if old_js_configure_substs or old_js_configure_defines: + js_config = config.copy() + pwd = os.getcwd() + try: + try: + os.makedirs('js/src') + except OSError as e: + if e.errno != errno.EEXIST: + raise + + os.chdir('js/src') + js_config['OLD_CONFIGURE_SUBSTS'] = old_js_configure_substs + js_config['OLD_CONFIGURE_DEFINES'] = old_js_configure_defines + # The build system frontend expects $objdir/js/src/config.status + # to have $objdir/js/src as topobjdir. + # We want forward slashes on all platforms. + js_config['TOPOBJDIR'] += '/js/src' + config_status(js_config, execute=False) + finally: + os.chdir(pwd) + return config_status(config) -def config_status(config): +def config_status(config, execute=True): # Sanitize config data to feed config.status # Ideally, all the backend and frontend code would handle the booleans, but # there are so many things involved, that it's easier to keep config.status @@ -58,13 +84,16 @@ def config_status(config): sanitized_config = {} sanitized_config['substs'] = { k: sanitized_bools(v) for k, v in config.iteritems() - if k not in ('DEFINES', 'non_global_defines', 'TOPSRCDIR', 'TOPOBJDIR', - 'CONFIG_STATUS_DEPS') + if k not in ('DEFINES', 'TOPSRCDIR', 'TOPOBJDIR', 'CONFIG_STATUS_DEPS', + 'OLD_CONFIGURE_SUBSTS', 'OLD_CONFIGURE_DEFINES') } + for k, v in config['OLD_CONFIGURE_SUBSTS']: + sanitized_config['substs'][k] = sanitized_bools(v) sanitized_config['defines'] = { k: sanitized_bools(v) for k, v in config['DEFINES'].iteritems() } - sanitized_config['non_global_defines'] = config['non_global_defines'] + for k, v in config['OLD_CONFIGURE_DEFINES']: + sanitized_config['defines'][k] = sanitized_bools(v) sanitized_config['topsrcdir'] = config['TOPSRCDIR'] sanitized_config['topobjdir'] = config['TOPOBJDIR'] sanitized_config['mozconfig'] = config.get('MOZCONFIG') @@ -72,7 +101,6 @@ def config_status(config): # Create config.status. Eventually, we'll want to just do the work it does # here, when we're able to skip configure tests/use cached results/not rely # on autoconf. - logging.getLogger('moz.configure').info('Creating config.status') encoding = 'mbcs' if sys.platform == 'win32' else 'utf-8' with codecs.open('config.status', 'w', encoding) as fh: fh.write(textwrap.dedent('''\ @@ -87,9 +115,9 @@ def config_status(config): for k, v in sanitized_config.iteritems(): fh.write('%s = encode(%s, encoding)\n' % (k, indented_repr(v))) fh.write("__all__ = ['topobjdir', 'topsrcdir', 'defines', " - "'non_global_defines', 'substs', 'mozconfig']") + "'substs', 'mozconfig']") - if config.get('MOZ_BUILD_APP') != 'js' or config.get('JS_STANDALONE'): + if execute: fh.write(textwrap.dedent(''' if __name__ == '__main__': from mozbuild.util import patch_main @@ -113,7 +141,7 @@ def config_status(config): # Other things than us are going to run this file, so we need to give it # executable permissions. os.chmod('config.status', 0o755) - if config.get('MOZ_BUILD_APP') != 'js' or config.get('JS_STANDALONE'): + if execute: from mozbuild.config_status import config_status # Some values in sanitized_config also have more complex types, such as diff --git a/devtools/client/aboutdebugging/src/actions/runtimes.js b/devtools/client/aboutdebugging/src/actions/runtimes.js index a0e133b897..bbc6cdcedc 100644 --- a/devtools/client/aboutdebugging/src/actions/runtimes.js +++ b/devtools/client/aboutdebugging/src/actions/runtimes.js @@ -56,23 +56,6 @@ const { const CONNECTION_TIMING_OUT_DELAY = 3000; const CONNECTION_CANCEL_DELAY = 13000; -async function getRuntimeIcon(runtime, channel) { - if (runtime.isFenix) { - switch (channel) { - case "release": - case "beta": - return "chrome://devtools/skin/images/aboutdebugging-fenix.svg"; - case "aurora": - default: - return "chrome://devtools/skin/images/aboutdebugging-fenix-nightly.svg"; - } - } - - return channel === "release" || channel === "beta" || channel === "aurora" - ? `chrome://devtools/skin/images/aboutdebugging-firefox-${channel}.svg` - : "chrome://devtools/skin/images/aboutdebugging-firefox-nightly.svg"; -} - function onRemoteDebuggerClientClosed() { window.AboutDebugging.onNetworkLocationsUpdated(); window.AboutDebugging.onUSBRuntimesUpdated(); @@ -121,7 +104,7 @@ function connectRuntime(id) { const deviceDescription = await clientWrapper.getDeviceDescription(); const compatibilityReport = await clientWrapper.checkVersionCompatibility(); - const icon = await getRuntimeIcon(runtime, deviceDescription.channel); + //const icon = "chrome://devtools/skin/images/aboutdebugging.svg" const { CONNECTION_PROMPT, @@ -165,7 +148,7 @@ function connectRuntime(id) { connectionPromptEnabled, info: { deviceName: deviceDescription.deviceName, - icon, + //icon, name: runtimeName, os: deviceDescription.os, type: runtime.type, diff --git a/devtools/client/aboutdebugging/src/components/sidebar/Sidebar.js b/devtools/client/aboutdebugging/src/components/sidebar/Sidebar.js index 8c4eee6ef1..8463327198 100644 --- a/devtools/client/aboutdebugging/src/components/sidebar/Sidebar.js +++ b/devtools/client/aboutdebugging/src/components/sidebar/Sidebar.js @@ -28,8 +28,8 @@ const SidebarItem = createFactory(require("./SidebarItem")); const SidebarFixedItem = createFactory(require("./SidebarFixedItem")); const SidebarRuntimeItem = createFactory(require("./SidebarRuntimeItem")); const RefreshDevicesButton = createFactory(require("./RefreshDevicesButton")); -const FIREFOX_ICON = - "chrome://devtools/skin/images/aboutdebugging-firefox-logo.svg"; +//const FIREFOX_ICON = +// "chrome://devtools/skin/images/aboutdebugging-firefox-logo.svg"; const CONNECT_ICON = "chrome://devtools/skin/images/settings.svg"; const GLOBE_ICON = "chrome://devtools/skin/images/aboutdebugging-globe-icon.svg"; @@ -213,7 +213,7 @@ class Sidebar extends PureComponent { Localized( { id: "about-debugging-sidebar-this-firefox", attrs: { name: true } }, SidebarFixedItem({ - icon: FIREFOX_ICON, + //icon: FIREFOX_ICON, isSelected: PAGE_TYPES.RUNTIME === selectedPage && selectedRuntimeId === RUNTIMES.THIS_FIREFOX, diff --git a/devtools/client/framework/test/browser.ini b/devtools/client/framework/test/browser.ini index d99ac7da5c..2de962275b 100644 --- a/devtools/client/framework/test/browser.ini +++ b/devtools/client/framework/test/browser.ini @@ -147,7 +147,6 @@ run-if = e10s [browser_toolbox_view_source_03.js] [browser_toolbox_view_source_04.js] [browser_toolbox_window_reload_target.js] -skip-if = os == 'win' && os_version == '6.1' && !debug # bug 1522720 [browser_toolbox_window_shortcuts.js] [browser_toolbox_window_title_changes.js] [browser_toolbox_window_title_frame_select.js] diff --git a/devtools/client/framework/test/browser_toolbox_window_reload_target.js b/devtools/client/framework/test/browser_toolbox_window_reload_target.js index 356e70441e..1e3314a4df 100644 --- a/devtools/client/framework/test/browser_toolbox_window_reload_target.js +++ b/devtools/client/framework/test/browser_toolbox_window_reload_target.js @@ -104,13 +104,30 @@ function testReload(shortcut, toolbox, toolID) { const mm = gBrowser.selectedBrowser.messageManager; return new Promise(resolve => { - // The inspector needs some special care. - const toolUpdated = - toolID === "inspector" - ? toolbox.getPanel("inspector").once("new-root") - : Promise.resolve(); + const observer = { + _isDocumentUnloaded: false, + _isNewRooted: false, + onMutation(mutations) { + for (const { type } of mutations) { + if (type === "documentUnload") { + this._isDocumentUnloaded = true; + } else if (type === "newRoot") { + this._isNewRooted = true; + } + } + }, + isReady() { + return this._isDocumentUnloaded && this._isNewRooted; + }, + }; + + if (toolbox.walker) { + observer.onMutation = observer.onMutation.bind(observer); + toolbox.walker.on("mutations", observer.onMutation); + } else { + observer.isReady = () => true; + } - const complete = () => { // If we have a jsdebugger panel, wait for it to complete its reload const jsdebugger = toolbox.getPanel("jsdebugger"); let onReloaded = Promise.resolve; @@ -118,9 +135,15 @@ function testReload(shortcut, toolbox, toolID) { onReloaded = jsdebugger.once("reloaded"); } + const complete = async () => { mm.removeMessageListener("devtools:test:load", complete); - toolUpdated.then(resolve); + // Wait for the documentUnload and newRoot were fired. + await waitUntil(() => observer.isReady()); + if (toolbox.walker) { + toolbox.walker.off("mutations", observer.onMutation); + } await onReloaded; + resolve(); }; mm.addMessageListener("devtools:test:load", complete); diff --git a/devtools/client/inspector/rules/test/browser.ini b/devtools/client/inspector/rules/test/browser.ini index 04cd3ab69f..2811c089b0 100644 --- a/devtools/client/inspector/rules/test/browser.ini +++ b/devtools/client/inspector/rules/test/browser.ini @@ -234,10 +234,13 @@ skip-if = os == 'linux' # focusEditableField times out consistently on linux. [browser_rules_multiple_properties_02.js] [browser_rules_non_ascii.js] [browser_rules_original-source-link.js] +skip-if = ccov #Bug 1432176 [browser_rules_original-source-link2.js] +skip-if = ccov #Bug 1432176 [browser_rules_preview-tooltips-sizes.js] [browser_rules_pseudo-element_01.js] [browser_rules_pseudo-element_02.js] +[browser_rules_pseudo-visited.js] [browser_rules_pseudo_lock_options.js] [browser_rules_refresh-no-flicker.js] [browser_rules_refresh-on-attribute-change_01.js] diff --git a/devtools/client/inspector/rules/test/browser_rules_pseudo-visited.js b/devtools/client/inspector/rules/test/browser_rules_pseudo-visited.js new file mode 100644 index 0000000000..f7f891ade7 --- /dev/null +++ b/devtools/client/inspector/rules/test/browser_rules_pseudo-visited.js @@ -0,0 +1,44 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Tests for visited/unvisited rule. + +const VISISTED_URI = URL_ROOT + "doc_variables_1.html"; + +const TEST_URI = ` + + visited link + unvisited link +`; + +add_task(async () => { + info("Open a particular url to make a visited link"); + const tab = await addTab(VISISTED_URI); + + info("Open tested page in the same tab"); + await BrowserTestUtils.loadURI( + tab.linkedBrowser, + "data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI) + ); + + info("Open the inspector"); + const { inspector, view } = await openRuleView(); + + info("Check whether the rule view is shown correctly for visited element"); + await selectNode("#visited", inspector); + ok(getRuleViewRule(view, "a:visited"), "Rule of a:visited is shown"); + ok(!getRuleViewRule(view, "a:link"), "Rule of a:link is not shown"); + ok(getRuleViewRule(view, "a"), "Rule of a is shown"); + + info("Check whether the rule view is shown correctly for unvisited element"); + await selectNode("#unvisited", inspector); + ok(!getRuleViewRule(view, "a:visited"), "Rule of a:visited is not shown"); + ok(getRuleViewRule(view, "a:link"), "Rule of a:link is shown"); + ok(getRuleViewRule(view, "a"), "Rule of a is shown"); +}); diff --git a/devtools/client/inspector/rules/test/browser_rules_pseudo_lock_options.js b/devtools/client/inspector/rules/test/browser_rules_pseudo_lock_options.js index f1e5630d55..a219b63464 100644 --- a/devtools/client/inspector/rules/test/browser_rules_pseudo_lock_options.js +++ b/devtools/client/inspector/rules/test/browser_rules_pseudo_lock_options.js @@ -23,6 +23,9 @@ const TEST_URI = ` div:focus-within { color: papayawhip; } + div:visited { + color: orange; + }

test div
`; diff --git a/devtools/client/jar.mn b/devtools/client/jar.mn index b5b407a529..5a2475e31d 100644 --- a/devtools/client/jar.mn +++ b/devtools/client/jar.mn @@ -88,13 +88,8 @@ devtools.jar: skin/images/filter-swatch.svg (themes/images/filter-swatch.svg) skin/images/aboutdebugging-connect-icon.svg (themes/images/aboutdebugging-connect-icon.svg) skin/images/aboutdebugging-error.svg (themes/images/aboutdebugging-error.svg) - skin/images/aboutdebugging-fenix-nightly.svg (themes/images/aboutdebugging-fenix-nightly.svg) - skin/images/aboutdebugging-fenix.svg (themes/images/aboutdebugging-fenix.svg) - skin/images/aboutdebugging-firefox-aurora.svg (themes/images/aboutdebugging-firefox-aurora.svg) - skin/images/aboutdebugging-firefox-beta.svg (themes/images/aboutdebugging-firefox-beta.svg) - skin/images/aboutdebugging-firefox-logo.svg (themes/images/aboutdebugging-firefox-logo.svg) - skin/images/aboutdebugging-firefox-nightly.svg (themes/images/aboutdebugging-firefox-nightly.svg) - skin/images/aboutdebugging-firefox-release.svg (themes/images/aboutdebugging-firefox-release.svg) +# skin/images/aboutdebugging-firefox-logo.svg (themes/images/aboutdebugging-firefox-logo.svg) +# skin/images/aboutdebugging-firefox-release.svg (themes/images/aboutdebugging-firefox-release.svg) skin/images/aboutdebugging-globe-icon.svg (themes/images/aboutdebugging-globe-icon.svg) skin/images/aboutdebugging-information.svg (themes/images/aboutdebugging-information.svg) skin/images/aboutdebugging-process-icon.svg (themes/images/aboutdebugging-process-icon.svg) diff --git a/devtools/client/locales/en-US/markers.properties b/devtools/client/locales/en-US/markers.properties index 030082ad04..23d5a73df9 100644 --- a/devtools/client/locales/en-US/markers.properties +++ b/devtools/client/locales/en-US/markers.properties @@ -118,7 +118,7 @@ marker.gcreason.label.PERIODIC_FULL_GC=Periodic Full GC marker.gcreason.label.INCREMENTAL_TOO_SLOW=Allocations Rate Too Fast marker.gcreason.label.COMPONENT_UTILS=Cu.forceGC marker.gcreason.label.MEM_PRESSURE=Low Memory -marker.gcreason.label.CC_WAITING=Forced by Cycle Collection +marker.gcreason.label.CC_FINISHED=Cycle Collection Finished marker.gcreason.label.CC_FORCED=Forced by Cycle Collection marker.gcreason.label.LOAD_END=Page Load Finished marker.gcreason.label.PAGE_HIDE=Moved to Background diff --git a/devtools/client/responsive/browser/tunnel.js b/devtools/client/responsive/browser/tunnel.js index 8eff13e9f5..e6401b8726 100644 --- a/devtools/client/responsive/browser/tunnel.js +++ b/devtools/client/responsive/browser/tunnel.js @@ -30,7 +30,6 @@ const SWAPPED_BROWSER_STATE = [ "_contentTitle", "_characterSet", "_contentPrincipal", - "_imageDocument", "_isSyntheticDocument", "_innerWindowID", ]; @@ -107,7 +106,6 @@ function tunnelToInnerBrowser(outer, inner) { inner._documentContentType = outer._documentContentType; inner._contentTitle = outer._contentTitle; inner._characterSet = outer._characterSet; - inner._imageDocument = outer._imageDocument; inner._isSyntheticDocument = outer._isSyntheticDocument; inner._innerWindowID = outer._innerWindowID; inner._remoteWebNavigationImpl._currentURI = @@ -482,7 +480,6 @@ MessageManagerTunnel.prototype = { "PageStyle:StyleSheets", // Messages sent to browser.js "DOMTitleChanged", - "ImageDocumentLoaded", "Forms:ShowDropDown", "Forms:HideDropDown", "InPermitUnload", diff --git a/devtools/client/themes/images/aboutdebugging-fenix-nightly.svg b/devtools/client/themes/images/aboutdebugging-fenix-nightly.svg deleted file mode 100644 index c87c2988a1..0000000000 --- a/devtools/client/themes/images/aboutdebugging-fenix-nightly.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/devtools/client/themes/images/aboutdebugging-fenix.svg b/devtools/client/themes/images/aboutdebugging-fenix.svg deleted file mode 100644 index 2a145d5013..0000000000 --- a/devtools/client/themes/images/aboutdebugging-fenix.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/devtools/client/themes/images/aboutdebugging-firefox-aurora.svg b/devtools/client/themes/images/aboutdebugging-firefox-aurora.svg deleted file mode 100644 index 7346d54b94..0000000000 --- a/devtools/client/themes/images/aboutdebugging-firefox-aurora.svg +++ /dev/null @@ -1,4 +0,0 @@ - -firefox-logo-developer-edition diff --git a/devtools/client/themes/images/aboutdebugging-firefox-beta.svg b/devtools/client/themes/images/aboutdebugging-firefox-beta.svg deleted file mode 100644 index 6cdc237fa9..0000000000 --- a/devtools/client/themes/images/aboutdebugging-firefox-beta.svg +++ /dev/null @@ -1,4 +0,0 @@ - -firefox-logo-beta diff --git a/devtools/client/themes/images/aboutdebugging-firefox-logo.svg b/devtools/client/themes/images/aboutdebugging-firefox-logo.svg deleted file mode 100644 index 7e9522a3be..0000000000 --- a/devtools/client/themes/images/aboutdebugging-firefox-logo.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/devtools/client/themes/images/aboutdebugging-firefox-nightly.svg b/devtools/client/themes/images/aboutdebugging-firefox-nightly.svg deleted file mode 100644 index bfed2982bc..0000000000 --- a/devtools/client/themes/images/aboutdebugging-firefox-nightly.svg +++ /dev/null @@ -1,4 +0,0 @@ - -firefox-logo-nightly diff --git a/devtools/client/themes/images/aboutdebugging-firefox-release.svg b/devtools/client/themes/images/aboutdebugging-firefox-release.svg deleted file mode 100644 index 46f2a42421..0000000000 --- a/devtools/client/themes/images/aboutdebugging-firefox-release.svg +++ /dev/null @@ -1,4 +0,0 @@ - -firefox-logo diff --git a/devtools/server/actors/animation-type-longhand.js b/devtools/server/actors/animation-type-longhand.js index 22217f4cb0..89bc990cf1 100644 --- a/devtools/server/actors/animation-type-longhand.js +++ b/devtools/server/actors/animation-type-longhand.js @@ -36,7 +36,6 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [ "-moz-box-orient", "-moz-box-pack", "box-sizing", - "-moz-button-appearance", "caption-side", "clear", "clip-rule", diff --git a/devtools/server/actors/breakpoint.js b/devtools/server/actors/breakpoint.js index 1c2f5b9a5a..8ea43d5937 100644 --- a/devtools/server/actors/breakpoint.js +++ b/devtools/server/actors/breakpoint.js @@ -169,7 +169,7 @@ BreakpointActor.prototype = { * @param frame Debugger.Frame * The stack frame that contained the breakpoint. */ - /* eslint-disable complexity */ + // eslint-disable-next-line complexity hit: function(frame) { // Don't pause if we are currently stepping (in or over) or the frame is // black-boxed. @@ -231,7 +231,6 @@ BreakpointActor.prototype = { return this.threadActor._pauseAndRespond(frame, reason); }, - /* eslint-enable complexity */ delete: function() { // Remove from the breakpoint store. diff --git a/devtools/server/actors/highlighters/flexbox.js b/devtools/server/actors/highlighters/flexbox.js index 99b1096efd..ebee53aaf9 100644 --- a/devtools/server/actors/highlighters/flexbox.js +++ b/devtools/server/actors/highlighters/flexbox.js @@ -943,10 +943,7 @@ function getRectFromFlexItemValues(item, container) { domRect.x -= paddingLeft + scrollX; domRect.y -= paddingTop + scrollY; - if ( - style.overflow === "visible" || - style.overflow === "-moz-hidden-unscrollable" - ) { + if (style.overflow === "visible" || style.overflow === "clip") { domRect.x -= borderLeftWidth; domRect.y -= borderTopWidth; } diff --git a/devtools/server/actors/storage.js b/devtools/server/actors/storage.js index 39c1879b0e..9351c5b293 100644 --- a/devtools/server/actors/storage.js +++ b/devtools/server/actors/storage.js @@ -589,7 +589,7 @@ StorageActors.createActor( case cookie.SAMESITE_STRICT: return COOKIE_SAMESITE.STRICT; } - // cookie.SAMESITE_UNSET + // cookie.SAMESITE_NONE return COOKIE_SAMESITE.UNSET; }, diff --git a/devtools/server/actors/styles.js b/devtools/server/actors/styles.js index 3cb4a016a5..6bd0dee94c 100644 --- a/devtools/server/actors/styles.js +++ b/devtools/server/actors/styles.js @@ -101,6 +101,8 @@ const BOLD_FONT_WEIGHT = 700; // Offset (in px) to avoid cutting off text edges of italic fonts. const FONT_PREVIEW_OFFSET = 4; +const NS_EVENT_STATE_VISITED = 1 << 24; + /** * The PageStyle actor lets the client look at the styles on a page, as * they are applied to a given node. @@ -770,7 +772,12 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, { * @returns Array */ _getElementRules: function(node, pseudo, inherited, options) { - const domRules = InspectorUtils.getCSSStyleRules(node, pseudo); + const domRules = InspectorUtils.getCSSStyleRules( + node, + pseudo, + _hasVisitedState(node) + ); + if (!domRules) { return []; } @@ -802,6 +809,7 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, { } const ruleActor = this._styleRef(domRule); + rules.push({ rule: ruleActor, inherited: inherited, @@ -885,14 +893,17 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, { const { bindingElement, pseudo } = CssLogic.getBindingElementAndPseudo( element ); + const relevantLinkVisited = _hasVisitedState(bindingElement); entry.matchedSelectors = []; + for (let i = 0; i < selectors.length; i++) { if ( InspectorUtils.selectorMatchesElement( bindingElement, domRule, i, - pseudo + pseudo, + relevantLinkVisited ) ) { entry.matchedSelectors.push(selectors[i]); @@ -2231,3 +2242,10 @@ function getTextAtLineColumn(text, line, column) { } exports.getTextAtLineColumn = getTextAtLineColumn; + +function _hasVisitedState(node) { + return ( + !!(InspectorUtils.getContentState(node) & NS_EVENT_STATE_VISITED) || + InspectorUtils.hasPseudoClassLock(node, ":visited") + ); +} diff --git a/devtools/shared/css/constants.js b/devtools/shared/css/constants.js index e3879971c5..58974742fc 100644 --- a/devtools/shared/css/constants.js +++ b/devtools/shared/css/constants.js @@ -27,6 +27,11 @@ exports.CSS_TYPES = { /** * Supported pseudo-class locks in the order in which they appear in the pseudo-class * panel in the Rules sidebar panel of the Inspector. - * FIXME: add ":visited" and ":link" after bug 713106 is fixed */ -exports.PSEUDO_CLASSES = [":hover", ":active", ":focus", ":focus-within"]; +exports.PSEUDO_CLASSES = [ + ":hover", + ":active", + ":focus", + ":focus-within", + ":visited", +]; diff --git a/devtools/shared/css/generated/properties-db.js b/devtools/shared/css/generated/properties-db.js index 1b33f253cc..d792a63630 100644 --- a/devtools/shared/css/generated/properties-db.js +++ b/devtools/shared/css/generated/properties-db.js @@ -8481,6 +8481,7 @@ exports.CSS_PROPERTIES = { "values": [ "-moz-hidden-unscrollable", "auto", + "clip", "hidden", "inherit", "initial", @@ -8514,6 +8515,7 @@ exports.CSS_PROPERTIES = { "values": [ "-moz-hidden-unscrollable", "auto", + "clip", "hidden", "inherit", "initial", @@ -8532,6 +8534,7 @@ exports.CSS_PROPERTIES = { "values": [ "-moz-hidden-unscrollable", "auto", + "clip", "hidden", "inherit", "initial", @@ -8566,6 +8569,7 @@ exports.CSS_PROPERTIES = { "values": [ "-moz-hidden-unscrollable", "auto", + "clip", "hidden", "inherit", "initial", @@ -8584,6 +8588,7 @@ exports.CSS_PROPERTIES = { "values": [ "-moz-hidden-unscrollable", "auto", + "clip", "hidden", "inherit", "initial", diff --git a/docshell/base/BrowsingContext.h b/docshell/base/BrowsingContext.h index aa321d0ff4..fa3ddb3e98 100644 --- a/docshell/base/BrowsingContext.h +++ b/docshell/base/BrowsingContext.h @@ -222,7 +222,6 @@ class BrowsingContext : public nsWrapperCache, public BrowsingContextBase { mWindowProxy = aWindowProxy; } - MOZ_DECLARE_WEAKREFERENCE_TYPENAME(BrowsingContext) NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(BrowsingContext) NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(BrowsingContext) diff --git a/docshell/base/moz.build b/docshell/base/moz.build index d6fa2f47de..068ec34e72 100644 --- a/docshell/base/moz.build +++ b/docshell/base/moz.build @@ -3,13 +3,13 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. with Files('**'): - BUG_COMPONENT = ('Core', 'Document Navigation') + BUG_COMPONENT = ('Core', 'DOM: Navigation') with Files('crashtests/430628*'): - BUG_COMPONENT = ('Core', 'Editor') + BUG_COMPONENT = ('Core', 'DOM: Editor') with Files('crashtests/432114*'): - BUG_COMPONENT = ('Core', 'Editor') + BUG_COMPONENT = ('Core', 'DOM: Editor') with Files('crashtests/500328*'): BUG_COMPONENT = ('Firefox', 'Bookmarks & History') diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 4ac2f27d0f..bc86134b6c 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -119,7 +119,7 @@ class nsDocShell final : public nsDocLoader, public nsIDOMStorageManager, public nsINetworkInterceptController, public nsIDeprecationWarner, - public mozilla::SupportsWeakPtr { + public mozilla::SupportsWeakPtr { public: enum InternalLoad : uint32_t { INTERNAL_LOAD_FLAGS_NONE = 0x0, @@ -174,11 +174,10 @@ class nsDocShell final : public nsDocLoader, private: virtual ~InterfaceRequestorProxy(); - InterfaceRequestorProxy() {} + InterfaceRequestorProxy() = default; nsWeakPtr mWeakPtr; }; - MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsDocShell) NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDocShell, nsDocLoader) NS_DECL_NSIDOCSHELL diff --git a/docshell/moz.build b/docshell/moz.build index 1586a5ad74..feca60ee87 100644 --- a/docshell/moz.build +++ b/docshell/moz.build @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. with Files('**'): - BUG_COMPONENT = ('Core', 'Document Navigation') + BUG_COMPONENT = ('Core', 'DOM: Navigation') DIRS += [ 'base', diff --git a/docshell/test/moz.build b/docshell/test/moz.build index fdb49cb198..a02cd1c405 100644 --- a/docshell/test/moz.build +++ b/docshell/test/moz.build @@ -1,5 +1,5 @@ with Files('**'): - BUG_COMPONENT = ('Core', 'Document Navigation') + BUG_COMPONENT = ('Core', 'DOM: Navigation') with Files('browser/*_bug234628*'): BUG_COMPONENT = ('Core', 'Internationalization') @@ -58,10 +58,6 @@ with Files('chrome/*690056*'): with Files('chrome/*92598*'): BUG_COMPONENT = ('Core', 'Networking: HTTP') -with Files('chrome/*private_hidden_window*'): - BUG_COMPONENT = ('Firefox', 'Private Browsing') - - with Files('iframesandbox/**'): BUG_COMPONENT = ('Core', 'Security') @@ -113,13 +109,13 @@ with Files('navigation/*13871.html'): BUG_COMPONENT = ('Core', 'Security') with Files('navigation/*386782*'): - BUG_COMPONENT = ('Core', 'Editor') + BUG_COMPONENT = ('Core', 'DOM: Editor') with Files('navigation/*430624*'): - BUG_COMPONENT = ('Core', 'Editor') + BUG_COMPONENT = ('Core', 'DOM: Editor') with Files('navigation/*430723*'): - BUG_COMPONENT = ('Core', 'User events and focus handling') + BUG_COMPONENT = ('Core', 'DOM: UI Events & Focus Handling') with Files('navigation/*child*'): BUG_COMPONENT = ('Core', 'Security') diff --git a/editor/libeditor/CompositionTransaction.h b/editor/libeditor/CompositionTransaction.h index 3621eebdb9..80a977defc 100644 --- a/editor/libeditor/CompositionTransaction.h +++ b/editor/libeditor/CompositionTransaction.h @@ -28,9 +28,8 @@ class Text; * composition string, modifying the composition string or its IME selection * ranges and commit or cancel the composition. */ -class CompositionTransaction final - : public EditTransactionBase, - public SupportsWeakPtr { +class CompositionTransaction final : public EditTransactionBase, + public SupportsWeakPtr { protected: CompositionTransaction(EditorBase& aEditorBase, const nsAString& aStringToInsert, @@ -53,8 +52,6 @@ class CompositionTransaction final EditorBase& aEditorBase, const nsAString& aStringToInsert, const EditorDOMPointInText& aPointToInsert); - MOZ_DECLARE_WEAKREFERENCE_TYPENAME(CompositionTransaction) - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CompositionTransaction, EditTransactionBase) diff --git a/editor/libeditor/EditorEventListener.cpp b/editor/libeditor/EditorEventListener.cpp index 8410d351b1..de2877cb99 100644 --- a/editor/libeditor/EditorEventListener.cpp +++ b/editor/libeditor/EditorEventListener.cpp @@ -443,7 +443,7 @@ NS_IMETHODIMP EditorEventListener::HandleEvent(Event* aEvent) { case eMouseClick: { WidgetMouseEvent* widgetMouseEvent = internalEvent->AsMouseEvent(); // Don't handle non-primary click events - if (widgetMouseEvent->mButton != MouseButton::eLeft) { + if (widgetMouseEvent->mButton != MouseButton::ePrimary) { return NS_OK; } [[fallthrough]]; diff --git a/editor/libeditor/HTMLEditor.h b/editor/libeditor/HTMLEditor.h index 1774ab6e8a..801a8e45fe 100644 --- a/editor/libeditor/HTMLEditor.h +++ b/editor/libeditor/HTMLEditor.h @@ -3242,10 +3242,11 @@ class HTMLEditor final : public TextEditor, * @param aRv Returns error if layout information is not * available or given element is not a table cell. */ - CellIndexes(Element& aCellElement, ErrorResult& aRv) + MOZ_CAN_RUN_SCRIPT CellIndexes(Element& aCellElement, PresShell* aPresShell, + ErrorResult& aRv) : mRow(-1), mColumn(-1) { MOZ_ASSERT(!aRv.Failed()); - Update(aCellElement, aRv); + Update(aCellElement, aPresShell, aRv); } /** @@ -3253,7 +3254,8 @@ class HTMLEditor final : public TextEditor, * * @param See above. */ - void Update(Element& aCellElement, ErrorResult& aRv); + MOZ_CAN_RUN_SCRIPT void Update(Element& aCellElement, PresShell* aPresShell, + ErrorResult& aRv); /** * This constructor initializes mRowIndex and mColumnIndex with indexes of @@ -3265,8 +3267,8 @@ class HTMLEditor final : public TextEditor, * which contains anchor of Selection, or layout * information is not available. */ - CellIndexes(HTMLEditor& aHTMLEditor, Selection& aSelection, - ErrorResult& aRv) + MOZ_CAN_RUN_SCRIPT CellIndexes(HTMLEditor& aHTMLEditor, + Selection& aSelection, ErrorResult& aRv) : mRow(-1), mColumn(-1) { Update(aHTMLEditor, aSelection, aRv); } @@ -3277,8 +3279,8 @@ class HTMLEditor final : public TextEditor, * * @param See above. */ - void Update(HTMLEditor& aHTMLEditor, Selection& aSelection, - ErrorResult& aRv); + MOZ_CAN_RUN_SCRIPT void Update(HTMLEditor& aHTMLEditor, + Selection& aSelection, ErrorResult& aRv); bool operator==(const CellIndexes& aOther) const { return mRow == aOther.mRow && mColumn == aOther.mColumn; @@ -3304,8 +3306,8 @@ class HTMLEditor final : public TextEditor, * first range is in the cell element, this does not treat it as the * cell element is selected. */ - CellAndIndexes(HTMLEditor& aHTMLEditor, Selection& aSelection, - ErrorResult& aRv) { + MOZ_CAN_RUN_SCRIPT CellAndIndexes(HTMLEditor& aHTMLEditor, + Selection& aSelection, ErrorResult& aRv) { Update(aHTMLEditor, aSelection, aRv); } @@ -3315,8 +3317,8 @@ class HTMLEditor final : public TextEditor, * in the cell element, this does not treat it as the cell element is * selected. */ - void Update(HTMLEditor& aHTMLEditor, Selection& aSelection, - ErrorResult& aRv); + MOZ_CAN_RUN_SCRIPT void Update(HTMLEditor& aHTMLEditor, + Selection& aSelection, ErrorResult& aRv); }; struct MOZ_STACK_CLASS CellData final { @@ -4100,9 +4102,11 @@ class HTMLEditor final : public TextEditor, * Returns NS_EDITOR_ELEMENT_NOT_FOUND if cell is not found even if aCell is * null. */ - nsresult GetCellContext(Element** aTable, Element** aCell, - nsINode** aCellParent, int32_t* aCellOffset, - int32_t* aRowIndex, int32_t* aColIndex); + MOZ_CAN_RUN_SCRIPT nsresult GetCellContext(Element** aTable, Element** aCell, + nsINode** aCellParent, + int32_t* aCellOffset, + int32_t* aRowIndex, + int32_t* aColIndex); nsresult GetCellSpansAt(Element* aTable, int32_t aRowIndex, int32_t aColIndex, int32_t& aActualRowSpan, int32_t& aActualColSpan); diff --git a/editor/libeditor/HTMLTableEditor.cpp b/editor/libeditor/HTMLTableEditor.cpp index 56c468aa2e..c720141772 100644 --- a/editor/libeditor/HTMLTableEditor.cpp +++ b/editor/libeditor/HTMLTableEditor.cpp @@ -1131,7 +1131,8 @@ nsresult HTMLEditor::DeleteTableCellWithTransaction( // When 2 or more cells are selected, ignore aNumberOfCellsToRemove and // remove all selected cells. - CellIndexes firstCellIndexes(*firstSelectedCellElement, error); + const RefPtr presShell{GetPresShell()}; + CellIndexes firstCellIndexes(*firstSelectedCellElement, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return error.StealNSResult(); @@ -1166,7 +1167,7 @@ nsresult HTMLEditor::DeleteTableCellWithTransaction( if (!cell) { break; } - CellIndexes nextSelectedCellIndexes(*cell, error); + CellIndexes nextSelectedCellIndexes(*cell, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return error.StealNSResult(); @@ -1223,7 +1224,7 @@ nsresult HTMLEditor::DeleteTableCellWithTransaction( if (!cell) { break; } - CellIndexes nextSelectedCellIndexes(*cell, error); + CellIndexes nextSelectedCellIndexes(*cell, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return error.StealNSResult(); @@ -1273,7 +1274,7 @@ nsresult HTMLEditor::DeleteTableCellWithTransaction( return NS_OK; } - CellIndexes nextCellIndexes(*nextCell, error); + CellIndexes nextCellIndexes(*nextCell, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return error.StealNSResult(); @@ -1351,7 +1352,8 @@ nsresult HTMLEditor::DeleteTableCellContentsWithTransaction() { } if (firstSelectedCellElement) { - CellIndexes firstCellIndexes(*firstSelectedCellElement, error); + const RefPtr presShell{GetPresShell()}; + CellIndexes firstCellIndexes(*firstSelectedCellElement, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return error.StealNSResult(); @@ -1464,7 +1466,8 @@ nsresult HTMLEditor::DeleteSelectedTableColumnsWithTransaction( MOZ_ASSERT(SelectionRefPtr()->RangeCount()); if (firstSelectedCellElement && SelectionRefPtr()->RangeCount() > 1) { - CellIndexes firstCellIndexes(*firstSelectedCellElement, error); + const RefPtr presShell{GetPresShell()}; + CellIndexes firstCellIndexes(*firstSelectedCellElement, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return error.StealNSResult(); @@ -1494,9 +1497,10 @@ nsresult HTMLEditor::DeleteSelectedTableColumnsWithTransaction( // If 2 or more cells are selected, remove all columns which contain selected // cells. I.e., we ignore aNumberOfColumnsToDelete in this case. + const RefPtr presShell{GetPresShell()}; for (cell = firstSelectedCellElement; cell;) { if (cell != firstSelectedCellElement) { - CellIndexes cellIndexes(*cell, error); + CellIndexes cellIndexes(*cell, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return error.StealNSResult(); @@ -1516,7 +1520,7 @@ nsresult HTMLEditor::DeleteSelectedTableColumnsWithTransaction( if (!cell) { break; } - CellIndexes cellIndexes(*cell, error); + CellIndexes cellIndexes(*cell, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return error.StealNSResult(); @@ -1721,7 +1725,8 @@ nsresult HTMLEditor::DeleteSelectedTableRowsWithTransaction( if (firstSelectedCellElement && SelectionRefPtr()->RangeCount() > 1) { // Fetch indexes again - may be different for selected cells - CellIndexes firstCellIndexes(*firstSelectedCellElement, error); + const RefPtr presShell{GetPresShell()}; + CellIndexes firstCellIndexes(*firstSelectedCellElement, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return error.StealNSResult(); @@ -1765,9 +1770,10 @@ nsresult HTMLEditor::DeleteSelectedTableRowsWithTransaction( // If 2 or more cells are selected, remove all rows which contain selected // cells. I.e., we ignore aNumberOfRowsToDelete in this case. + const RefPtr presShell{GetPresShell()}; for (cell = firstSelectedCellElement; cell;) { if (cell != firstSelectedCellElement) { - CellIndexes cellIndexes(*cell, error); + CellIndexes cellIndexes(*cell, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return error.StealNSResult(); @@ -1787,7 +1793,7 @@ nsresult HTMLEditor::DeleteSelectedTableRowsWithTransaction( if (!cell) { break; } - CellIndexes cellIndexes(*cell, error); + CellIndexes cellIndexes(*cell, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return error.StealNSResult(); @@ -2671,7 +2677,8 @@ NS_IMETHODIMP HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) { // as well as the "non-contiguous" cells, so user can see what happened. ErrorResult error; - CellAndIndexes firstSelectedCell(*this, *SelectionRefPtr(), error); + CellAndIndexes firstSelectedCell(*this, MOZ_KnownLive(*SelectionRefPtr()), + error); if (error.Failed()) { NS_WARNING("CellAndIndexes failed"); return EditorBase::ToGenericNSResult(error.StealNSResult()); @@ -3432,7 +3439,7 @@ NS_IMETHODIMP HTMLEditor::GetCellIndexes(Element* aCellElement, // Use cell element which contains anchor of Selection when aCellElement is // nullptr. ErrorResult error; - CellIndexes cellIndexes(*this, *SelectionRefPtr(), error); + CellIndexes cellIndexes(*this, MOZ_KnownLive(*SelectionRefPtr()), error); if (error.Failed()) { return EditorBase::ToGenericNSResult(error.StealNSResult()); } @@ -3442,7 +3449,8 @@ NS_IMETHODIMP HTMLEditor::GetCellIndexes(Element* aCellElement, } ErrorResult error; - CellIndexes cellIndexes(*aCellElement, error); + const RefPtr presShell{GetPresShell()}; + CellIndexes cellIndexes(*aCellElement, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return EditorBase::ToGenericNSResult(error.StealNSResult()); @@ -3467,16 +3475,26 @@ void HTMLEditor::CellIndexes::Update(HTMLEditor& aHTMLEditor, aRv.Throw(NS_ERROR_FAILURE); return; } - Update(*cellElement, aRv); + + RefPtr presShell{aHTMLEditor.GetPresShell()}; + Update(*cellElement, presShell, aRv); NS_WARNING_ASSERTION(!aRv.Failed(), "CellIndexes::Update() failed"); } -void HTMLEditor::CellIndexes::Update(Element& aCellElement, ErrorResult& aRv) { +void HTMLEditor::CellIndexes::Update(Element& aCellElement, + PresShell* aPresShell, ErrorResult& aRv) { MOZ_ASSERT(!aRv.Failed()); - // XXX If the table cell is created immediately before this call, e.g., - // using innerHTML, frames have not been created yet. In such case, - // shouldn't we flush pending layout? + // If the table cell is created immediately before this call, e.g., using + // innerHTML, frames have not been created yet. Hence, flush layout to create + // them. + if (NS_WARN_IF(!aPresShell)) { + aRv.Throw(NS_ERROR_INVALID_ARG); + return; + } + + aPresShell->FlushPendingNotifications(FlushType::Frames); + nsIFrame* frameOfCell = aCellElement.GetPrimaryFrame(); if (!frameOfCell) { NS_WARNING("There was no layout information of aCellElement"); @@ -3856,7 +3874,8 @@ nsresult HTMLEditor::GetCellContext(Element** aTable, Element** aCell, // Get the rest of the related data only if requested if (aRowIndex || aColumnIndex) { ErrorResult error; - CellIndexes cellIndexes(*cell, error); + const RefPtr presShell{GetPresShell()}; + CellIndexes cellIndexes(*cell, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return error.StealNSResult(); @@ -4056,7 +4075,7 @@ NS_IMETHODIMP HTMLEditor::GetFirstSelectedCellInTable(int32_t* aRowIndex, *aCellElement = nullptr; ErrorResult error; - CellAndIndexes result(*this, *SelectionRefPtr(), error); + CellAndIndexes result(*this, MOZ_KnownLive(*SelectionRefPtr()), error); if (error.Failed()) { NS_WARNING("CellAndIndexes failed"); return EditorBase::ToGenericNSResult(error.StealNSResult()); @@ -4084,7 +4103,9 @@ void HTMLEditor::CellAndIndexes::Update(HTMLEditor& aHTMLEditor, return; } - mIndexes.Update(*mElement, aRv); + const RefPtr presShell{aHTMLEditor.GetPresShell()}; + const RefPtr element{mElement}; + mIndexes.Update(*element, presShell, aRv); NS_WARNING_ASSERTION(!aRv.Failed(), "CellIndexes::Update() failed"); } @@ -4356,11 +4377,12 @@ NS_IMETHODIMP HTMLEditor::GetSelectedCellsType(Element* aElement, // Store indexes of each row/col to avoid duplication of searches nsTArray indexArray; + const RefPtr presShell{GetPresShell()}; bool allCellsInRowAreSelected = false; bool allCellsInColAreSelected = false; IgnoredErrorResult ignoredError; while (selectedCell) { - CellIndexes selectedCellIndexes(*selectedCell, error); + CellIndexes selectedCellIndexes(*selectedCell, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return EditorBase::ToGenericNSResult(error.StealNSResult()); @@ -4398,7 +4420,7 @@ NS_IMETHODIMP HTMLEditor::GetSelectedCellsType(Element* aElement, ignoredError.SuppressException(); while (selectedCell) { - CellIndexes selectedCellIndexes(*selectedCell, error); + CellIndexes selectedCellIndexes(*selectedCell, presShell, error); if (error.Failed()) { NS_WARNING("CellIndexes failed"); return EditorBase::ToGenericNSResult(error.StealNSResult()); diff --git a/editor/libeditor/PlaceholderTransaction.h b/editor/libeditor/PlaceholderTransaction.h index 418e13b780..8a45315589 100644 --- a/editor/libeditor/PlaceholderTransaction.h +++ b/editor/libeditor/PlaceholderTransaction.h @@ -21,9 +21,8 @@ class EditorBase; * transactions it has absorbed. */ -class PlaceholderTransaction final - : public EditAggregateTransaction, - public SupportsWeakPtr { +class PlaceholderTransaction final : public EditAggregateTransaction, + public SupportsWeakPtr { protected: PlaceholderTransaction(EditorBase& aEditorBase, nsStaticAtom& aName, Maybe&& aSelState); @@ -47,8 +46,6 @@ class PlaceholderTransaction final return transaction.forget(); } - MOZ_DECLARE_WEAKREFERENCE_TYPENAME(PlaceholderTransaction) - NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PlaceholderTransaction, diff --git a/editor/libeditor/moz.build b/editor/libeditor/moz.build index 046d53bcaa..8806f9c123 100644 --- a/editor/libeditor/moz.build +++ b/editor/libeditor/moz.build @@ -89,3 +89,6 @@ FINAL_LIBRARY = 'xul' if CONFIG['CC_TYPE'] in ('clang', 'gcc'): CXXFLAGS += ['-Wno-error=shadow'] + +with Files("tests/*1151186*"): + BUG_COMPONENT = ("Core", "DOM: UI Events & Focus Handling") diff --git a/editor/moz.build b/editor/moz.build index e8397bc2c7..be2cccc22d 100644 --- a/editor/moz.build +++ b/editor/moz.build @@ -29,5 +29,5 @@ TESTING_JS_MODULES += [ 'AsyncSpellCheckTestHelper.jsm', ] -with Files('**'): - BUG_COMPONENT = ('Core', 'Editor') +with Files('**'): + BUG_COMPONENT = ('Core', 'DOM: Editor') diff --git a/editor/nsITableEditor.idl b/editor/nsITableEditor.idl index 38360ceb97..a89a41bd2c 100644 --- a/editor/nsITableEditor.idl +++ b/editor/nsITableEditor.idl @@ -239,6 +239,7 @@ interface nsITableEditor : nsISupports * column. If colspan is set to 2 or more, the * start column index is used. */ + [can_run_script] void getCellIndexes(in Element aCellElement, out long aRowIndex, out long aColumnIndex); @@ -414,6 +415,7 @@ interface nsITableEditor : nsISupports * TableSelectionMode::Column All cells are in 1 or more columns * and in each column, all cells are selected */ + [can_run_script] uint32_t getSelectedCellsType(in Element aElement); /** @@ -451,6 +453,7 @@ interface nsITableEditor : nsISupports * range of Selection. Even if this is not found, * this returns null, not throwing exception. */ + [can_run_script] Element getFirstSelectedCellInTable(out long aRowIndex, out long aColIndex); /** diff --git a/extensions/auth/nsHttpNegotiateAuth.cpp b/extensions/auth/nsHttpNegotiateAuth.cpp index a8b5ddb551..7d3e0ed7b6 100644 --- a/extensions/auth/nsHttpNegotiateAuth.cpp +++ b/extensions/auth/nsHttpNegotiateAuth.cpp @@ -21,6 +21,7 @@ #include "nsIHttpAuthenticableChannel.h" #include "nsIAuthModule.h" #include "nsIPrefBranch.h" +#include "nsIPrefService.h" #include "nsIProxyInfo.h" #include "nsIURI.h" #include "nsCOMPtr.h" diff --git a/extensions/permissions/PermissionDelegateHandler.cpp b/extensions/permissions/PermissionDelegateHandler.cpp index 38c7ac44c0..d6a0d8fc38 100644 --- a/extensions/permissions/PermissionDelegateHandler.cpp +++ b/extensions/permissions/PermissionDelegateHandler.cpp @@ -9,6 +9,7 @@ #include "nsIPrincipal.h" #include "nsContentPermissionHelper.h" +#include "mozilla/StaticPrefs_dom.h" #include "mozilla/StaticPrefs_permissions.h" #include "mozilla/dom/Document.h" #include "mozilla/dom/FeaturePolicyUtils.h" diff --git a/extensions/permissions/nsPermissionManager.cpp b/extensions/permissions/nsPermissionManager.cpp index b37fb29497..707e8d7394 100644 --- a/extensions/permissions/nsPermissionManager.cpp +++ b/extensions/permissions/nsPermissionManager.cpp @@ -29,9 +29,6 @@ #include "nsContentUtils.h" #include "nsPIDOMWindow.h" #include "mozilla/dom/Document.h" -#ifdef ANDROID -# include "mozilla/jni/Utils.h" // for jni::IsFennec -#endif #include "mozilla/net/NeckoMessageUtils.h" #include "mozilla/Preferences.h" #include "nsReadLine.h" @@ -1028,7 +1025,6 @@ nsresult nsPermissionManager::Init() { observerService->AddObserver(this, "profile-do-change", true); observerService->AddObserver(this, "testonly-reload-permissions-from-disk", true); - observerService->AddObserver(this, "clear-origin-attributes-data", true); } // ignore failure here, since it's non-fatal (we can run fine without @@ -2648,8 +2644,6 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports* aSubject, RemoveAllFromMemory(); CloseDB(false); InitDB(false); - } else if (!nsCRT::strcmp(aTopic, "clear-origin-attributes-data")) { - return RemovePermissionsWithAttributes(nsDependentString(someData)); } return NS_OK; @@ -2665,7 +2659,8 @@ nsresult nsPermissionManager::RemoveAllModifiedSince( }); } -nsresult nsPermissionManager::RemovePermissionsWithAttributes( +NS_IMETHODIMP +nsPermissionManager::RemovePermissionsWithAttributes( const nsAString& aPattern) { ENSURE_NOT_CHILD_PROCESS; mozilla::OriginAttributesPattern pattern; diff --git a/extensions/permissions/nsPermissionManager.h b/extensions/permissions/nsPermissionManager.h index a400d4146c..bbb659908c 100644 --- a/extensions/permissions/nsPermissionManager.h +++ b/extensions/permissions/nsPermissionManager.h @@ -207,6 +207,9 @@ class nsPermissionManager final : public nsIPermissionManager, */ static void Startup(); + nsresult RemovePermissionsWithAttributes( + mozilla::OriginAttributesPattern& aAttrs); + /** * See `nsIPermissionManager::GetPermissionsWithKey` for more info on * permission keys. @@ -282,6 +285,15 @@ class nsPermissionManager final : public nsIPermissionManager, // From ContentChild. nsresult RemoveAllFromIPC(); + /** + * Returns false if this permission manager wouldn't have the permission + * requested available. + * + * If aType is empty, checks that the permission manager would have all + * permissions available for the given principal. + */ + bool PermissionAvailable(nsIPrincipal* aPrincipal, const nsACString& aType); + /** * The content process doesn't have access to every permission. Instead, when * LOAD_DOCUMENT_URI channels for http://, https://, and ftp:// URIs are @@ -580,19 +592,6 @@ class nsPermissionManager final : public nsIPermissionManager, template nsresult RemovePermissionEntries(T aCondition); - nsresult RemovePermissionsWithAttributes(const nsAString& aPattern); - nsresult RemovePermissionsWithAttributes( - mozilla::OriginAttributesPattern& aAttrs); - - /** - * Returns false if this permission manager wouldn't have the permission - * requested available. - * - * If aType is nullptr, checks that the permission manager would have all - * permissions available for the given principal. - */ - bool PermissionAvailable(nsIPrincipal* aPrincipal, const nsACString& aType); - nsRefPtrHashtable mPermissionKeyPromiseMap; diff --git a/extensions/permissions/test/PermissionTestUtils.jsm b/extensions/permissions/test/PermissionTestUtils.jsm index 31b5277e75..7183252dd0 100644 --- a/extensions/permissions/test/PermissionTestUtils.jsm +++ b/extensions/permissions/test/PermissionTestUtils.jsm @@ -8,13 +8,11 @@ "use strict"; -let pm = Cc["@mozilla.org/permissionmanager;1"].getService( - Ci.nsIPermissionManager -); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); -let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService( - Ci.nsIScriptSecurityManager -); +let pm = Services.perms; + +let secMan = Services.scriptSecurityManager; const EXPORTED_SYMBOLS = ["PermissionTestUtils"]; diff --git a/extensions/permissions/test/unit/test_permmanager_cleardata.js b/extensions/permissions/test/unit/test_permmanager_cleardata.js index 0dc002a8b0..4abf67daa2 100644 --- a/extensions/permissions/test/unit/test_permmanager_cleardata.js +++ b/extensions/permissions/test/unit/test_permmanager_cleardata.js @@ -11,22 +11,21 @@ function createPrincipal(aOrigin, aOriginAttributes) { ); } -// Return the data required by 'clear-origin-attributes-data' notification. function getData(aPattern) { return JSON.stringify(aPattern); } // Use aEntries to create principals, add permissions to them and check that they have them. -// Then, it is notifying 'clear-origin-attributes-data' with the given aData and check if the permissions +// Then, it is removing origin attributes with the given aData and check if the permissions // of principals[i] matches the permission in aResults[i]. function test(aEntries, aData, aResults) { let principals = []; - for (entry of aEntries) { + for (const entry of aEntries) { principals.push(createPrincipal(entry.origin, entry.originAttributes)); } - for (principal of principals) { + for (const principal of principals) { Assert.equal( pm.testPermissionFromPrincipal(principal, "test/clear-origin"), pm.UNKNOWN_ACTION @@ -44,7 +43,9 @@ function test(aEntries, aData, aResults) { ); } - Services.obs.notifyObservers(null, "clear-origin-attributes-data", aData); + // `clear-origin-attributes-data` notification is removed from permission + // manager + pm.removePermissionsWithAttributes(aData); var length = aEntries.length; for (let i = 0; i < length; ++i) { @@ -63,9 +64,7 @@ function test(aEntries, aData, aResults) { function run_test() { do_get_profile(); - pm = Cc["@mozilla.org/permissionmanager;1"].getService( - Ci.nsIPermissionManager - ); + pm = Services.perms; let entries = [ { origin: "http://example.com", originAttributes: {} }, diff --git a/extensions/permissions/test/unit/test_permmanager_matches.js b/extensions/permissions/test/unit/test_permmanager_matches.js index 099fb48142..32d7adf45f 100644 --- a/extensions/permissions/test/unit/test_permmanager_matches.js +++ b/extensions/permissions/test/unit/test_permmanager_matches.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +var attrs; + function matches_always(perm, principals) { principals.forEach(principal => { Assert.ok( @@ -42,13 +44,9 @@ function matches_never(perm, principals) { function run_test() { // initialize the permission manager service - let pm = Cc["@mozilla.org/permissionmanager;1"].getService( - Ci.nsIPermissionManager - ); + let pm = Services.perms; - let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService( - Ci.nsIScriptSecurityManager - ); + let secMan = Services.scriptSecurityManager; // Add some permissions let uri0 = NetUtil.newURI("http://google.com/search?q=foo#hashtag"); diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_4-7.js b/extensions/permissions/test/unit/test_permmanager_migrate_4-7.js index e7836cbc9d..fcd07d145d 100644 --- a/extensions/permissions/test/unit/test_permmanager_migrate_4-7.js +++ b/extensions/permissions/test/unit/test_permmanager_migrate_4-7.js @@ -91,6 +91,7 @@ add_task(async function test() { } // Add some rows to the database + // eslint-disable-next-line no-unused-vars let created = [ insertHost("foo.com", "A", 1, 0, 0, 0, 0, false), insertHost("foo.com", "C", 1, 0, 0, 0, 0, false), diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_4-7_no_history.js b/extensions/permissions/test/unit/test_permmanager_migrate_4-7_no_history.js index af0752fa69..a3330f2e53 100644 --- a/extensions/permissions/test/unit/test_permmanager_migrate_4-7_no_history.js +++ b/extensions/permissions/test/unit/test_permmanager_migrate_4-7_no_history.js @@ -131,6 +131,7 @@ add_task(function test() { } // Add some rows to the database + // eslint-disable-next-line no-unused-vars let created = [ insertHost("foo.com", "A", 1, 0, 0, 0, 0, false), insertHost("foo.com", "C", 1, 0, 0, 0, 0, false), diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_5-7a.js b/extensions/permissions/test/unit/test_permmanager_migrate_5-7a.js index ab75c3848d..38c2293fb1 100644 --- a/extensions/permissions/test/unit/test_permmanager_migrate_5-7a.js +++ b/extensions/permissions/test/unit/test_permmanager_migrate_5-7a.js @@ -109,7 +109,6 @@ add_task(async function test() { modificationTime, }; } - function insertHost( host, type, @@ -158,6 +157,7 @@ add_task(async function test() { ]; // Add some rows to the database + // eslint-disable-next-line no-unused-vars let created = [ insertHost("foo.com", "A", 1, 0, 0, 0, 0, false), insertHost("foo.com", "C", 1, 0, 0, 0, 0, false), diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_5-7b.js b/extensions/permissions/test/unit/test_permmanager_migrate_5-7b.js index 70d242fad2..796f58a132 100644 --- a/extensions/permissions/test/unit/test_permmanager_migrate_5-7b.js +++ b/extensions/permissions/test/unit/test_permmanager_migrate_5-7b.js @@ -49,7 +49,6 @@ add_task(function test() { ); let id = 0; - function insertOrigin( origin, type, @@ -85,6 +84,7 @@ add_task(function test() { }; } + // eslint-disable-next-line no-unused-vars let created5 = [ insertOrigin("https://foo.com", "A", 2, 0, 0, 0), insertOrigin("http://foo.com", "A", 2, 0, 0, 0), diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_6-7a.js b/extensions/permissions/test/unit/test_permmanager_migrate_6-7a.js index 1c68126330..fef13ba062 100644 --- a/extensions/permissions/test/unit/test_permmanager_migrate_6-7a.js +++ b/extensions/permissions/test/unit/test_permmanager_migrate_6-7a.js @@ -158,6 +158,7 @@ add_task(async function test() { ]; // Add some rows to the database + // eslint-disable-next-line no-unused-vars let created = [ insertHost("foo.com", "A", 1, 0, 0, 0, 0, false), insertHost("foo.com", "C", 1, 0, 0, 0, 0, false), diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_6-7b.js b/extensions/permissions/test/unit/test_permmanager_migrate_6-7b.js index 6181d30aaa..97feb673cd 100644 --- a/extensions/permissions/test/unit/test_permmanager_migrate_6-7b.js +++ b/extensions/permissions/test/unit/test_permmanager_migrate_6-7b.js @@ -49,7 +49,6 @@ add_task(function test() { ); let id = 0; - function insertOrigin( origin, type, @@ -85,6 +84,7 @@ add_task(function test() { }; } + // eslint-disable-next-line no-unused-vars let created6 = [ insertOrigin("https://foo.com", "A", 2, 0, 0, 0), insertOrigin("http://foo.com", "A", 2, 0, 0, 0), diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_7-8.js b/extensions/permissions/test/unit/test_permmanager_migrate_7-8.js index 37525b45fd..14c812e453 100644 --- a/extensions/permissions/test/unit/test_permmanager_migrate_7-8.js +++ b/extensions/permissions/test/unit/test_permmanager_migrate_7-8.js @@ -157,7 +157,7 @@ add_task(async function test() { isInBrowserElement, }; } - + // eslint-disable-next-line no-unused-vars let created7 = [ insertOrigin("https://foo.com", "A", 2, 0, 0, 0), insertOrigin("http://foo.com", "A", 2, 0, 0, 0), @@ -166,6 +166,7 @@ add_task(async function test() { ]; // Add some rows to the database + // eslint-disable-next-line no-unused-vars let created = [ insertHost("foo.com", "A", 1, 0, 0, 0, 0, false), insertHost("foo.com", "C", 1, 0, 0, 0, 0, false), diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_9-10.js b/extensions/permissions/test/unit/test_permmanager_migrate_9-10.js index edd1897861..d03f24038f 100644 --- a/extensions/permissions/test/unit/test_permmanager_migrate_9-10.js +++ b/extensions/permissions/test/unit/test_permmanager_migrate_9-10.js @@ -144,7 +144,7 @@ add_task(async function test() { isInBrowserElement, }; } - + // eslint-disable-next-line no-unused-vars let created7 = [ insertOrigin("https://foo.com", "A", 2, 0, 0, 0), insertOrigin("http://foo.com", "A", 2, 0, 0, 0), @@ -152,6 +152,7 @@ add_task(async function test() { ]; // Add some rows to the database + // eslint-disable-next-line no-unused-vars let created = [ insertHost("foo.com", "A", 1, 0, 0, 0, 0, false), insertHost("foo.com", "B", 1, 0, 0, 0, 1000, false), diff --git a/extensions/permissions/test/unit/test_permmanager_removeall.js b/extensions/permissions/test/unit/test_permmanager_removeall.js index 607e811b91..1c688cd514 100644 --- a/extensions/permissions/test/unit/test_permmanager_removeall.js +++ b/extensions/permissions/test/unit/test_permmanager_removeall.js @@ -6,9 +6,7 @@ function run_test() { var dir = do_get_profile(); // initialize the permission manager service - var pm = Cc["@mozilla.org/permissionmanager;1"].getService( - Ci.nsIPermissionManager - ); + var pm = Services.perms; // get the db file var file = dir.clone(); diff --git a/extensions/pref/autoconfig/src/nsAutoConfig.cpp b/extensions/pref/autoconfig/src/nsAutoConfig.cpp index 7fcd4f0cfc..51af896fe3 100644 --- a/extensions/pref/autoconfig/src/nsAutoConfig.cpp +++ b/extensions/pref/autoconfig/src/nsAutoConfig.cpp @@ -12,6 +12,7 @@ #include "nsAppDirectoryServiceDefs.h" #include "nsIObserverService.h" #include "nsLiteralString.h" +#include "nsIPrefService.h" #include "nsIPromptService.h" #include "nsIInputStream.h" #include "nsIOutputStream.h" diff --git a/extensions/spellcheck/hunspell/tests/unit/test_hunspell.js b/extensions/spellcheck/hunspell/tests/unit/test_hunspell.js index 3a93ed4fa0..77ff1635e8 100644 --- a/extensions/spellcheck/hunspell/tests/unit/test_hunspell.js +++ b/extensions/spellcheck/hunspell/tests/unit/test_hunspell.js @@ -151,9 +151,10 @@ const tests = [ ["warn", "iso-8859-1"], ]; +// eslint-disable-next-line no-shadow function* do_get_file_by_line(file, charset) { dump("getting file by line for file " + file.path + "\n"); - dump("using charset " + charset + "\n"); + dump("using charset1" + charset + "\n"); let fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( Ci.nsIFileInputStream ); @@ -165,7 +166,7 @@ function* do_get_file_by_line(file, charset) { lis.init(fis, charset, 1024, 0); lis.QueryInterface(Ci.nsIUnicharLineInputStream); - var val = {}; + let val = {}; while (lis.readLine(val)) { yield val.value; val = {}; @@ -191,7 +192,7 @@ function do_run_test(checker, name, charset, todo_good, todo_bad) { if (good.exists()) { var good_counter = 0; - for (val of do_get_file_by_line(good, charset)) { + for (const val of do_get_file_by_line(good, charset)) { let todo = false; good_counter++; if (todo_good && todo_good[good_counter]) { @@ -210,7 +211,7 @@ function do_run_test(checker, name, charset, todo_good, todo_bad) { if (bad.exists()) { var bad_counter = 0; - for (val of do_get_file_by_line(bad, charset)) { + for (const val of do_get_file_by_line(bad, charset)) { let todo = false; bad_counter++; if (todo_bad && todo_bad[bad_counter]) { @@ -241,7 +242,7 @@ function run_test() { spellChecker.loadDictionariesFromDir(testdir); function do_run_test_closure(test) { - [name, charset, todo_good, todo_bad] = test; + let [name, charset, todo_good, todo_bad] = test; do_run_test(spellChecker, name, charset, todo_good, todo_bad); } diff --git a/extensions/spellcheck/hunspell/tests/unit/test_hunspell_unicode_paths.js b/extensions/spellcheck/hunspell/tests/unit/test_hunspell_unicode_paths.js index 6c9719d4ee..019f854291 100644 --- a/extensions/spellcheck/hunspell/tests/unit/test_hunspell_unicode_paths.js +++ b/extensions/spellcheck/hunspell/tests/unit/test_hunspell_unicode_paths.js @@ -5,8 +5,6 @@ const { XPCOMUtils } = ChromeUtils.import( ); const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm"); -Cu.importGlobalProperties(["TextEncoder"]); - XPCOMUtils.defineLazyServiceGetter( this, "spellCheck", diff --git a/extensions/spellcheck/tests/mochitest/helper_bug1170484.js b/extensions/spellcheck/tests/mochitest/helper_bug1170484.js index 53bb34d465..be6505bb44 100644 --- a/extensions/spellcheck/tests/mochitest/helper_bug1170484.js +++ b/extensions/spellcheck/tests/mochitest/helper_bug1170484.js @@ -1,10 +1,12 @@ const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); +/* eslint-env mozilla/frame-script */ + // Chrome scripts are run with synchronous messages, so make sure we're completely // decoupled from the content process before doing this work. Cu.dispatch(function() { let chromeWin = Services.ww.activeWindow; - contextMenu = chromeWin.document.getElementById("contentAreaContextMenu"); + let contextMenu = chromeWin.document.getElementById("contentAreaContextMenu"); var suggestion = contextMenu.querySelector(".spell-suggestion"); suggestion.doCommand(); contextMenu.hidePopup(); diff --git a/extensions/spellcheck/tests/mochitest/test_bug1170484.html b/extensions/spellcheck/tests/mochitest/test_bug1170484.html index 8201557afa..e32fcf4c3c 100644 --- a/extensions/spellcheck/tests/mochitest/test_bug1170484.html +++ b/extensions/spellcheck/tests/mochitest/test_bug1170484.html @@ -14,6 +14,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1170484 /** Test for Bug 1170484 **/ SimpleTest.waitForExplicitFinish(); + /* global onSpellCheck */ SpecialPowers.Cu.import( "resource://testing-common/AsyncSpellCheckTestHelper.jsm", window); diff --git a/extensions/spellcheck/tests/mochitest/test_bug1272623.html b/extensions/spellcheck/tests/mochitest/test_bug1272623.html index fadc8c8264..ed3fa3dfdb 100644 --- a/extensions/spellcheck/tests/mochitest/test_bug1272623.html +++ b/extensions/spellcheck/tests/mochitest/test_bug1272623.html @@ -23,6 +23,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1272623 - Mozilla Bug 431054

-
 
diff --git a/widget/tests/test_mouse_event_with_control_on_mac.html b/widget/tests/test_mouse_event_with_control_on_mac.html
new file mode 100644
index 0000000000..516eafc861
--- /dev/null
+++ b/widget/tests/test_mouse_event_with_control_on_mac.html
@@ -0,0 +1,114 @@
+
+
+  Test control+click on Mac
+  
+  
+  
+  
+  
+
+
+
+ + + diff --git a/widget/uikit/nsWindow.mm b/widget/uikit/nsWindow.mm index 7cad5d9d7a..c09ed4857a 100644 --- a/widget/uikit/nsWindow.mm +++ b/widget/uikit/nsWindow.mm @@ -134,7 +134,7 @@ class nsAutoRetainUIKitObject { event.mRefPoint = aPoint; event.mClickCount = 1; - event.button = MouseButton::eLeft; + event.button = MouseButton::ePrimary; event.mTime = PR_IntervalNow(); event.inputSource = MouseEvent_Binding::MOZ_SOURCE_UNKNOWN; diff --git a/widget/windows/IMMHandler.cpp b/widget/windows/IMMHandler.cpp index 97657b2d86..088ddcab98 100644 --- a/widget/windows/IMMHandler.cpp +++ b/widget/windows/IMMHandler.cpp @@ -2469,13 +2469,13 @@ nsresult IMMHandler::OnMouseButtonEvent( BYTE button; switch (aIMENotification.mMouseButtonEventData.mButton) { - case MouseButton::eLeft: + case MouseButton::ePrimary: button = IMEMOUSE_LDOWN; break; case MouseButton::eMiddle: button = IMEMOUSE_MDOWN; break; - case MouseButton::eRight: + case MouseButton::eSecondary: button = IMEMOUSE_RDOWN; break; default: diff --git a/widget/windows/KeyboardLayout.cpp b/widget/windows/KeyboardLayout.cpp index 83a68c80be..1326f04197 100644 --- a/widget/windows/KeyboardLayout.cpp +++ b/widget/windows/KeyboardLayout.cpp @@ -917,10 +917,10 @@ void ModifierKeyState::InitMouseEvent(WidgetInputEvent& aMouseEvent) const { WidgetMouseEventBase& mouseEvent = *aMouseEvent.AsMouseEventBase(); mouseEvent.mButtons = 0; if (::GetKeyState(VK_LBUTTON) < 0) { - mouseEvent.mButtons |= MouseButtonsFlag::eLeftFlag; + mouseEvent.mButtons |= MouseButtonsFlag::ePrimaryFlag; } if (::GetKeyState(VK_RBUTTON) < 0) { - mouseEvent.mButtons |= MouseButtonsFlag::eRightFlag; + mouseEvent.mButtons |= MouseButtonsFlag::eSecondaryFlag; } if (::GetKeyState(VK_MBUTTON) < 0) { mouseEvent.mButtons |= MouseButtonsFlag::eMiddleFlag; diff --git a/widget/windows/TSFTextStore.cpp b/widget/windows/TSFTextStore.cpp index 9894a18801..5470ceb11d 100644 --- a/widget/windows/TSFTextStore.cpp +++ b/widget/windows/TSFTextStore.cpp @@ -529,11 +529,11 @@ static nsCString GetDisplayAttrStr(const TF_DISPLAYATTRIBUTE& aDispAttr) { static const char* GetMouseButtonName(int16_t aButton) { switch (aButton) { - case MouseButton::eLeft: + case MouseButton::ePrimary: return "LeftButton"; case MouseButton::eMiddle: return "MiddleButton"; - case MouseButton::eRight: + case MouseButton::eSecondary: return "RightButton"; default: return "UnknownButton"; @@ -550,10 +550,10 @@ static nsCString GetMouseButtonsName(int16_t aButtons) { return NS_LITERAL_CSTRING("no buttons"); } nsCString names; - if (aButtons & MouseButtonsFlag::eLeftFlag) { + if (aButtons & MouseButtonsFlag::ePrimaryFlag) { names = "LeftButton"; } - if (aButtons & MouseButtonsFlag::eRightFlag) { + if (aButtons & MouseButtonsFlag::eSecondaryFlag) { ADD_SEPARATOR_IF_NECESSARY(names); names += "RightButton"; } @@ -6438,13 +6438,13 @@ nsresult TSFTextStore::OnMouseButtonEventInternal( aIMENotification.mMouseButtonEventData.mEventMessage == eMouseUp; if (!isMouseUp) { switch (aIMENotification.mMouseButtonEventData.mButton) { - case MouseButton::eLeft: + case MouseButton::ePrimary: buttonStatus = MK_LBUTTON; break; case MouseButton::eMiddle: buttonStatus = MK_MBUTTON; break; - case MouseButton::eRight: + case MouseButton::eSecondary: buttonStatus = MK_RBUTTON; break; } diff --git a/widget/windows/WinHeaderOnlyUtils.h b/widget/windows/WinHeaderOnlyUtils.h index 13d69ba54a..8226e94626 100644 --- a/widget/windows/WinHeaderOnlyUtils.h +++ b/widget/windows/WinHeaderOnlyUtils.h @@ -11,15 +11,23 @@ #include #include +#include + #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/DynamicallyLinkedFunctionPtr.h" #include "mozilla/Maybe.h" -#include "mozilla/Result.h" +#include "mozilla/ResultVariant.h" +#include "mozilla/Tuple.h" #include "mozilla/UniquePtr.h" #include "mozilla/WindowsVersion.h" #include "nsWindowsHelpers.h" +#if defined(MOZILLA_INTERNAL_API) +# include "nsIFile.h" +# include "nsString.h" +#endif // defined(MOZILLA_INTERNAL_API) + /** * This header is intended for self-contained, header-only, utility code for * Win32. It may be used outside of xul.dll, in places such as firefox.exe or @@ -401,6 +409,128 @@ class MOZ_RAII AutoVirtualProtect final { WindowsError mError; }; +inline UniquePtr GetFullModulePath(HMODULE aModule) { + DWORD bufLen = MAX_PATH; + mozilla::UniquePtr buf; + DWORD retLen; + + while (true) { + buf = mozilla::MakeUnique(bufLen); + retLen = ::GetModuleFileNameW(aModule, buf.get(), bufLen); + if (!retLen) { + return nullptr; + } + + if (retLen == bufLen && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + bufLen *= 2; + continue; + } + + break; + } + + // Upon success, retLen *excludes* the null character + ++retLen; + + // Since we're likely to have a bunch of unused space in buf, let's reallocate + // a string to the actual size of the file name. + auto result = mozilla::MakeUnique(retLen); + if (wcscpy_s(result.get(), retLen, buf.get())) { + return nullptr; + } + + return result; +} + +inline UniquePtr GetFullBinaryPath() { + return GetFullModulePath(nullptr); +} + +class ModuleVersion final { + public: + explicit ModuleVersion(const VS_FIXEDFILEINFO& aFixedInfo) + : mVersion((static_cast(aFixedInfo.dwFileVersionMS) << 32) | + static_cast(aFixedInfo.dwFileVersionLS)) {} + + explicit ModuleVersion(const uint64_t aVersion) : mVersion(aVersion) {} + + ModuleVersion(const ModuleVersion& aOther) : mVersion(aOther.mVersion) {} + + uint64_t AsInteger() const { return mVersion; } + + operator uint64_t() const { return AsInteger(); } + + Tuple AsTuple() const { + uint16_t major = static_cast((mVersion >> 48) & 0xFFFFU); + uint16_t minor = static_cast((mVersion >> 32) & 0xFFFFU); + uint16_t patch = static_cast((mVersion >> 16) & 0xFFFFU); + uint16_t build = static_cast(mVersion & 0xFFFFU); + + return MakeTuple(major, minor, patch, build); + } + + explicit operator bool() const { return !!mVersion; } + + bool operator<(const ModuleVersion& aOther) const { + return mVersion < aOther.mVersion; + } + + bool operator<(const uint64_t& aOther) const { return mVersion < aOther; } + + private: + const uint64_t mVersion; +}; + +inline WindowsErrorResult GetModuleVersion( + const wchar_t* aModuleFullPath) { + DWORD verInfoLen = ::GetFileVersionInfoSizeW(aModuleFullPath, nullptr); + if (!verInfoLen) { + return Err(WindowsError::FromLastError()); + } + + auto verInfoBuf = MakeUnique(verInfoLen); + if (!::GetFileVersionInfoW(aModuleFullPath, 0, verInfoLen, + verInfoBuf.get())) { + return Err(WindowsError::FromLastError()); + } + + UINT fixedInfoLen; + VS_FIXEDFILEINFO* fixedInfo = nullptr; + if (!::VerQueryValueW(verInfoBuf.get(), L"\\", + reinterpret_cast(&fixedInfo), &fixedInfoLen)) { + // VerQueryValue may fail if the resource does not exist. This is not an + // error; we'll return 0 in this case. + return ModuleVersion(0ULL); + } + + return ModuleVersion(*fixedInfo); +} + +inline WindowsErrorResult GetModuleVersion(HMODULE aModule) { + UniquePtr fullPath(GetFullModulePath(aModule)); + if (!fullPath) { + return Err(WindowsError::CreateGeneric()); + } + + return GetModuleVersion(fullPath.get()); +} + +#if defined(MOZILLA_INTERNAL_API) +inline WindowsErrorResult GetModuleVersion(nsIFile* aFile) { + if (!aFile) { + return Err(WindowsError::FromHResult(E_INVALIDARG)); + } + + nsAutoString fullPath; + nsresult rv = aFile->GetPath(fullPath); + if (NS_FAILED(rv)) { + return Err(WindowsError::CreateGeneric()); + } + + return GetModuleVersion(fullPath.get()); +} +#endif // defined(MOZILLA_INTERNAL_API) + struct CoTaskMemFreeDeleter { void operator()(void* aPtr) { ::CoTaskMemFree(aPtr); } }; diff --git a/widget/windows/WindowsUIUtils.cpp b/widget/windows/WindowsUIUtils.cpp index 5aa3475d6a..7009c32e3c 100644 --- a/widget/windows/WindowsUIUtils.cpp +++ b/widget/windows/WindowsUIUtils.cpp @@ -13,6 +13,7 @@ #include "nsIObserverService.h" #include "nsIAppShellService.h" #include "nsAppShellCID.h" +#include "mozilla/ResultVariant.h" #include "mozilla/Services.h" #include "mozilla/WidgetUtils.h" #include "mozilla/WindowsVersion.h" diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 6c5ea53d4a..e587809a62 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -123,6 +123,7 @@ #include "WinTaskbar.h" #include "WidgetUtils.h" #include "nsIWidgetListener.h" +#include "mozilla/dom/Document.h" #include "mozilla/dom/MouseEventBinding.h" #include "mozilla/dom/Touch.h" #include "mozilla/gfx/2D.h" @@ -139,6 +140,7 @@ #include "InProcessWinCompositorWidget.h" #include "InputDeviceUtils.h" #include "ScreenHelperWin.h" +#include "mozilla/StaticPrefs_dom.h" #include "mozilla/StaticPrefs_layout.h" #include "nsIGfxInfo.h" @@ -1930,7 +1932,7 @@ nsresult nsWindow::BeginResizeDrag(WidgetGUIEvent* aEvent, int32_t aHorizontal, return NS_ERROR_INVALID_ARG; } - if (aEvent->AsMouseEvent()->mButton != MouseButton::eLeft) { + if (aEvent->AsMouseEvent()->mButton != MouseButton::ePrimary) { // you can only begin a resize drag with the left mouse button return NS_ERROR_INVALID_ARG; } @@ -4286,13 +4288,13 @@ bool nsWindow::DispatchMouseEvent(EventMessage aEventMessage, WPARAM wParam, BYTE eventButton; switch (aButton) { - case MouseButton::eLeft: + case MouseButton::ePrimary: eventButton = VK_LBUTTON; break; case MouseButton::eMiddle: eventButton = VK_MBUTTON; break; - case MouseButton::eRight: + case MouseButton::eSecondary: eventButton = VK_RBUTTON; break; default: @@ -4353,13 +4355,13 @@ bool nsWindow::DispatchMouseEvent(EventMessage aEventMessage, WPARAM wParam, switch (aEventMessage) { case eMouseDown: switch (aButton) { - case MouseButton::eLeft: + case MouseButton::ePrimary: pluginEvent.event = WM_LBUTTONDOWN; break; case MouseButton::eMiddle: pluginEvent.event = WM_MBUTTONDOWN; break; - case MouseButton::eRight: + case MouseButton::eSecondary: pluginEvent.event = WM_RBUTTONDOWN; break; default: @@ -4368,13 +4370,13 @@ bool nsWindow::DispatchMouseEvent(EventMessage aEventMessage, WPARAM wParam, break; case eMouseUp: switch (aButton) { - case MouseButton::eLeft: + case MouseButton::ePrimary: pluginEvent.event = WM_LBUTTONUP; break; case MouseButton::eMiddle: pluginEvent.event = WM_MBUTTONUP; break; - case MouseButton::eRight: + case MouseButton::eSecondary: pluginEvent.event = WM_RBUTTONUP; break; default: @@ -4383,13 +4385,13 @@ bool nsWindow::DispatchMouseEvent(EventMessage aEventMessage, WPARAM wParam, break; case eMouseDoubleClick: switch (aButton) { - case MouseButton::eLeft: + case MouseButton::ePrimary: pluginEvent.event = WM_LBUTTONDBLCLK; break; case MouseButton::eMiddle: pluginEvent.event = WM_MBUTTONDBLCLK; break; - case MouseButton::eRight: + case MouseButton::eSecondary: pluginEvent.event = WM_RBUTTONDBLCLK; break; default: @@ -4422,16 +4424,16 @@ bool nsWindow::DispatchMouseEvent(EventMessage aEventMessage, WPARAM wParam, if (sCurrentWindow == nullptr || sCurrentWindow != this) { if ((nullptr != sCurrentWindow) && (!sCurrentWindow->mInDtor)) { LPARAM pos = sCurrentWindow->lParamToClient(lParamToScreen(lParam)); - sCurrentWindow->DispatchMouseEvent(eMouseExitFromWidget, wParam, - pos, false, MouseButton::eLeft, - aInputSource, aPointerInfo); + sCurrentWindow->DispatchMouseEvent( + eMouseExitFromWidget, wParam, pos, false, MouseButton::ePrimary, + aInputSource, aPointerInfo); } sCurrentWindow = this; if (!mInDtor) { LPARAM pos = sCurrentWindow->lParamToClient(lParamToScreen(lParam)); - sCurrentWindow->DispatchMouseEvent(eMouseEnterIntoWidget, wParam, - pos, false, MouseButton::eLeft, - aInputSource, aPointerInfo); + sCurrentWindow->DispatchMouseEvent( + eMouseEnterIntoWidget, wParam, pos, false, + MouseButton::ePrimary, aInputSource, aPointerInfo); } } } @@ -5357,7 +5359,7 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, result = DispatchMouseEvent(eMouseMove, wParam, lParam, false, - MouseButton::eLeft, MOUSE_INPUT_SOURCE(), + MouseButton::ePrimary, MOUSE_INPUT_SOURCE(), mPointerEvents.GetCachedPointerInfo(msg, wParam)); if (userMovedMouse) { DispatchPendingEvents(); @@ -5374,7 +5376,7 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, case WM_LBUTTONDOWN: { result = DispatchMouseEvent(eMouseDown, wParam, lParam, false, - MouseButton::eLeft, MOUSE_INPUT_SOURCE(), + MouseButton::ePrimary, MOUSE_INPUT_SOURCE(), mPointerEvents.GetCachedPointerInfo(msg, wParam)); DispatchPendingEvents(); } break; @@ -5382,7 +5384,7 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, case WM_LBUTTONUP: { result = DispatchMouseEvent(eMouseUp, wParam, lParam, false, - MouseButton::eLeft, MOUSE_INPUT_SOURCE(), + MouseButton::ePrimary, MOUSE_INPUT_SOURCE(), mPointerEvents.GetCachedPointerInfo(msg, wParam)); DispatchPendingEvents(); } break; @@ -5408,7 +5410,7 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, // WM_MOUSELEAVE. LPARAM pos = lParamToClient(::GetMessagePos()); DispatchMouseEvent(eMouseExitFromWidget, mouseState, pos, false, - MouseButton::eLeft, MOUSE_INPUT_SOURCE()); + MouseButton::ePrimary, MOUSE_INPUT_SOURCE()); } break; case MOZ_WM_PEN_LEAVES_HOVER_OF_DIGITIZER: { @@ -5419,7 +5421,7 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, WinPointerInfo pointerInfo; pointerInfo.pointerId = pointerId; DispatchMouseEvent(eMouseExitFromWidget, wParam, pos, false, - MouseButton::eLeft, + MouseButton::ePrimary, MouseEvent_Binding::MOZ_SOURCE_PEN, &pointerInfo); InkCollector::sInkCollector->ClearTarget(); InkCollector::sInkCollector->ClearPointerId(); @@ -5450,7 +5452,7 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, result = DispatchMouseEvent( eContextMenu, wParam, pos, contextMenukey, - contextMenukey ? MouseButton::eLeft : MouseButton::eRight, + contextMenukey ? MouseButton::ePrimary : MouseButton::eSecondary, MOUSE_INPUT_SOURCE()); if (lParam != -1 && !result && mCustomNonClient && mDraggableRegion.Contains(GET_X_LPARAM(pos), GET_Y_LPARAM(pos))) { @@ -5473,7 +5475,7 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, case WM_LBUTTONDBLCLK: result = DispatchMouseEvent(eMouseDoubleClick, wParam, lParam, false, - MouseButton::eLeft, MOUSE_INPUT_SOURCE()); + MouseButton::ePrimary, MOUSE_INPUT_SOURCE()); DispatchPendingEvents(); break; @@ -5517,7 +5519,7 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, case WM_RBUTTONDOWN: result = DispatchMouseEvent(eMouseDown, wParam, lParam, false, - MouseButton::eRight, MOUSE_INPUT_SOURCE(), + MouseButton::eSecondary, MOUSE_INPUT_SOURCE(), mPointerEvents.GetCachedPointerInfo(msg, wParam)); DispatchPendingEvents(); break; @@ -5525,33 +5527,36 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, case WM_RBUTTONUP: result = DispatchMouseEvent(eMouseUp, wParam, lParam, false, - MouseButton::eRight, MOUSE_INPUT_SOURCE(), + MouseButton::eSecondary, MOUSE_INPUT_SOURCE(), mPointerEvents.GetCachedPointerInfo(msg, wParam)); DispatchPendingEvents(); break; case WM_RBUTTONDBLCLK: - result = DispatchMouseEvent(eMouseDoubleClick, wParam, lParam, false, - MouseButton::eRight, MOUSE_INPUT_SOURCE()); + result = + DispatchMouseEvent(eMouseDoubleClick, wParam, lParam, false, + MouseButton::eSecondary, MOUSE_INPUT_SOURCE()); DispatchPendingEvents(); break; case WM_NCRBUTTONDOWN: - result = DispatchMouseEvent(eMouseDown, 0, lParamToClient(lParam), false, - MouseButton::eRight, MOUSE_INPUT_SOURCE()); + result = + DispatchMouseEvent(eMouseDown, 0, lParamToClient(lParam), false, + MouseButton::eSecondary, MOUSE_INPUT_SOURCE()); DispatchPendingEvents(); break; case WM_NCRBUTTONUP: - result = DispatchMouseEvent(eMouseUp, 0, lParamToClient(lParam), false, - MouseButton::eRight, MOUSE_INPUT_SOURCE()); + result = + DispatchMouseEvent(eMouseUp, 0, lParamToClient(lParam), false, + MouseButton::eSecondary, MOUSE_INPUT_SOURCE()); DispatchPendingEvents(); break; case WM_NCRBUTTONDBLCLK: - result = - DispatchMouseEvent(eMouseDoubleClick, 0, lParamToClient(lParam), - false, MouseButton::eRight, MOUSE_INPUT_SOURCE()); + result = DispatchMouseEvent(eMouseDoubleClick, 0, lParamToClient(lParam), + false, MouseButton::eSecondary, + MOUSE_INPUT_SOURCE()); DispatchPendingEvents(); break; @@ -5682,9 +5687,9 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, case WM_NCLBUTTONDBLCLK: DispatchMouseEvent(eMouseDoubleClick, 0, lParamToClient(lParam), false, - MouseButton::eLeft, MOUSE_INPUT_SOURCE()); + MouseButton::ePrimary, MOUSE_INPUT_SOURCE()); result = DispatchMouseEvent(eMouseUp, 0, lParamToClient(lParam), false, - MouseButton::eLeft, MOUSE_INPUT_SOURCE()); + MouseButton::ePrimary, MOUSE_INPUT_SOURCE()); DispatchPendingEvents(); break; @@ -8149,11 +8154,11 @@ bool nsWindow::OnPointerEvents(UINT msg, WPARAM aWParam, LPARAM aLParam) { // We don't support chorded buttons for pen. Keep the button at // WM_POINTERDOWN. - static mozilla::MouseButton sLastPenDownButton = MouseButton::eLeft; + static mozilla::MouseButton sLastPenDownButton = MouseButton::ePrimary; static bool sPointerDown = false; EventMessage message; - mozilla::MouseButton button = MouseButton::eLeft; + mozilla::MouseButton button = MouseButton::ePrimary; switch (msg) { case WM_POINTERDOWN: { LayoutDeviceIntPoint eventPoint(GET_X_LPARAM(aLParam), @@ -8161,15 +8166,15 @@ bool nsWindow::OnPointerEvents(UINT msg, WPARAM aWParam, LPARAM aLParam) { sLastPointerDownPoint.x = eventPoint.x; sLastPointerDownPoint.y = eventPoint.y; message = eMouseDown; - button = IS_POINTER_SECONDBUTTON_WPARAM(aWParam) ? MouseButton::eRight - : MouseButton::eLeft; + button = IS_POINTER_SECONDBUTTON_WPARAM(aWParam) ? MouseButton::eSecondary + : MouseButton::ePrimary; sLastPenDownButton = button; sPointerDown = true; } break; case WM_POINTERUP: message = eMouseUp; MOZ_ASSERT(sPointerDown, "receive WM_POINTERUP w/o WM_POINTERDOWN"); - button = sPointerDown ? sLastPenDownButton : MouseButton::eLeft; + button = sPointerDown ? sLastPenDownButton : MouseButton::ePrimary; sPointerDown = false; break; case WM_POINTERUPDATE: @@ -8208,9 +8213,9 @@ bool nsWindow::OnPointerEvents(UINT msg, WPARAM aWParam, LPARAM aLParam) { // Windows defines the pen pressure is normalized to a range between 0 and // 1024. Convert it to float. float pressure = penInfo.pressure ? (float)penInfo.pressure / 1024 : 0; - int16_t buttons = sPointerDown ? button == MouseButton::eLeft - ? MouseButtonsFlag::eLeftFlag - : MouseButtonsFlag::eRightFlag + int16_t buttons = sPointerDown ? button == MouseButton::ePrimary + ? MouseButtonsFlag::ePrimaryFlag + : MouseButtonsFlag::eSecondaryFlag : MouseButtonsFlag::eNoButtons; WinPointerInfo pointerInfo(pointerId, penInfo.tiltX, penInfo.tiltY, pressure, buttons); diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index 1a54365e20..920f79033f 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -238,7 +238,7 @@ class nsWindow final : public nsWindowBase { virtual bool DispatchMouseEvent( mozilla::EventMessage aEventMessage, WPARAM wParam, LPARAM lParam, bool aIsContextMenuKey = false, - int16_t aButton = mozilla::MouseButton::eLeft, + int16_t aButton = mozilla::MouseButton::ePrimary, uint16_t aInputSource = mozilla::dom::MouseEvent_Binding::MOZ_SOURCE_MOUSE, WinPointerInfo* aPointerInfo = nullptr); diff --git a/xpcom/base/ClearOnShutdown.cpp b/xpcom/base/ClearOnShutdown.cpp index df4a198521..8f767942a6 100644 --- a/xpcom/base/ClearOnShutdown.cpp +++ b/xpcom/base/ClearOnShutdown.cpp @@ -12,6 +12,21 @@ Array, sShutdownObservers; ShutdownPhase sCurrentShutdownPhase = ShutdownPhase::NotInShutdown; +void InsertIntoShutdownList(ShutdownObserver* aObserver, ShutdownPhase aPhase) { + // Adding a ClearOnShutdown for a "past" phase is an error. + if (PastShutdownPhase(aPhase)) { + MOZ_ASSERT(false, "ClearOnShutdown for phase that already was cleared"); + aObserver->Shutdown(); + delete aObserver; + return; + } + + if (!(sShutdownObservers[static_cast(aPhase)])) { + sShutdownObservers[static_cast(aPhase)] = new ShutdownList(); + } + sShutdownObservers[static_cast(aPhase)]->insertBack(aObserver); +} + } // namespace ClearOnShutdown_Internal // Called when XPCOM is shutting down, after all shutdown notifications have @@ -21,8 +36,11 @@ void KillClearOnShutdown(ShutdownPhase aPhase) { MOZ_ASSERT(NS_IsMainThread()); // Shutdown only goes one direction... - MOZ_ASSERT(static_cast(sCurrentShutdownPhase) < - static_cast(aPhase)); + MOZ_ASSERT(!PastShutdownPhase(aPhase)); + + // Set the phase before notifying observers to make sure that they can't run + // any code which isn't allowed to run after the start of this phase. + sCurrentShutdownPhase = aPhase; // It's impossible to add an entry for a "past" phase; this is blocked in // ClearOnShutdown, but clear them out anyways in case there are phases diff --git a/xpcom/base/ClearOnShutdown.h b/xpcom/base/ClearOnShutdown.h index c499e2cca9..d2119a06a7 100644 --- a/xpcom/base/ClearOnShutdown.h +++ b/xpcom/base/ClearOnShutdown.h @@ -10,8 +10,10 @@ #include "mozilla/Array.h" #include "MainThreadUtils.h" +#include + /* - * This header exports one public method in the mozilla namespace: + * This header exports two public methods in the mozilla namespace: * * template * void ClearOnShutdown(SmartPtr *aPtr, aPhase=ShutdownPhase::ShutdownFinal) @@ -33,9 +35,18 @@ * know will live until the program shuts down. In practice, these are likely * global variables, which should be Static{Ref,Auto}Ptr. * - * ClearOnShutdown is currently main-thread only because we don't want to - * accidentally free an object from a different thread than the one it was - * created on. + * template + * void RunOnShutdown(CallableT&& aCallable, + * aPhase = ShutdownPhase::ShutdownFinal) + * + * This function takes a callable and executes it upon shutdown at the start of + * the specified phase. If the phase has already occurred when RunOnShutdown() + * is called, it will cause a MOZ_ASSERT. In case a phase is not explicitly + * cleared, we will clear it on the next phase that occurs. + * + * ClearOnShutdown and RunOnShutdown are both currently main-thread only because + * we don't want to accidentally free an object from a different thread than the + * one it was created on. */ namespace mozilla { @@ -77,6 +88,27 @@ class PointerClearer : public ShutdownObserver { SmartPtr* mPtr; }; +class FunctionInvoker : public ShutdownObserver { + public: + template + explicit FunctionInvoker(CallableT&& aCallable) + : mCallable(std::forward(aCallable)) {} + + virtual void Shutdown() override { + if (!mCallable) { + return; + } + + mCallable(); + } + + private: + std::function mCallable; +}; + +void InsertIntoShutdownList(ShutdownObserver* aShutdownObserver, + ShutdownPhase aPhase); + typedef LinkedList ShutdownList; extern Array, static_cast(ShutdownPhase::ShutdownPhase_Length)> @@ -93,19 +125,26 @@ inline void ClearOnShutdown( MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aPhase != ShutdownPhase::ShutdownPhase_Length); - // Adding a ClearOnShutdown for a "past" phase is an error. - if (!(static_cast(sCurrentShutdownPhase) < - static_cast(aPhase))) { - MOZ_ASSERT(false, "ClearOnShutdown for phase that already was cleared"); - *aPtr = nullptr; - return; - } + InsertIntoShutdownList(new PointerClearer(aPtr), aPhase); +} - if (!(sShutdownObservers[static_cast(aPhase)])) { - sShutdownObservers[static_cast(aPhase)] = new ShutdownList(); - } - sShutdownObservers[static_cast(aPhase)]->insertBack( - new PointerClearer(aPtr)); +template +inline void RunOnShutdown(CallableT&& aCallable, + ShutdownPhase aPhase = ShutdownPhase::ShutdownFinal) { + using namespace ClearOnShutdown_Internal; + + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aPhase != ShutdownPhase::ShutdownPhase_Length); + + InsertIntoShutdownList( + new FunctionInvoker(std::forward(aCallable)), aPhase); +} + +inline bool PastShutdownPhase(ShutdownPhase aPhase) { + MOZ_ASSERT(NS_IsMainThread()); + + return size_t(ClearOnShutdown_Internal::sCurrentShutdownPhase) >= + size_t(aPhase); } // Called when XPCOM is shutting down, after all shutdown notifications have diff --git a/xpcom/base/CycleCollectedJSContext.cpp b/xpcom/base/CycleCollectedJSContext.cpp index 1ed8a78766..dfa0d88bda 100644 --- a/xpcom/base/CycleCollectedJSContext.cpp +++ b/xpcom/base/CycleCollectedJSContext.cpp @@ -352,8 +352,8 @@ void CycleCollectedJSContext::PromiseRejectionTrackerCallback( init.mReason = JS::GetPromiseResult(aPromise); RefPtr event = - PromiseRejectionEvent::Constructor( - owner, NS_LITERAL_STRING("rejectionhandled"), init); + PromiseRejectionEvent::Constructor(owner, u"rejectionhandled"_ns, + init); RefPtr asyncDispatcher = new AsyncEventDispatcher(owner, event); @@ -499,8 +499,6 @@ void CycleCollectedJSContext::IsIdleGCTaskNeeded() const { } return NS_OK; } - - nsresult Cancel() override { return NS_OK; } }; if (Runtime()->IsIdleGCTaskNeeded()) { @@ -701,8 +699,8 @@ NS_IMETHODIMP CycleCollectedJSContext::NotifyUnhandledRejections::Run() { init.mCancelable = true; RefPtr event = - PromiseRejectionEvent::Constructor( - target, NS_LITERAL_STRING("unhandledrejection"), init); + PromiseRejectionEvent::Constructor(target, u"unhandledrejection"_ns, + init); // We don't use the result of dispatching event here to check whether to // report the Promise to console. target->DispatchEvent(*event); @@ -736,15 +734,16 @@ nsresult CycleCollectedJSContext::NotifyUnhandledRejections::Cancel() { return NS_OK; } -class FinalizationRegistryCleanup::CleanupRunnable : public CancelableRunnable { +class FinalizationRegistryCleanup::CleanupRunnable + : public DiscardableRunnable { public: explicit CleanupRunnable(FinalizationRegistryCleanup* aCleanupWork) - : CancelableRunnable("CleanupRunnable"), mCleanupWork(aCleanupWork) {} + : DiscardableRunnable("CleanupRunnable"), mCleanupWork(aCleanupWork) {} // MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See // bug 1535398. MOZ_CAN_RUN_SCRIPT_BOUNDARY - NS_IMETHODIMP Run() { + NS_IMETHOD Run() override { mCleanupWork->DoCleanup(); return NS_OK; } diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index f8c3e5cdaa..8ae687d62f 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -120,7 +120,7 @@ struct DeferredFinalizeFunctionHolder { void* data; }; -class IncrementalFinalizeRunnable : public CancelableRunnable { +class IncrementalFinalizeRunnable : public DiscardableRunnable { typedef AutoTArray DeferredFinalizeArray; typedef CycleCollectedJSRuntime::DeferredFinalizerTable DeferredFinalizerTable; @@ -699,6 +699,8 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSContext* aCx) #ifdef MOZ_JS_DEV_ERROR_INTERCEPTOR JS_SetErrorInterceptorCallback(mJSRuntime, &mErrorInterceptor); #endif // MOZ_JS_DEV_ERROR_INTERCEPTOR + + JS_SetDestroyZoneCallback(aCx, OnZoneDestroyed); } #ifdef NS_BUILD_REFCNT_LOGGING @@ -733,11 +735,14 @@ void CycleCollectedJSRuntime::Shutdown(JSContext* cx) { #ifdef DEBUG mShutdownCalled = true; #endif + + JS_SetDestroyZoneCallback(cx, nullptr); } CycleCollectedJSRuntime::~CycleCollectedJSRuntime() { MOZ_COUNT_DTOR(CycleCollectedJSRuntime); MOZ_ASSERT(!mDeferredFinalizerTable.Count()); + MOZ_ASSERT(!mFinalizeRunnable); MOZ_ASSERT(mShutdownCalled); } @@ -1506,7 +1511,7 @@ void CycleCollectedJSRuntime::DumpJSHeap(FILE* aFile) { IncrementalFinalizeRunnable::IncrementalFinalizeRunnable( CycleCollectedJSRuntime* aRt, DeferredFinalizerTable& aFinalizers) - : CancelableRunnable("IncrementalFinalizeRunnable"), + : DiscardableRunnable("IncrementalFinalizeRunnable"), mRuntime(aRt), mFinalizeFunctionToRun(0), mReleasing(false) { @@ -1521,10 +1526,12 @@ IncrementalFinalizeRunnable::IncrementalFinalizeRunnable( iter.Remove(); } + MOZ_ASSERT(mDeferredFinalizeFunctions.Length()); } IncrementalFinalizeRunnable::~IncrementalFinalizeRunnable() { - MOZ_ASSERT(this != mRuntime->mFinalizeRunnable); + MOZ_ASSERT(!mDeferredFinalizeFunctions.Length()); + MOZ_ASSERT(!mRuntime); } void IncrementalFinalizeRunnable::ReleaseNow(bool aLimited) { @@ -1573,8 +1580,10 @@ void IncrementalFinalizeRunnable::ReleaseNow(bool aLimited) { if (mFinalizeFunctionToRun == mDeferredFinalizeFunctions.Length()) { MOZ_ASSERT(mRuntime->mFinalizeRunnable == this); mDeferredFinalizeFunctions.Clear(); + CycleCollectedJSRuntime* runtime = mRuntime; + mRuntime = nullptr; // NB: This may delete this! - mRuntime->mFinalizeRunnable = nullptr; + runtime->mFinalizeRunnable = nullptr; } } @@ -1582,12 +1591,13 @@ NS_IMETHODIMP IncrementalFinalizeRunnable::Run() { AUTO_PROFILER_LABEL("IncrementalFinalizeRunnable::Run", GCCC); - if (mRuntime->mFinalizeRunnable != this) { + if (!mDeferredFinalizeFunctions.Length()) { /* These items were already processed synchronously in JSGC_END. */ - MOZ_ASSERT(!mDeferredFinalizeFunctions.Length()); + MOZ_ASSERT(!mRuntime); return NS_OK; } + MOZ_ASSERT(mRuntime->mFinalizeRunnable == this); TimeStamp start = TimeStamp::Now(); ReleaseNow(true); @@ -1596,6 +1606,8 @@ IncrementalFinalizeRunnable::Run() { if (NS_FAILED(rv)) { ReleaseNow(false); } + } else { + MOZ_ASSERT(!mRuntime); } uint32_t duration = (uint32_t)((TimeStamp::Now() - start).ToMilliseconds()); @@ -1735,12 +1747,21 @@ void CycleCollectedJSRuntime::PrepareWaitingZonesForGC() { JS::PrepareForFullGC(cx); } else { for (auto iter = mZonesWaitingForGC.Iter(); !iter.Done(); iter.Next()) { - JS::PrepareZoneForGC(iter.Get()->GetKey()); + JS::PrepareZoneForGC(cx, iter.Get()->GetKey()); } mZonesWaitingForGC.Clear(); } } +/* static */ +void CycleCollectedJSRuntime::OnZoneDestroyed(JSFreeOp* aFop, JS::Zone* aZone) { + // Remove the zone from the set of zones waiting for GC, if present. This can + // happen if a zone is added to the set during an incremental GC in which it + // is later destroyed. + CycleCollectedJSRuntime* runtime = Get(); + runtime->mZonesWaitingForGC.RemoveEntry(aZone); +} + void CycleCollectedJSRuntime::EnvironmentPreparer::invoke( JS::HandleObject global, js::ScriptEnvironmentPreparer::Closure& closure) { MOZ_ASSERT(JS_IsGlobalObject(global)); diff --git a/xpcom/base/CycleCollectedJSRuntime.h b/xpcom/base/CycleCollectedJSRuntime.h index 17874abc36..3d6e2402ee 100644 --- a/xpcom/base/CycleCollectedJSRuntime.h +++ b/xpcom/base/CycleCollectedJSRuntime.h @@ -334,6 +334,8 @@ class CycleCollectedJSRuntime { mZonesWaitingForGC.PutEntry(aZone); } + static void OnZoneDestroyed(JSFreeOp* aFop, JS::Zone* aZone); + // Prepare any zones for GC that have been passed to AddZoneWaitingForGC() // since the last GC or since the last call to PrepareWaitingZonesForGC(), // whichever was most recent. If there were no such zones, prepare for a diff --git a/xpcom/base/LogCommandLineHandler.cpp b/xpcom/base/LogCommandLineHandler.cpp index 5518b15a5c..bf9ed2400a 100644 --- a/xpcom/base/LogCommandLineHandler.cpp +++ b/xpcom/base/LogCommandLineHandler.cpp @@ -17,8 +17,7 @@ void LoggingHandleCommandLineArgs( // Used for the `-MOZ_LOG ` form of argument. nsAutoCString env; - auto const names = {NS_LITERAL_CSTRING("MOZ_LOG"), - NS_LITERAL_CSTRING("MOZ_LOG_FILE")}; + auto const names = {"MOZ_LOG"_ns, "MOZ_LOG_FILE"_ns}; for (int arg = 1; arg < argc; ++arg) { Tokenizer p(argv[arg]); diff --git a/xpcom/base/moz.build b/xpcom/base/moz.build index e47f67497b..3bf381313c 100644 --- a/xpcom/base/moz.build +++ b/xpcom/base/moz.build @@ -84,7 +84,6 @@ EXPORTS += [ 'nsQueryObject.h', 'nsSystemInfo.h', 'nsTraceRefcnt.h', - 'nsTWeakRef.h', 'nsVersionComparator.h', 'nsWeakReference.h', ] diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index c50e18919f..8c0ad1b26b 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -1329,10 +1329,10 @@ struct CCGraphDescriber : public LinkedListElement { Type mType; }; -class LogStringMessageAsync : public CancelableRunnable { +class LogStringMessageAsync : public DiscardableRunnable { public: explicit LogStringMessageAsync(const nsAString& aMsg) - : mozilla::CancelableRunnable("LogStringMessageAsync"), mMsg(aMsg) {} + : mozilla::DiscardableRunnable("LogStringMessageAsync"), mMsg(aMsg) {} NS_IMETHOD Run() override { nsCOMPtr cs = @@ -1408,7 +1408,7 @@ class nsCycleCollectorLogSinkToFile final : public nsICycleCollectorLogSink { if (!mGCLog.mStream) { return NS_ERROR_UNEXPECTED; } - CloseLog(&mGCLog, NS_LITERAL_STRING("Garbage")); + CloseLog(&mGCLog, u"Garbage"_ns); return NS_OK; } @@ -1416,7 +1416,7 @@ class nsCycleCollectorLogSinkToFile final : public nsICycleCollectorLogSink { if (!mCCLog.mStream) { return NS_ERROR_UNEXPECTED; } - CloseLog(&mCCLog, NS_LITERAL_STRING("Cycle")); + CloseLog(&mCCLog, u"Cycle"_ns); return NS_OK; } @@ -1466,8 +1466,8 @@ class nsCycleCollectorLogSinkToFile final : public nsICycleCollectorLogSink { // aFilename under a memory-reporting-specific folder // (/data/local/tmp/memory-reports). Otherwise, it will open a // file named aFilename under "NS_OS_TEMP_DIR". - nsresult rv = nsDumpUtils::OpenTempFile( - filename, &logFile, NS_LITERAL_CSTRING("memory-reports")); + nsresult rv = + nsDumpUtils::OpenTempFile(filename, &logFile, "memory-reports"_ns); if (NS_FAILED(rv)) { NS_IF_RELEASE(logFile); return nullptr; @@ -1528,8 +1528,8 @@ class nsCycleCollectorLogSinkToFile final : public nsICycleCollectorLogSink { // Log to the error console. nsAutoString logPath; logFileFinalDestination->GetPath(logPath); - nsAutoString msg = aCollectorKind + - NS_LITERAL_STRING(" Collector log dumped to ") + logPath; + nsAutoString msg = + aCollectorKind + u" Collector log dumped to "_ns + logPath; // We don't want any JS to run between ScanRoots and CollectWhite calls, // and since ScanRoots calls this method, better to log the message @@ -2038,7 +2038,8 @@ void CCGraphBuilder::DoneAddingRoots() { MOZ_NEVER_INLINE bool CCGraphBuilder::BuildGraph(SliceBudget& aBudget) { const intptr_t kNumNodesBetweenTimeChecks = 1000; - const intptr_t kStep = SliceBudget::CounterReset / kNumNodesBetweenTimeChecks; + const intptr_t kStep = + SliceBudget::StepsPerTimeCheck / kNumNodesBetweenTimeChecks; MOZ_ASSERT(mCurrNode); @@ -3430,7 +3431,7 @@ bool nsCycleCollector::Collect(ccType aCCType, SliceBudget& aBudget, } if (continueSlice) { // Force SliceBudget::isOverBudget to check the time. - aBudget.step(SliceBudget::CounterReset); + aBudget.step(SliceBudget::StepsPerTimeCheck); continueSlice = !aBudget.isOverBudget(); } } while (continueSlice); diff --git a/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp b/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp index 3fdc9bc5e6..1ff9641233 100644 --- a/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp +++ b/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp @@ -30,7 +30,7 @@ void nsCycleCollectionParticipant::NoteJSChild(JS::GCCellPtr aGCThing, void TraceCallbackFunc::Trace(JS::Heap* aPtr, const char* aName, void* aClosure) const { if (aPtr->unbarrieredGet().isGCThing()) { - mCallback(JS::GCCellPtr(aPtr->unbarrieredGet()), aName, aClosure); + mCallback(aPtr->unbarrieredGet().toGCCellPtr(), aName, aClosure); } } diff --git a/xpcom/base/nsDumpUtils.cpp b/xpcom/base/nsDumpUtils.cpp index da126a9e83..63eb942bb9 100644 --- a/xpcom/base/nsDumpUtils.cpp +++ b/xpcom/base/nsDumpUtils.cpp @@ -289,7 +289,7 @@ int FifoWatcher::OpenFd() { } } - rv = file->AppendNative(NS_LITERAL_CSTRING("debug_info_trigger")); + rv = file->AppendNative("debug_info_trigger"_ns); if (NS_WARN_IF(NS_FAILED(rv))) { return -1; } diff --git a/xpcom/base/nsIMemoryReporter.idl b/xpcom/base/nsIMemoryReporter.idl index 5df883e448..90ca6a0cbc 100644 --- a/xpcom/base/nsIMemoryReporter.idl +++ b/xpcom/base/nsIMemoryReporter.idl @@ -609,8 +609,8 @@ nsresult RegisterNonJSSizeOfTab(NonJSSizeOfTabFn aSizeOfTabFn); // variables. The (void) is there because we should always ignore the return // value of the callback, because callback failures aren't fatal. #define MOZ_COLLECT_REPORT(path, kind, units, amount, description) \ - (void)aHandleReport->Callback(EmptyCString(), NS_LITERAL_CSTRING(path), \ + (void)aHandleReport->Callback(EmptyCString(), nsLiteralCString(path), \ kind, units, amount, \ - NS_LITERAL_CSTRING(description), aData) + nsLiteralCString(description), aData) %} diff --git a/xpcom/base/nsMacUtilsImpl.cpp b/xpcom/base/nsMacUtilsImpl.cpp index 8d36c79f74..46fca11633 100644 --- a/xpcom/base/nsMacUtilsImpl.cpp +++ b/xpcom/base/nsMacUtilsImpl.cpp @@ -169,7 +169,7 @@ bool nsMacUtilsImpl::GetAppPath(nsCString& aAppPath) { // The binary path resides within the .app dir in Contents/MacOS, // e.g., Firefox.app/Contents/MacOS/firefox. Search backwards in // the binary path for the end of .app path. - auto pattern = NS_LITERAL_CSTRING("/Contents/MacOS/"); + auto pattern = "/Contents/MacOS/"_ns; nsAutoCString::const_iterator start, end; appBinaryPath.BeginReading(start); appBinaryPath.EndReading(end); @@ -415,12 +415,14 @@ nsresult nsMacUtilsImpl::GetRepoDir(nsIFile** aRepoDir) { #if defined(MOZ_SANDBOX) MOZ_ASSERT(mozilla::IsDevelopmentBuild()); #endif - return GetDirFromBundlePlist(NS_LITERAL_STRING(MAC_DEV_REPO_KEY), aRepoDir); + return GetDirFromBundlePlist(NS_LITERAL_STRING_FROM_CSTRING(MAC_DEV_REPO_KEY), + aRepoDir); } nsresult nsMacUtilsImpl::GetObjDir(nsIFile** aObjDir) { #if defined(MOZ_SANDBOX) MOZ_ASSERT(mozilla::IsDevelopmentBuild()); #endif - return GetDirFromBundlePlist(NS_LITERAL_STRING(MAC_DEV_OBJ_KEY), aObjDir); + return GetDirFromBundlePlist(NS_LITERAL_STRING_FROM_CSTRING(MAC_DEV_OBJ_KEY), + aObjDir); } diff --git a/xpcom/base/nsMemoryInfoDumper.cpp b/xpcom/base/nsMemoryInfoDumper.cpp index 2ad959ec4e..2835d47f38 100644 --- a/xpcom/base/nsMemoryInfoDumper.cpp +++ b/xpcom/base/nsMemoryInfoDumper.cpp @@ -212,12 +212,11 @@ bool SetupFifo() { FifoWatcher* fw = FifoWatcher::GetSingleton(); // Dump our memory reports (but run this on the main thread!). - fw->RegisterCallback(NS_LITERAL_CSTRING("memory report"), doMemoryReport); - fw->RegisterCallback(NS_LITERAL_CSTRING("minimize memory report"), - doMemoryReport); + fw->RegisterCallback("memory report"_ns, doMemoryReport); + fw->RegisterCallback("minimize memory report"_ns, doMemoryReport); // Dump GC and CC logs (from the main thread). - fw->RegisterCallback(NS_LITERAL_CSTRING("gc log"), doGCCCDump); - fw->RegisterCallback(NS_LITERAL_CSTRING("abbreviated gc log"), doGCCCDump); + fw->RegisterCallback("gc log"_ns, doGCCCDump); + fw->RegisterCallback("abbreviated gc log"_ns, doGCCCDump); # ifdef DEBUG fifoCallbacksRegistered = true; @@ -510,7 +509,7 @@ class TempDirFinishCallback final : public nsIFinishDumpingCallback { } #ifdef ANDROID - rv = reportsFinalFile->AppendNative(NS_LITERAL_CSTRING("memory-reports")); + rv = reportsFinalFile->AppendNative("memory-reports"_ns); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -551,7 +550,7 @@ class TempDirFinishCallback final : public nsIFinishDumpingCallback { return rv; } - nsString msg = NS_LITERAL_STRING("nsIMemoryInfoDumper dumped reports to "); + nsString msg = u"nsIMemoryInfoDumper dumped reports to "_ns; msg.Append(path); return cs->LogStringMessage(msg.get()); } @@ -672,9 +671,9 @@ nsMemoryInfoDumper::DumpMemoryInfoToTempDir(const nsAString& aIdentifier, // In Android case, this function will open a file named aFilename under // specific folder (/data/local/tmp/memory-reports). Otherwise, it will // open a file named aFilename under "NS_OS_TEMP_DIR". - rv = nsDumpUtils::OpenTempFile( - NS_LITERAL_CSTRING("incomplete-") + reportsFinalFilename, - getter_AddRefs(reportsTmpFile), NS_LITERAL_CSTRING("memory-reports")); + rv = nsDumpUtils::OpenTempFile("incomplete-"_ns + reportsFinalFilename, + getter_AddRefs(reportsTmpFile), + "memory-reports"_ns); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -709,7 +708,7 @@ nsresult nsMemoryInfoDumper::OpenDMDFile(const nsAString& aIdentifier, int aPid, nsresult rv; nsCOMPtr dmdFile; rv = nsDumpUtils::OpenTempFile(dmdFilename, getter_AddRefs(dmdFile), - NS_LITERAL_CSTRING("memory-reports")); + "memory-reports"_ns); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp index 887f33d4f9..457fe65f7a 100644 --- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -904,9 +904,9 @@ class WindowsAddressSpaceReporter final : public nsIMemoryReporter { // Append the segment count. path.AppendPrintf("(segments=%u)", entry->mCount); - aHandleReport->Callback( - EmptyCString(), path, KIND_OTHER, UNITS_BYTES, entry->mSize, - NS_LITERAL_CSTRING("From MEMORY_BASIC_INFORMATION."), aData); + aHandleReport->Callback(EmptyCString(), path, KIND_OTHER, UNITS_BYTES, + entry->mSize, "From MEMORY_BASIC_INFORMATION."_ns, + aData); } return NS_OK; @@ -1433,8 +1433,8 @@ class ThreadsReporter final : public nsIMemoryReporter { aHandleReport->Callback( EmptyCString(), path, KIND_NONHEAP, UNITS_BYTES, thread.mPrivateSize, - NS_LITERAL_CSTRING("The sizes of thread stacks which have been " - "committed to memory."), + nsLiteralCString("The sizes of thread stacks which have been " + "committed to memory."), aData); } diff --git a/xpcom/base/nsMessageLoop.cpp b/xpcom/base/nsMessageLoop.cpp index 5cd79c1959..6b74324260 100644 --- a/xpcom/base/nsMessageLoop.cpp +++ b/xpcom/base/nsMessageLoop.cpp @@ -25,10 +25,8 @@ namespace { * Note that the MessageLoop owns this object and will delete it after it calls * Run(). Tread lightly. */ -class MessageLoopIdleTask : public Runnable, - public SupportsWeakPtr { +class MessageLoopIdleTask : public Runnable, public SupportsWeakPtr { public: - MOZ_DECLARE_WEAKREFERENCE_TYPENAME(MessageLoopIdleTask) MessageLoopIdleTask(nsIRunnable* aTask, uint32_t aEnsureRunsAfterMS); NS_IMETHOD Run() override; diff --git a/xpcom/base/nsTWeakRef.h b/xpcom/base/nsTWeakRef.h deleted file mode 100644 index 70f6282b9b..0000000000 --- a/xpcom/base/nsTWeakRef.h +++ /dev/null @@ -1,157 +0,0 @@ -/* 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 nsTWeakRef_h__ -#define nsTWeakRef_h__ - -#ifndef nsDebug_h___ -# include "nsDebug.h" -#endif - -/** - * A weak reference class for use with generic C++ objects. NOT THREADSAFE! - * - * Example usage: - * - * class A { - * public: - * A() : mWeakSelf(this) { - * } - * ~A() { - * mWeakSelf.forget(); - * } - * void Bar() { printf("Bar!\n"); } - * const nsTWeakRef &AsWeakRef() const { return mWeakSelf; } - * private: - * nsTWeakRef mWeakSelf; - * }; - * - * class B { - * public: - * void SetA(const nsTWeakRef &a) { - * mA = a; - * } - * void Foo() { - * if (mA) - * mA->Bar(); - * } - * private: - * nsTWeakRef mA; - * }; - * - * void Test() { - * B b; - * { - * A a; - * b.SetA(a.AsWeakRef()); - * b.Foo(); // prints "Bar!" - * } - * b.Foo(); // prints nothing because |a| has already been destroyed - * } - * - * One can imagine much more complex examples, especially when asynchronous - * event processing is involved. - * - * Keep in mind that you should only ever need a class like this when you have - * multiple instances of B, such that it is not possible for A and B to simply - * have pointers to one another. - */ -template -class nsTWeakRef { - public: - ~nsTWeakRef() {} - - /** - * Construct from an object pointer (may be null). - */ - explicit nsTWeakRef(Type* aObj = nullptr) { - if (aObj) { - mRef = new Inner(aObj); - } else { - mRef = nullptr; - } - } - - /** - * Construct from another weak reference object. - */ - explicit nsTWeakRef(const nsTWeakRef& aOther) : mRef(aOther.mRef) {} - - /** - * Assign from an object pointer. - */ - nsTWeakRef& operator=(Type* aObj) { - if (aObj) { - mRef = new Inner(aObj); - } else { - mRef = nullptr; - } - return *this; - } - - /** - * Assign from another weak reference object. - */ - nsTWeakRef& operator=(const nsTWeakRef& aOther) { - mRef = aOther.mRef; - return *this; - } - - /** - * Get the referenced object. This method may return null if the reference - * has been cleared or if an out-of-memory error occurred at assignment. - */ - Type* get() const { return mRef ? mRef->mObj : nullptr; } - - /** - * Called to "null out" the weak reference. Typically, the object referenced - * by this weak reference calls this method when it is being destroyed. - * @returns The former referenced object. - */ - Type* forget() { - Type* obj; - if (mRef) { - obj = mRef->mObj; - mRef->mObj = nullptr; - mRef = nullptr; - } else { - obj = nullptr; - } - return obj; - } - - /** - * Allow |*this| to be treated as a |Type*| for convenience. - */ - operator Type*() const { return get(); } - - /** - * Allow |*this| to be treated as a |Type*| for convenience. Use with - * caution since this method will crash if the referenced object is null. - */ - Type* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { - NS_ASSERTION( - mRef && mRef->mObj, - "You can't dereference a null weak reference with operator->()."); - return get(); - } - - private: - struct Inner { - int mCnt; - Type* mObj; - - explicit Inner(Type* aObj) : mCnt(1), mObj(aObj) {} - void AddRef() { ++mCnt; } - void Release() { - if (--mCnt == 0) { - delete this; - } - } - }; - - RefPtr mRef; -}; - -#endif // nsTWeakRef_h__ diff --git a/xpcom/base/nscore.h b/xpcom/base/nscore.h index f08fe35c2a..c649ee9e43 100644 --- a/xpcom/base/nscore.h +++ b/xpcom/base/nscore.h @@ -222,8 +222,6 @@ struct UnusedZero { static constexpr bool value = true; static constexpr StorageType nullValue = NS_OK; - static constexpr StorageType GetDefaultValue() { return NS_ERROR_FAILURE; } - static constexpr void AssertValid(StorageType aValue) {} static constexpr const nsresult& Inspect(const StorageType& aValue) { return aValue; diff --git a/xpcom/build/IOInterposer.cpp b/xpcom/build/IOInterposer.cpp index a69d045e25..6ef41ea086 100644 --- a/xpcom/build/IOInterposer.cpp +++ b/xpcom/build/IOInterposer.cpp @@ -22,8 +22,6 @@ #include "PoisonIOInterposer.h" #include "prenv.h" -using namespace mozilla; - namespace { /** Find if a vector contains a specific element */ @@ -62,13 +60,13 @@ struct ObserverLists { // These are implemented as vectors since they are allowed to survive gecko, // without reporting leaks. This is necessary for the IOInterposer to be used // for late-write checks. - std::vector mCreateObservers; - std::vector mReadObservers; - std::vector mWriteObservers; - std::vector mFSyncObservers; - std::vector mStatObservers; - std::vector mCloseObservers; - std::vector mStageObservers; + std::vector mCreateObservers; + std::vector mReadObservers; + std::vector mWriteObservers; + std::vector mFSyncObservers; + std::vector mStatObservers; + std::vector mCloseObservers; + std::vector mStageObservers; }; class PerThreadData { @@ -82,7 +80,7 @@ class PerThreadData { ~PerThreadData() { MOZ_COUNT_DTOR(PerThreadData); } - void CallObservers(IOInterposeObserver::Observation& aObservation) { + void CallObservers(mozilla::IOInterposeObserver::Observation& aObservation) { // Prevent recursive reporting. if (mIsHandlingObservation) { return; @@ -90,27 +88,27 @@ class PerThreadData { mIsHandlingObservation = true; // Decide which list of observers to inform - std::vector* observers = nullptr; + std::vector* observers = nullptr; switch (aObservation.ObservedOperation()) { - case IOInterposeObserver::OpCreateOrOpen: + case mozilla::IOInterposeObserver::OpCreateOrOpen: observers = &mObserverLists->mCreateObservers; break; - case IOInterposeObserver::OpRead: + case mozilla::IOInterposeObserver::OpRead: observers = &mObserverLists->mReadObservers; break; - case IOInterposeObserver::OpWrite: + case mozilla::IOInterposeObserver::OpWrite: observers = &mObserverLists->mWriteObservers; break; - case IOInterposeObserver::OpFSync: + case mozilla::IOInterposeObserver::OpFSync: observers = &mObserverLists->mFSyncObservers; break; - case IOInterposeObserver::OpStat: + case mozilla::IOInterposeObserver::OpStat: observers = &mObserverLists->mStatObservers; break; - case IOInterposeObserver::OpClose: + case mozilla::IOInterposeObserver::OpClose: observers = &mObserverLists->mCloseObservers; break; - case IOInterposeObserver::OpNextStage: + case mozilla::IOInterposeObserver::OpNextStage: observers = &mObserverLists->mStageObservers; break; default: { @@ -157,7 +155,8 @@ class PerThreadData { class MasterList { public: MasterList() - : mObservedOperations(IOInterposeObserver::OpNone), mIsEnabled(true) { + : mObservedOperations(mozilla::IOInterposeObserver::OpNone), + mIsEnabled(true) { MOZ_COUNT_CTOR(MasterList); } @@ -166,9 +165,9 @@ class MasterList { inline void Disable() { mIsEnabled = false; } inline void Enable() { mIsEnabled = true; } - void Register(IOInterposeObserver::Operation aOp, - IOInterposeObserver* aObserver) { - IOInterposer::AutoLock lock(mLock); + void Register(mozilla::IOInterposeObserver::Operation aOp, + mozilla::IOInterposeObserver* aObserver) { + mozilla::IOInterposer::AutoLock lock(mLock); ObserverLists* newLists = nullptr; if (mObserverLists) { @@ -178,44 +177,44 @@ class MasterList { } // You can register to observe multiple types of observations // but you'll never be registered twice for the same observations. - if (aOp & IOInterposeObserver::OpCreateOrOpen && + if (aOp & mozilla::IOInterposeObserver::OpCreateOrOpen && !VectorContains(newLists->mCreateObservers, aObserver)) { newLists->mCreateObservers.push_back(aObserver); } - if (aOp & IOInterposeObserver::OpRead && + if (aOp & mozilla::IOInterposeObserver::OpRead && !VectorContains(newLists->mReadObservers, aObserver)) { newLists->mReadObservers.push_back(aObserver); } - if (aOp & IOInterposeObserver::OpWrite && + if (aOp & mozilla::IOInterposeObserver::OpWrite && !VectorContains(newLists->mWriteObservers, aObserver)) { newLists->mWriteObservers.push_back(aObserver); } - if (aOp & IOInterposeObserver::OpFSync && + if (aOp & mozilla::IOInterposeObserver::OpFSync && !VectorContains(newLists->mFSyncObservers, aObserver)) { newLists->mFSyncObservers.push_back(aObserver); } - if (aOp & IOInterposeObserver::OpStat && + if (aOp & mozilla::IOInterposeObserver::OpStat && !VectorContains(newLists->mStatObservers, aObserver)) { newLists->mStatObservers.push_back(aObserver); } - if (aOp & IOInterposeObserver::OpClose && + if (aOp & mozilla::IOInterposeObserver::OpClose && !VectorContains(newLists->mCloseObservers, aObserver)) { newLists->mCloseObservers.push_back(aObserver); } - if (aOp & IOInterposeObserver::OpNextStage && + if (aOp & mozilla::IOInterposeObserver::OpNextStage && !VectorContains(newLists->mStageObservers, aObserver)) { newLists->mStageObservers.push_back(aObserver); } mObserverLists = newLists; mObservedOperations = - (IOInterposeObserver::Operation)(mObservedOperations | aOp); + (mozilla::IOInterposeObserver::Operation)(mObservedOperations | aOp); mCurrentGeneration++; } - void Unregister(IOInterposeObserver::Operation aOp, - IOInterposeObserver* aObserver) { - IOInterposer::AutoLock lock(mLock); + void Unregister(mozilla::IOInterposeObserver::Operation aOp, + mozilla::IOInterposeObserver* aObserver) { + mozilla::IOInterposer::AutoLock lock(mLock); ObserverLists* newLists = nullptr; if (mObserverLists) { @@ -224,53 +223,54 @@ class MasterList { newLists = new ObserverLists(); } - if (aOp & IOInterposeObserver::OpCreateOrOpen) { + if (aOp & mozilla::IOInterposeObserver::OpCreateOrOpen) { VectorRemove(newLists->mCreateObservers, aObserver); if (newLists->mCreateObservers.empty()) { - mObservedOperations = (IOInterposeObserver::Operation)( - mObservedOperations & ~IOInterposeObserver::OpCreateOrOpen); + mObservedOperations = (mozilla::IOInterposeObserver::Operation)( + mObservedOperations & + ~mozilla::IOInterposeObserver::OpCreateOrOpen); } } - if (aOp & IOInterposeObserver::OpRead) { + if (aOp & mozilla::IOInterposeObserver::OpRead) { VectorRemove(newLists->mReadObservers, aObserver); if (newLists->mReadObservers.empty()) { - mObservedOperations = (IOInterposeObserver::Operation)( - mObservedOperations & ~IOInterposeObserver::OpRead); + mObservedOperations = (mozilla::IOInterposeObserver::Operation)( + mObservedOperations & ~mozilla::IOInterposeObserver::OpRead); } } - if (aOp & IOInterposeObserver::OpWrite) { + if (aOp & mozilla::IOInterposeObserver::OpWrite) { VectorRemove(newLists->mWriteObservers, aObserver); if (newLists->mWriteObservers.empty()) { - mObservedOperations = (IOInterposeObserver::Operation)( - mObservedOperations & ~IOInterposeObserver::OpWrite); + mObservedOperations = (mozilla::IOInterposeObserver::Operation)( + mObservedOperations & ~mozilla::IOInterposeObserver::OpWrite); } } - if (aOp & IOInterposeObserver::OpFSync) { + if (aOp & mozilla::IOInterposeObserver::OpFSync) { VectorRemove(newLists->mFSyncObservers, aObserver); if (newLists->mFSyncObservers.empty()) { - mObservedOperations = (IOInterposeObserver::Operation)( - mObservedOperations & ~IOInterposeObserver::OpFSync); + mObservedOperations = (mozilla::IOInterposeObserver::Operation)( + mObservedOperations & ~mozilla::IOInterposeObserver::OpFSync); } } - if (aOp & IOInterposeObserver::OpStat) { + if (aOp & mozilla::IOInterposeObserver::OpStat) { VectorRemove(newLists->mStatObservers, aObserver); if (newLists->mStatObservers.empty()) { - mObservedOperations = (IOInterposeObserver::Operation)( - mObservedOperations & ~IOInterposeObserver::OpStat); + mObservedOperations = (mozilla::IOInterposeObserver::Operation)( + mObservedOperations & ~mozilla::IOInterposeObserver::OpStat); } } - if (aOp & IOInterposeObserver::OpClose) { + if (aOp & mozilla::IOInterposeObserver::OpClose) { VectorRemove(newLists->mCloseObservers, aObserver); if (newLists->mCloseObservers.empty()) { - mObservedOperations = (IOInterposeObserver::Operation)( - mObservedOperations & ~IOInterposeObserver::OpClose); + mObservedOperations = (mozilla::IOInterposeObserver::Operation)( + mObservedOperations & ~mozilla::IOInterposeObserver::OpClose); } } - if (aOp & IOInterposeObserver::OpNextStage) { + if (aOp & mozilla::IOInterposeObserver::OpNextStage) { VectorRemove(newLists->mStageObservers, aObserver); if (newLists->mStageObservers.empty()) { - mObservedOperations = (IOInterposeObserver::Operation)( - mObservedOperations & ~IOInterposeObserver::OpNextStage); + mObservedOperations = (mozilla::IOInterposeObserver::Operation)( + mObservedOperations & ~mozilla::IOInterposeObserver::OpNextStage); } } mObserverLists = newLists; @@ -283,11 +283,11 @@ class MasterList { } // If the generation counts don't match then we need to update the current // thread's observer list with the new master list. - IOInterposer::AutoLock lock(mLock); + mozilla::IOInterposer::AutoLock lock(mLock); aPtd.SetObserverLists(mCurrentGeneration, mObserverLists); } - inline bool IsObservedOperation(IOInterposeObserver::Operation aOp) { + inline bool IsObservedOperation(mozilla::IOInterposeObserver::Operation aOp) { // The quick reader may observe that no locks are being employed here, // hence the result of the operations is truly undefined. However, most // computers will usually return either true or false, which is good enough. @@ -303,31 +303,34 @@ class MasterList { // unregister observers during shutdown an OffTheBooksMutex is not an option // either, as its base calls into sDeadlockDetector which may be nullptr // during shutdown. - IOInterposer::Mutex mLock; + mozilla::IOInterposer::Mutex mLock; // Flags tracking which operations are being observed - IOInterposeObserver::Operation mObservedOperations; + mozilla::IOInterposeObserver::Operation mObservedOperations; // Used for quickly disabling everything by IOInterposer::Disable() - Atomic mIsEnabled; + mozilla::Atomic mIsEnabled; // Used to inform threads that the master observer list has changed - Atomic mCurrentGeneration; + mozilla::Atomic mCurrentGeneration; }; // Special observation used by IOInterposer::EnteringNextStage() -class NextStageObservation : public IOInterposeObserver::Observation { +class NextStageObservation : public mozilla::IOInterposeObserver::Observation { public: NextStageObservation() - : IOInterposeObserver::Observation(IOInterposeObserver::OpNextStage, - "IOInterposer", false) { - mStart = TimeStamp::Now(); + : mozilla::IOInterposeObserver::Observation( + mozilla::IOInterposeObserver::OpNextStage, "IOInterposer", false) { + mStart = mozilla::TimeStamp::Now(); mEnd = mStart; } }; // List of observers registered -static StaticAutoPtr sMasterList; +static mozilla::StaticAutoPtr sMasterList; static MOZ_THREAD_LOCAL(PerThreadData*) sThreadLocalData; static bool sThreadLocalDataInitialized; -} // namespace + +} // anonymous namespace + +namespace mozilla { IOInterposeObserver::Observation::Observation(Operation aOperation, const char* aReference, @@ -520,3 +523,5 @@ void IOInterposer::EnteringNextStage() { NextStageObservation observation; Report(observation); } + +} // namespace mozilla diff --git a/xpcom/build/LateWriteChecks.cpp b/xpcom/build/LateWriteChecks.cpp index 09a4a89d9a..289b5b70fc 100644 --- a/xpcom/build/LateWriteChecks.cpp +++ b/xpcom/build/LateWriteChecks.cpp @@ -34,8 +34,6 @@ #include "LateWriteChecks.h" -using namespace mozilla; - /*************************** Auxiliary Declarations ***************************/ // This a wrapper over a file descriptor that provides a Printf method and @@ -54,9 +52,9 @@ class SHA1Stream { str.AppendPrintf(aFormat, list); va_end(list); mSHA1.update(str.get(), str.Length()); - Unused << fwrite(str.get(), 1, str.Length(), mFile); + mozilla::Unused << fwrite(str.get(), 1, str.Length(), mFile); } - void Finish(SHA1Sum::Hash& aHash) { + void Finish(mozilla::SHA1Sum::Hash& aHash) { int fd = fileno(mFile); fflush(mFile); //MozillaUnRegisterDebugFD(fd); @@ -67,7 +65,7 @@ class SHA1Stream { private: FILE* mFile; - SHA1Sum mSHA1; + mozilla::SHA1Sum mSHA1; }; static void RecordStackWalker(uint32_t aFrameNumber, void* aPC, void* aSP, @@ -83,8 +81,8 @@ static void RecordStackWalker(uint32_t aFrameNumber, void* aPC, void* aSP, * An implementation of IOInterposeObserver to be registered with IOInterposer. * This observer logs all writes as late writes. */ -class LateWriteObserver final : public IOInterposeObserver { - using char_type = filesystem::Path::value_type; +class LateWriteObserver final : public mozilla::IOInterposeObserver { + using char_type = mozilla::filesystem::Path::value_type; public: explicit LateWriteObserver(const char_type* aProfileDirectory) @@ -94,20 +92,23 @@ class LateWriteObserver final : public IOInterposeObserver { mProfileDirectory = nullptr; } - void Observe(IOInterposeObserver::Observation& aObservation) override; + void Observe( + mozilla::IOInterposeObserver::Observation& aObservation) override; private: char_type* mProfileDirectory; }; -void LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb) { +void LateWriteObserver::Observe( + mozilla::IOInterposeObserver::Observation& aOb) { // Crash if that is the shutdown check mode - if (gShutdownChecks == SCM_CRASH) { + if (mozilla::gShutdownChecks == mozilla::SCM_CRASH) { MOZ_CRASH(); } - // If we have shutdown mode SCM_NOTHING or we can't record then abort - if (gShutdownChecks == SCM_NOTHING || !Telemetry::CanRecordExtended()) { + // If we have shutdown mode mozilla::SCM_NOTHING or we can't record then abort + if (mozilla::gShutdownChecks == mozilla::SCM_NOTHING || + !mozilla::Telemetry::CanRecordExtended()) { return; } @@ -117,7 +118,8 @@ void LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb) { MozStackWalk(RecordStackWalker, /* skipFrames */ 0, /* maxFrames */ 0, &rawStack); - Telemetry::ProcessedStack stack = Telemetry::GetStackAndModules(rawStack); + mozilla::Telemetry::ProcessedStack stack = + mozilla::Telemetry::GetStackAndModules(rawStack); nsTAutoString nameAux(mProfileDirectory); nameAux.AppendLiteral(NS_SLASH "Telemetry.LateWriteTmpXXXXXX"); @@ -159,7 +161,7 @@ void LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb) { size_t numModules = stack.GetNumModules(); sha1Stream.Printf("%u\n", (unsigned)numModules); for (size_t i = 0; i < numModules; ++i) { - Telemetry::ProcessedStack::Module module = stack.GetModule(i); + mozilla::Telemetry::ProcessedStack::Module module = stack.GetModule(i); sha1Stream.Printf("%s %s\n", module.mBreakpadId.get(), NS_ConvertUTF16toUTF8(module.mName).get()); } @@ -167,7 +169,7 @@ void LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb) { size_t numFrames = stack.GetStackSize(); sha1Stream.Printf("%u\n", (unsigned)numFrames); for (size_t i = 0; i < numFrames; ++i) { - const Telemetry::ProcessedStack::Frame& frame = stack.GetFrame(i); + const mozilla::Telemetry::ProcessedStack::Frame& frame = stack.GetFrame(i); // NOTE: We write the offsets, while the atos tool expects a value with // the virtual address added. For example, running otool -l on the the // firefox binary shows @@ -180,7 +182,7 @@ void LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb) { sha1Stream.Printf("%d %x\n", frame.mModIndex, (unsigned)frame.mOffset); } - SHA1Sum::Hash sha1; + mozilla::SHA1Sum::Hash sha1; sha1Stream.Finish(sha1); // Note: These files should be deleted by telemetry once it reads them. If @@ -190,7 +192,7 @@ void LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb) { // We append the sha1 of the contents to the file name. This provides a simple // client side deduplication. - nsAutoString finalName(NS_LITERAL_STRING("Telemetry.LateWriteFinal-")); + nsAutoString finalName(u"Telemetry.LateWriteFinal-"_ns); for (int i = 0; i < 20; ++i) { finalName.AppendPrintf("%02x", sha1[i]); } @@ -200,7 +202,7 @@ void LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb) { /******************************* Setup/Teardown *******************************/ -static StaticAutoPtr sLateWriteObserver; +static mozilla::StaticAutoPtr sLateWriteObserver; namespace mozilla { diff --git a/xpcom/build/MainThreadIOLogger.cpp b/xpcom/build/MainThreadIOLogger.cpp index fced3ccc75..6685adcf94 100644 --- a/xpcom/build/MainThreadIOLogger.cpp +++ b/xpcom/build/MainThreadIOLogger.cpp @@ -61,15 +61,15 @@ class MainThreadIOLoggerImpl final : public mozilla::IOInterposeObserver { static void sIOThreadFunc(void* aArg); void IOThreadFunc(); - TimeStamp mLogStartTime; + mozilla::TimeStamp mLogStartTime; const char* mFileName; PRThread* mIOThread; - IOInterposer::Monitor mMonitor; + mozilla::IOInterposer::Monitor mMonitor; bool mShutdownRequired; std::vector mObservations; }; -static StaticAutoPtr sImpl; +static mozilla::StaticAutoPtr sImpl; MainThreadIOLoggerImpl::MainThreadIOLoggerImpl() : mFileName(nullptr), mIOThread(nullptr), mShutdownRequired(false) {} @@ -80,7 +80,7 @@ MainThreadIOLoggerImpl::~MainThreadIOLoggerImpl() { } { // Scope for lock - IOInterposer::MonitorAutoLock lock(mMonitor); + mozilla::IOInterposer::MonitorAutoLock lock(mMonitor); mShutdownRequired = true; lock.Notify(); } @@ -120,15 +120,15 @@ void MainThreadIOLoggerImpl::IOThreadFunc() { PRFileDesc* fd = PR_Open(mFileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, PR_IRUSR | PR_IWUSR | PR_IRGRP); if (!fd) { - IOInterposer::MonitorAutoLock lock(mMonitor); + mozilla::IOInterposer::MonitorAutoLock lock(mMonitor); mShutdownRequired = true; std::vector().swap(mObservations); return; } - mLogStartTime = TimeStamp::Now(); + mLogStartTime = mozilla::TimeStamp::Now(); { // Scope for lock - IOInterposer::MonitorAutoLock lock(mMonitor); + mozilla::IOInterposer::MonitorAutoLock lock(mMonitor); while (true) { while (!mShutdownRequired && mObservations.empty()) { lock.Wait(); @@ -141,14 +141,15 @@ void MainThreadIOLoggerImpl::IOThreadFunc() { observationsToWrite.swap(mObservations); // Release the lock so that we're not holding anybody up during I/O - IOInterposer::MonitorAutoUnlock unlock(mMonitor); + mozilla::IOInterposer::MonitorAutoUnlock unlock(mMonitor); // Now write the events. for (auto i = observationsToWrite.begin(), e = observationsToWrite.end(); i != e; ++i) { if (i->mObservation.ObservedOperation() == OpNextStage) { - PR_fprintf(fd, "%f,NEXT-STAGE\n", - (TimeStamp::Now() - mLogStartTime).ToMilliseconds()); + PR_fprintf( + fd, "%f,NEXT-STAGE\n", + (mozilla::TimeStamp::Now() - mLogStartTime).ToMilliseconds()); continue; } double durationMs = i->mObservation.Duration().ToMilliseconds(); @@ -185,7 +186,7 @@ void MainThreadIOLoggerImpl::Observe(Observation& aObservation) { if (!mFileName || !IsMainThread()) { return; } - IOInterposer::MonitorAutoLock lock(mMonitor); + mozilla::IOInterposer::MonitorAutoLock lock(mMonitor); if (mShutdownRequired) { // The writer thread isn't running. Don't enqueue any more data. return; diff --git a/xpcom/build/NSPRInterposer.cpp b/xpcom/build/NSPRInterposer.cpp index bad0a8e643..5f7b4f581a 100644 --- a/xpcom/build/NSPRInterposer.cpp +++ b/xpcom/build/NSPRInterposer.cpp @@ -20,8 +20,6 @@ namespace { -using namespace mozilla; - /* Original IO methods */ PRCloseFN sCloseFn = nullptr; PRReadFN sReadFn = nullptr; @@ -54,13 +52,13 @@ static int32_t GetPathFromFd(int32_t aFd, char* aBuf, size_t aBufSize) { /** * RAII class for timing the duration of an NSPR I/O call and reporting the - * result to the IOInterposeObserver API. + * result to the mozilla::IOInterposeObserver API. */ -class NSPRIOAutoObservation : public IOInterposeObserver::Observation { +class NSPRIOAutoObservation : public mozilla::IOInterposeObserver::Observation { public: - explicit NSPRIOAutoObservation(IOInterposeObserver::Operation aOp, + explicit NSPRIOAutoObservation(mozilla::IOInterposeObserver::Operation aOp, PRFileDesc* aFd) - : IOInterposeObserver::Observation(aOp, "NSPRIOInterposer") { + : mozilla::IOInterposeObserver::Observation(aOp, "NSPRIOInterposer") { char filename[MAXPATHLEN]; if (mShouldReport && aFd && GetPathFromFd(PR_FileDesc2NativeHandle(aFd), filename, @@ -83,7 +81,7 @@ PRStatus PR_CALLBACK interposedClose(PRFileDesc* aFd) { // If we don't have a valid original function pointer something is very wrong. NS_ASSERTION(sCloseFn, "NSPR IO Interposing: sCloseFn is NULL"); - NSPRIOAutoObservation timer(IOInterposeObserver::OpClose, aFd); + NSPRIOAutoObservation timer(mozilla::IOInterposeObserver::OpClose, aFd); return sCloseFn(aFd); } @@ -91,7 +89,7 @@ int32_t PR_CALLBACK interposedRead(PRFileDesc* aFd, void* aBuf, int32_t aAmt) { // If we don't have a valid original function pointer something is very wrong. NS_ASSERTION(sReadFn, "NSPR IO Interposing: sReadFn is NULL"); - NSPRIOAutoObservation timer(IOInterposeObserver::OpRead, aFd); + NSPRIOAutoObservation timer(mozilla::IOInterposeObserver::OpRead, aFd); return sReadFn(aFd, aBuf, aAmt); } @@ -100,7 +98,7 @@ int32_t PR_CALLBACK interposedWrite(PRFileDesc* aFd, const void* aBuf, // If we don't have a valid original function pointer something is very wrong. NS_ASSERTION(sWriteFn, "NSPR IO Interposing: sWriteFn is NULL"); - NSPRIOAutoObservation timer(IOInterposeObserver::OpWrite, aFd); + NSPRIOAutoObservation timer(mozilla::IOInterposeObserver::OpWrite, aFd); return sWriteFn(aFd, aBuf, aAmt); } @@ -108,7 +106,7 @@ PRStatus PR_CALLBACK interposedFSync(PRFileDesc* aFd) { // If we don't have a valid original function pointer something is very wrong. NS_ASSERTION(sFSyncFn, "NSPR IO Interposing: sFSyncFn is NULL"); - NSPRIOAutoObservation timer(IOInterposeObserver::OpFSync, aFd); + NSPRIOAutoObservation timer(mozilla::IOInterposeObserver::OpFSync, aFd); return sFSyncFn(aFd); } @@ -116,7 +114,7 @@ PRStatus PR_CALLBACK interposedFileInfo(PRFileDesc* aFd, PRFileInfo* aInfo) { // If we don't have a valid original function pointer something is very wrong. NS_ASSERTION(sFileInfoFn, "NSPR IO Interposing: sFileInfoFn is NULL"); - NSPRIOAutoObservation timer(IOInterposeObserver::OpStat, aFd); + NSPRIOAutoObservation timer(mozilla::IOInterposeObserver::OpStat, aFd); return sFileInfoFn(aFd, aInfo); } @@ -125,7 +123,7 @@ PRStatus PR_CALLBACK interposedFileInfo64(PRFileDesc* aFd, // If we don't have a valid original function pointer something is very wrong. NS_ASSERTION(sFileInfo64Fn, "NSPR IO Interposing: sFileInfo64Fn is NULL"); - NSPRIOAutoObservation timer(IOInterposeObserver::OpStat, aFd); + NSPRIOAutoObservation timer(mozilla::IOInterposeObserver::OpStat, aFd); return sFileInfo64Fn(aFd, aInfo); } diff --git a/xpcom/build/PoisonIOInterposerBase.cpp b/xpcom/build/PoisonIOInterposerBase.cpp index fbb50731b0..5ae3880d98 100644 --- a/xpcom/build/PoisonIOInterposerBase.cpp +++ b/xpcom/build/PoisonIOInterposerBase.cpp @@ -34,8 +34,6 @@ inline mozilla::Maybe FileDescriptorToHandle(int aFd) { } #endif /* if not XP_WIN */ -using namespace mozilla; - namespace { struct DebugFilesAutoLockTraits { @@ -45,7 +43,7 @@ struct DebugFilesAutoLockTraits { static void release(type aL) { PR_Unlock(aL); } }; -class DebugFilesAutoLock : public Scoped { +class DebugFilesAutoLock : public mozilla::Scoped { static PRLock* Lock; public: @@ -66,7 +64,7 @@ class DebugFilesAutoLock : public Scoped { } DebugFilesAutoLock() - : Scoped(getDebugFileIDsLock()) { + : mozilla::Scoped(getDebugFileIDsLock()) { PR_Lock(get()); } }; @@ -216,7 +214,7 @@ void MozillaRegisterDebugHandle(intptr_t aHandle) { } void MozillaRegisterDebugFD(int aFd) { - Maybe handle = FileDescriptorToHandle(aFd); + mozilla::Maybe handle = FileDescriptorToHandle(aFd); if (!handle.isSome()) { return; } @@ -239,7 +237,7 @@ void MozillaUnRegisterDebugHandle(intptr_t aHandle) { } void MozillaUnRegisterDebugFD(int aFd) { - Maybe handle = FileDescriptorToHandle(aFd); + mozilla::Maybe handle = FileDescriptorToHandle(aFd); if (!handle.isSome()) { return; } @@ -258,11 +256,11 @@ void MozillaUnRegisterDebugFILE(FILE* aFile) { } // extern "C" #ifdef MOZ_REPLACE_MALLOC -void DebugFdRegistry::RegisterHandle(intptr_t aHandle) { +void mozilla::DebugFdRegistry::RegisterHandle(intptr_t aHandle) { MozillaRegisterDebugHandle(aHandle); } -void DebugFdRegistry::UnRegisterHandle(intptr_t aHandle) { +void mozilla::DebugFdRegistry::UnRegisterHandle(intptr_t aHandle) { MozillaUnRegisterDebugHandle(aHandle); } #endif diff --git a/xpcom/build/PoisonIOInterposerMac.cpp b/xpcom/build/PoisonIOInterposerMac.cpp index 8003c77be6..d56ec133e3 100644 --- a/xpcom/build/PoisonIOInterposerMac.cpp +++ b/xpcom/build/PoisonIOInterposerMac.cpp @@ -37,8 +37,6 @@ namespace { -using namespace mozilla; - // Bit tracking if poisoned writes are enabled static bool sIsEnabled = false; @@ -53,25 +51,27 @@ bool IsIPCWrite(int aFd, const struct stat& aBuf); /** * RAII class for timing the duration of an I/O call and reporting the result - * to the IOInterposeObserver API. + * to the mozilla::IOInterposeObserver API. */ -class MacIOAutoObservation : public IOInterposeObserver::Observation { +class MacIOAutoObservation : public mozilla::IOInterposeObserver::Observation { public: - MacIOAutoObservation(IOInterposeObserver::Operation aOp, int aFd) - : IOInterposeObserver::Observation(aOp, sReference, - sIsEnabled && !IsDebugFile(aFd)), + MacIOAutoObservation(mozilla::IOInterposeObserver::Operation aOp, int aFd) + : mozilla::IOInterposeObserver::Observation( + aOp, sReference, sIsEnabled && !mozilla::IsDebugFile(aFd)), mFd(aFd), mHasQueriedFilename(false) {} - MacIOAutoObservation(IOInterposeObserver::Operation aOp, int aFd, + MacIOAutoObservation(mozilla::IOInterposeObserver::Operation aOp, int aFd, const void* aBuf, size_t aCount) - : IOInterposeObserver::Observation( + : mozilla::IOInterposeObserver::Observation( aOp, sReference, - sIsEnabled && !IsDebugFile(aFd) && IsValidWrite(aFd, aBuf, aCount)), + sIsEnabled && !mozilla::IsDebugFile(aFd) && + IsValidWrite(aFd, aBuf, aCount)), mFd(aFd), mHasQueriedFilename(false) {} - // Custom implementation of IOInterposeObserver::Observation::Filename + // Custom implementation of + // mozilla::IOInterposeObserver::Observation::Filename void Filename(nsAString& aFilename) override; ~MacIOAutoObservation() { Report(); } @@ -160,7 +160,7 @@ bool IsValidWrite(int aFd, const void* aWbuf, size_t aCount) { // content. This is needed because dbm doesn't keep track of dirty bits // and can end up writing the same data to disk twice. Once when the // user (nss) asks it to sync and once when closing the database. - auto wbuf2 = MakeUniqueFallible(aCount); + auto wbuf2 = mozilla::MakeUniqueFallible(aCount); if (!wbuf2) { return true; } @@ -201,7 +201,8 @@ typedef ssize_t (*aio_write_t)(struct aiocb* aAioCbp); ssize_t wrap_aio_write(struct aiocb* aAioCbp); FuncData aio_write_data = {0, (void*)wrap_aio_write, (void*)aio_write}; ssize_t wrap_aio_write(struct aiocb* aAioCbp) { - MacIOAutoObservation timer(IOInterposeObserver::OpWrite, aAioCbp->aio_fildes); + MacIOAutoObservation timer(mozilla::IOInterposeObserver::OpWrite, + aAioCbp->aio_fildes); aio_write_t old_write = (aio_write_t)aio_write_data.Buffer; return old_write(aAioCbp); @@ -214,7 +215,7 @@ typedef ssize_t (*pwrite_t)(int aFd, const void* buf, size_t aNumBytes, template ssize_t wrap_pwrite_temp(int aFd, const void* aBuf, size_t aNumBytes, off_t aOffset) { - MacIOAutoObservation timer(IOInterposeObserver::OpWrite, aFd); + MacIOAutoObservation timer(mozilla::IOInterposeObserver::OpWrite, aFd); pwrite_t old_write = (pwrite_t)foo.Buffer; return old_write(aFd, aBuf, aNumBytes, aOffset); } @@ -234,8 +235,8 @@ DEFINE_PWRITE_DATA(pwrite_NOCANCEL, "pwrite$NOCANCEL"); typedef ssize_t (*writev_t)(int aFd, const struct iovec* aIov, int aIovCount); template ssize_t wrap_writev_temp(int aFd, const struct iovec* aIov, int aIovCount) { - MacIOAutoObservation timer(IOInterposeObserver::OpWrite, aFd, nullptr, - aIovCount); + MacIOAutoObservation timer(mozilla::IOInterposeObserver::OpWrite, aFd, + nullptr, aIovCount); writev_t old_write = (writev_t)foo.Buffer; return old_write(aFd, aIov, aIovCount); } @@ -255,7 +256,8 @@ DEFINE_WRITEV_DATA(writev_NOCANCEL, "writev$NOCANCEL"); typedef ssize_t (*write_t)(int aFd, const void* aBuf, size_t aCount); template ssize_t wrap_write_temp(int aFd, const void* aBuf, size_t aCount) { - MacIOAutoObservation timer(IOInterposeObserver::OpWrite, aFd, aBuf, aCount); + MacIOAutoObservation timer(mozilla::IOInterposeObserver::OpWrite, aFd, aBuf, + aCount); write_t old_write = (write_t)foo.Buffer; return old_write(aFd, aBuf, aCount); } @@ -283,7 +285,7 @@ FuncData* Functions[] = {&aio_write_data, &writev_data, &writev_NOCANCEL_UNIX2003_data, &writev_UNIX2003_data, &writev_NOCANCEL_data}; -const int NumFunctions = ArrayLength(Functions); +const int NumFunctions = mozilla::ArrayLength(Functions); } // namespace diff --git a/xpcom/build/PoisonIOInterposerWin.cpp b/xpcom/build/PoisonIOInterposerWin.cpp index c3483348a4..6548a097ab 100644 --- a/xpcom/build/PoisonIOInterposerWin.cpp +++ b/xpcom/build/PoisonIOInterposerWin.cpp @@ -25,8 +25,6 @@ # include "replace_malloc_bridge.h" #endif -using namespace mozilla; - namespace { // Keep track of poisoned state. Notice that there is no reason to lock access @@ -107,15 +105,15 @@ typedef NTSTATUS(NTAPI* NtQueryFullAttributesFileFn)( /** * RAII class for timing the duration of an I/O call and reporting the result - * to the IOInterposeObserver API. + * to the mozilla::IOInterposeObserver API. */ -class WinIOAutoObservation : public IOInterposeObserver::Observation { +class WinIOAutoObservation : public mozilla::IOInterposeObserver::Observation { public: - WinIOAutoObservation(IOInterposeObserver::Operation aOp, HANDLE aFileHandle, - const LARGE_INTEGER* aOffset) - : IOInterposeObserver::Observation( + WinIOAutoObservation(mozilla::IOInterposeObserver::Operation aOp, + HANDLE aFileHandle, const LARGE_INTEGER* aOffset) + : mozilla::IOInterposeObserver::Observation( aOp, sReference, - !IsDebugFile(reinterpret_cast(aFileHandle))), + !mozilla::IsDebugFile(reinterpret_cast(aFileHandle))), mFileHandle(aFileHandle), mHasQueriedFilename(false) { if (mShouldReport) { @@ -123,13 +121,14 @@ class WinIOAutoObservation : public IOInterposeObserver::Observation { } } - WinIOAutoObservation(IOInterposeObserver::Operation aOp, nsAString& aFilename) - : IOInterposeObserver::Observation(aOp, sReference), + WinIOAutoObservation(mozilla::IOInterposeObserver::Operation aOp, + nsAString& aFilename) + : mozilla::IOInterposeObserver::Observation(aOp, sReference), mFileHandle(nullptr), mHasQueriedFilename(false) { if (mShouldReport) { nsAutoString dosPath; - if (NtPathToDosPath(aFilename, dosPath)) { + if (mozilla::NtPathToDosPath(aFilename, dosPath)) { mFilename = dosPath; } else { // If we can't get a dosPath, what we have is better than nothing. @@ -140,7 +139,8 @@ class WinIOAutoObservation : public IOInterposeObserver::Observation { } } - // Custom implementation of IOInterposeObserver::Observation::Filename + // Custom implementation of + // mozilla::IOInterposeObserver::Observation::Filename void Filename(nsAString& aFilename) override; ~WinIOAutoObservation() { Report(); } @@ -165,7 +165,8 @@ void WinIOAutoObservation::Filename(nsAString& aFilename) { } nsAutoString filename; - if (mFileHandle && HandleToFilename(mFileHandle, mOffset, filename)) { + if (mFileHandle && + mozilla::HandleToFilename(mFileHandle, mOffset, filename)) { mFilename = filename; } mHasQueriedFilename = true; @@ -176,17 +177,19 @@ void WinIOAutoObservation::Filename(nsAString& aFilename) { /*************************** IO Interposing Methods ***************************/ // Function pointers to original functions -static WindowsDllInterceptor::FuncHookType +static mozilla::WindowsDllInterceptor::FuncHookType gOriginalNtCreateFile; -static WindowsDllInterceptor::FuncHookType gOriginalNtReadFile; -static WindowsDllInterceptor::FuncHookType +static mozilla::WindowsDllInterceptor::FuncHookType + gOriginalNtReadFile; +static mozilla::WindowsDllInterceptor::FuncHookType gOriginalNtReadFileScatter; -static WindowsDllInterceptor::FuncHookType gOriginalNtWriteFile; -static WindowsDllInterceptor::FuncHookType +static mozilla::WindowsDllInterceptor::FuncHookType + gOriginalNtWriteFile; +static mozilla::WindowsDllInterceptor::FuncHookType gOriginalNtWriteFileGather; -static WindowsDllInterceptor::FuncHookType +static mozilla::WindowsDllInterceptor::FuncHookType gOriginalNtFlushBuffersFile; -static WindowsDllInterceptor::FuncHookType +static mozilla::WindowsDllInterceptor::FuncHookType gOriginalNtQueryFullAttributesFile; static NTSTATUS NTAPI InterposedNtCreateFile( @@ -202,7 +205,8 @@ static NTSTATUS NTAPI InterposedNtCreateFile( ? aObjectAttributes->ObjectName->Length / sizeof(WCHAR) : 0; nsDependentSubstring filename(buf, len); - WinIOAutoObservation timer(IOInterposeObserver::OpCreateOrOpen, filename); + WinIOAutoObservation timer(mozilla::IOInterposeObserver::OpCreateOrOpen, + filename); // Something is badly wrong if this function is undefined MOZ_ASSERT(gOriginalNtCreateFile); @@ -221,7 +225,8 @@ static NTSTATUS NTAPI InterposedNtReadFile(HANDLE aFileHandle, HANDLE aEvent, PLARGE_INTEGER aOffset, PULONG aKey) { // Report IO - WinIOAutoObservation timer(IOInterposeObserver::OpRead, aFileHandle, aOffset); + WinIOAutoObservation timer(mozilla::IOInterposeObserver::OpRead, aFileHandle, + aOffset); // Something is badly wrong if this function is undefined MOZ_ASSERT(gOriginalNtReadFile); @@ -236,7 +241,8 @@ static NTSTATUS NTAPI InterposedNtReadFileScatter( PIO_STATUS_BLOCK aIoStatus, FILE_SEGMENT_ELEMENT* aSegments, ULONG aLength, PLARGE_INTEGER aOffset, PULONG aKey) { // Report IO - WinIOAutoObservation timer(IOInterposeObserver::OpRead, aFileHandle, aOffset); + WinIOAutoObservation timer(mozilla::IOInterposeObserver::OpRead, aFileHandle, + aOffset); // Something is badly wrong if this function is undefined MOZ_ASSERT(gOriginalNtReadFileScatter); @@ -255,7 +261,7 @@ static NTSTATUS NTAPI InterposedNtWriteFile(HANDLE aFileHandle, HANDLE aEvent, PLARGE_INTEGER aOffset, PULONG aKey) { // Report IO - WinIOAutoObservation timer(IOInterposeObserver::OpWrite, aFileHandle, + WinIOAutoObservation timer(mozilla::IOInterposeObserver::OpWrite, aFileHandle, aOffset); // Something is badly wrong if this function is undefined @@ -272,7 +278,7 @@ static NTSTATUS NTAPI InterposedNtWriteFileGather( PIO_STATUS_BLOCK aIoStatus, FILE_SEGMENT_ELEMENT* aSegments, ULONG aLength, PLARGE_INTEGER aOffset, PULONG aKey) { // Report IO - WinIOAutoObservation timer(IOInterposeObserver::OpWrite, aFileHandle, + WinIOAutoObservation timer(mozilla::IOInterposeObserver::OpWrite, aFileHandle, aOffset); // Something is badly wrong if this function is undefined @@ -287,7 +293,7 @@ static NTSTATUS NTAPI InterposedNtWriteFileGather( static NTSTATUS NTAPI InterposedNtFlushBuffersFile( HANDLE aFileHandle, PIO_STATUS_BLOCK aIoStatusBlock) { // Report IO - WinIOAutoObservation timer(IOInterposeObserver::OpFSync, aFileHandle, + WinIOAutoObservation timer(mozilla::IOInterposeObserver::OpFSync, aFileHandle, nullptr); // Something is badly wrong if this function is undefined @@ -307,7 +313,7 @@ static NTSTATUS NTAPI InterposedNtQueryFullAttributesFile( ? aObjectAttributes->ObjectName->Length / sizeof(WCHAR) : 0; nsDependentSubstring filename(buf, len); - WinIOAutoObservation timer(IOInterposeObserver::OpStat, filename); + WinIOAutoObservation timer(mozilla::IOInterposeObserver::OpStat, filename); // Something is badly wrong if this function is undefined MOZ_ASSERT(gOriginalNtQueryFullAttributesFile); @@ -322,7 +328,7 @@ static NTSTATUS NTAPI InterposedNtQueryFullAttributesFile( /******************************** IO Poisoning ********************************/ // Windows DLL interceptor -static WindowsDllInterceptor sNtDllInterceptor; +static mozilla::WindowsDllInterceptor sNtDllInterceptor; namespace mozilla { diff --git a/xpcom/build/XPCOM.h b/xpcom/build/XPCOM.h index 0f04f9c0c0..024869c9c9 100644 --- a/xpcom/build/XPCOM.h +++ b/xpcom/build/XPCOM.h @@ -32,7 +32,6 @@ #include "nsISupports.h" #include "nsTArray.h" -#include "nsTWeakRef.h" #include "nsCOMPtr.h" #include "nsCOMArray.h" diff --git a/xpcom/build/XPCOMInit.cpp b/xpcom/build/XPCOMInit.cpp index 29f176f1c1..cec15d15e1 100644 --- a/xpcom/build/XPCOMInit.cpp +++ b/xpcom/build/XPCOMInit.cpp @@ -100,7 +100,6 @@ #include "gfxPlatform.h" -using namespace mozilla; using base::AtExitManager; using mozilla::ipc::BrowserProcessSubThread; @@ -114,7 +113,7 @@ static AtExitManager* sExitManager; static MessageLoop* sMessageLoop; static bool sCommandLineWasInitialized; static BrowserProcessSubThread* sIOThread; -static BackgroundHangMonitor* sMainHangMonitor; +static mozilla::BackgroundHangMonitor* sMainHangMonitor; } /* anonymous namespace */ @@ -173,7 +172,7 @@ const mozilla::Module kXPCOMModule = { nullptr, nullptr, nullptr, - Module::ALLOW_IN_GPU_RDD_VR_AND_SOCKET_PROCESS}; + mozilla::Module::ALLOW_IN_GPU_RDD_VR_AND_SOCKET_PROCESS}; // gDebug will be freed during shutdown. static nsIDebug2* gDebug = nullptr; @@ -184,7 +183,7 @@ NS_GetDebug(nsIDebug2** aResult) { } class ICUReporter final : public nsIMemoryReporter, - public CountingAllocatorBase { + public mozilla::CountingAllocatorBase { public: NS_DECL_ISUPPORTS @@ -215,11 +214,11 @@ class ICUReporter final : public nsIMemoryReporter, NS_IMPL_ISUPPORTS(ICUReporter, nsIMemoryReporter) /* static */ template <> -CountingAllocatorBase::AmountType - CountingAllocatorBase::sAmount(0); +mozilla::CountingAllocatorBase::AmountType + mozilla::CountingAllocatorBase::sAmount(0); class OggReporter final : public nsIMemoryReporter, - public CountingAllocatorBase { + public mozilla::CountingAllocatorBase { public: NS_DECL_ISUPPORTS @@ -241,15 +240,16 @@ class OggReporter final : public nsIMemoryReporter, NS_IMPL_ISUPPORTS(OggReporter, nsIMemoryReporter) /* static */ template <> -CountingAllocatorBase::AmountType - CountingAllocatorBase::sAmount(0); +mozilla::CountingAllocatorBase::AmountType + mozilla::CountingAllocatorBase::sAmount(0); static bool sInitializedJS = false; // Note that on OSX, aBinDirectory will point to .app/Contents/Resources/browser EXPORT_XPCOM_API(nsresult) NS_InitXPCOM(nsIServiceManager** aResult, nsIFile* aBinDirectory, - nsIDirectoryServiceProvider* aAppFileLocationProvider) { + nsIDirectoryServiceProvider* aAppFileLocationProvider, + bool aInitJSContext) { static bool sInitialized = false; if (sInitialized) { return NS_ERROR_FAILURE; @@ -307,8 +307,9 @@ NS_InitXPCOM(nsIServiceManager** aResult, nsIFile* aBinDirectory, if (XRE_IsParentProcess() && !BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) { - UniquePtr ioThread = - MakeUnique(BrowserProcessSubThread::IO); + mozilla::UniquePtr ioThread = + mozilla::MakeUnique( + BrowserProcessSubThread::IO); base::Thread::Options options; options.message_loop_type = MessageLoop::TYPE_IO; @@ -326,8 +327,8 @@ NS_InitXPCOM(nsIServiceManager** aResult, nsIFile* aBinDirectory, } AUTO_PROFILER_INIT2; - // Init the SystemGroup for dispatching main thread runnables. - SystemGroup::InitStatic(); + // Init the mozilla::SystemGroup for dispatching main thread runnables. + mozilla::SystemGroup::InitStatic(); // Set up the timer globals/timer thread rv = nsTimerImpl::Startup(); @@ -351,8 +352,7 @@ NS_InitXPCOM(nsIServiceManager** aResult, nsIFile* aBinDirectory, rv = aBinDirectory->IsDirectory(&value); if (NS_SUCCEEDED(rv) && value) { - nsDirectoryService::gService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, - aBinDirectory); + nsDirectoryService::gService->SetCurrentProcessDirectory(aBinDirectory); } } @@ -393,7 +393,7 @@ NS_InitXPCOM(nsIServiceManager** aResult, nsIFile* aBinDirectory, return NS_ERROR_FAILURE; } - rv = binaryFile->AppendNative(NS_LITERAL_CSTRING("nonexistent-executable")); + rv = binaryFile->AppendNative("nonexistent-executable"_ns); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -459,10 +459,9 @@ NS_InitXPCOM(nsIServiceManager** aResult, nsIFile* aBinDirectory, // to the directory service. nsDirectoryService::gService->RegisterCategoryProviders(); - // Init SharedThreadPool (which needs the service manager). - SharedThreadPool::InitStatics(); + // Init mozilla::SharedThreadPool (which needs the service manager). + mozilla::SharedThreadPool::InitStatics(); - mozilla::ScriptPreloader::GetSingleton(); mozilla::scache::StartupCache::GetSingleton(); mozilla::AvailableMemoryTracker::Init(); @@ -488,6 +487,10 @@ NS_InitXPCOM(nsIServiceManager** aResult, nsIFile* aBinDirectory, mozilla::dom::JSExecutionManager::Initialize(); + if (aInitJSContext) { + xpc::InitializeJSContext(); + } + return NS_OK; } @@ -511,8 +514,8 @@ NS_InitMinimalXPCOM() { return rv; } - // Init the SystemGroup for dispatching main thread runnables. - SystemGroup::InitStatic(); + // Init the mozilla::SystemGroup for dispatching main thread runnables. + mozilla::SystemGroup::InitStatic(); // Set up the timer globals/timer thread. rv = nsTimerImpl::Startup(); @@ -535,7 +538,7 @@ NS_InitMinimalXPCOM() { return NS_ERROR_UNEXPECTED; } - SharedThreadPool::InitStatics(); + mozilla::SharedThreadPool::InitStatics(); mozilla::Telemetry::Init(); mozilla::BackgroundHangMonitor::Startup(); diff --git a/xpcom/build/nsXPCOM.h b/xpcom/build/nsXPCOM.h index e377df504f..b3e0dd330a 100644 --- a/xpcom/build/nsXPCOM.h +++ b/xpcom/build/nsXPCOM.h @@ -62,6 +62,9 @@ struct Module; * component registry preferences and so on; or use * nullptr for the default behaviour. * + * @param aInitJSContext Whether the nsXPCJSContext should be initialized at + * this point. + * * @see NS_NewLocalFile * @see nsIFile * @see nsIDirectoryServiceProvider @@ -74,7 +77,8 @@ struct Module; */ XPCOM_API(nsresult) NS_InitXPCOM(nsIServiceManager** aResult, nsIFile* aBinDirectory, - nsIDirectoryServiceProvider* aAppFileLocationProvider); + nsIDirectoryServiceProvider* aAppFileLocationProvider, + bool aInitJSContext = true); /** * Initialize only minimal components of XPCOM. This ensures nsThreadManager, diff --git a/xpcom/components/ManifestParser.cpp b/xpcom/components/ManifestParser.cpp index dce301027c..6b9cc70f3c 100644 --- a/xpcom/components/ManifestParser.cpp +++ b/xpcom/components/ManifestParser.cpp @@ -267,8 +267,7 @@ static bool CheckOsFlag(const nsAString& aFlag, const nsAString& aData, bool result = CheckStringFlag(aFlag, aData, aValue, aResult); #if defined(XP_UNIX) && !defined(XP_DARWIN) && !defined(ANDROID) if (result && aResult == eBad) { - result = - CheckStringFlag(aFlag, aData, NS_LITERAL_STRING("likeunix"), aResult); + result = CheckStringFlag(aFlag, aData, u"likeunix"_ns, aResult); } #endif return result; diff --git a/xpcom/components/gen_static_components.py b/xpcom/components/gen_static_components.py index 1571091921..1dbe471c9c 100644 --- a/xpcom/components/gen_static_components.py +++ b/xpcom/components/gen_static_components.py @@ -355,7 +355,7 @@ class ModuleEntry(object): if self.jsm: res += ( ' nsCOMPtr inst;\n' - ' MOZ_TRY(ConstructJSMComponent(NS_LITERAL_CSTRING(%s),\n' + ' MOZ_TRY(ConstructJSMComponent(nsLiteralCString(%s),\n' ' %s,\n' ' getter_AddRefs(inst)));' '\n' % (json.dumps(self.jsm), json.dumps(self.constructor))) diff --git a/xpcom/components/nsComponentManager.cpp b/xpcom/components/nsComponentManager.cpp index baff9917d6..96269075ff 100644 --- a/xpcom/components/nsComponentManager.cpp +++ b/xpcom/components/nsComponentManager.cpp @@ -199,8 +199,8 @@ class MOZ_STACK_CLASS EntryWrapper final { nsCString ModuleDescription() { MATCH(nsCString, return entry->mModule ? entry->mModule->Description() - : NS_LITERAL_CSTRING(""), - return NS_LITERAL_CSTRING("")); + : ""_ns, + return ""_ns); } private: @@ -310,9 +310,6 @@ extern const mozilla::Module kLayoutModule; extern const mozilla::Module kKeyValueModule; extern const mozilla::Module kXREModule; extern const mozilla::Module kEmbeddingModule; -#if defined(MOZ_WIDGET_ANDROID) -extern const mozilla::Module kBrowserModule; -#endif static nsTArray* sExtraStaticModules; @@ -398,9 +395,6 @@ nsresult nsComponentManagerImpl::Init() { RegisterModule(&kKeyValueModule); RegisterModule(&kXREModule); RegisterModule(&kEmbeddingModule); -#if defined(MOZ_WIDGET_ANDROID) - RegisterModule(&kBrowserModule); -#endif for (uint32_t i = 0; i < sExtraStaticModules->Length(); ++i) { RegisterModule((*sExtraStaticModules)[i]); @@ -457,8 +451,7 @@ nsresult nsComponentManagerImpl::Init() { if (greOmnijar) { cl->location.Init(greOmnijar, "chrome.manifest"); } else { - nsCOMPtr lf = - CloneAndAppend(greDir, NS_LITERAL_CSTRING("chrome.manifest")); + nsCOMPtr lf = CloneAndAppend(greDir, "chrome.manifest"_ns); cl->location.Init(lf); } @@ -474,8 +467,7 @@ nsresult nsComponentManagerImpl::Init() { if (!equals) { cl = sModuleLocations->AppendElement(); cl->type = NS_APP_LOCATION; - nsCOMPtr lf = - CloneAndAppend(appDir, NS_LITERAL_CSTRING("chrome.manifest")); + nsCOMPtr lf = CloneAndAppend(appDir, "chrome.manifest"_ns); cl->location.Init(lf); } } @@ -1089,10 +1081,8 @@ nsComponentManagerImpl::CreateInstance(const nsCID& aClass, #ifdef SHOW_CI_ON_EXISTING_SERVICE if (entry->ServiceInstance()) { nsAutoCString message; - message = - NS_LITERAL_CSTRING("You are calling CreateInstance \"") + - AutoIDString(aClass) + - NS_LITERAL_CSTRING("\" when a service for this CID already exists!"); + message = "You are calling CreateInstance \""_ns + AutoIDString(aClass) + + "\" when a service for this CID already exists!"_ns; NS_ERROR(message.get()); } #endif @@ -1172,9 +1162,9 @@ nsComponentManagerImpl::CreateInstanceByContractID(const char* aContractID, if (entry->ServiceInstance()) { nsAutoCString message; message = - NS_LITERAL_CSTRING("You are calling CreateInstance \"") + + "You are calling CreateInstance \""_ns + nsDependentCString(aContractID) + - NS_LITERAL_CSTRING( + nsLiteralCString( "\" when a service for this CID already exists! " "Add it to abusedContracts to track down the service consumer."); NS_ERROR(message.get()); @@ -1884,8 +1874,7 @@ nsComponentManagerImpl::AddBootstrappedManifestLocation(nsIFile* aLocation) { return XRE_AddJarManifestLocation(NS_BOOTSTRAPPED_LOCATION, aLocation); } - nsCOMPtr manifest = - CloneAndAppend(aLocation, NS_LITERAL_CSTRING("chrome.manifest")); + nsCOMPtr manifest = CloneAndAppend(aLocation, "chrome.manifest"_ns); return XRE_AddManifestLocation(NS_BOOTSTRAPPED_LOCATION, manifest); } @@ -1911,8 +1900,7 @@ nsComponentManagerImpl::RemoveBootstrappedManifestLocation(nsIFile* aLocation) { if (Substring(path, path.Length() - 4).EqualsLiteral(".xpi")) { elem.location.Init(aLocation, "chrome.manifest"); } else { - nsCOMPtr lf = - CloneAndAppend(aLocation, NS_LITERAL_CSTRING("chrome.manifest")); + nsCOMPtr lf = CloneAndAppend(aLocation, "chrome.manifest"_ns); elem.location.Init(lf); } diff --git a/xpcom/components/nsComponentManager.h b/xpcom/components/nsComponentManager.h index 77c5699f36..dc118238f8 100644 --- a/xpcom/components/nsComponentManager.h +++ b/xpcom/components/nsComponentManager.h @@ -7,7 +7,6 @@ #include "nsXPCOM.h" -#include "xpcom-private.h" #include "nsIComponentManager.h" #include "nsIComponentRegistrar.h" #include "nsIMemoryReporter.h" diff --git a/xpcom/ds/AtomArray.h b/xpcom/ds/AtomArray.h index d09eed5f00..bded74bf24 100644 --- a/xpcom/ds/AtomArray.h +++ b/xpcom/ds/AtomArray.h @@ -11,7 +11,7 @@ class nsAtom; namespace mozilla { -typedef nsTArray> AtomArray; +typedef AutoTArray, 4> AtomArray; } #endif // mozilla_AtomArray_h diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py index ce35a37200..c9aa0f70dc 100644 --- a/xpcom/ds/StaticAtoms.py +++ b/xpcom/ds/StaticAtoms.py @@ -405,6 +405,7 @@ STATIC_ATOMS = [ Atom("enctype", "enctype"), Atom("end", "end"), Atom("endEvent", "endEvent"), + Atom("enterkeyhint", "enterkeyhint"), Atom("equalsize", "equalsize"), Atom("error", "error"), Atom("ethiopic_numeric", "ethiopic-numeric"), @@ -1894,6 +1895,58 @@ STATIC_ATOMS = [ Atom("onmozvisualresize", "onmozvisualresize"), Atom("onmozvisualscroll", "onmozvisualscroll"), + # Miscellaneous events included for memory usage optimization (see bug 1542885) + Atom("onDOMAutoComplete", "onDOMAutoComplete"), + Atom("onDOMContentLoaded", "onDOMContentLoaded"), + Atom("onDOMDocElementInserted", "onDOMDocElementInserted"), + Atom("onDOMFormBeforeSubmit", "onDOMFormBeforeSubmit"), + Atom("onDOMFormHasPassword", "onDOMFormHasPassword"), + Atom("onDOMFrameContentLoaded", "onDOMFrameContentLoaded"), + Atom("onDOMHeadElementParsed", "onDOMHeadElementParsed"), + Atom("onDOMInputPasswordAdded", "onDOMInputPasswordAdded"), + Atom("onDOMLinkAdded", "onDOMLinkAdded"), + Atom("onDOMLinkChanged", "onDOMLinkChanged"), + Atom("onDOMMetaAdded", "onDOMMetaAdded"), + Atom("onDOMMetaChanged", "onDOMMetaChanged"), + Atom("onDOMMetaRemoved", "onDOMMetaRemoved"), + Atom("onDOMPopupBlocked", "onDOMPopupBlocked"), + Atom("onDOMTitleChanged", "onDOMTitleChanged"), + Atom("onDOMWindowClose", "onDOMWindowClose"), + Atom("onDOMWindowCreated", "onDOMWindowCreated"), + Atom("onDOMWindowFocus", "onDOMWindowFocus"), + Atom("onFullZoomChange", "onFullZoomChange"), + Atom("onGloballyAutoplayBlocked", "onGloballyAutoplayBlocked"), + Atom("onHiddenPlugin", "onHiddenPlugin"), + Atom("onMozApplicationManifest", "onMozApplicationManifest"), + Atom("onMozDOMFullscreen_Entered", "onMozDOMFullscreen:Entered"), + Atom("onMozDOMFullscreen_Exit", "onMozDOMFullscreen:Exit"), + Atom("onMozDOMFullscreen_Exited", "onMozDOMFullscreen:Exited"), + Atom("onMozDOMFullscreen_NewOrigin", "onMozDOMFullscreen:NewOrigin"), + Atom("onMozDOMFullscreen_Request", "onMozDOMFullscreen:Request"), + Atom("onMozDOMPointerLock_Entered", "onMozDOMPointerLock:Entered"), + Atom("onMozDOMPointerLock_Exited", "onMozDOMPointerLock:Exited"), + Atom("onMozInvalidForm", "onMozInvalidForm"), + Atom("onMozLocalStorageChanged", "onMozLocalStorageChanged"), + Atom("onMozOpenDateTimePicker", "onMozOpenDateTimePicker"), + Atom("onMozSessionStorageChanged", "onMozSessionStorageChanged"), + Atom("onMozTogglePictureInPicture", "onMozTogglePictureInPicture"), + Atom("onPluginBindingAttached", "onPluginBindingAttached"), + Atom("onPluginCrashed", "onPluginCrashed"), + Atom("onPluginInstantiated", "onPluginInstantiated"), + Atom("onPluginOutdated", "onPluginOutdated"), + Atom("onPluginRemoved", "onPluginRemoved"), + Atom("onPrintingError", "onPrintingError"), + Atom("onTextZoomChange", "onTextZoomChange"), + Atom("onUAWidgetSetupOrChange", "onUAWidgetSetupOrChange"), + Atom("onUAWidgetTeardown", "onUAWidgetTeardown"), + Atom("onUnselectedTabHover_Disable", "onUnselectedTabHover:Disable"), + Atom("onUnselectedTabHover_Enable", "onUnselectedTabHover:Enable"), + Atom("onZoomChangeUsingMouseWheel", "onZoomChangeUsingMouseWheel"), + Atom("onmozshowdropdown", "onmozshowdropdown"), + Atom("onmozshowdropdown_sourcetouch", "onmozshowdropdown-sourcetouch"), + Atom("onprintPreviewUpdate", "onprintPreviewUpdate"), + Atom("onscrollend", "onscrollend"), + # WebExtensions Atom("moz_extension", "moz-extension"), Atom("all_urlsPermission", ""), diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index b281571eea..ebdcb0431c 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -428,9 +428,9 @@ void nsAtomSubTable::GCLocked(GCKind aKind) { if (nonZeroRefcountAtomsCount == 0) { nonZeroRefcountAtoms = name; } else if (nonZeroRefcountAtomsCount < 20) { - nonZeroRefcountAtoms += NS_LITERAL_CSTRING(",") + name; + nonZeroRefcountAtoms += ","_ns + name; } else if (nonZeroRefcountAtomsCount == 20) { - nonZeroRefcountAtoms += NS_LITERAL_CSTRING(",..."); + nonZeroRefcountAtoms += ",..."_ns; } nonZeroRefcountAtomsCount++; } diff --git a/xpcom/ds/nsExpirationTracker.h b/xpcom/ds/nsExpirationTracker.h index cf16b775b5..724c8681f6 100644 --- a/xpcom/ds/nsExpirationTracker.h +++ b/xpcom/ds/nsExpirationTracker.h @@ -311,7 +311,7 @@ class ExpirationTrackerImpl { friend class Iterator; - bool IsEmptyLocked(const AutoLock& aAutoLock) { + bool IsEmptyLocked(const AutoLock& aAutoLock) const { for (uint32_t i = 0; i < K; ++i) { if (!mGenerations[i].IsEmpty()) { return false; @@ -320,6 +320,26 @@ class ExpirationTrackerImpl { return true; } + size_t Length(const AutoLock& aAutoLock) const { + size_t len = 0; + for (uint32_t i = 0; i < K; ++i) { + len += mGenerations[i].Length(); + } + return len; + } + + // @return The amount of memory used by this ExpirationTrackerImpl, excluding + // sizeof(*this). If you want to measure anything hanging off the mGenerations + // array, you must iterate over the elements and measure them individually; + // hence the "Shallow" prefix. + size_t ShallowSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { + size_t bytes = 0; + for (uint32_t i = 0; i < K; ++i) { + bytes += mGenerations[i].ShallowSizeOfExcludingThis(aMallocSizeOf); + } + return bytes; + } + protected: /** * This must be overridden to catch notifications. It is called whenever diff --git a/xpcom/ds/nsObserverService.cpp b/xpcom/ds/nsObserverService.cpp index e56255bf1a..2b342b22d0 100644 --- a/xpcom/ds/nsObserverService.cpp +++ b/xpcom/ds/nsObserverService.cpp @@ -97,10 +97,10 @@ nsObserverService::CollectReports(nsIHandleReportCallback* aHandleReport, aHandleReport->Callback( /* process */ EmptyCString(), suspectPath, KIND_OTHER, UNITS_COUNT, suspect.mReferentCount, - NS_LITERAL_CSTRING("A topic with a suspiciously large number of " - "referents. This may be symptomatic of a leak " - "if the number of referents is high with " - "respect to the number of windows."), + nsLiteralCString("A topic with a suspiciously large number of " + "referents. This may be symptomatic of a leak " + "if the number of referents is high with " + "respect to the number of windows."), aData); } @@ -187,8 +187,7 @@ nsresult nsObserverService::FilterHttpOnTopics(const char* aTopic) { do_GetService(NS_CONSOLESERVICE_CONTRACTID)); nsCOMPtr error( do_CreateInstance(NS_SCRIPTERROR_CONTRACTID)); - error->Init(NS_LITERAL_STRING( - "http-on-* observers only work in the parent process"), + error->Init(u"http-on-* observers only work in the parent process"_ns, EmptyString(), EmptyString(), 0, 0, nsIScriptError::warningFlag, "chrome javascript", false /* from private window */, true /* from chrome context */); diff --git a/xpcom/idl-parser/xpidl/runtests.py b/xpcom/idl-parser/xpidl/runtests.py index 8d4570d312..6ee5b889ea 100644 --- a/xpcom/idl-parser/xpidl/runtests.py +++ b/xpcom/idl-parser/xpidl/runtests.py @@ -63,13 +63,15 @@ void bar(); self.assertEqual(xpidl.TypeId("void"), m.type) def testMethodParams(self): - i = self.p.parse("""[uuid(abc)] interface foo { -long bar(in long a, in float b, [array] in long c); -};""", filename='f') + i = self.p.parse(""" + [scriptable, uuid(aaa)] interface nsISupports {}; + [uuid(abc)] interface foo : nsISupports { + long bar(in long a, in float b, [array] in long c); + };""", filename='f') i.resolve([], self.p, {}) self.assertTrue(isinstance(i, xpidl.IDL)) - self.assertTrue(isinstance(i.productions[0], xpidl.Interface)) - iface = i.productions[0] + self.assertTrue(isinstance(i.productions[1], xpidl.Interface)) + iface = i.productions[1] m = iface.members[0] self.assertTrue(isinstance(m, xpidl.Method)) self.assertEqual("bar", m.name) @@ -97,10 +99,12 @@ attribute long bar; self.assertEqual(xpidl.TypeId("long"), a.type) def testOverloadedVirtual(self): - i = self.p.parse("""[uuid(abc)] interface foo { -attribute long bar; -void getBar(); -};""", filename='f') + i = self.p.parse(""" + [scriptable, uuid(00000000-0000-0000-0000-000000000000)] interface nsISupports {}; + [uuid(abc)] interface foo : nsISupports { + attribute long bar; + void getBar(); + };""", filename='f') self.assertTrue(isinstance(i, xpidl.IDL)) i.resolve([], self.p, {}) @@ -114,9 +118,24 @@ void getBar(); self.assertEqual( e.args[0], "Unexpected overloaded virtual method GetBar in interface foo") + def testNotISupports(self): + i = self.p.parse(""" + [uuid(abc)] interface foo {}; + """, filename='f') + self.assertTrue(isinstance(i, xpidl.IDL)) + try: + i.resolve([], self.p, {}) + self.assertTrue(False, + "Must check that interfaces inherit from nsISupports") + except xpidl.IDLError as e: + self.assertEqual( + e.message, + "Interface 'foo' must inherit from nsISupports") + def testBuiltinClassParent(self): i = self.p.parse(""" - [scriptable, builtinclass, uuid(abc)] interface foo {}; + [scriptable, uuid(aaa)] interface nsISupports {}; + [scriptable, builtinclass, uuid(abc)] interface foo : nsISupports {}; [scriptable, uuid(def)] interface bar : foo {}; """, filename='f') self.assertTrue(isinstance(i, xpidl.IDL)) @@ -132,7 +151,8 @@ void getBar(); def testScriptableNotXPCOM(self): # notxpcom method requires builtinclass on the interface i = self.p.parse(""" - [scriptable, uuid(abc)] interface nsIScriptableWithNotXPCOM { + [scriptable, uuid(aaa)] interface nsISupports {}; + [scriptable, uuid(abc)] interface nsIScriptableWithNotXPCOM : nsISupports { [notxpcom] void method2(); }; """, filename='f') @@ -150,7 +170,8 @@ void getBar(); # notxpcom attribute requires builtinclass on the interface i = self.p.parse(""" interface nsISomeInterface; - [scriptable, uuid(abc)] interface nsIScriptableWithNotXPCOM { + [scriptable, uuid(aaa)] interface nsISupports {}; + [scriptable, uuid(abc)] interface nsIScriptableWithNotXPCOM : nsISupports { [notxpcom] attribute nsISomeInterface attrib; }; """, filename='f') diff --git a/xpcom/idl-parser/xpidl/rust.py b/xpcom/idl-parser/xpidl/rust.py index c628539769..93d96b124f 100644 --- a/xpcom/idl-parser/xpidl/rust.py +++ b/xpcom/idl-parser/xpidl/rust.py @@ -479,12 +479,7 @@ def write_interface(iface, fd): if iface.namemap is None: raise Exception("Interface was not resolved.") - # if we see a base class-less type other than nsISupports, we just need - # to discard anything else about it other than its constants. - if iface.base is None and iface.name != "nsISupports": - assert len([m for m in iface.members - if type(m) == xpidl.Attribute or type(m) == xpidl.Method]) == 0 - return + assert iface.base or (iface.name == "nsISupports") # Extract the UUID's information so that it can be written into the struct definition names = uuid_decoder.match(iface.attributes.uuid).groupdict() diff --git a/xpcom/idl-parser/xpidl/rust_macros.py b/xpcom/idl-parser/xpidl/rust_macros.py index fec08e02ea..45b37d5f4a 100644 --- a/xpcom/idl-parser/xpidl/rust_macros.py +++ b/xpcom/idl-parser/xpidl/rust_macros.py @@ -51,12 +51,7 @@ def write_interface(iface, fd): if iface.namemap is None: raise Exception("Interface was not resolved.") - # if we see a base class-less type other than nsISupports, we just need - # to discard anything else about it other than its constants. - if iface.base is None and iface.name != "nsISupports": - assert len([m for m in iface.members - if type(m) == xpidl.Attribute or type(m) == xpidl.Method]) == 0 - return + assert iface.base or (iface.name == "nsISupports") base = 'Some("%s")' % iface.base if iface.base is not None else 'None' try: diff --git a/xpcom/idl-parser/xpidl/xpidl.py b/xpcom/idl-parser/xpidl/xpidl.py index 9d6ba2bf78..ea9483e50b 100644 --- a/xpcom/idl-parser/xpidl/xpidl.py +++ b/xpcom/idl-parser/xpidl/xpidl.py @@ -680,7 +680,7 @@ class Interface(object): if self.attributes.function: has_method = False for member in self.members: - if member.kind is 'method': + if member.kind == 'method': if has_method: raise IDLError( "interface '%s' has multiple methods, but marked 'function'" % @@ -705,6 +705,9 @@ class Interface(object): raise IDLError("interface '%s' is not builtinclass but derives from " "builtinclass '%s'" % (self.name, self.base), self.location) + elif self.name != 'nsISupports': + raise IDLError("Interface '%s' must inherit from nsISupports" % + self.name, self.location) for member in self.members: member.resolve(self) diff --git a/xpcom/io/Base64.cpp b/xpcom/io/Base64.cpp index aba99dba01..389d25a22d 100644 --- a/xpcom/io/Base64.cpp +++ b/xpcom/io/Base64.cpp @@ -200,7 +200,7 @@ nsresult EncodeInputStream(nsIInputStream* aInputStream, T& aDest, state.c[2] = '\0'; state.buffer = aOffset + aDest.BeginWriting(); - while (1) { + while (true) { uint32_t read = 0; rv = aInputStream->ReadSegments(&EncodeInputStream_Encoder, @@ -357,37 +357,61 @@ nsresult Base64Encode(const char* aBinary, uint32_t aBinaryLen, return NS_OK; } -template -static nsresult Base64EncodeHelper(const T& aBinary, T& aBase64) { - // Check for overflow. - if (aBinary.Length() > (UINT32_MAX / 4) * 3) { - return NS_ERROR_FAILURE; - } - - if (aBinary.IsEmpty()) { - aBase64.Truncate(); +template +static nsresult Base64EncodeHelper(const T* const aBinary, + const size_t aBinaryLen, U& aBase64) { + if (aBinaryLen == 0) { + if (!Append) { + aBase64.Truncate(); + } return NS_OK; } - uint32_t base64Len = ((aBinary.Length() + 2) / 3) * 4; + const uint32_t prefixLen = Append ? aBase64.Length() : 0; + const auto base64LenOrErr = [aBinaryLen, + prefixLen]() -> Result { + // XXX(sg) Necessary to silence bad warning about unused lambda capture when + // Append is false. + (void)prefixLen; + CheckedUint32 res = aBinaryLen; + // base 64 encoded length is 4/3rds the length of the input data, rounded up + res += 2; + res /= 3; + res *= 4; + res += prefixLen; + if (!res.isValid()) { + return Err(NS_ERROR_FAILURE); + } + return res.value(); + }(); + if (base64LenOrErr.isErr()) { + return base64LenOrErr.inspectErr(); + } + const uint32_t base64Len = base64LenOrErr.inspect(); - nsresult rv; - auto handle = aBase64.BulkWrite(base64Len, 0, false, rv); - if (NS_FAILED(rv)) { - return rv; + auto handleOrErr = aBase64.BulkWrite(base64Len, prefixLen, false); + if (handleOrErr.isErr()) { + return handleOrErr.unwrapErr(); } - Encode(aBinary.BeginReading(), aBinary.Length(), handle.Elements()); + auto handle = handleOrErr.unwrap(); + + Encode(aBinary, aBinaryLen, handle.Elements() + prefixLen); handle.Finish(base64Len, false); return NS_OK; } +nsresult Base64EncodeAppend(const char* aBinary, uint32_t aBinaryLen, + nsAString& aBase64) { + return Base64EncodeHelper(aBinary, aBinaryLen, aBase64); +} + nsresult Base64Encode(const nsACString& aBinary, nsACString& aBase64) { - return Base64EncodeHelper(aBinary, aBase64); + return Base64EncodeHelper(aBinary.BeginReading(), aBinary.Length(), aBase64); } nsresult Base64Encode(const nsAString& aBinary, nsAString& aBase64) { - return Base64EncodeHelper(aBinary, aBase64); + return Base64EncodeHelper(aBinary.BeginReading(), aBinary.Length(), aBase64); } template @@ -533,17 +557,18 @@ static nsresult Base64DecodeString(const T& aBase64, T& aBinary) { uint32_t binaryLen = ((aBase64.Length() * 3) / 4); - nsresult rv; - auto handle = aBinary.BulkWrite(binaryLen, 0, false, rv); - if (NS_FAILED(rv)) { + auto handleOrErr = aBinary.BulkWrite(binaryLen, 0, false); + if (handleOrErr.isErr()) { // Must not touch the handle if failing here, but we // already truncated the string at the top, so it's // unchanged. - return rv; + return handleOrErr.unwrapErr(); } - rv = Base64DecodeHelper(aBase64.BeginReading(), aBase64.Length(), - handle.Elements(), &binaryLen); + auto handle = handleOrErr.unwrap(); + + nsresult rv = Base64DecodeHelper(aBase64.BeginReading(), aBase64.Length(), + handle.Elements(), &binaryLen); if (NS_FAILED(rv)) { // Retruncate to match old semantics of this method. handle.Finish(0, true); @@ -662,12 +687,13 @@ nsresult Base64URLEncode(uint32_t aBinaryLen, const uint8_t* aBinary, // Allocate a buffer large enough to hold the encoded string with padding. uint32_t base64Len = ((aBinaryLen + 2) / 3) * 4; - nsresult rv; - auto handle = aBase64.BulkWrite(base64Len, 0, false, rv); - if (NS_FAILED(rv)) { - return rv; + auto handleOrErr = aBase64.BulkWrite(base64Len, 0, false); + if (handleOrErr.isErr()) { + return handleOrErr.unwrapErr(); } + auto handle = handleOrErr.unwrap(); + char* base64 = handle.Elements(); uint32_t index = 0; diff --git a/xpcom/io/Base64.h b/xpcom/io/Base64.h index 99fbb314fe..762d0e937b 100644 --- a/xpcom/io/Base64.h +++ b/xpcom/io/Base64.h @@ -20,6 +20,11 @@ namespace mozilla { uint32_t aCount, uint32_t aOffset = 0); +// Encode 8-bit data of a given length and append the Base64 encoded data to +// aBase64. +[[nodiscard]] nsresult Base64EncodeAppend(const char* aBinary, + uint32_t aBinaryLen, + nsAString& aBase64); [[nodiscard]] nsresult Base64Encode(const char* aBinary, uint32_t aBinaryLen, char** aBase64); [[nodiscard]] nsresult Base64Encode(const nsACString& aBinary, diff --git a/xpcom/io/SpecialSystemDirectory.cpp b/xpcom/io/SpecialSystemDirectory.cpp index 8b4d6bc46a..be7f3f09fc 100644 --- a/xpcom/io/SpecialSystemDirectory.cpp +++ b/xpcom/io/SpecialSystemDirectory.cpp @@ -404,7 +404,7 @@ static nsresult GetUnixXDGUserDirectory(SystemDirectories aSystemDirectory, return rv; } - rv = file->AppendNative(NS_LITERAL_CSTRING("Desktop")); + rv = file->AppendNative("Desktop"_ns); } else { // no fallback for the other XDG dirs rv = NS_ERROR_FAILURE; diff --git a/xpcom/io/SpecialSystemDirectory.h b/xpcom/io/SpecialSystemDirectory.h index 25a289bbb6..1c16124220 100644 --- a/xpcom/io/SpecialSystemDirectory.h +++ b/xpcom/io/SpecialSystemDirectory.h @@ -17,7 +17,8 @@ extern void StartupSpecialSystemDirectory(); enum SystemDirectories { OS_TemporaryDirectory = 2, - OS_CurrentProcessDirectory = 3, + // 3 Used to be OS_CurrentProcessDirectory, which we never actually + // supported getting... OS_CurrentWorkingDirectory = 4, Win_SystemDirectory = 201, diff --git a/xpcom/io/nsBinaryStream.cpp b/xpcom/io/nsBinaryStream.cpp index dffd38c88d..eb32ed91de 100644 --- a/xpcom/io/nsBinaryStream.cpp +++ b/xpcom/io/nsBinaryStream.cpp @@ -784,9 +784,9 @@ nsBinaryInputStream::ReadByteArray(uint32_t aLength, } NS_IMETHODIMP -nsBinaryInputStream::ReadArrayBuffer(uint32_t aLength, +nsBinaryInputStream::ReadArrayBuffer(uint64_t aLength, JS::Handle aBuffer, - JSContext* aCx, uint32_t* aReadLength) { + JSContext* aCx, uint64_t* aReadLength) { if (!aBuffer.isObject()) { return NS_ERROR_FAILURE; } @@ -795,20 +795,20 @@ nsBinaryInputStream::ReadArrayBuffer(uint32_t aLength, return NS_ERROR_FAILURE; } - uint32_t bufferLength = JS::GetArrayBufferByteLength(buffer); + size_t bufferLength = JS::GetArrayBufferByteLength(buffer); if (bufferLength < aLength) { return NS_ERROR_FAILURE; } - uint32_t bufSize = std::min(aLength, 4096); + uint32_t bufSize = std::min(aLength, 4096); UniquePtr buf = MakeUnique(bufSize); - uint32_t pos = 0; + uint64_t pos = 0; *aReadLength = 0; do { // Read data into temporary buffer. uint32_t bytesRead; - uint32_t amount = std::min(aLength - pos, bufSize); + uint32_t amount = std::min(aLength - pos, bufSize); nsresult rv = Read(buf.get(), amount, &bytesRead); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; diff --git a/xpcom/io/nsDirectoryService.cpp b/xpcom/io/nsDirectoryService.cpp index 1a90f3c94c..ad3873d3a2 100644 --- a/xpcom/io/nsDirectoryService.cpp +++ b/xpcom/io/nsDirectoryService.cpp @@ -52,21 +52,23 @@ nsresult nsDirectoryService::GetCurrentProcessDirectory(nsIFile** aFile) return NS_ERROR_FAILURE; } - nsCOMPtr file; - gService->Get(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), - getter_AddRefs(file)); - if (file) { - file.forget(aFile); - return NS_OK; + if (!mXCurProcD) { + nsCOMPtr file; + if (NS_SUCCEEDED(BinaryPath::GetFile(getter_AddRefs(file)))) { + nsresult rv = file->GetParent(getter_AddRefs(mXCurProcD)); + if (NS_FAILED(rv)) { + return rv; + } + } } - - if (NS_SUCCEEDED(BinaryPath::GetFile(getter_AddRefs(file)))) { - return file->GetParent(aFile); - } - NS_ERROR("unable to get current process directory"); - return NS_ERROR_FAILURE; + return mXCurProcD->Clone(aFile); } // GetCurrentProcessDirectory() +nsresult nsDirectoryService::SetCurrentProcessDirectory(nsIFile* aFile) { + mXCurProcD = aFile; + return NS_OK; +} + StaticRefPtr nsDirectoryService::gService; nsDirectoryService::nsDirectoryService() : mHashtable(128) {} @@ -314,7 +316,7 @@ static nsresult GetLowIntegrityTempBase(nsIFile** aLowIntegrityTempBase) { return rv; } - rv = localFile->Append(NS_LITERAL_STRING(MOZ_USER_DIR)); + rv = localFile->Append(NS_LITERAL_STRING_FROM_CSTRING(MOZ_USER_DIR)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -355,9 +357,6 @@ nsDirectoryService::GetFile(const char* aProp, bool* aPersistent, } else if (inAtom == nsGkAtoms::DirectoryService_OS_TemporaryDirectory) { rv = GetSpecialSystemDirectory(OS_TemporaryDirectory, getter_AddRefs(localFile)); - } else if (inAtom == nsGkAtoms::DirectoryService_OS_CurrentProcessDirectory) { - rv = GetSpecialSystemDirectory(OS_CurrentProcessDirectory, - getter_AddRefs(localFile)); } else if (inAtom == nsGkAtoms::DirectoryService_OS_CurrentWorkingDirectory) { rv = GetSpecialSystemDirectory(OS_CurrentWorkingDirectory, getter_AddRefs(localFile)); diff --git a/xpcom/io/nsDirectoryService.h b/xpcom/io/nsDirectoryService.h index 63e9c56595..4b7e3a345a 100644 --- a/xpcom/io/nsDirectoryService.h +++ b/xpcom/io/nsDirectoryService.h @@ -13,9 +13,6 @@ #include "mozilla/Attributes.h" #include "mozilla/StaticPtr.h" -#define NS_XPCOM_INIT_CURRENT_PROCESS_DIR \ - "MozBinD" // Can be used to set NS_XPCOM_CURRENT_PROCESS_DIR - // CANNOT be used to GET a location #define NS_DIRECTORY_SERVICE_CID \ { \ 0xf00152d0, 0xb40b, 0x11d3, { \ @@ -46,10 +43,12 @@ class nsDirectoryService final : public nsIDirectoryService, static mozilla::StaticRefPtr gService; + nsresult SetCurrentProcessDirectory(nsIFile* aFile); + nsresult GetCurrentProcessDirectory(nsIFile** aFile); + private: ~nsDirectoryService(); - - nsresult GetCurrentProcessDirectory(nsIFile** aFile); + nsCOMPtr mXCurProcD; nsInterfaceHashtable mHashtable; nsTArray> mProviders; diff --git a/xpcom/io/nsIBinaryInputStream.idl b/xpcom/io/nsIBinaryInputStream.idl index 897d0651de..ebc7da605e 100644 --- a/xpcom/io/nsIBinaryInputStream.idl +++ b/xpcom/io/nsIBinaryInputStream.idl @@ -77,7 +77,7 @@ interface nsIBinaryInputStream : nsIInputStream { * @return The number of bytes actually read into aArrayBuffer. */ [implicit_jscontext] - unsigned long readArrayBuffer(in uint32_t aLength, in jsval aArrayBuffer); + uint64_t readArrayBuffer(in uint64_t aLength, in jsval aArrayBuffer); }; %{C++ diff --git a/xpcom/io/nsLocalFileUnix.cpp b/xpcom/io/nsLocalFileUnix.cpp index 238d5d4290..4d12484732 100644 --- a/xpcom/io/nsLocalFileUnix.cpp +++ b/xpcom/io/nsLocalFileUnix.cpp @@ -32,7 +32,6 @@ # endif #endif -#include "xpcom-private.h" #include "nsDirectoryServiceDefs.h" #include "nsCRT.h" #include "nsCOMPtr.h" @@ -70,6 +69,43 @@ static nsresult MacErrorMapper(OSErr inErr); #include "nsTraceRefcnt.h" #include "nsHashKeys.h" +/** + * we need these for statfs() + */ +#ifdef HAVE_SYS_STATVFS_H +# if defined(__osf__) && defined(__DECCXX) +extern "C" int statvfs(const char*, struct statvfs*); +# endif +# include +#endif + +#ifdef HAVE_SYS_STATFS_H +# include +#endif + +#ifdef HAVE_SYS_VFS_H +# include +#endif + +#ifdef HAVE_SYS_MOUNT_H +# include +# include +#endif + +#if defined(HAVE_STATVFS64) && (!defined(LINUX) && !defined(__osf__)) +# define STATFS statvfs64 +# define F_BSIZE f_frsize +#elif defined(HAVE_STATVFS) && (!defined(LINUX) && !defined(__osf__)) +# define STATFS statvfs +# define F_BSIZE f_frsize +#elif defined(HAVE_STATFS64) +# define STATFS statfs64 +# define F_BSIZE f_bsize +#elif defined(HAVE_STATFS) +# define STATFS statfs +# define F_BSIZE f_bsize +#endif + using namespace mozilla; #define ENSURE_STAT_CACHE() \ @@ -654,7 +690,7 @@ nsresult nsLocalFile::GetNativeTargetPathName(nsIFile* aNewParent, return rv; } - aResult = dirName + NS_LITERAL_CSTRING("/") + Substring(nameBegin, nameEnd); + aResult = dirName + "/"_ns + Substring(nameBegin, nameEnd); return NS_OK; } @@ -1969,7 +2005,7 @@ nsLocalFile::Launch() { rv = mimeService->GetTypeFromFile(this, type); } - nsAutoCString fileUri = NS_LITERAL_CSTRING("file://") + mPath; + nsAutoCString fileUri = "file://"_ns + mPath; return java::GeckoAppShell::OpenUriExternal( NS_ConvertUTF8toUTF16(fileUri), NS_ConvertUTF8toUTF16(type), EmptyString(), EmptyString(), EmptyString(), EmptyString()) diff --git a/xpcom/io/nsLocalFileUnix.h b/xpcom/io/nsLocalFileUnix.h index 22038c3a36..2318a9a50b 100644 --- a/xpcom/io/nsLocalFileUnix.h +++ b/xpcom/io/nsLocalFileUnix.h @@ -22,43 +22,6 @@ # include "nsILocalFileMac.h" #endif -/** - * we need these for statfs() - */ -#ifdef HAVE_SYS_STATVFS_H -# if defined(__osf__) && defined(__DECCXX) -extern "C" int statvfs(const char*, struct statvfs*); -# endif -# include -#endif - -#ifdef HAVE_SYS_STATFS_H -# include -#endif - -#ifdef HAVE_SYS_VFS_H -# include -#endif - -#ifdef HAVE_SYS_MOUNT_H -# include -# include -#endif - -#if defined(HAVE_STATVFS64) && (!defined(LINUX) && !defined(__osf__)) -# define STATFS statvfs64 -# define F_BSIZE f_frsize -#elif defined(HAVE_STATVFS) && (!defined(LINUX) && !defined(__osf__)) -# define STATFS statvfs -# define F_BSIZE f_frsize -#elif defined(HAVE_STATFS64) -# define STATFS statfs64 -# define F_BSIZE f_bsize -#elif defined(HAVE_STATFS) -# define STATFS statfs -# define F_BSIZE f_bsize -#endif - // stat64 and lstat64 are deprecated on OS X. Normal stat and lstat are // 64-bit by default on OS X 10.6+. #if defined(HAVE_STAT64) && defined(HAVE_LSTAT64) && !defined(XP_DARWIN) diff --git a/xpcom/io/nsLocalFileWin.cpp b/xpcom/io/nsLocalFileWin.cpp index 1532c18832..529b190bf0 100644 --- a/xpcom/io/nsLocalFileWin.cpp +++ b/xpcom/io/nsLocalFileWin.cpp @@ -1335,7 +1335,7 @@ nsresult nsLocalFile::AppendInternal(const nsString& aNode, } // catches the remaining cases of prefixes - if (StringBeginsWith(aNode, NS_LITERAL_STRING("..\\"))) { + if (StringBeginsWith(aNode, u"..\\"_ns)) { return NS_ERROR_FILE_UNRECOGNIZED_PATH; } } @@ -1433,7 +1433,7 @@ nsLocalFile::Normalize() { if (currentDir.Last() == '\\') { path.Replace(0, 2, currentDir); } else { - path.Replace(0, 2, currentDir + NS_LITERAL_STRING("\\")); + path.Replace(0, 2, currentDir + u"\\"_ns); } } diff --git a/xpcom/io/nsMultiplexInputStream.cpp b/xpcom/io/nsMultiplexInputStream.cpp index 650863ddd3..71cc46a0f9 100644 --- a/xpcom/io/nsMultiplexInputStream.cpp +++ b/xpcom/io/nsMultiplexInputStream.cpp @@ -814,7 +814,7 @@ nsMultiplexInputStream::CloseWithStatus(nsresult aStatus) { return Close(); } // This class is used to inform nsMultiplexInputStream that it's time to execute // the asyncWait callback. -class AsyncWaitRunnable final : public CancelableRunnable { +class AsyncWaitRunnable final : public DiscardableRunnable { RefPtr mStream; public: @@ -836,7 +836,7 @@ class AsyncWaitRunnable final : public CancelableRunnable { private: explicit AsyncWaitRunnable(nsMultiplexInputStream* aStream) - : CancelableRunnable("AsyncWaitRunnable"), mStream(aStream) { + : DiscardableRunnable("AsyncWaitRunnable"), mStream(aStream) { MOZ_ASSERT(aStream); } }; diff --git a/xpcom/io/nsNativeCharsetUtils.cpp b/xpcom/io/nsNativeCharsetUtils.cpp index 5afa14eed6..bcf5712aea 100644 --- a/xpcom/io/nsNativeCharsetUtils.cpp +++ b/xpcom/io/nsNativeCharsetUtils.cpp @@ -2,8 +2,6 @@ * 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 "xpcom-private.h" - //----------------------------------------------------------------------------- // Non-Windows //----------------------------------------------------------------------------- diff --git a/xpcom/io/nsStorageStream.cpp b/xpcom/io/nsStorageStream.cpp index 31d538dde2..05bb21bb73 100644 --- a/xpcom/io/nsStorageStream.cpp +++ b/xpcom/io/nsStorageStream.cpp @@ -601,8 +601,10 @@ void nsStorageInputStream::SerializeInternal(InputStreamParams& aParams, rv = Tell(&offset); MOZ_ASSERT(NS_SUCCEEDED(rv)); - auto handle = combined.BulkWrite(remaining, 0, false, rv); - MOZ_ASSERT(NS_SUCCEEDED(rv)); + auto handleOrErr = combined.BulkWrite(remaining, 0, false); + MOZ_ASSERT(!handleOrErr.isErr()); + + auto handle = handleOrErr.unwrap(); uint32_t numRead = 0; diff --git a/xpcom/moz.build b/xpcom/moz.build index 37699dbf2d..06adb5c747 100644 --- a/xpcom/moz.build +++ b/xpcom/moz.build @@ -38,7 +38,6 @@ TEST_DIRS += [ CONFIGURE_DEFINE_FILES += [ 'xpcom-config.h', - 'xpcom-private.h', ] EXPORTS += [ diff --git a/xpcom/rust/gtest/nsstring/Test.cpp b/xpcom/rust/gtest/nsstring/Test.cpp index c601b52ee7..4e14c7bca5 100644 --- a/xpcom/rust/gtest/nsstring/Test.cpp +++ b/xpcom/rust/gtest/nsstring/Test.cpp @@ -160,3 +160,18 @@ TEST(RustNsString, InlineCapacityFromRust) EXPECT_EQ(cStrCapacity, 92U); EXPECT_EQ(strCapacity, 92U); } + +extern "C" void Rust_VoidStringFromRust(nsACString* aCStr, nsAString* aStr); +TEST(RustNsString, VoidStringFromRust) +{ + nsAutoCString cs; + nsAutoString s; + + EXPECT_FALSE(cs.IsVoid()); + EXPECT_FALSE(s.IsVoid()); + + Rust_VoidStringFromRust(&cs, &s); + + EXPECT_TRUE(cs.IsVoid()); + EXPECT_TRUE(s.IsVoid()); +} diff --git a/xpcom/rust/gtest/nsstring/test.rs b/xpcom/rust/gtest/nsstring/test.rs index 18640994c5..25ec4ee2ef 100644 --- a/xpcom/rust/gtest/nsstring/test.rs +++ b/xpcom/rust/gtest/nsstring/test.rs @@ -122,3 +122,9 @@ pub extern "C" fn Rust_WriteToBufferFromRust( fallible_s_buf[2] = b'C' as u16; } } + +#[no_mangle] +pub extern "C" fn Rust_VoidStringFromRust(cs: &mut nsACString, s: &mut nsAString) { + cs.set_is_void(true); + s.set_is_void(true); +} diff --git a/xpcom/rust/nsstring/src/lib.rs b/xpcom/rust/nsstring/src/lib.rs index 2485a3598b..698a335f58 100644 --- a/xpcom/rust/nsstring/src/lib.rs +++ b/xpcom/rust/nsstring/src/lib.rs @@ -546,6 +546,23 @@ macro_rules! define_string_types { } } + /// Mark the string's data as void. If `true`, the string will be truncated. + /// + /// A void string is generally converted to a `null` JS value by bindings code. + pub fn set_is_void(&mut self, is_void: bool) { + if is_void { + self.truncate(); + } + unsafe { + self.as_repr_mut().as_mut().dataflags.set(DataFlags::VOIDED, is_void); + } + } + + /// Returns whether the string's data is voided. + pub fn is_void(&self) -> bool { + self.as_repr().dataflags.contains(DataFlags::VOIDED) + } + /// Set the length of the string to the passed-in length, and expand /// the backing capacity to match. This method is unsafe as it can /// expose uninitialized memory when len is greater than the current diff --git a/xpcom/string/nsLiteralString.h b/xpcom/string/nsLiteralString.h index 4e2a31fa92..b148a411bd 100644 --- a/xpcom/string/nsLiteralString.h +++ b/xpcom/string/nsLiteralString.h @@ -12,6 +12,12 @@ #include "mozilla/Char16.h" +#define NS_CSTRING_LITERAL_AS_STRING_LITERAL(s) u"" s + +#define NS_LITERAL_STRING_FROM_CSTRING(s) \ + static_cast( \ + nsLiteralString(NS_CSTRING_LITERAL_AS_STRING_LITERAL(s))) + #define NS_LITERAL_STRING(s) \ static_cast(nsLiteralString(u"" s)) #define NS_NAMED_LITERAL_STRING(n, s) const nsLiteralString n(u"" s) @@ -20,4 +26,12 @@ static_cast(nsLiteralCString("" s)) #define NS_NAMED_LITERAL_CSTRING(n, s) const nsLiteralCString n("" s) +constexpr auto operator""_ns(const char* aStr, std::size_t aLen) { + return nsLiteralCString{aStr, aLen}; +} + +constexpr auto operator""_ns(const char16_t* aStr, std::size_t aLen) { + return nsLiteralString{aStr, aLen}; +} + #endif /* !defined(nsLiteralString_h___) */ diff --git a/xpcom/string/nsStringBuffer.h b/xpcom/string/nsStringBuffer.h index f675b02e8f..b1ecac9d53 100644 --- a/xpcom/string/nsStringBuffer.h +++ b/xpcom/string/nsStringBuffer.h @@ -11,22 +11,6 @@ template struct already_AddRefed; -/* - * Add a canary field to protect against double-frees of nsStringBuffer and - * other potential heap corruptions. We intend to back this out before 58 hits - * beta. - */ -#if (defined(DEBUG) || defined(NIGHTLY_BUILD)) && !defined(MOZ_ASAN) -# define STRING_BUFFER_CANARY 1 -#endif - -#ifdef STRING_BUFFER_CANARY -enum nsStringBufferCanary : uint32_t { - CANARY_OK = 0xaf57c8fa, - CANARY_POISON = 0x534dc0f5 -}; -#endif - /** * This structure precedes the string buffers "we" allocate. It may be the * case that nsTAString::mData does not point to one of these special @@ -43,10 +27,6 @@ class nsStringBuffer { std::atomic mRefCount; uint32_t mStorageSize; -#ifdef STRING_BUFFER_CANARY - uint32_t mCanary; -#endif - public: /** * Allocates a new string buffer, with given size in bytes and a @@ -94,11 +74,7 @@ class nsStringBuffer { * call to the nsStringBuffer::Data method. */ static nsStringBuffer* FromData(void* aData) { - nsStringBuffer* sb = reinterpret_cast(aData) - 1; -#ifdef STRING_BUFFER_CANARY - if (MOZ_UNLIKELY(sb->mCanary != CANARY_OK)) sb->FromDataCanaryCheckFailed(); -#endif - return sb; + return reinterpret_cast(aData) - 1; } /** @@ -192,15 +168,6 @@ class nsStringBuffer { */ size_t SizeOfIncludingThisEvenIfShared( mozilla::MallocSizeOf aMallocSizeOf) const; - -#ifdef STRING_BUFFER_CANARY - /* - * Called by FromData if the canary check failed. This is out-of-line in - * nsSubstring.cpp so that MOZ_CRASH_UNSAFE_PRINTF is available via #includes. - * It is not available in FromData due to #include-order. - */ - void FromDataCanaryCheckFailed() const; -#endif }; #endif /* !defined(nsStringBuffer_h__ */ diff --git a/xpcom/string/nsStringObsolete.cpp b/xpcom/string/nsStringObsolete.cpp index cd220582b5..b53dc2244d 100644 --- a/xpcom/string/nsStringObsolete.cpp +++ b/xpcom/string/nsStringObsolete.cpp @@ -788,6 +788,9 @@ int32_t nsTString::Find(const self_type& aString, int32_t aOffset, return result; } +template int32_t nsTString::Find(const self_type&, int32_t, + int32_t) const; + template template int32_t nsTString::Find(const char_type* aString, int32_t aOffset, @@ -795,6 +798,9 @@ int32_t nsTString::Find(const char_type* aString, int32_t aOffset, return Find(nsTDependentString(aString), aOffset, aCount); } +template int32_t nsTString::Find(const char_type*, int32_t, + int32_t) const; + template template int32_t nsTString::RFind(const self_type& aString, int32_t aOffset, @@ -810,6 +816,9 @@ int32_t nsTString::RFind(const self_type& aString, int32_t aOffset, return result; } +template int32_t nsTString::RFind(const self_type&, int32_t, + int32_t) const; + template template int32_t nsTString::RFind(const char_type* aString, int32_t aOffset, @@ -817,6 +826,9 @@ int32_t nsTString::RFind(const char_type* aString, int32_t aOffset, return RFind(nsTDependentString(aString), aOffset, aCount); } +template int32_t nsTString::RFind(const char_type*, int32_t, + int32_t) const; + template template int32_t nsTString::FindCharInSet(const char* aSet, int32_t aOffset) const { @@ -831,6 +843,8 @@ int32_t nsTString::FindCharInSet(const char* aSet, int32_t aOffset) const { return result; } +template int32_t nsTString::FindCharInSet(const char*, int32_t) const; + template template void nsTString::ReplaceChar(const char* aSet, char16_t aNewChar) { @@ -881,6 +895,9 @@ int32_t nsTStringRepr::Compare(const char_type* aString, bool aIgnoreCase, return result; } +template int32_t nsTStringRepr::Compare(const char_type*, bool, + int32_t) const; + template template bool nsTStringRepr::EqualsIgnoreCase(const incompatible_char_type* aString, @@ -910,6 +927,9 @@ bool nsTStringRepr::EqualsIgnoreCase(const incompatible_char_type* aString, return result == 0; } +template bool nsTStringRepr::EqualsIgnoreCase( + const incompatible_char_type*, int32_t) const; + } // namespace detail } // namespace mozilla diff --git a/xpcom/string/nsSubstring.cpp b/xpcom/string/nsSubstring.cpp index 8348be75d4..a18535f018 100644 --- a/xpcom/string/nsSubstring.cpp +++ b/xpcom/string/nsSubstring.cpp @@ -18,7 +18,6 @@ #include "nsString.h" #include "nsStringBuffer.h" #include "nsDependentString.h" -#include "nsPrintfCString.h" #include "nsMemory.h" #include "prprf.h" #include "nsCOMPtr.h" @@ -34,19 +33,6 @@ # include #endif -#ifdef STRING_BUFFER_CANARY -# define CHECK_STRING_BUFFER_CANARY(c) \ - do { \ - if ((c) != CANARY_OK) { \ - MOZ_CRASH_UNSAFE_PRINTF("Bad canary value 0x%x", c); \ - } \ - } while (0) -#else -# define CHECK_STRING_BUFFER_CANARY(c) \ - do { \ - } while (0) -#endif - using mozilla::Atomic; // --------------------------------------------------------------------------- @@ -183,8 +169,6 @@ void nsStringBuffer::AddRef() { } void nsStringBuffer::Release() { - CHECK_STRING_BUFFER_CANARY(mCanary); - // Since this may be the last release on this thread, we need // release semantics so that prior writes on this thread are visible // to the thread that destroys the object when it reads mValue with @@ -197,9 +181,6 @@ void nsStringBuffer::Release() { // the last release on other threads, that is, to ensure that // writes prior to that release are now visible on this thread. count = mRefCount.load(std::memory_order_acquire); -#ifdef STRING_BUFFER_CANARY - mCanary = CANARY_POISON; -#endif STRING_STAT_INCREMENT(Free); free(this); // we were allocated with |malloc| @@ -221,9 +202,6 @@ already_AddRefed nsStringBuffer::Alloc(size_t aSize) { hdr->mRefCount = 1; hdr->mStorageSize = aSize; -#ifdef STRING_BUFFER_CANARY - hdr->mCanary = CANARY_OK; -#endif NS_LOG_ADDREF(hdr, 1, "nsStringBuffer", sizeof(*hdr)); } return dont_AddRef(hdr); @@ -232,7 +210,6 @@ already_AddRefed nsStringBuffer::Alloc(size_t aSize) { nsStringBuffer* nsStringBuffer::Realloc(nsStringBuffer* aHdr, size_t aSize) { STRING_STAT_INCREMENT(Realloc); - CHECK_STRING_BUFFER_CANARY(aHdr->mCanary); NS_ASSERTION(aSize != 0, "zero capacity allocation not allowed"); NS_ASSERTION(sizeof(nsStringBuffer) + aSize <= size_t(uint32_t(-1)) && sizeof(nsStringBuffer) + aSize > aSize, @@ -321,12 +298,6 @@ size_t nsStringBuffer::SizeOfIncludingThisEvenIfShared( return aMallocSizeOf(this); } -#ifdef STRING_BUFFER_CANARY -void nsStringBuffer::FromDataCanaryCheckFailed() const { - MOZ_CRASH_UNSAFE_PRINTF("Bad canary value 0x%x in FromData", mCanary); -} -#endif - // --------------------------------------------------------------------------- // define nsAString diff --git a/xpcom/string/nsTDependentSubstring.cpp b/xpcom/string/nsTDependentSubstring.cpp index 5210ba6a0b..0ec5b66e71 100644 --- a/xpcom/string/nsTDependentSubstring.cpp +++ b/xpcom/string/nsTDependentSubstring.cpp @@ -81,6 +81,11 @@ const nsTDependentSubstring Substring(const T* aStart, const T* aEnd) { return nsTDependentSubstring(aStart, aEnd); } +template nsTDependentSubstring const Substring(char const*, + char const*); +template nsTDependentSubstring const Substring( + char16_t const*, char16_t const*); + #if defined(MOZ_USE_CHAR16_WRAPPER) const nsTDependentSubstring Substring(char16ptr_t aData, uint32_t aLength) { diff --git a/xpcom/string/nsTDependentSubstring.h b/xpcom/string/nsTDependentSubstring.h index 34af7f6d84..6698697272 100644 --- a/xpcom/string/nsTDependentSubstring.h +++ b/xpcom/string/nsTDependentSubstring.h @@ -128,6 +128,12 @@ inline const nsTDependentSubstring Substring(const T* aData, template const nsTDependentSubstring Substring(const T* aStart, const T* aEnd); +extern template const nsTDependentSubstring Substring(const char* aStart, + const char* aEnd); + +extern template const nsTDependentSubstring Substring( + const char16_t* aStart, const char16_t* aEnd); + #if defined(MOZ_USE_CHAR16_WRAPPER) inline const nsTDependentSubstring Substring(char16ptr_t aData, uint32_t aLength); diff --git a/xpcom/string/nsTLiteralString.h b/xpcom/string/nsTLiteralString.h index 7b9d24b643..168af91d08 100644 --- a/xpcom/string/nsTLiteralString.h +++ b/xpcom/string/nsTLiteralString.h @@ -45,9 +45,7 @@ class nsTLiteralString : public mozilla::detail::nsTStringRepr { template explicit constexpr nsTLiteralString(const char_type (&aStr)[N]) - : base_string_type(const_cast(aStr), N - 1, - DataFlags::TERMINATED | DataFlags::LITERAL, - ClassFlags::NULL_TERMINATED) {} + : nsTLiteralString(aStr, N - 1) {} /** * For compatibility with existing code that requires const ns[C]String*. @@ -73,13 +71,31 @@ class nsTLiteralString : public mozilla::detail::nsTStringRepr { #endif /** - * Prohibit get() on temporaries as in nsLiteralCString("x").get(). + * Prohibit get() on temporaries as in "x"_ns.get(). * These should be written as just "x", using a string literal directly. */ const typename raw_type::type get() const&& = delete; const typename raw_type::type get() const& { return this->mData; } +// At least older gcc versions do not accept these friend declarations, +// complaining about an "invalid argument list" here, but not where the actual +// operators are defined or used. We make the supposed-to-be-private constructor +// public when building with gcc, relying on the default clang builds to fail if +// any non-private use of that constructor would get into the codebase. +#if defined(__clang__) private: + friend constexpr auto operator"" _ns(const char* aStr, std::size_t aLen); + friend constexpr auto operator"" _ns(const char16_t* aStr, std::size_t aLen); +#else + public: +#endif + // Only for use by operator"" + constexpr nsTLiteralString(const char_type* aStr, size_t aLen) + : base_string_type(const_cast(aStr), aLen, + DataFlags::TERMINATED | DataFlags::LITERAL, + ClassFlags::NULL_TERMINATED) {} + + public: // NOT TO BE IMPLEMENTED template nsTLiteralString(char_type (&aStr)[N]) = delete; diff --git a/xpcom/string/nsTStringComparator.cpp b/xpcom/string/nsTStringComparator.cpp index 97502fe5ab..3be53ceda7 100644 --- a/xpcom/string/nsTStringComparator.cpp +++ b/xpcom/string/nsTStringComparator.cpp @@ -36,6 +36,16 @@ int NS_FASTCALL Compare(const mozilla::detail::nsTStringRepr& aLhs, return result; } +template int NS_FASTCALL +Compare(mozilla::detail::nsTStringRepr const&, + mozilla::detail::nsTStringRepr const&, + nsTStringComparator const&); + +template int NS_FASTCALL +Compare(mozilla::detail::nsTStringRepr const&, + mozilla::detail::nsTStringRepr const&, + nsTStringComparator const&); + template int nsTDefaultStringComparator::operator()(const char_type* aLhs, const char_type* aRhs, diff --git a/xpcom/string/nsTStringObsolete.cpp b/xpcom/string/nsTStringObsolete.cpp index be2d2aabd4..bef30dd47f 100644 --- a/xpcom/string/nsTStringObsolete.cpp +++ b/xpcom/string/nsTStringObsolete.cpp @@ -139,6 +139,8 @@ void nsTString::StripChars(const incompatible_char_type* aSet) { } } +template void nsTString::StripChars(const incompatible_char_type*); + template template bool nsTString::StripChars(const incompatible_char_type* aSet, @@ -152,6 +154,9 @@ bool nsTString::StripChars(const incompatible_char_type* aSet, return true; } +template bool nsTString::StripChars(const incompatible_char_type*, + const fallible_t&); + template void nsTString::StripChars(const char_type* aSet) { nsTSubstring::StripChars(aSet); @@ -206,6 +211,8 @@ void nsTString::ReplaceChar(const char_type* aSet, char_type aNewChar) { } } +template void nsTString::ReplaceChar(const char*, char16_t); + void ReleaseData(void* aData, nsAString::DataFlags aFlags); template diff --git a/xpcom/string/nsTStringRepr.h b/xpcom/string/nsTStringRepr.h index ae3e8e2ee6..e856e768cb 100644 --- a/xpcom/string/nsTStringRepr.h +++ b/xpcom/string/nsTStringRepr.h @@ -10,6 +10,7 @@ #include "mozilla/Char16.h" #include "mozilla/fallible.h" #include "nsStringFlags.h" +#include "nsStringIterator.h" #include "nsCharTraits.h" template @@ -195,9 +196,7 @@ class nsTStringRepr { size_type NS_FASTCALL CountChar(char_type) const; int32_t NS_FASTCALL FindChar(char_type, index_type aOffset = 0) const; - inline bool Contains(char_type aChar) const { - return FindChar(aChar) != kNotFound; - } + bool Contains(char_type aChar) const; // Equality. bool NS_FASTCALL Equals(const self_type&) const; @@ -279,6 +278,21 @@ class nsTStringRepr { return EqualsASCII(aStr, N - 1); } + // EqualsLiteral must ONLY be called with an actual literal string, or + // a char array *constant* declared without an explicit size and with an + // initializer that is a string literal or is otherwise null-terminated. + // Use EqualsASCII for other char array variables. + // (Although this method may happen to produce expected results for other + // char arrays that have bound one greater than the sequence of interest, + // such use is discouraged for reasons of readability and maintainability.) + // The template trick to acquire the array bound at compile time without + // using a macro is due to Corey Kosak, with much thanks. + template >> + inline bool EqualsLiteral(const char_type (&aStr)[N]) const { + return *this == nsTLiteralString(aStr); + } + // The LowerCaseEquals methods compare the ASCII-lowercase version of // this string (lowercasing only ASCII uppercase characters) to some // ASCII/Literal string. The ASCII string is *not* lowercased for @@ -350,6 +364,16 @@ Compare(const mozilla::detail::nsTStringRepr& aLhs, const mozilla::detail::nsTStringRepr& aRhs, const nsTStringComparator& = nsTDefaultStringComparator()); +extern template int NS_FASTCALL +Compare(const mozilla::detail::nsTStringRepr&, + const mozilla::detail::nsTStringRepr&, + const nsTStringComparator&); + +extern template int NS_FASTCALL +Compare(const mozilla::detail::nsTStringRepr&, + const mozilla::detail::nsTStringRepr&, + const nsTStringComparator&); + template inline constexpr bool operator!=( const mozilla::detail::nsTStringRepr& aLhs, diff --git a/xpcom/string/nsTSubstring.cpp b/xpcom/string/nsTSubstring.cpp index da8818b692..9f6030779f 100644 --- a/xpcom/string/nsTSubstring.cpp +++ b/xpcom/string/nsTSubstring.cpp @@ -7,6 +7,7 @@ #include "mozilla/MathAlgorithms.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Printf.h" +#include "mozilla/ResultExtensions.h" #include "nsASCIIMask.h" @@ -61,15 +62,13 @@ inline const nsTAutoString* AsAutoString(const nsTSubstring* aStr) { } template -mozilla::BulkWriteHandle nsTSubstring::BulkWrite( - size_type aCapacity, size_type aPrefixToPreserve, bool aAllowShrinking, - nsresult& aRv) { +mozilla::Result, nsresult> +nsTSubstring::BulkWrite(size_type aCapacity, size_type aPrefixToPreserve, + bool aAllowShrinking) { auto r = StartBulkWriteImpl(aCapacity, aPrefixToPreserve, aAllowShrinking); if (MOZ_UNLIKELY(r.isErr())) { - aRv = r.unwrapErr(); - return mozilla::BulkWriteHandle(nullptr, 0); + return r.propagateErr(); } - aRv = NS_OK; return mozilla::BulkWriteHandle(this, r.unwrap()); } @@ -1054,6 +1053,11 @@ int32_t nsTStringRepr::FindChar(char_type aChar, index_type aOffset) const { return -1; } +template +bool nsTStringRepr::Contains(char_type aChar) const { + return FindChar(aChar) != kNotFound; +} + } // namespace detail } // namespace mozilla @@ -1265,64 +1269,13 @@ static int FormatWithoutTrailingZeros(char (&aBuf)[40], double aDouble, int aPrecision) { static const DoubleToStringConverter converter( DoubleToStringConverter::UNIQUE_ZERO | + DoubleToStringConverter::NO_TRAILING_ZERO | DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN, "Infinity", "NaN", 'e', -6, 21, 6, 1); double_conversion::StringBuilder builder(aBuf, sizeof(aBuf)); - bool exponential_notation = false; - converter.ToPrecision(aDouble, aPrecision, &exponential_notation, &builder); + converter.ToPrecision(aDouble, aPrecision, &builder); int length = builder.position(); - char* formattedDouble = builder.Finalize(); - - // If we have a shorter string than aPrecision, it means we have a special - // value (NaN or Infinity). All other numbers will be formatted with at - // least aPrecision digits. - if (length <= aPrecision) { - return length; - } - - char* end = formattedDouble + length; - char* decimalPoint = strchr(aBuf, '.'); - // No trailing zeros to remove. - if (!decimalPoint) { - return length; - } - - if (MOZ_UNLIKELY(exponential_notation)) { - // We need to check for cases like 1.00000e-10 (yes, this is - // disgusting). - char* exponent = end - 1; - for (;; --exponent) { - if (*exponent == 'e') { - break; - } - } - char* zerosBeforeExponent = exponent - 1; - for (; zerosBeforeExponent != decimalPoint; --zerosBeforeExponent) { - if (*zerosBeforeExponent != '0') { - break; - } - } - if (zerosBeforeExponent == decimalPoint) { - --zerosBeforeExponent; - } - // Slide the exponent to the left over the trailing zeros. Don't - // worry about copying the trailing NUL character. - size_t exponentSize = end - exponent; - memmove(zerosBeforeExponent + 1, exponent, exponentSize); - length -= exponent - (zerosBeforeExponent + 1); - } else { - char* trailingZeros = end - 1; - for (; trailingZeros != decimalPoint; --trailingZeros) { - if (*trailingZeros != '0') { - break; - } - } - if (trailingZeros == decimalPoint) { - --trailingZeros; - } - length -= end - (trailingZeros + 1); - } - + builder.Finalize(); return length; } diff --git a/xpcom/string/nsTSubstring.h b/xpcom/string/nsTSubstring.h index e9f0228b88..743fc37956 100644 --- a/xpcom/string/nsTSubstring.h +++ b/xpcom/string/nsTSubstring.h @@ -1182,11 +1182,6 @@ class nsTSubstring : public mozilla::detail::nsTStringRepr { * performed when the string is already mutable and the requested * capacity is smaller than the current capacity. * - * aRv takes a reference to an nsresult that will be set to - * NS_OK on success or to NS_ERROR_OUT_OF_MEMORY on failure, - * because mozilla::Result cannot wrap move-only types at - * this time. - * * If this method returns successfully, you must not access * the string except through the returned BulkWriteHandle * until either the BulkWriteHandle goes out of scope or @@ -1202,10 +1197,8 @@ class nsTSubstring : public mozilla::detail::nsTStringRepr { * content has been written, which results in a * cache-friendly linear write pattern. */ - mozilla::BulkWriteHandle NS_FASTCALL BulkWrite(size_type aCapacity, - size_type aPrefixToPreserve, - bool aAllowShrinking, - nsresult& aRv); + mozilla::Result, nsresult> NS_FASTCALL BulkWrite( + size_type aCapacity, size_type aPrefixToPreserve, bool aAllowShrinking); /** * THIS IS NOT REALLY A PUBLIC METHOD! DO NOT CALL FROM OUTSIDE diff --git a/xpcom/string/nsTSubstringTuple.cpp b/xpcom/string/nsTSubstringTuple.cpp index bafde8d77b..78257faf0e 100644 --- a/xpcom/string/nsTSubstringTuple.cpp +++ b/xpcom/string/nsTSubstringTuple.cpp @@ -2,6 +2,7 @@ * 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 "nsTSubstringTuple.h" #include "mozilla/CheckedInt.h" /** diff --git a/xpcom/string/precompiled_templates.cpp b/xpcom/string/precompiled_templates.cpp index 86997f7eb3..f246a48936 100644 --- a/xpcom/string/precompiled_templates.cpp +++ b/xpcom/string/precompiled_templates.cpp @@ -5,7 +5,7 @@ #include "nsString.h" // This file provides concrete instantiations for externed string template -// classes and functions. +// classes. // ================ // Template classes @@ -39,60 +39,3 @@ template class nsTSubstringSplitter; template class nsTDefaultStringComparator; template class nsTDefaultStringComparator; - -// ============================= -// Templated top-level functions -// ============================= - -template int NS_FASTCALL -Compare(mozilla::detail::nsTStringRepr const&, - mozilla::detail::nsTStringRepr const&, - nsTStringComparator const&); - -template int NS_FASTCALL -Compare(mozilla::detail::nsTStringRepr const&, - mozilla::detail::nsTStringRepr const&, - nsTStringComparator const&); - -template nsTDependentSubstring const Substring(char const*, - char const*); - -template nsTDependentSubstring const Substring( - char16_t const*, char16_t const*); - -// ========================================================= -// Templated member functions that are conditionally enabled -// ========================================================= - -template int32_t nsTString::Find(const self_type&, int32_t, - int32_t) const; - -template int32_t nsTString::Find(const char_type*, int32_t, - int32_t) const; - -template int32_t nsTString::RFind(const self_type&, int32_t, - int32_t) const; - -template int32_t nsTString::RFind(const char_type*, int32_t, - int32_t) const; - -template int32_t nsTString::FindCharInSet(const char*, int32_t) const; - -namespace mozilla { -namespace detail { - -template int32_t nsTStringRepr::Compare(const char_type*, bool, - int32_t) const; - -template bool nsTStringRepr::EqualsIgnoreCase( - const incompatible_char_type*, int32_t) const; - -} // namespace detail -} // namespace mozilla - -template bool nsTString::StripChars(const incompatible_char_type*, - const fallible_t&); - -template void nsTString::StripChars(const incompatible_char_type*); - -template void nsTString::ReplaceChar(const char*, char16_t); diff --git a/xpcom/tests/TestHarness.h b/xpcom/tests/TestHarness.h index 0dafba67f4..59610bdb01 100644 --- a/xpcom/tests/TestHarness.h +++ b/xpcom/tests/TestHarness.h @@ -142,7 +142,7 @@ class ScopedXPCOM : public nsIDirectoryServiceProvider2 { getter_AddRefs(profD)); NS_ENSURE_SUCCESS(rv, nullptr); - rv = profD->Append(NS_LITERAL_STRING("cpp-unit-profd")); + rv = profD->Append(u"cpp-unit-profd"_ns); NS_ENSURE_SUCCESS(rv, nullptr); rv = profD->CreateUnique(nsIFile::DIRECTORY_TYPE, 0755); @@ -184,7 +184,7 @@ class ScopedXPCOM : public nsIDirectoryServiceProvider2 { nsAutoCString leafName; mGREBinD->GetNativeLeafName(leafName); if (leafName.EqualsLiteral("Resources")) { - mGREBinD->SetNativeLeafName(NS_LITERAL_CSTRING("MacOS")); + mGREBinD->SetNativeLeafName("MacOS"_ns); } #endif diff --git a/xpcom/tests/gtest/TestAtoms.cpp b/xpcom/tests/gtest/TestAtoms.cpp index ff8290eed4..6a0165f829 100644 --- a/xpcom/tests/gtest/TestAtoms.cpp +++ b/xpcom/tests/gtest/TestAtoms.cpp @@ -54,7 +54,7 @@ TEST(Atoms, 16vs8) TEST(Atoms, Null) { - nsAutoString str(NS_LITERAL_STRING("string with a \0 char")); + nsAutoString str(u"string with a \0 char"_ns); nsDependentString strCut(str.get()); EXPECT_FALSE(str.Equals(strCut)); diff --git a/xpcom/tests/gtest/TestBase64.cpp b/xpcom/tests/gtest/TestBase64.cpp index f5147816ad..c79ca13215 100644 --- a/xpcom/tests/gtest/TestBase64.cpp +++ b/xpcom/tests/gtest/TestBase64.cpp @@ -243,6 +243,31 @@ TEST(Base64, RFC4648Encoding) } } +TEST(Base64, RFC4648Encoding_TransformAndAppend_EmptyPrefix) +{ + for (auto& testcase : sRFC4648TestCases) { + nsDependentCString in(testcase.mInput); + nsAutoString out; + nsresult rv = + mozilla::Base64EncodeAppend(in.BeginReading(), in.Length(), out); + ASSERT_TRUE(NS_SUCCEEDED(rv)); + ASSERT_TRUE(out.EqualsASCII(testcase.mOutput)); + } +} + +TEST(Base64, RFC4648Encoding_TransformAndAppend_NonEmptyPrefix) +{ + for (auto& testcase : sRFC4648TestCases) { + nsDependentCString in(testcase.mInput); + nsAutoString out{u"foo"_ns}; + nsresult rv = + mozilla::Base64EncodeAppend(in.BeginReading(), in.Length(), out); + ASSERT_TRUE(NS_SUCCEEDED(rv)); + ASSERT_TRUE(StringBeginsWith(out, u"foo"_ns)); + ASSERT_TRUE(Substring(out, 3).EqualsASCII(testcase.mOutput)); + } +} + TEST(Base64, RFC4648Decoding) { for (auto& testcase : sRFC4648TestCases) { diff --git a/xpcom/tests/gtest/TestDafsa.cpp b/xpcom/tests/gtest/TestDafsa.cpp index fa036bcdec..4db34ecd07 100644 --- a/xpcom/tests/gtest/TestDafsa.cpp +++ b/xpcom/tests/gtest/TestDafsa.cpp @@ -20,16 +20,16 @@ TEST(Dafsa, StringsFound) { Dafsa d(dafsa_test_1::kDafsa); - int tag = d.Lookup(NS_LITERAL_CSTRING("foo.bar.baz")); + int tag = d.Lookup("foo.bar.baz"_ns); EXPECT_EQ(tag, 1); - tag = d.Lookup(NS_LITERAL_CSTRING("a.test.string")); + tag = d.Lookup("a.test.string"_ns); EXPECT_EQ(tag, 0); - tag = d.Lookup(NS_LITERAL_CSTRING("a.test.string2")); + tag = d.Lookup("a.test.string2"_ns); EXPECT_EQ(tag, 2); - tag = d.Lookup(NS_LITERAL_CSTRING("aaaa")); + tag = d.Lookup("aaaa"_ns); EXPECT_EQ(tag, 4); } @@ -38,23 +38,23 @@ TEST(Dafsa, StringsNotFound) Dafsa d(dafsa_test_1::kDafsa); // Matches all but last letter. - int tag = d.Lookup(NS_LITERAL_CSTRING("foo.bar.ba")); + int tag = d.Lookup("foo.bar.ba"_ns); EXPECT_EQ(tag, Dafsa::kKeyNotFound); // Matches prefix with extra letter. - tag = d.Lookup(NS_LITERAL_CSTRING("a.test.strings")); + tag = d.Lookup("a.test.strings"_ns); EXPECT_EQ(tag, Dafsa::kKeyNotFound); // Matches small portion. - tag = d.Lookup(NS_LITERAL_CSTRING("a.test")); + tag = d.Lookup("a.test"_ns); EXPECT_EQ(tag, Dafsa::kKeyNotFound); // Matches repeating pattern with extra letters. - tag = d.Lookup(NS_LITERAL_CSTRING("aaaaa")); + tag = d.Lookup("aaaaa"_ns); EXPECT_EQ(tag, Dafsa::kKeyNotFound); // Empty string. - tag = d.Lookup(NS_LITERAL_CSTRING("")); + tag = d.Lookup(""_ns); EXPECT_EQ(tag, Dafsa::kKeyNotFound); } @@ -62,7 +62,7 @@ TEST(Dafsa, HugeString) { Dafsa d(dafsa_test_1::kDafsa); - int tag = d.Lookup(NS_LITERAL_CSTRING( + int tag = d.Lookup(nsLiteralCString( "This is a very long string that is larger than the dafsa itself. " "This is a very long string that is larger than the dafsa itself. " "This is a very long string that is larger than the dafsa itself. " diff --git a/xpcom/tests/gtest/TestEventTargetQI.cpp b/xpcom/tests/gtest/TestEventTargetQI.cpp index ee7e39e1e3..804f7b28df 100644 --- a/xpcom/tests/gtest/TestEventTargetQI.cpp +++ b/xpcom/tests/gtest/TestEventTargetQI.cpp @@ -38,8 +38,7 @@ TEST(TestEventTargetQI, ThreadPool) TEST(TestEventTargetQI, SharedThreadPool) { - nsCOMPtr thing = - SharedThreadPool::Get(NS_LITERAL_CSTRING("TestPool"), 1); + nsCOMPtr thing = SharedThreadPool::Get("TestPool"_ns, 1); EXPECT_TRUE(thing); EXPECT_FALSE(TestQITo(thing)); @@ -71,8 +70,7 @@ TEST(TestEventTargetQI, ThrottledEventQueue) TEST(TestEventTargetQI, LazyIdleThread) { - nsCOMPtr thing = - new LazyIdleThread(0, NS_LITERAL_CSTRING("TestThread")); + nsCOMPtr thing = new LazyIdleThread(0, "TestThread"_ns); EXPECT_TRUE(thing); EXPECT_TRUE(TestQITo(thing)); diff --git a/xpcom/tests/gtest/TestFile.cpp b/xpcom/tests/gtest/TestFile.cpp index 9acada97bc..b89a11121d 100644 --- a/xpcom/tests/gtest/TestFile.cpp +++ b/xpcom/tests/gtest/TestFile.cpp @@ -494,7 +494,7 @@ TEST(TestFile, Unprefixed) gTestWithPrefix_Win = false; #endif - SetupAndTestFunctions(NS_LITERAL_STRING("mozfiletests"), + SetupAndTestFunctions(u"mozfiletests"_ns, /* aTestCreateUnique */ true, /* aTestNormalize */ true); @@ -507,7 +507,7 @@ TEST(TestFile, Unprefixed) // SetUseDOSDevicePathSyntax if it's on Windows for NewFile) TEST(TestFile, PrefixedOnWin) { - SetupAndTestFunctions(NS_LITERAL_STRING("mozfiletests"), + SetupAndTestFunctions(u"mozfiletests"_ns, /* aTestCreateUnique */ true, /* aTestNormalize */ true); } @@ -535,7 +535,7 @@ TEST(TestFile, PrefixedOnWin_ComponentEndsWithPeriod) { // Bypass the normalization for this because it would strip the trailing // period. - SetupAndTestFunctions(NS_LITERAL_STRING("mozfiletests."), + SetupAndTestFunctions(u"mozfiletests."_ns, /* aTestCreateUnique */ true, /* aTestNormalize */ false); } diff --git a/xpcom/tests/gtest/TestFilePreferencesWin.cpp b/xpcom/tests/gtest/TestFilePreferencesWin.cpp index 16ad5a037b..fdf777c6f4 100644 --- a/xpcom/tests/gtest/TestFilePreferencesWin.cpp +++ b/xpcom/tests/gtest/TestFilePreferencesWin.cpp @@ -8,110 +8,103 @@ TEST(FilePreferencesWin, Normalization) { nsAutoString normalized; - mozilla::FilePreferences::testing::NormalizePath(NS_LITERAL_STRING("foo"), + mozilla::FilePreferences::testing::NormalizePath(u"foo"_ns, normalized); + ASSERT_TRUE(normalized == u"foo"_ns); + + mozilla::FilePreferences::testing::NormalizePath(u"\\foo"_ns, normalized); + ASSERT_TRUE(normalized == u"\\foo"_ns); + + mozilla::FilePreferences::testing::NormalizePath(u"\\\\foo"_ns, normalized); + ASSERT_TRUE(normalized == u"\\\\foo"_ns); + + mozilla::FilePreferences::testing::NormalizePath(u"foo\\some"_ns, normalized); + ASSERT_TRUE(normalized == u"foo\\some"_ns); + + mozilla::FilePreferences::testing::NormalizePath(u"\\\\.\\foo"_ns, normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("foo")); + ASSERT_TRUE(normalized == u"\\\\foo"_ns); - mozilla::FilePreferences::testing::NormalizePath(NS_LITERAL_STRING("\\foo"), + mozilla::FilePreferences::testing::NormalizePath(u"\\\\."_ns, normalized); + ASSERT_TRUE(normalized == u"\\\\"_ns); + + mozilla::FilePreferences::testing::NormalizePath(u"\\\\.\\"_ns, normalized); + ASSERT_TRUE(normalized == u"\\\\"_ns); + + mozilla::FilePreferences::testing::NormalizePath(u"\\\\.\\."_ns, normalized); + ASSERT_TRUE(normalized == u"\\\\"_ns); + + mozilla::FilePreferences::testing::NormalizePath(u"\\\\foo\\bar"_ns, normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\foo")); + ASSERT_TRUE(normalized == u"\\\\foo\\bar"_ns); - mozilla::FilePreferences::testing::NormalizePath(NS_LITERAL_STRING("\\\\foo"), + mozilla::FilePreferences::testing::NormalizePath(u"\\\\foo\\bar\\"_ns, normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo")); + ASSERT_TRUE(normalized == u"\\\\foo\\bar\\"_ns); - mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("foo\\some"), normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("foo\\some")); - - mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\.\\foo"), normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo")); - - mozilla::FilePreferences::testing::NormalizePath(NS_LITERAL_STRING("\\\\."), + mozilla::FilePreferences::testing::NormalizePath(u"\\\\foo\\bar\\."_ns, normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\")); + ASSERT_TRUE(normalized == u"\\\\foo\\bar\\"_ns); - mozilla::FilePreferences::testing::NormalizePath(NS_LITERAL_STRING("\\\\.\\"), + mozilla::FilePreferences::testing::NormalizePath(u"\\\\foo\\bar\\.\\"_ns, normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\")); + ASSERT_TRUE(normalized == u"\\\\foo\\bar\\"_ns); + + mozilla::FilePreferences::testing::NormalizePath(u"\\\\foo\\bar\\..\\"_ns, + normalized); + ASSERT_TRUE(normalized == u"\\\\foo\\"_ns); + + mozilla::FilePreferences::testing::NormalizePath(u"\\\\foo\\bar\\.."_ns, + normalized); + ASSERT_TRUE(normalized == u"\\\\foo\\"_ns); + + mozilla::FilePreferences::testing::NormalizePath(u"\\\\foo\\..\\bar\\..\\"_ns, + normalized); + ASSERT_TRUE(normalized == u"\\\\"_ns); + + mozilla::FilePreferences::testing::NormalizePath(u"\\\\foo\\..\\bar"_ns, + normalized); + ASSERT_TRUE(normalized == u"\\\\bar"_ns); + + mozilla::FilePreferences::testing::NormalizePath(u"\\\\foo\\bar\\..\\..\\"_ns, + normalized); + ASSERT_TRUE(normalized == u"\\\\"_ns); mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\.\\."), normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\")); - - mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\foo\\bar"), normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\bar")); - - mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\foo\\bar\\"), normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\bar\\")); - - mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\foo\\bar\\."), normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\bar\\")); - - mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\foo\\bar\\.\\"), normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\bar\\")); - - mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\foo\\bar\\..\\"), normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\")); - - mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\foo\\bar\\.."), normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\")); - - mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\foo\\..\\bar\\..\\"), normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\")); - - mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\foo\\..\\bar"), normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\bar")); - - mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\foo\\bar\\..\\..\\"), normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\")); - - mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\foo\\bar\\.\\..\\.\\..\\"), normalized); - ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\")); + u"\\\\foo\\bar\\.\\..\\.\\..\\"_ns, normalized); + ASSERT_TRUE(normalized == u"\\\\"_ns); bool result; - result = mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\.."), normalized); + result = mozilla::FilePreferences::testing::NormalizePath(u"\\\\.."_ns, + normalized); + ASSERT_FALSE(result); + + result = mozilla::FilePreferences::testing::NormalizePath(u"\\\\..\\"_ns, + normalized); + ASSERT_FALSE(result); + + result = mozilla::FilePreferences::testing::NormalizePath(u"\\\\.\\..\\"_ns, + normalized); ASSERT_FALSE(result); result = mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\..\\"), normalized); + u"\\\\foo\\\\bar"_ns, normalized); ASSERT_FALSE(result); result = mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\.\\..\\"), normalized); + u"\\\\foo\\bar\\..\\..\\..\\..\\"_ns, normalized); ASSERT_FALSE(result); - result = mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\foo\\\\bar"), normalized); + result = mozilla::FilePreferences::testing::NormalizePath(u"\\\\\\"_ns, + normalized); ASSERT_FALSE(result); - result = mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\foo\\bar\\..\\..\\..\\..\\"), normalized); + result = mozilla::FilePreferences::testing::NormalizePath(u"\\\\.\\\\"_ns, + normalized); ASSERT_FALSE(result); - result = mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\\\"), normalized); - ASSERT_FALSE(result); - - result = mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\.\\\\"), normalized); - ASSERT_FALSE(result); - - result = mozilla::FilePreferences::testing::NormalizePath( - NS_LITERAL_STRING("\\\\..\\\\"), normalized); + result = mozilla::FilePreferences::testing::NormalizePath(u"\\\\..\\\\"_ns, + normalized); ASSERT_FALSE(result); } @@ -123,27 +116,26 @@ TEST(FilePreferencesWin, AccessUNC) mozilla::FilePreferences::testing::SetBlockUNCPaths(false); - rv = lf->InitWithPath(NS_LITERAL_STRING("\\\\nice\\..\\evil\\share")); + rv = lf->InitWithPath(u"\\\\nice\\..\\evil\\share"_ns); ASSERT_EQ(rv, NS_OK); mozilla::FilePreferences::testing::SetBlockUNCPaths(true); - rv = lf->InitWithPath(NS_LITERAL_STRING("\\\\nice\\..\\evil\\share")); + rv = lf->InitWithPath(u"\\\\nice\\..\\evil\\share"_ns); ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED); - mozilla::FilePreferences::testing::AddDirectoryToWhitelist( - NS_LITERAL_STRING("\\\\nice")); + mozilla::FilePreferences::testing::AddDirectoryToWhitelist(u"\\\\nice"_ns); - rv = lf->InitWithPath(NS_LITERAL_STRING("\\\\nice\\share")); + rv = lf->InitWithPath(u"\\\\nice\\share"_ns); ASSERT_EQ(rv, NS_OK); - rv = lf->InitWithPath(NS_LITERAL_STRING("\\\\nice\\..\\evil\\share")); + rv = lf->InitWithPath(u"\\\\nice\\..\\evil\\share"_ns); ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED); } TEST(FilePreferencesWin, AccessDOSDevicePath) { - const auto devicePathSpecifier = NS_LITERAL_STRING("\\\\?\\"); + const auto devicePathSpecifier = u"\\\\?\\"_ns; nsCOMPtr lf = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID); @@ -151,15 +143,13 @@ TEST(FilePreferencesWin, AccessDOSDevicePath) mozilla::FilePreferences::testing::SetBlockUNCPaths(true); - rv = lf->InitWithPath(devicePathSpecifier + - NS_LITERAL_STRING("evil\\z:\\share")); + rv = lf->InitWithPath(devicePathSpecifier + u"evil\\z:\\share"_ns); ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED); - rv = lf->InitWithPath(devicePathSpecifier + - NS_LITERAL_STRING("UNC\\evil\\share")); + rv = lf->InitWithPath(devicePathSpecifier + u"UNC\\evil\\share"_ns); ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED); - rv = lf->InitWithPath(devicePathSpecifier + NS_LITERAL_STRING("C:\\")); + rv = lf->InitWithPath(devicePathSpecifier + u"C:\\"_ns); ASSERT_EQ(rv, NS_OK); nsCOMPtr base; @@ -179,26 +169,26 @@ TEST(FilePreferencesWin, StartsWithDiskDesignatorAndBackslash) bool result; result = mozilla::FilePreferences::StartsWithDiskDesignatorAndBackslash( - NS_LITERAL_STRING("\\\\UNC\\path")); + u"\\\\UNC\\path"_ns); ASSERT_FALSE(result); result = mozilla::FilePreferences::StartsWithDiskDesignatorAndBackslash( - NS_LITERAL_STRING("\\single\\backslash")); + u"\\single\\backslash"_ns); ASSERT_FALSE(result); result = mozilla::FilePreferences::StartsWithDiskDesignatorAndBackslash( - NS_LITERAL_STRING("C:relative")); + u"C:relative"_ns); ASSERT_FALSE(result); result = mozilla::FilePreferences::StartsWithDiskDesignatorAndBackslash( - NS_LITERAL_STRING("\\\\?\\C:\\")); + u"\\\\?\\C:\\"_ns); ASSERT_FALSE(result); result = mozilla::FilePreferences::StartsWithDiskDesignatorAndBackslash( - NS_LITERAL_STRING("C:\\")); + u"C:\\"_ns); ASSERT_TRUE(result); result = mozilla::FilePreferences::StartsWithDiskDesignatorAndBackslash( - NS_LITERAL_STRING("c:\\")); + u"c:\\"_ns); ASSERT_TRUE(result); } diff --git a/xpcom/tests/gtest/TestLogCommandLineHandler.cpp b/xpcom/tests/gtest/TestLogCommandLineHandler.cpp index 9765221357..8ffe06ccb1 100644 --- a/xpcom/tests/gtest/TestLogCommandLineHandler.cpp +++ b/xpcom/tests/gtest/TestLogCommandLineHandler.cpp @@ -46,26 +46,26 @@ TEST(LogCommandLineHandler, MOZ_LOG_regular) results.Clear(); mozilla::LoggingHandleCommandLineArgs(array_size(argv1), argv1, callback); EXPECT_TRUE(results.Length() == 1); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=module1:5,module2:4,sync,timestamp") - .Equals(results[0])); + EXPECT_TRUE( + "MOZ_LOG=module1:5,module2:4,sync,timestamp"_ns.Equals(results[0])); char const* argv2[] = {"", "-MOZ_LOG=modules"}; results.Clear(); mozilla::LoggingHandleCommandLineArgs(array_size(argv2), argv2, callback); EXPECT_TRUE(results.Length() == 1); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); + EXPECT_TRUE("MOZ_LOG=modules"_ns.Equals(results[0])); char const* argv3[] = {"", "--MOZ_LOG", "modules"}; results.Clear(); mozilla::LoggingHandleCommandLineArgs(array_size(argv3), argv3, callback); EXPECT_TRUE(results.Length() == 1); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); + EXPECT_TRUE("MOZ_LOG=modules"_ns.Equals(results[0])); char const* argv4[] = {"", "--MOZ_LOG=modules"}; results.Clear(); mozilla::LoggingHandleCommandLineArgs(array_size(argv4), argv4, callback); EXPECT_TRUE(results.Length() == 1); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); + EXPECT_TRUE("MOZ_LOG=modules"_ns.Equals(results[0])); } TEST(LogCommandLineHandler, MOZ_LOG_and_FILE_regular) @@ -81,38 +81,37 @@ TEST(LogCommandLineHandler, MOZ_LOG_and_FILE_regular) results.Clear(); mozilla::LoggingHandleCommandLineArgs(array_size(argv1), argv1, callback); EXPECT_TRUE(results.Length() == 2); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); - EXPECT_TRUE( - NS_LITERAL_CSTRING("MOZ_LOG_FILE=c:\\file/path").Equals(results[1])); + EXPECT_TRUE("MOZ_LOG=modules"_ns.Equals(results[0])); + EXPECT_TRUE("MOZ_LOG_FILE=c:\\file/path"_ns.Equals(results[1])); char const* argv2[] = {"", "-MOZ_LOG=modules", "-MOZ_LOG_FILE=file"}; results.Clear(); mozilla::LoggingHandleCommandLineArgs(array_size(argv2), argv2, callback); EXPECT_TRUE(results.Length() == 2); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG_FILE=file").Equals(results[1])); + EXPECT_TRUE("MOZ_LOG=modules"_ns.Equals(results[0])); + EXPECT_TRUE("MOZ_LOG_FILE=file"_ns.Equals(results[1])); char const* argv3[] = {"", "--MOZ_LOG", "modules", "--MOZ_LOG_FILE", "file"}; results.Clear(); mozilla::LoggingHandleCommandLineArgs(array_size(argv3), argv3, callback); EXPECT_TRUE(results.Length() == 2); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG_FILE=file").Equals(results[1])); + EXPECT_TRUE("MOZ_LOG=modules"_ns.Equals(results[0])); + EXPECT_TRUE("MOZ_LOG_FILE=file"_ns.Equals(results[1])); char const* argv4[] = {"", "--MOZ_LOG=modules", "--MOZ_LOG_FILE=file"}; results.Clear(); mozilla::LoggingHandleCommandLineArgs(array_size(argv4), argv4, callback); EXPECT_TRUE(results.Length() == 2); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG_FILE=file").Equals(results[1])); + EXPECT_TRUE("MOZ_LOG=modules"_ns.Equals(results[0])); + EXPECT_TRUE("MOZ_LOG_FILE=file"_ns.Equals(results[1])); char const* argv5[] = {"", "--MOZ_LOG", "modules", "-P", "foo", "--MOZ_LOG_FILE", "file"}; results.Clear(); mozilla::LoggingHandleCommandLineArgs(array_size(argv5), argv5, callback); EXPECT_TRUE(results.Length() == 2); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG_FILE=file").Equals(results[1])); + EXPECT_TRUE("MOZ_LOG=modules"_ns.Equals(results[0])); + EXPECT_TRUE("MOZ_LOG_FILE=file"_ns.Equals(results[1])); } TEST(LogCommandLineHandler, MOZ_LOG_fuzzy) @@ -161,20 +160,20 @@ TEST(LogCommandLineHandler, MOZ_LOG_overlapping) results.Clear(); mozilla::LoggingHandleCommandLineArgs(array_size(argv1), argv1, callback); EXPECT_TRUE(results.Length() == 2); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules1").Equals(results[0])); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules2").Equals(results[1])); + EXPECT_TRUE("MOZ_LOG=modules1"_ns.Equals(results[0])); + EXPECT_TRUE("MOZ_LOG=modules2"_ns.Equals(results[1])); char const* argv2[] = {"", "-MOZ_LOG", "--MOZ_LOG", "modules"}; results.Clear(); mozilla::LoggingHandleCommandLineArgs(array_size(argv2), argv2, callback); EXPECT_TRUE(results.Length() == 1); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); + EXPECT_TRUE("MOZ_LOG=modules"_ns.Equals(results[0])); char const* argv3[] = {"", "-MOZ_LOG_FILE", "-MOZ_LOG", "modules"}; results.Clear(); mozilla::LoggingHandleCommandLineArgs(array_size(argv3), argv3, callback); EXPECT_TRUE(results.Length() == 1); - EXPECT_TRUE(NS_LITERAL_CSTRING("MOZ_LOG=modules").Equals(results[0])); + EXPECT_TRUE("MOZ_LOG=modules"_ns.Equals(results[0])); char const* argv4[] = {"", "-MOZ_LOG", "-MOZ_LOG_FILE", "-MOZ_LOG"}; results.Clear(); diff --git a/xpcom/tests/gtest/TestMruCache.cpp b/xpcom/tests/gtest/TestMruCache.cpp index 58c959a73f..07b97cb99a 100644 --- a/xpcom/tests/gtest/TestMruCache.cpp +++ b/xpcom/tests/gtest/TestMruCache.cpp @@ -237,7 +237,7 @@ TEST(MruCache, TestRemove) // Fill it up. for (char i = 1; i < 32; i++) { const nsCString key = MakeStringKey(i); - mru.Put(key, StringStruct{key, NS_LITERAL_CSTRING("foo")}); + mru.Put(key, StringStruct{key, "foo"_ns}); } // Now remove each value. @@ -382,12 +382,12 @@ TEST(MruCache, TestLookupAndSetWithMove) StringStructMap mru; const nsCString key = MakeStringKey((char)1); - StringStruct val{key, NS_LITERAL_CSTRING("foo")}; + StringStruct val{key, "foo"_ns}; auto p = mru.Lookup(key); EXPECT_FALSE(p); p.Set(std::move(val)); EXPECT_TRUE(p.Data().mKey == key); - EXPECT_TRUE(p.Data().mOther == NS_LITERAL_CSTRING("foo")); + EXPECT_TRUE(p.Data().mOther == "foo"_ns); } diff --git a/xpcom/tests/gtest/TestObserverService.cpp b/xpcom/tests/gtest/TestObserverService.cpp index bc842d3a96..f3f6603832 100644 --- a/xpcom/tests/gtest/TestObserverService.cpp +++ b/xpcom/tests/gtest/TestObserverService.cpp @@ -107,12 +107,12 @@ TEST(ObserverService, AddObserver) do_CreateInstance("@mozilla.org/observer-service;1"); // Add a strong ref. - RefPtr a = new TestObserver(NS_LITERAL_STRING("A")); + RefPtr a = new TestObserver(u"A"_ns); nsresult rv = svc->AddObserver(a, "Foo", false); testResult(rv); // Add a few weak ref. - RefPtr b = new TestObserver(NS_LITERAL_STRING("B")); + RefPtr b = new TestObserver(u"B"_ns); rv = svc->AddObserver(b, "Bar", true); testResult(rv); } @@ -122,9 +122,9 @@ TEST(ObserverService, RemoveObserver) nsCOMPtr svc = do_CreateInstance("@mozilla.org/observer-service;1"); - RefPtr a = new TestObserver(NS_LITERAL_STRING("A")); - RefPtr b = new TestObserver(NS_LITERAL_STRING("B")); - RefPtr c = new TestObserver(NS_LITERAL_STRING("C")); + RefPtr a = new TestObserver(u"A"_ns); + RefPtr b = new TestObserver(u"B"_ns); + RefPtr c = new TestObserver(u"C"_ns); svc->AddObserver(a, "Foo", false); svc->AddObserver(b, "Foo", true); @@ -153,7 +153,7 @@ TEST(ObserverService, EnumerateEmpty) TestExpectedCount(svc, "A", 0); // Now add an observer and enumerate an unobserved topic. - RefPtr a = new TestObserver(NS_LITERAL_STRING("A")); + RefPtr a = new TestObserver(u"A"_ns); testResult(svc->AddObserver(a, "Foo", false)); TestExpectedCount(svc, "A", 0); @@ -166,13 +166,13 @@ TEST(ObserverService, Enumerate) const size_t kFooCount = 10; for (size_t i = 0; i < kFooCount; i++) { - RefPtr a = new TestObserver(NS_LITERAL_STRING("A")); + RefPtr a = new TestObserver(u"A"_ns); testResult(svc->AddObserver(a, "Foo", false)); } const size_t kBarCount = kFooCount / 2; for (size_t i = 0; i < kBarCount; i++) { - RefPtr a = new TestObserver(NS_LITERAL_STRING("A")); + RefPtr a = new TestObserver(u"A"_ns); testResult(svc->AddObserver(a, "Bar", false)); } @@ -190,7 +190,7 @@ TEST(ObserverService, EnumerateWeakRefs) const size_t kFooCount = 10; for (size_t i = 0; i < kFooCount; i++) { - RefPtr a = new TestObserver(NS_LITERAL_STRING("A")); + RefPtr a = new TestObserver(u"A"_ns); testResult(svc->AddObserver(a, "Foo", true)); } @@ -199,8 +199,8 @@ TEST(ObserverService, EnumerateWeakRefs) // Now test a mixture. for (size_t i = 0; i < kFooCount; i++) { - RefPtr a = new TestObserver(NS_LITERAL_STRING("A")); - RefPtr b = new TestObserver(NS_LITERAL_STRING("B")); + RefPtr a = new TestObserver(u"A"_ns); + RefPtr b = new TestObserver(u"B"_ns); // Register a as weak for "Foo". testResult(svc->AddObserver(a, "Foo", true)); @@ -213,9 +213,9 @@ TEST(ObserverService, EnumerateWeakRefs) TestExpectedCount(svc, "Foo", kFooCount); // Now add a couple weak refs, but don't go out of scope. - RefPtr a = new TestObserver(NS_LITERAL_STRING("A")); + RefPtr a = new TestObserver(u"A"_ns); testResult(svc->AddObserver(a, "Foo", true)); - RefPtr b = new TestObserver(NS_LITERAL_STRING("B")); + RefPtr b = new TestObserver(u"B"_ns); testResult(svc->AddObserver(b, "Foo", true)); // Expect all the observers from before and the two new ones. @@ -232,10 +232,8 @@ TEST(ObserverService, TestNotify) nsCOMPtr svc = do_CreateInstance("@mozilla.org/observer-service;1"); - RefPtr aObserver = - new TestObserver(NS_LITERAL_STRING("Observer-A")); - RefPtr bObserver = - new TestObserver(NS_LITERAL_STRING("Observer-B")); + RefPtr aObserver = new TestObserver(u"Observer-A"_ns); + RefPtr bObserver = new TestObserver(u"Observer-B"_ns); // Add two observers for topicA. testResult(svc->AddObserver(aObserver, topicA.get(), false)); diff --git a/xpcom/tests/gtest/TestStrings.cpp b/xpcom/tests/gtest/TestStrings.cpp index 09d7a99423..4b92d0b29f 100644 --- a/xpcom/tests/gtest/TestStrings.cpp +++ b/xpcom/tests/gtest/TestStrings.cpp @@ -568,7 +568,7 @@ TEST_F(Strings, DependentStrings) { TEST_F(Strings, assign) { nsCString result; - test_assign_helper(NS_LITERAL_CSTRING("a") + NS_LITERAL_CSTRING("b"), result); + test_assign_helper("a"_ns + "b"_ns, result); EXPECT_STREQ(result.get(), "ab"); } @@ -663,7 +663,7 @@ TEST_F(Strings, findinreadable) { nsACString::const_iterator delim_begin(begin), delim_end(end); // Search for last !/ at the end of the string - EXPECT_TRUE(FindInReadable(NS_LITERAL_CSTRING("!/"), delim_begin, delim_end)); + EXPECT_TRUE(FindInReadable("!/"_ns, delim_begin, delim_end)); char* r = ToNewCString(Substring(delim_begin, delim_end)); // Should match the first "!/" but not the last EXPECT_NE(delim_end, end); @@ -674,8 +674,7 @@ TEST_F(Strings, findinreadable) { delim_end = end; // Search for first jar: - EXPECT_TRUE( - FindInReadable(NS_LITERAL_CSTRING("jar:"), delim_begin, delim_end)); + EXPECT_TRUE(FindInReadable("jar:"_ns, delim_begin, delim_end)); r = ToNewCString(Substring(delim_begin, delim_end)); // Should not match the first jar:, but the second one @@ -687,8 +686,7 @@ TEST_F(Strings, findinreadable) { delim_begin = begin; delim_begin++; delim_end = end; - EXPECT_TRUE( - FindInReadable(NS_LITERAL_CSTRING("jar:"), delim_begin, delim_end)); + EXPECT_TRUE(FindInReadable("jar:"_ns, delim_begin, delim_end)); r = ToNewCString(Substring(delim_begin, delim_end)); // Should not match the first jar:, but the second one @@ -697,8 +695,7 @@ TEST_F(Strings, findinreadable) { free(r); // Should not find a match - EXPECT_FALSE( - FindInReadable(NS_LITERAL_CSTRING("gecko"), delim_begin, delim_end)); + EXPECT_FALSE(FindInReadable("gecko"_ns, delim_begin, delim_end)); // When no match is found, range should be empty EXPECT_EQ(delim_begin, delim_end); @@ -707,8 +704,7 @@ TEST_F(Strings, findinreadable) { delim_begin = begin; for (int i = 0; i < 6; i++) delim_begin++; delim_end = end; - EXPECT_FALSE( - FindInReadable(NS_LITERAL_CSTRING("jar:"), delim_begin, delim_end)); + EXPECT_FALSE(FindInReadable("jar:"_ns, delim_begin, delim_end)); // When no match is found, range should be empty EXPECT_EQ(delim_begin, delim_end); @@ -717,8 +713,7 @@ TEST_F(Strings, findinreadable) { delim_begin = begin; delim_end = end; for (int i = 0; i < 7; i++) delim_end--; - EXPECT_FALSE( - FindInReadable(NS_LITERAL_CSTRING("classic"), delim_begin, delim_end)); + EXPECT_FALSE(FindInReadable("classic"_ns, delim_begin, delim_end)); // When no match is found, range should be empty EXPECT_EQ(delim_begin, delim_end); @@ -736,8 +731,7 @@ TEST_F(Strings, rfindinreadable) { nsACString::const_iterator delim_begin(begin), delim_end(end); // Search for last !/ at the end of the string - EXPECT_TRUE( - RFindInReadable(NS_LITERAL_CSTRING("!/"), delim_begin, delim_end)); + EXPECT_TRUE(RFindInReadable("!/"_ns, delim_begin, delim_end)); char* r = ToNewCString(Substring(delim_begin, delim_end)); // Should match the last "!/" EXPECT_EQ(delim_end, end); @@ -748,8 +742,7 @@ TEST_F(Strings, rfindinreadable) { delim_end = end; // Search for last jar: but not the first one... - EXPECT_TRUE( - RFindInReadable(NS_LITERAL_CSTRING("jar:"), delim_begin, delim_end)); + EXPECT_TRUE(RFindInReadable("jar:"_ns, delim_begin, delim_end)); r = ToNewCString(Substring(delim_begin, delim_end)); // Should not match the first jar:, but the second one @@ -761,8 +754,7 @@ TEST_F(Strings, rfindinreadable) { delim_begin = begin; delim_end = begin; for (int i = 0; i < 6; i++) delim_end++; - EXPECT_TRUE( - RFindInReadable(NS_LITERAL_CSTRING("jar:"), delim_begin, delim_end)); + EXPECT_TRUE(RFindInReadable("jar:"_ns, delim_begin, delim_end)); r = ToNewCString(Substring(delim_begin, delim_end)); // Should not match the first jar:, but the second one @@ -773,8 +765,7 @@ TEST_F(Strings, rfindinreadable) { // Should not find a match delim_begin = begin; delim_end = end; - EXPECT_FALSE( - RFindInReadable(NS_LITERAL_CSTRING("gecko"), delim_begin, delim_end)); + EXPECT_FALSE(RFindInReadable("gecko"_ns, delim_begin, delim_end)); // When no match is found, range should be empty EXPECT_EQ(delim_begin, delim_end); @@ -783,8 +774,7 @@ TEST_F(Strings, rfindinreadable) { delim_begin = begin; for (int i = 0; i < 6; i++) delim_begin++; delim_end = end; - EXPECT_FALSE( - RFindInReadable(NS_LITERAL_CSTRING("jar:"), delim_begin, delim_end)); + EXPECT_FALSE(RFindInReadable("jar:"_ns, delim_begin, delim_end)); // When no match is found, range should be empty EXPECT_EQ(delim_begin, delim_end); @@ -793,8 +783,7 @@ TEST_F(Strings, rfindinreadable) { delim_begin = begin; delim_end = end; for (int i = 0; i < 7; i++) delim_end--; - EXPECT_FALSE( - RFindInReadable(NS_LITERAL_CSTRING("classic"), delim_begin, delim_end)); + EXPECT_FALSE(RFindInReadable("classic"_ns, delim_begin, delim_end)); // When no match is found, range should be empty EXPECT_EQ(delim_begin, delim_end); @@ -965,8 +954,8 @@ TEST_F(Strings, concat) { nsCString bar("bar"); const nsACString& barRef = bar; - const nsPromiseFlatCString& result = PromiseFlatCString( - NS_LITERAL_CSTRING("foo") + NS_LITERAL_CSTRING(",") + barRef); + const nsPromiseFlatCString& result = + PromiseFlatCString("foo"_ns + ","_ns + barRef); EXPECT_STREQ(result.get(), "foo,bar"); } @@ -1328,13 +1317,12 @@ static void test_strip_chars_helper(const char16_t* str, const char16_t* strip, TEST(String, strip_chars) { - test_strip_chars_helper(u"foo \r \nbar", u" \n\r", - NS_LITERAL_STRING("foobar")); - test_strip_chars_helper(u"\r\nfoo\r\n", u" \n\r", NS_LITERAL_STRING("foo")); - test_strip_chars_helper(u"foo", u" \n\r", NS_LITERAL_STRING("foo")); - test_strip_chars_helper(u"foo", u"fo", NS_LITERAL_STRING("")); - test_strip_chars_helper(u"foo", u"foo", NS_LITERAL_STRING("")); - test_strip_chars_helper(u" foo", u" ", NS_LITERAL_STRING("foo")); + test_strip_chars_helper(u"foo \r \nbar", u" \n\r", u"foobar"_ns); + test_strip_chars_helper(u"\r\nfoo\r\n", u" \n\r", u"foo"_ns); + test_strip_chars_helper(u"foo", u" \n\r", u"foo"_ns); + test_strip_chars_helper(u"foo", u"fo", u""_ns); + test_strip_chars_helper(u"foo", u"foo", u""_ns); + test_strip_chars_helper(u" foo", u" ", u"foo"_ns); } TEST_F(Strings, append_with_capacity) { @@ -1398,12 +1386,14 @@ TEST_F(Strings, legacy_set_length_semantics) { #endif TEST_F(Strings, bulk_write) { - nsresult rv; nsCString s; const char* ptrTwoThousand; { - auto handle = s.BulkWrite(500, 0, true, rv); - EXPECT_EQ(rv, NS_OK); + auto handleOrErr = s.BulkWrite(500, 0, true); + EXPECT_TRUE(handleOrErr.isOk()); + + auto handle = handleOrErr.unwrap(); + auto span = handle.AsSpan(); for (auto&& c : span) { c = 'a'; @@ -1428,11 +1418,10 @@ TEST_F(Strings, bulk_write) { } TEST_F(Strings, bulk_write_fail) { - nsresult rv; nsCString s; { - auto handle = s.BulkWrite(500, 0, true, rv); - EXPECT_EQ(rv, NS_OK); + auto handleOrErr = s.BulkWrite(500, 0, true); + EXPECT_TRUE(handleOrErr.isOk()); } EXPECT_EQ(s.Length(), 3U); EXPECT_TRUE(s.Equals(u8"\uFFFD")); @@ -1541,20 +1530,19 @@ static void test_tofloat_helper(const nsString& aStr, float aExpected, } TEST_F(Strings, tofloat) { - test_tofloat_helper(NS_LITERAL_STRING("42"), 42.f, true); - test_tofloat_helper(NS_LITERAL_STRING("42.0"), 42.f, true); - test_tofloat_helper(NS_LITERAL_STRING("-42"), -42.f, true); - test_tofloat_helper(NS_LITERAL_STRING("+42"), 42, true); - test_tofloat_helper(NS_LITERAL_STRING("13.37"), 13.37f, true); - test_tofloat_helper(NS_LITERAL_STRING("1.23456789"), 1.23456789f, true); - test_tofloat_helper(NS_LITERAL_STRING("1.98765432123456"), 1.98765432123456f, - true); - test_tofloat_helper(NS_LITERAL_STRING("0"), 0.f, true); - test_tofloat_helper(NS_LITERAL_STRING("1.e5"), 100000, true); - test_tofloat_helper(NS_LITERAL_STRING(""), 0.f, false); - test_tofloat_helper(NS_LITERAL_STRING("42foo"), 42.f, false); - test_tofloat_helper(NS_LITERAL_STRING("foo"), 0.f, false); - test_tofloat_helper(NS_LITERAL_STRING("1.5e-"), 1.5f, false); + test_tofloat_helper(u"42"_ns, 42.f, true); + test_tofloat_helper(u"42.0"_ns, 42.f, true); + test_tofloat_helper(u"-42"_ns, -42.f, true); + test_tofloat_helper(u"+42"_ns, 42, true); + test_tofloat_helper(u"13.37"_ns, 13.37f, true); + test_tofloat_helper(u"1.23456789"_ns, 1.23456789f, true); + test_tofloat_helper(u"1.98765432123456"_ns, 1.98765432123456f, true); + test_tofloat_helper(u"0"_ns, 0.f, true); + test_tofloat_helper(u"1.e5"_ns, 100000, true); + test_tofloat_helper(u""_ns, 0.f, false); + test_tofloat_helper(u"42foo"_ns, 42.f, false); + test_tofloat_helper(u"foo"_ns, 0.f, false); + test_tofloat_helper(u"1.5e-"_ns, 1.5f, false); } static void test_tofloat_allow_trailing_chars_helper(const nsString& aStr, @@ -1570,17 +1558,12 @@ static void test_tofloat_allow_trailing_chars_helper(const nsString& aStr, } TEST_F(Strings, ToFloatAllowTrailingChars) { - test_tofloat_allow_trailing_chars_helper(NS_LITERAL_STRING(""), 0.f, false); - test_tofloat_allow_trailing_chars_helper(NS_LITERAL_STRING("foo"), 0.f, - false); - test_tofloat_allow_trailing_chars_helper(NS_LITERAL_STRING("42foo"), 42.f, - true); - test_tofloat_allow_trailing_chars_helper(NS_LITERAL_STRING("42-5"), 42.f, - true); - test_tofloat_allow_trailing_chars_helper(NS_LITERAL_STRING("13.37.8"), 13.37f, - true); - test_tofloat_allow_trailing_chars_helper(NS_LITERAL_STRING("1.5e-"), 1.5f, - true); + test_tofloat_allow_trailing_chars_helper(u""_ns, 0.f, false); + test_tofloat_allow_trailing_chars_helper(u"foo"_ns, 0.f, false); + test_tofloat_allow_trailing_chars_helper(u"42foo"_ns, 42.f, true); + test_tofloat_allow_trailing_chars_helper(u"42-5"_ns, 42.f, true); + test_tofloat_allow_trailing_chars_helper(u"13.37.8"_ns, 13.37f, true); + test_tofloat_allow_trailing_chars_helper(u"1.5e-"_ns, 1.5f, true); } static void test_todouble_helper(const nsString& aStr, double aExpected, @@ -1595,22 +1578,21 @@ static void test_todouble_helper(const nsString& aStr, double aExpected, } TEST_F(Strings, todouble) { - test_todouble_helper(NS_LITERAL_STRING("42"), 42, true); - test_todouble_helper(NS_LITERAL_STRING("42.0"), 42, true); - test_todouble_helper(NS_LITERAL_STRING("-42"), -42, true); - test_todouble_helper(NS_LITERAL_STRING("+42"), 42, true); - test_todouble_helper(NS_LITERAL_STRING("13.37"), 13.37, true); - test_todouble_helper(NS_LITERAL_STRING("1.23456789"), 1.23456789, true); - test_todouble_helper(NS_LITERAL_STRING("1.98765432123456"), 1.98765432123456, + test_todouble_helper(u"42"_ns, 42, true); + test_todouble_helper(u"42.0"_ns, 42, true); + test_todouble_helper(u"-42"_ns, -42, true); + test_todouble_helper(u"+42"_ns, 42, true); + test_todouble_helper(u"13.37"_ns, 13.37, true); + test_todouble_helper(u"1.23456789"_ns, 1.23456789, true); + test_todouble_helper(u"1.98765432123456"_ns, 1.98765432123456, true); + test_todouble_helper(u"123456789.98765432123456"_ns, 123456789.98765432123456, true); - test_todouble_helper(NS_LITERAL_STRING("123456789.98765432123456"), - 123456789.98765432123456, true); - test_todouble_helper(NS_LITERAL_STRING("0"), 0, true); - test_todouble_helper(NS_LITERAL_STRING("1.e5"), 100000, true); - test_todouble_helper(NS_LITERAL_STRING(""), 0, false); - test_todouble_helper(NS_LITERAL_STRING("42foo"), 42, false); - test_todouble_helper(NS_LITERAL_STRING("foo"), 0, false); - test_todouble_helper(NS_LITERAL_STRING("1.5e-"), 1.5, false); + test_todouble_helper(u"0"_ns, 0, true); + test_todouble_helper(u"1.e5"_ns, 100000, true); + test_todouble_helper(u""_ns, 0, false); + test_todouble_helper(u"42foo"_ns, 42, false); + test_todouble_helper(u"foo"_ns, 0, false); + test_todouble_helper(u"1.5e-"_ns, 1.5, false); } static void test_todouble_allow_trailing_chars_helper(const nsString& aStr, @@ -1626,16 +1608,12 @@ static void test_todouble_allow_trailing_chars_helper(const nsString& aStr, } TEST_F(Strings, ToDoubleAllowTrailingChars) { - test_todouble_allow_trailing_chars_helper(NS_LITERAL_STRING(""), 0, false); - test_todouble_allow_trailing_chars_helper(NS_LITERAL_STRING("foo"), 0, false); - test_todouble_allow_trailing_chars_helper(NS_LITERAL_STRING("42foo"), 42, - true); - test_todouble_allow_trailing_chars_helper(NS_LITERAL_STRING("42-5"), 42, - true); - test_todouble_allow_trailing_chars_helper(NS_LITERAL_STRING("13.37.8"), 13.37, - true); - test_todouble_allow_trailing_chars_helper(NS_LITERAL_STRING("1.5e-"), 1.5, - true); + test_todouble_allow_trailing_chars_helper(u""_ns, 0, false); + test_todouble_allow_trailing_chars_helper(u"foo"_ns, 0, false); + test_todouble_allow_trailing_chars_helper(u"42foo"_ns, 42, true); + test_todouble_allow_trailing_chars_helper(u"42-5"_ns, 42, true); + test_todouble_allow_trailing_chars_helper(u"13.37.8"_ns, 13.37, true); + test_todouble_allow_trailing_chars_helper(u"1.5e-"_ns, 1.5, true); } TEST_F(Strings, Split) { @@ -1707,9 +1685,9 @@ TEST_F(Strings, Split) { counter = 0; for (const nsAString& token : wide.Split(' ')) { if (counter == 0) { - EXPECT_TRUE(token.Equals(NS_LITERAL_STRING("hello"))); + EXPECT_TRUE(token.Equals(u"hello"_ns)); } else if (counter == 1) { - EXPECT_TRUE(token.Equals(NS_LITERAL_STRING("world"))); + EXPECT_TRUE(token.Equals(u"world"_ns)); } counter++; } @@ -2482,7 +2460,7 @@ CONVERSION_BENCH(PerfUTF8toUTF16VIThousand, CopyUTF8toUTF16, mViThousandUtf8, nsAutoString); // Tests for usability of nsTLiteralString in constant expressions. -static_assert(NS_LITERAL_STRING("").IsEmpty()); +static_assert(u""_ns.IsEmpty()); constexpr auto testStringA = NS_LITERAL_STRING("a"); static_assert(!testStringA.IsEmpty()); diff --git a/xpcom/tests/gtest/TestTextFormatter.cpp b/xpcom/tests/gtest/TestTextFormatter.cpp index ed510afe72..88bb7a9404 100644 --- a/xpcom/tests/gtest/TestTextFormatter.cpp +++ b/xpcom/tests/gtest/TestTextFormatter.cpp @@ -8,7 +8,7 @@ TEST(TextFormatter, Tests) { - nsAutoString fmt(NS_LITERAL_STRING("%3$s %4$S %1$d %2$d %2$d %3$s")); + nsAutoString fmt(u"%3$s %4$S %1$d %2$d %2$d %3$s"_ns); char utf8[] = "Hello"; char16_t ucs2[] = {'W', 'o', 'r', 'l', 'd', 0x4e00, 0xAc00, 0xFF45, 0x0103, 0x00}; diff --git a/xpcom/tests/gtest/TestTokenizer.cpp b/xpcom/tests/gtest/TestTokenizer.cpp index 1e1796ee58..24f008156f 100644 --- a/xpcom/tests/gtest/TestTokenizer.cpp +++ b/xpcom/tests/gtest/TestTokenizer.cpp @@ -26,11 +26,11 @@ TEST(Tokenizer, HTTPResponse) // Real life test, HTTP response Tokenizer p( - NS_LITERAL_CSTRING("HTTP/1.0 304 Not modified\r\n" - "ETag: hallo\r\n" - "Content-Length: 16\r\n" - "\r\n" - "This is the body")); + nsLiteralCString("HTTP/1.0 304 Not modified\r\n" + "ETag: hallo\r\n" + "Content-Length: 16\r\n" + "\r\n" + "This is the body")); EXPECT_TRUE(p.CheckWord("HTTP")); EXPECT_TRUE(p.CheckChar('/')); @@ -99,7 +99,7 @@ TEST(Tokenizer, Main) // Synthetic code-specific test - Tokenizer p(NS_LITERAL_CSTRING("test123 ,15 \t*\r\n%xx,-15\r\r")); + Tokenizer p("test123 ,15 \t*\r\n%xx,-15\r\r"_ns); EXPECT_TRUE(p.Next(t)); EXPECT_TRUE(t.Type() == Tokenizer::TOKEN_WORD); @@ -213,11 +213,11 @@ TEST(Tokenizer, Main16) // Synthetic code-specific test - Tokenizer16 p(NS_LITERAL_STRING("test123 ,15 \t*\r\n%xx,-15\r\r")); + Tokenizer16 p(u"test123 ,15 \t*\r\n%xx,-15\r\r"_ns); EXPECT_TRUE(p.Next(t)); EXPECT_TRUE(t.Type() == Tokenizer16::TOKEN_WORD); - EXPECT_TRUE(t.AsString() == NS_LITERAL_STRING("test123")); + EXPECT_TRUE(t.AsString() == u"test123"_ns); Tokenizer16::Token u; EXPECT_FALSE(p.Check(u)); @@ -272,21 +272,21 @@ TEST(Tokenizer, Main16) nsAutoString claim; p.Claim(claim, Tokenizer16::EXCLUDE_LAST); - EXPECT_TRUE(claim == NS_LITERAL_STRING("*\r\n")); + EXPECT_TRUE(claim == u"*\r\n"_ns); p.Claim(claim, Tokenizer16::INCLUDE_LAST); - EXPECT_TRUE(claim == NS_LITERAL_STRING("*\r\n%")); + EXPECT_TRUE(claim == u"*\r\n%"_ns); p.Rollback(); EXPECT_TRUE(p.CheckChar('%')); p.Record(Tokenizer16::INCLUDE_LAST); - EXPECT_FALSE(p.CheckWord(NS_LITERAL_STRING("xy"))); + EXPECT_FALSE(p.CheckWord(u"xy"_ns)); - EXPECT_TRUE(p.CheckWord(NS_LITERAL_STRING("xx"))); + EXPECT_TRUE(p.CheckWord(u"xx"_ns)); p.Claim(claim, Tokenizer16::INCLUDE_LAST); - EXPECT_TRUE(claim == NS_LITERAL_STRING("%xx")); + EXPECT_TRUE(claim == u"%xx"_ns); EXPECT_TRUE(p.Next(t)); EXPECT_TRUE(t.Type() == Tokenizer16::TOKEN_CHAR); @@ -325,7 +325,7 @@ TEST(Tokenizer, SingleWord) { // Single word with numbers in it test - Tokenizer p(NS_LITERAL_CSTRING("test123")); + Tokenizer p("test123"_ns); EXPECT_TRUE(p.CheckWord("test123")); EXPECT_TRUE(p.CheckEOF()); @@ -335,7 +335,7 @@ TEST(Tokenizer, EndingAfterNumber) { // An end handling after a number - Tokenizer p(NS_LITERAL_CSTRING("123")); + Tokenizer p("123"_ns); EXPECT_FALSE(p.CheckWord("123")); EXPECT_TRUE(p.Check(Tokenizer::Token::Number(123))); @@ -348,7 +348,7 @@ TEST(Tokenizer, BadInteger) // A bad integer test - Tokenizer p(NS_LITERAL_CSTRING("189234891274981758617846178651647620587135")); + Tokenizer p("189234891274981758617846178651647620587135"_ns); EXPECT_TRUE(p.Next(t)); EXPECT_TRUE(t.Type() == Tokenizer::TOKEN_ERROR); @@ -361,7 +361,7 @@ TEST(Tokenizer, CheckExpectedTokenValue) // Check expected token value test - Tokenizer p(NS_LITERAL_CSTRING("blue velvet")); + Tokenizer p("blue velvet"_ns); EXPECT_FALSE(p.Check(Tokenizer::TOKEN_INTEGER, t)); @@ -386,13 +386,13 @@ TEST(Tokenizer, HasFailed) // HasFailed test - Tokenizer p1(NS_LITERAL_CSTRING("a b")); + Tokenizer p1("a b"_ns); while (p1.Next(t) && t.Type() != Tokenizer::TOKEN_CHAR) ; EXPECT_TRUE(p1.HasFailed()); - Tokenizer p2(NS_LITERAL_CSTRING("a b ?!c")); + Tokenizer p2("a b ?!c"_ns); EXPECT_FALSE(p2.CheckChar('c')); EXPECT_TRUE(p2.HasFailed()); @@ -460,7 +460,7 @@ TEST(Tokenizer, Construction) } { - Tokenizer p1(NS_LITERAL_CSTRING("test")); + Tokenizer p1("test"_ns); EXPECT_TRUE(p1.CheckWord("test")); EXPECT_TRUE(p1.CheckEOF()); } @@ -474,15 +474,14 @@ TEST(Tokenizer, Construction) TEST(Tokenizer, Customization) { - Tokenizer p1(NS_LITERAL_CSTRING("test-custom*words and\tdefault-whites"), - nullptr, "-*"); + Tokenizer p1("test-custom*words and\tdefault-whites"_ns, nullptr, "-*"); EXPECT_TRUE(p1.CheckWord("test-custom*words")); EXPECT_TRUE(p1.CheckWhite()); EXPECT_TRUE(p1.CheckWord("and")); EXPECT_TRUE(p1.CheckWhite()); EXPECT_TRUE(p1.CheckWord("default-whites")); - Tokenizer p2(NS_LITERAL_CSTRING("test, custom,whites"), ", "); + Tokenizer p2("test, custom,whites"_ns, ", "); EXPECT_TRUE(p2.CheckWord("test")); EXPECT_TRUE(p2.CheckWhite()); EXPECT_TRUE(p2.CheckWhite()); @@ -490,8 +489,7 @@ TEST(Tokenizer, Customization) EXPECT_TRUE(p2.CheckWhite()); EXPECT_TRUE(p2.CheckWord("whites")); - Tokenizer p3(NS_LITERAL_CSTRING("test, custom, whites-and#word-chars"), ",", - "-#"); + Tokenizer p3("test, custom, whites-and#word-chars"_ns, ",", "-#"); EXPECT_TRUE(p3.CheckWord("test")); EXPECT_TRUE(p3.CheckWhite()); EXPECT_FALSE(p3.CheckWhite()); @@ -787,12 +785,11 @@ TEST(Tokenizer, ReadUntil) EXPECT_TRUE(f == "Hello;test 4,"); p.Rollback(); - EXPECT_TRUE( - p.ReadUntil(Tokenizer::Token::Word(NS_LITERAL_CSTRING("test")), f)); + EXPECT_TRUE(p.ReadUntil(Tokenizer::Token::Word("test"_ns), f)); EXPECT_TRUE(f == "Hello;"); p.Rollback(); - EXPECT_TRUE(p.ReadUntil(Tokenizer::Token::Word(NS_LITERAL_CSTRING("test")), f, + EXPECT_TRUE(p.ReadUntil(Tokenizer::Token::Word("test"_ns), f, Tokenizer::INCLUDE_LAST)); EXPECT_TRUE(f == "Hello;test"); EXPECT_TRUE(p.ReadUntil(Tokenizer::Token::Char(','), f)); @@ -947,13 +944,13 @@ TEST(Tokenizer, Incremental) [&](Token const& t, IncrementalTokenizer& i) -> nsresult { switch (++test) { case 1: - EXPECT_TRUE(t.Equals(Token::Word(NS_LITERAL_CSTRING("test1")))); + EXPECT_TRUE(t.Equals(Token::Word("test1"_ns))); break; case 2: EXPECT_TRUE(t.Equals(Token::Char(','))); break; case 3: - EXPECT_TRUE(t.Equals(Token::Word(NS_LITERAL_CSTRING("test2")))); + EXPECT_TRUE(t.Equals(Token::Word("test2"_ns))); break; case 4: EXPECT_TRUE(t.Equals(Token::Char(','))); @@ -965,7 +962,7 @@ TEST(Tokenizer, Incremental) EXPECT_TRUE(t.Equals(Token::Char(','))); break; case 7: - EXPECT_TRUE(t.Equals(Token::Word(NS_LITERAL_CSTRING("test3")))); + EXPECT_TRUE(t.Equals(Token::Word("test3"_ns))); break; case 8: EXPECT_TRUE(t.Equals(Token::EndOfFile())); @@ -996,17 +993,17 @@ TEST(Tokenizer, IncrementalRollback) [&](Token const& t, IncrementalTokenizer& i) -> nsresult { switch (++test) { case 1: - EXPECT_TRUE(t.Equals(Token::Word(NS_LITERAL_CSTRING("test1")))); + EXPECT_TRUE(t.Equals(Token::Word("test1"_ns))); break; case 2: EXPECT_TRUE(t.Equals(Token::Char(','))); break; case 3: - EXPECT_TRUE(t.Equals(Token::Word(NS_LITERAL_CSTRING("test2")))); + EXPECT_TRUE(t.Equals(Token::Word("test2"_ns))); i.Rollback(); // so that we get the token again break; case 4: - EXPECT_TRUE(t.Equals(Token::Word(NS_LITERAL_CSTRING("test2")))); + EXPECT_TRUE(t.Equals(Token::Word("test2"_ns))); break; case 5: EXPECT_TRUE(t.Equals(Token::Char(','))); @@ -1018,7 +1015,7 @@ TEST(Tokenizer, IncrementalRollback) EXPECT_TRUE(t.Equals(Token::Char(','))); break; case 8: - EXPECT_TRUE(t.Equals(Token::Word(NS_LITERAL_CSTRING("test3")))); + EXPECT_TRUE(t.Equals(Token::Word("test3"_ns))); break; case 9: EXPECT_TRUE(t.Equals(Token::EndOfFile())); @@ -1050,7 +1047,7 @@ TEST(Tokenizer, IncrementalNeedMoreInput) Token t2; switch (++test) { case 1: - EXPECT_TRUE(t.Equals(Token::Word(NS_LITERAL_CSTRING("a")))); + EXPECT_TRUE(t.Equals(Token::Word("a"_ns))); break; case 2: case 3: @@ -1059,7 +1056,7 @@ TEST(Tokenizer, IncrementalNeedMoreInput) EXPECT_TRUE(t.Equals(Token::Whitespace())); if (i.Next(t2)) { EXPECT_TRUE(test == 5); - EXPECT_TRUE(t2.Equals(Token::Word(NS_LITERAL_CSTRING("bb")))); + EXPECT_TRUE(t2.Equals(Token::Word("bb"_ns))); } else { EXPECT_TRUE(test < 5); i.NeedMoreInput(); @@ -1069,7 +1066,7 @@ TEST(Tokenizer, IncrementalNeedMoreInput) EXPECT_TRUE(t.Equals(Token::Char(','))); break; case 7: - EXPECT_TRUE(t.Equals(Token::Word(NS_LITERAL_CSTRING("c")))); + EXPECT_TRUE(t.Equals(Token::Word("c"_ns))); return NS_ERROR_FAILURE; default: EXPECT_TRUE(false); @@ -1112,7 +1109,7 @@ TEST(Tokenizer, IncrementalCustom) EXPECT_TRUE(t.Equals(custom)); break; case 2: - EXPECT_TRUE(t.Equals(Token::Word(NS_LITERAL_CSTRING("bla")))); + EXPECT_TRUE(t.Equals(Token::Word("bla"_ns))); break; case 3: EXPECT_TRUE(t.Equals(Token::EndOfFile())); @@ -1124,11 +1121,11 @@ TEST(Tokenizer, IncrementalCustom) nullptr, "-"); custom = i.AddCustomToken("some-test", Tokenizer::CASE_SENSITIVE); - i.FeedInput(NS_LITERAL_CSTRING("some-")); + i.FeedInput("some-"_ns); EXPECT_TRUE(test == 0); - i.FeedInput(NS_LITERAL_CSTRING("tes")); + i.FeedInput("tes"_ns); EXPECT_TRUE(test == 0); - i.FeedInput(NS_LITERAL_CSTRING("tbla")); + i.FeedInput("tbla"_ns); EXPECT_TRUE(test == 1); i.FinishInput(); EXPECT_TRUE(test == 3); @@ -1265,17 +1262,17 @@ TEST(Tokenizer, IncrementalBuffering1) Unused << i.AddCustomToken("bb", Tokenizer::CASE_SENSITIVE); i.SetTokenizingMode(Tokenizer::Mode::CUSTOM_ONLY); - i.FeedInput(NS_LITERAL_CSTRING("01234")); + i.FeedInput("01234"_ns); EXPECT_TRUE(test == 1); EXPECT_TRUE(observedFragment.EqualsLiteral("012")); - i.FeedInput(NS_LITERAL_CSTRING("5")); + i.FeedInput("5"_ns); EXPECT_TRUE(test == 1); - i.FeedInput(NS_LITERAL_CSTRING("6789aa")); + i.FeedInput("6789aa"_ns); EXPECT_TRUE(test == 2); EXPECT_TRUE(observedFragment.EqualsLiteral("3456789")); - i.FeedInput(NS_LITERAL_CSTRING("aqwert")); + i.FeedInput("aqwert"_ns); EXPECT_TRUE(test == 4); EXPECT_TRUE(observedFragment.EqualsLiteral("qwe")); @@ -1321,13 +1318,13 @@ TEST(Tokenizer, IncrementalBuffering2) Unused << i.AddCustomToken("bbbbb", Tokenizer::CASE_SENSITIVE); i.SetTokenizingMode(Tokenizer::Mode::CUSTOM_ONLY); - i.FeedInput(NS_LITERAL_CSTRING("01234")); + i.FeedInput("01234"_ns); EXPECT_TRUE(test == 0); - i.FeedInput(NS_LITERAL_CSTRING("5")); + i.FeedInput("5"_ns); EXPECT_TRUE(test == 1); - i.FeedInput(NS_LITERAL_CSTRING("6789aa")); + i.FeedInput("6789aa"_ns); EXPECT_TRUE(test == 2); - i.FeedInput(NS_LITERAL_CSTRING("aqwert")); + i.FeedInput("aqwert"_ns); EXPECT_TRUE(test == 4); i.FinishInput(); EXPECT_TRUE(test == 6); diff --git a/xpcom/tests/gtest/TestUTF.cpp b/xpcom/tests/gtest/TestUTF.cpp index aa91b5097e..2985112ab6 100644 --- a/xpcom/tests/gtest/TestUTF.cpp +++ b/xpcom/tests/gtest/TestUTF.cpp @@ -32,11 +32,11 @@ TEST(UTF, Valid) nsCString tmp8("string "); AppendUTF16toUTF8(str16, tmp8); - EXPECT_TRUE(tmp8.Equals(NS_LITERAL_CSTRING("string ") + str8)); + EXPECT_TRUE(tmp8.Equals("string "_ns + str8)); - nsString tmp16(NS_LITERAL_STRING("string ")); + nsString tmp16(u"string "_ns); AppendUTF8toUTF16(str8, tmp16); - EXPECT_TRUE(tmp16.Equals(NS_LITERAL_STRING("string ") + str16)); + EXPECT_TRUE(tmp16.Equals(u"string "_ns + str16)); EXPECT_EQ(CompareUTF8toUTF16(str8, str16), 0); } @@ -52,7 +52,7 @@ TEST(UTF, Invalid16) nsCString tmp8("string "); AppendUTF16toUTF8(str16, tmp8); - EXPECT_TRUE(tmp8.Equals(NS_LITERAL_CSTRING("string ") + str8)); + EXPECT_TRUE(tmp8.Equals("string "_ns + str8)); EXPECT_EQ(CompareUTF8toUTF16(str8, str16), 0); } @@ -66,9 +66,9 @@ TEST(UTF, Invalid8) EXPECT_TRUE(NS_ConvertUTF8toUTF16(str8).Equals(str16)); - nsString tmp16(NS_LITERAL_STRING("string ")); + nsString tmp16(u"string "_ns); AppendUTF8toUTF16(str8, tmp16); - EXPECT_TRUE(tmp16.Equals(NS_LITERAL_STRING("string ") + str16)); + EXPECT_TRUE(tmp16.Equals(u"string "_ns + str16)); EXPECT_EQ(CompareUTF8toUTF16(str8, str16), 0); } @@ -82,9 +82,9 @@ TEST(UTF, Malformed8) EXPECT_TRUE(NS_ConvertUTF8toUTF16(str8).Equals(str16)); - nsString tmp16(NS_LITERAL_STRING("string ")); + nsString tmp16(u"string "_ns); AppendUTF8toUTF16(str8, tmp16); - EXPECT_TRUE(tmp16.Equals(NS_LITERAL_STRING("string ") + str16)); + EXPECT_TRUE(tmp16.Equals(u"string "_ns + str16)); EXPECT_EQ(CompareUTF8toUTF16(str8, str16), 0); } diff --git a/xpcom/tests/windows/TestNtPathToDosPath.cpp b/xpcom/tests/windows/TestNtPathToDosPath.cpp index 5407caf8ec..8e5a85d5e9 100644 --- a/xpcom/tests/windows/TestNtPathToDosPath.cpp +++ b/xpcom/tests/windows/TestNtPathToDosPath.cpp @@ -149,7 +149,7 @@ TEST(NtPathToDosPath, Tests) EXPECT_TRUE(TestNtPathToDosPath(L"\\Device\\LanmanRedirector\\127.0.0.1\\C$", L"\\\\127.0.0.1\\C$")); - DriveMapping drvMapping(NS_LITERAL_STRING("\\\\127.0.0.1\\C$")); + DriveMapping drvMapping(u"\\\\127.0.0.1\\C$"_ns); // Only run these tests if we were able to map; some machines don't have perms if (drvMapping.Init()) { wchar_t expected[] = L" :\\"; diff --git a/xpcom/threads/CPUUsageWatcher.cpp b/xpcom/threads/CPUUsageWatcher.cpp index 63841cd6c6..6181cf6750 100644 --- a/xpcom/threads/CPUUsageWatcher.cpp +++ b/xpcom/threads/CPUUsageWatcher.cpp @@ -229,7 +229,7 @@ void CPUUsageWatcher::AnnotateHang(BackgroundHangAnnotations& aAnnotations) { } if (mExternalUsageRatio > mExternalUsageThreshold) { - aAnnotations.AddAnnotation(NS_LITERAL_STRING("ExternalCPUHigh"), true); + aAnnotations.AddAnnotation(u"ExternalCPUHigh"_ns, true); } } diff --git a/xpcom/threads/CPUUsageWatcher.h b/xpcom/threads/CPUUsageWatcher.h index 59471344b5..507549c3dc 100644 --- a/xpcom/threads/CPUUsageWatcher.h +++ b/xpcom/threads/CPUUsageWatcher.h @@ -9,6 +9,7 @@ #include "mozilla/HangAnnotations.h" #include "mozilla/BackgroundHangMonitor.h" +#include "mozilla/Result.h" // We only support OSX and Windows, because on Linux we're forced to read // from /proc/stat in order to get global CPU values. We would prefer to not @@ -19,8 +20,10 @@ namespace mozilla { +// Start error values at 1 to allow using the UnusedZero Result +// optimization. enum CPUUsageWatcherError : uint8_t { - ClockGetTimeError, + ClockGetTimeError = 1, GetNumberOfProcessorsError, GetProcessTimesError, GetSystemTimesError, @@ -28,6 +31,14 @@ enum CPUUsageWatcherError : uint8_t { ProcStatError, }; +namespace detail { + +template <> +struct UnusedZero : UnusedZeroEnum { +}; + +} // namespace detail + class CPUUsageHangAnnotator : public BackgroundHangAnnotator { public: }; diff --git a/xpcom/threads/IdleTaskRunner.cpp b/xpcom/threads/IdleTaskRunner.cpp index 9811ba109d..c9d5971504 100644 --- a/xpcom/threads/IdleTaskRunner.cpp +++ b/xpcom/threads/IdleTaskRunner.cpp @@ -10,8 +10,8 @@ namespace mozilla { already_AddRefed IdleTaskRunner::Create( - const CallbackType& aCallback, const char* aRunnableName, uint32_t aDelay, - int64_t aBudget, bool aRepeating, + const CallbackType& aCallback, const char* aRunnableName, + uint32_t aMaxDelay, int64_t aNonIdleBudget, bool aRepeating, const MayStopProcessingCallbackType& aMayStopProcessing, TaskCategory aTaskCategory) { if (aMayStopProcessing && aMayStopProcessing()) { @@ -19,21 +19,21 @@ already_AddRefed IdleTaskRunner::Create( } RefPtr runner = - new IdleTaskRunner(aCallback, aRunnableName, aDelay, aBudget, aRepeating, - aMayStopProcessing, aTaskCategory); + new IdleTaskRunner(aCallback, aRunnableName, aMaxDelay, aNonIdleBudget, + aRepeating, aMayStopProcessing, aTaskCategory); runner->Schedule(false); // Initial scheduling shouldn't use idle dispatch. return runner.forget(); } IdleTaskRunner::IdleTaskRunner( - const CallbackType& aCallback, const char* aRunnableName, uint32_t aDelay, - int64_t aBudget, bool aRepeating, + const CallbackType& aCallback, const char* aRunnableName, + uint32_t aMaxDelay, int64_t aNonIdleBudget, bool aRepeating, const MayStopProcessingCallbackType& aMayStopProcessing, TaskCategory aTaskCategory) - : IdleRunnable(aRunnableName), + : CancelableIdleRunnable(aRunnableName), mCallback(aCallback), - mDelay(aDelay), - mBudget(TimeDuration::FromMilliseconds(aBudget)), + mDelay(aMaxDelay), + mBudget(TimeDuration::FromMilliseconds(aNonIdleBudget)), mRepeating(aRepeating), mTimerActive(false), mMayStopProcessing(aMayStopProcessing), @@ -78,10 +78,15 @@ static void TimedOut(nsITimer* aTimer, void* aClosure) { void IdleTaskRunner::SetDeadline(mozilla::TimeStamp aDeadline) { mDeadline = aDeadline; -}; +} + +void IdleTaskRunner::SetBudget(int64_t aBudget) { + mBudget = TimeDuration::FromMilliseconds(aBudget); +} void IdleTaskRunner::SetTimer(uint32_t aDelay, nsIEventTarget* aTarget) { MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aTarget->IsOnCurrentThread()); // aTarget is always the main thread event target provided from // NS_DispatchToCurrentThreadQueue(). We ignore aTarget here to ensure that // CollectorRunner always run specifically on SystemGroup::EventTargetFor( @@ -143,8 +148,8 @@ void IdleTaskRunner::Schedule(bool aAllowIdleDispatch) { // We weren't allowed to do idle dispatch immediately, do it after a // short timeout. mScheduleTimer->InitWithNamedFuncCallback( - ScheduleTimedOut, this, 16, nsITimer::TYPE_ONE_SHOT_LOW_PRIORITY, - mName); + ScheduleTimedOut, this, 16 /* ms */, + nsITimer::TYPE_ONE_SHOT_LOW_PRIORITY, mName); } } } diff --git a/xpcom/threads/IdleTaskRunner.h b/xpcom/threads/IdleTaskRunner.h index 959dcc6be9..4eb506be2b 100644 --- a/xpcom/threads/IdleTaskRunner.h +++ b/xpcom/threads/IdleTaskRunner.h @@ -12,12 +12,11 @@ namespace mozilla { -// A general purpose repeating callback runner (it can be configured -// to a one-time runner, too.) If it is running repeatedly, -// one has to either explicitly Cancel() the runner or have -// MayContinueProcessing() callback return false to completely remove -// the runner. -class IdleTaskRunner final : public IdleRunnable { +// A general purpose repeating callback runner (it can be configured to a +// one-time runner, too.) If it is running repeatedly, one has to either +// explicitly Cancel() the runner or have MayStopProcessing() callback return +// true to completely remove the runner. +class IdleTaskRunner final : public CancelableIdleRunnable { public: // Return true if some meaningful work was done. using CallbackType = std::function; @@ -28,24 +27,35 @@ class IdleTaskRunner final : public IdleRunnable { using MayStopProcessingCallbackType = std::function; public: + // An IdleTaskRunner will attempt to run in idle time, with a budget computed + // based on a (capped) estimate for how much idle time is available. If there + // is no idle time within `aMaxDelay` ms, it will fall back to running using + // a specified `aNonIdleBudget`. static already_AddRefed Create( - const CallbackType& aCallback, const char* aRunnableName, uint32_t aDelay, - int64_t aBudget, bool aRepeating, + const CallbackType& aCallback, const char* aRunnableName, + uint32_t aMaxDelay, int64_t aNonIdleBudget, bool aRepeating, const MayStopProcessingCallbackType& aMayStopProcessing, TaskCategory aTaskCategory = TaskCategory::Count); NS_IMETHOD Run() override; + // (Used by the task triggering code.) Record the end of the current idle + // period, or null if not running during idle time. void SetDeadline(mozilla::TimeStamp aDeadline) override; + void SetTimer(uint32_t aDelay, nsIEventTarget* aTarget) override; + // Update the non-idle time budgeted for this callback. This really only + // makes sense for a repeating runner. + void SetBudget(int64_t aBudget); + nsresult Cancel() override; void Schedule(bool aAllowIdleDispatch); private: explicit IdleTaskRunner( - const CallbackType& aCallback, const char* aRunnableName, uint32_t aDelay, - int64_t aBudget, bool aRepeating, + const CallbackType& aCallback, const char* aRunnableName, + uint32_t aMaxDelay, int64_t aNonIdleBudget, bool aRepeating, const MayStopProcessingCallbackType& aMayStopProcessing, TaskCategory aTaskCategory); ~IdleTaskRunner(); @@ -55,9 +65,19 @@ class IdleTaskRunner final : public IdleRunnable { nsCOMPtr mTimer; nsCOMPtr mScheduleTimer; CallbackType mCallback; + + // Wait this long for idle time before giving up and running a non-idle + // callback. uint32_t mDelay; + + // If running during idle time, the expected end of the current idle period. + // The null timestamp when the run is triggered by aMaxDelay instead of idle. TimeStamp mDeadline; + + // The expected amount of time the callback will run for, when not running + // during idle time. TimeDuration mBudget; + bool mRepeating; bool mTimerActive; MayStopProcessingCallbackType mMayStopProcessing; diff --git a/xpcom/threads/ThreadEventQueue.cpp b/xpcom/threads/ThreadEventQueue.cpp index 18f4ab95a0..257e4e5b3d 100644 --- a/xpcom/threads/ThreadEventQueue.cpp +++ b/xpcom/threads/ThreadEventQueue.cpp @@ -5,6 +5,7 @@ #include "mozilla/ThreadEventQueue.h" #include "mozilla/EventQueue.h" +#include "GeckoProfiler.h" #include "LeakRefPtr.h" #include "nsComponentManagerUtils.h" #include "nsIThreadInternal.h" diff --git a/xpcom/threads/ThrottledEventQueue.cpp b/xpcom/threads/ThrottledEventQueue.cpp index 7c4420eaa8..fba5f09d99 100644 --- a/xpcom/threads/ThrottledEventQueue.cpp +++ b/xpcom/threads/ThrottledEventQueue.cpp @@ -254,8 +254,10 @@ class ThrottledEventQueue::Inner final : public nsISupports { static already_AddRefed Create(nsISerialEventTarget* aBaseTarget, const char* aName, uint32_t aPriority) { MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(ClearOnShutdown_Internal::sCurrentShutdownPhase == - ShutdownPhase::NotInShutdown); + // FIXME: This assertion only worked when `sCurrentShutdownPhase` was not + // being updated. + // MOZ_ASSERT(ClearOnShutdown_Internal::sCurrentShutdownPhase == + // ShutdownPhase::NotInShutdown); RefPtr ref = new Inner(aBaseTarget, aName, aPriority); return ref.forget(); diff --git a/xpcom/threads/moz.build b/xpcom/threads/moz.build index 03d922adb8..b439f29dda 100644 --- a/xpcom/threads/moz.build +++ b/xpcom/threads/moz.build @@ -28,6 +28,7 @@ XPCOM_MANIFESTS += [ EXPORTS += [ 'MainThreadUtils.h', 'nsICancelableRunnable.h', + 'nsIDiscardableRunnable.h', 'nsIIdleRunnable.h', 'nsMemoryPressure.h', 'nsProcess.h', diff --git a/xpcom/threads/nsICancelableRunnable.h b/xpcom/threads/nsICancelableRunnable.h index f15b9c8a87..ed2ce25c6b 100644 --- a/xpcom/threads/nsICancelableRunnable.h +++ b/xpcom/threads/nsICancelableRunnable.h @@ -19,8 +19,9 @@ class nsICancelableRunnable : public nsISupports { NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICANCELABLERUNNABLE_IID) /* - * Cancels a pending task. If the task has already been executed this will - * be a no-op. Calling this method twice is considered an error. + * Cancels a pending task, so that calling run() on the task is a no-op. + * Calling cancel after the task execution has begun will be a no-op. + * Calling this method twice is considered an error. * * @throws NS_ERROR_UNEXPECTED * Indicates that the runnable has already been canceled. diff --git a/xpcom/threads/nsIDiscardableRunnable.h b/xpcom/threads/nsIDiscardableRunnable.h new file mode 100644 index 0000000000..9edfb84575 --- /dev/null +++ b/xpcom/threads/nsIDiscardableRunnable.h @@ -0,0 +1,39 @@ +/* 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 XPCOM_THREADS_NSIDISCARDABLERUNNABLE_H_ +#define XPCOM_THREADS_NSIDISCARDABLERUNNABLE_H_ + +#include "nsISupports.h" + +/** + * An interface implemented by nsIRunnable tasks for which nsIRunnable::Run() + * might not be called. + */ +#define NS_IDISCARDABLERUNNABLE_IID \ + { \ + 0xde93dc4c, 0x755c, 0x4cdc, { \ + 0x96, 0x76, 0x35, 0xc6, 0x48, 0x81, 0x59, 0x78 \ + } \ + } + +class NS_NO_VTABLE nsIDiscardableRunnable : public nsISupports { + public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDISCARDABLERUNNABLE_IID) + + /** + * Called exactly once on a queued task only if nsIRunnable::Run() is not + * called. + */ + virtual void OnDiscard() = 0; + + protected: + nsIDiscardableRunnable() = default; + virtual ~nsIDiscardableRunnable() = default; +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIDiscardableRunnable, + NS_IDISCARDABLERUNNABLE_IID) + +#endif // XPCOM_THREADS_NSIDISCARDABLERUNNABLE_H_ diff --git a/xpcom/threads/nsThreadManager.cpp b/xpcom/threads/nsThreadManager.cpp index e17653cb89..0940b06a3f 100644 --- a/xpcom/threads/nsThreadManager.cpp +++ b/xpcom/threads/nsThreadManager.cpp @@ -69,7 +69,7 @@ nsresult BackgroundEventTarget::Init() { nsCOMPtr pool(new nsThreadPool()); NS_ENSURE_TRUE(pool, NS_ERROR_FAILURE); - nsresult rv = pool->SetName(NS_LITERAL_CSTRING("BackgroundThreadPool")); + nsresult rv = pool->SetName("BackgroundThreadPool"_ns); NS_ENSURE_SUCCESS(rv, rv); // Use potentially more conservative stack size. @@ -88,7 +88,7 @@ nsresult BackgroundEventTarget::Init() { nsCOMPtr ioPool(new nsThreadPool()); NS_ENSURE_TRUE(pool, NS_ERROR_FAILURE); - rv = ioPool->SetName(NS_LITERAL_CSTRING("BgIOThreadPool")); + rv = ioPool->SetName("BgIOThreadPool"_ns); NS_ENSURE_SUCCESS(rv, rv); // Use potentially more conservative stack size. @@ -602,7 +602,7 @@ bool nsThreadManager::IsNSThread() const { NS_IMETHODIMP nsThreadManager::NewThread(uint32_t aCreationFlags, uint32_t aStackSize, nsIThread** aResult) { - return NewNamedThread(NS_LITERAL_CSTRING(""), aStackSize, aResult); + return NewNamedThread(""_ns, aStackSize, aResult); } NS_IMETHODIMP diff --git a/xpcom/threads/nsThreadUtils.cpp b/xpcom/threads/nsThreadUtils.cpp index 710ac2637b..dd98b31e59 100644 --- a/xpcom/threads/nsThreadUtils.cpp +++ b/xpcom/threads/nsThreadUtils.cpp @@ -75,14 +75,22 @@ Runnable::GetName(nsACString& aName) { } # endif -NS_IMPL_ISUPPORTS_INHERITED(CancelableRunnable, Runnable, nsICancelableRunnable) +NS_IMPL_ISUPPORTS_INHERITED(DiscardableRunnable, Runnable, + nsIDiscardableRunnable) -nsresult CancelableRunnable::Cancel() { - // Do nothing - return NS_OK; +NS_IMPL_ISUPPORTS_INHERITED(CancelableRunnable, DiscardableRunnable, + nsICancelableRunnable) + +void CancelableRunnable::OnDiscard() { + // Tasks that implement Cancel() can be safely cleaned up if it turns out + // that the task will not run. + (void)NS_WARN_IF(NS_FAILED(Cancel())); } -NS_IMPL_ISUPPORTS_INHERITED(IdleRunnable, CancelableRunnable, nsIIdleRunnable) +NS_IMPL_ISUPPORTS_INHERITED(IdleRunnable, DiscardableRunnable, nsIIdleRunnable) + +NS_IMPL_ISUPPORTS_INHERITED(CancelableIdleRunnable, CancelableRunnable, + nsIIdleRunnable) NS_IMPL_ISUPPORTS_INHERITED(PrioritizableRunnable, Runnable, nsIRunnablePriority) @@ -327,20 +335,38 @@ extern nsresult NS_DispatchToMainThreadQueue( return rv; } -class IdleRunnableWrapper final : public IdleRunnable { +class IdleRunnableWrapper final : public Runnable, + public nsIDiscardableRunnable, + public nsIIdleRunnable { public: explicit IdleRunnableWrapper(already_AddRefed&& aEvent) - : mRunnable(std::move(aEvent)) {} + : Runnable("IdleRunnableWrapper"), + mRunnable(std::move(aEvent)), + mDiscardable(do_QueryInterface(mRunnable)) {} + + NS_DECL_ISUPPORTS_INHERITED NS_IMETHOD Run() override { if (!mRunnable) { return NS_OK; } CancelTimer(); + // Don't clear mDiscardable because that would cause QueryInterface to + // change behavior during the lifetime of an instance. nsCOMPtr runnable = std::move(mRunnable); return runnable->Run(); } + // nsIDiscardableRunnable + void OnDiscard() override { + if (!mRunnable) { + // Run() was already called from TimedOut(). + return; + } + mDiscardable->OnDiscard(); + mRunnable = nullptr; + } + static void TimedOut(nsITimer* aTimer, void* aClosure) { RefPtr runnable = static_cast(aClosure); @@ -381,8 +407,17 @@ class IdleRunnableWrapper final : public IdleRunnable { nsCOMPtr mTimer; nsCOMPtr mRunnable; + nsCOMPtr mDiscardable; }; +NS_IMPL_ADDREF_INHERITED(IdleRunnableWrapper, Runnable) +NS_IMPL_RELEASE_INHERITED(IdleRunnableWrapper, Runnable) + +NS_INTERFACE_MAP_BEGIN(IdleRunnableWrapper) + NS_INTERFACE_MAP_ENTRY(nsIIdleRunnable) + NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDiscardableRunnable, mDiscardable) +NS_INTERFACE_MAP_END_INHERITING(Runnable) + extern nsresult NS_DispatchToThreadQueue(already_AddRefed&& aEvent, uint32_t aTimeout, nsIThread* aThread, EventQueuePriority aQueue) { diff --git a/xpcom/threads/nsThreadUtils.h b/xpcom/threads/nsThreadUtils.h index dfe668099c..cc4b675c32 100644 --- a/xpcom/threads/nsThreadUtils.h +++ b/xpcom/threads/nsThreadUtils.h @@ -19,6 +19,7 @@ #include "mozilla/Tuple.h" #include "nsCOMPtr.h" #include "nsICancelableRunnable.h" +#include "nsIDiscardableRunnable.h" #include "nsIIdlePeriod.h" #include "nsIIdleRunnable.h" #include "nsINamed.h" @@ -496,15 +497,44 @@ class Runnable : public nsIRunnable Runnable& operator=(const Runnable&&) = delete; }; -// This class is designed to be subclassed. -class CancelableRunnable : public Runnable, public nsICancelableRunnable { +// This is a base class for tasks that might not be run, such as those that may +// be dispatched to workers. +// The owner of an event target will call either Run() or OnDiscard() +// exactly once. +// Derived classes should override Run(). An OnDiscard() override may +// provide cleanup when Run() will not be called. +class DiscardableRunnable : public Runnable, public nsIDiscardableRunnable { public: NS_DECL_ISUPPORTS_INHERITED + // nsIDiscardableRunnable + void OnDiscard() override {} + + DiscardableRunnable() = delete; + explicit DiscardableRunnable(const char* aName) : Runnable(aName) {} + + protected: + virtual ~DiscardableRunnable() = default; + + private: + DiscardableRunnable(const DiscardableRunnable&) = delete; + DiscardableRunnable& operator=(const DiscardableRunnable&) = delete; + DiscardableRunnable& operator=(const DiscardableRunnable&&) = delete; +}; + +// This class is designed to be subclassed. +// Derived classes should override Run() and Cancel() to provide that +// calling Run() after Cancel() is a no-op. +class CancelableRunnable : public DiscardableRunnable, + public nsICancelableRunnable { + public: + NS_DECL_ISUPPORTS_INHERITED + // nsIDiscardableRunnable + void OnDiscard() override; // nsICancelableRunnable - virtual nsresult Cancel() override; + virtual nsresult Cancel() override = 0; CancelableRunnable() = delete; - explicit CancelableRunnable(const char* aName) : Runnable(aName) {} + explicit CancelableRunnable(const char* aName) : DiscardableRunnable(aName) {} protected: virtual ~CancelableRunnable() = default; @@ -516,12 +546,12 @@ class CancelableRunnable : public Runnable, public nsICancelableRunnable { }; // This class is designed to be subclassed. -class IdleRunnable : public CancelableRunnable, public nsIIdleRunnable { +class IdleRunnable : public DiscardableRunnable, public nsIIdleRunnable { public: NS_DECL_ISUPPORTS_INHERITED - IdleRunnable() : CancelableRunnable("IdleRunnable") {} - explicit IdleRunnable(const char* aName) : CancelableRunnable(aName) {} + IdleRunnable() : DiscardableRunnable("IdleRunnable") {} + explicit IdleRunnable(const char* aName) : DiscardableRunnable(aName) {} protected: virtual ~IdleRunnable() = default; @@ -532,6 +562,25 @@ class IdleRunnable : public CancelableRunnable, public nsIIdleRunnable { IdleRunnable& operator=(const IdleRunnable&&) = delete; }; +// This class is designed to be subclassed. +class CancelableIdleRunnable : public CancelableRunnable, + public nsIIdleRunnable { + public: + NS_DECL_ISUPPORTS_INHERITED + + CancelableIdleRunnable() : CancelableRunnable("CancelableIdleRunnable") {} + explicit CancelableIdleRunnable(const char* aName) + : CancelableRunnable(aName) {} + + protected: + virtual ~CancelableIdleRunnable() = default; + + private: + CancelableIdleRunnable(const CancelableIdleRunnable&) = delete; + CancelableIdleRunnable& operator=(const CancelableIdleRunnable&) = delete; + CancelableIdleRunnable& operator=(const CancelableIdleRunnable&&) = delete; +}; + // This class is designed to be a wrapper of a real runnable to support event // prioritizable. class PrioritizableRunnable : public Runnable, public nsIRunnablePriority { @@ -720,12 +769,13 @@ class nsRunnableMethod Kind == mozilla::RunnableKind::Standard, mozilla::Runnable, std::conditional_t>, + mozilla::CancelableIdleRunnable>>, protected mozilla::detail::TimerBehaviour { using BaseType = std::conditional_t< Kind == mozilla::RunnableKind::Standard, mozilla::Runnable, std::conditional_t>; + mozilla::CancelableRunnable, + mozilla::CancelableIdleRunnable>>; public: nsRunnableMethod(const char* aName) : BaseType(aName) {} @@ -1172,7 +1222,8 @@ class RunnableMethodImpl final virtual ~RunnableMethodImpl() { Revoke(); }; static void TimedOut(nsITimer* aTimer, void* aClosure) { static_assert(IsIdle(Kind), "Don't use me!"); - RefPtr r = static_cast(aClosure); + RefPtr r = + static_cast(aClosure); r->SetDeadline(TimeStamp()); r->Run(); r->Cancel(); diff --git a/xpcom/xpcom-private.h.in b/xpcom/xpcom-private.h.in deleted file mode 100644 index d089d1ec50..0000000000 --- a/xpcom/xpcom-private.h.in +++ /dev/null @@ -1,38 +0,0 @@ -/* 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/. */ - -/* The following defines are only used by the xpcom implementation */ - -#ifndef _XPCOM_PRIVATE_H_ -#define _XPCOM_PRIVATE_H_ - -/* Define if getpagesize() is available */ -#undef HAVE_GETPAGESIZE - -/* Define if statvfs64() is available */ -#undef HAVE_STATVFS64 - -/* Define if statvfs() is available */ -#undef HAVE_STATVFS - -/* Define if statfs64() is available */ -#undef HAVE_STATFS64 - -/* Define if statfs() is available */ -#undef HAVE_STATFS - -/* Define if is present */ -#undef HAVE_SYS_STATVFS_H - -/* Define if is present */ -#undef HAVE_SYS_STATFS_H - -/* Define if is present */ -#undef HAVE_SYS_VFS_H - -/* Define if is present */ -#undef HAVE_SYS_MOUNT_H - -#endif /* _XPCOM_PRIVATE_H_ */ - diff --git a/xpfe/appshell/nsContentTreeOwner.cpp b/xpfe/appshell/nsContentTreeOwner.cpp index b9cadb98bb..6cc052a092 100644 --- a/xpfe/appshell/nsContentTreeOwner.cpp +++ b/xpfe/appshell/nsContentTreeOwner.cpp @@ -282,8 +282,7 @@ nsContentTreeOwner::SetPersistence(bool aPersistPosition, bool aPersistSize, ErrorResult rv; if (saveString) { - docShellElement->SetAttribute(NS_LITERAL_STRING("persist"), persistString, - rv); + docShellElement->SetAttribute(u"persist"_ns, persistString, rv); } return NS_OK;