From f855ceaa314261aee496fe5a209f283750b1896c Mon Sep 17 00:00:00 2001 From: roytam1 Date: Tue, 4 Apr 2023 12:14:15 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1163826 - Add remainder of top .jp sites to CSS unprefixing service whitelist. r=dholbert (8ed22f2638) - Bug 1165834: Add alicdn.com (used by taobao.com) to the CSS Unprefixing Service whitelist. r=miketaylr (30d150c28c) - Bug 1166792 - Add 3rd batch of top .jp sites to CSS unprefixing service whitelists. r=dholbert (e4073c1f09) - Bug 1170375 - Add 4th batch of top .jp sites to CSS unprefixing service whitelists. r=dholbert (d741e57cb0) - Bug 1207850 - Temporary fix for canceling the pump used by FetchBody. r=nsm (bc85cb1500) - Bug 1224865: Don't set a document in FetchDriver for requests in workers. r=bkelly (7bcb0bd16b) - Bug 1108181 - Make Headers iterable; r=bzbarsky (da8d6f8bb2) - Bug 1217501 P5 Relax guard checking on Headers with existing headers. r=ehsan (75ec3b6ae5) - Bug 1207882 - Use a separate build target for config/buildid. r=gps (ad9f536aac) - Bug 1216697 - Unship Request.cache until the implementation is finished; r=bzbarsky (49264a21d8) - Bug 1218119 - Simplify defining worker prefs; r=baku (8987aa23c3) - namespace (d88c3b7fc6) - Bug 1179489 - Don't count service workers towards an origin's max worker quota; r=nsm (ce5e1345ba) - Bug 1151646 - Cleanup, r=khuey. (d119d19ea7) - Bug 1118778 - Write upload properties from upload.py; r=glandium (f8745ffda8) - Bug 1194741 - Display upload output; r=nalexander (7adaa41d11) - Bug 1197293 - allow for TC builds that don't use 'make upload'; r=ted (e671e7c651) - Bug 1137000 - Add support for SDK building to moz-automation.mk. r=mshal (69b7ccb3c8) - Bug 1175895 - aid greppability of MOZ_AUTOMATION_*; r=ted (c9a099f168) - Bug 1198179 - Kill gen_mach_buildprops.py; r=ted (fa74e1930f) - Bug 1198179 - make upload.py write properties even if not uploading; r=ted (e7ca79b807) - Bug 8623031 - Move desktop build logic to a container neutral location; r=dustin (81dc866373) - Bug 1187139 (part 1) - Replace nsBaseHashtable::Enumerate() calls in accessible/ with iterators. r=tbsaunde. (7a75c73d17) - Bug 1187139 (part 2) - Replace nsBaseHashtable::Enumerate() calls in accessible/ with iterators. r=tbsaunde. (c631350ddb) - Bug 1187139 (part 3) - Replace nsBaseHashtable::Enumerate() calls in accessible/ with iterators. r=tbsaunde. (052cced2ca) - Bug 1225396 part 4 - Remove @@iterator workaround in Codegen.py. r=bz (3b05ddc4f0) - Bug 1048695 part 1. Pass the set of globals where a member should NOT be exposed to MemberCondition. r=peterv (d5c9040323) - Bug 1048695 part 2. Make interface members not be exposed based on their nonExposedGlobals. r=peterv (e852319bd0) - Bug 1229493 - Stop shell-only modules classes being reported as standard classes r=shu (4a6457af8d) - Bug 1151646 - Fix static analysis bustage. (347564b4d2) - Bug 1231051 - Moz2Dify nsNativeThemeCocoa::DrawWidgetBackground. r=mstange. (cbcbe17e30) - Bug 1178984 - Crashes at nsMenuBarX::RemoveMenuAtIndex. r=spohl (6e5869ae28) - leftovers of Bug 1151345 - Add debug logging to help decipher this bug. r=spohl (22d42fc66d) --- accessible/base/nsAccCache.h | 40 +-- accessible/xpcom/xpcAccessibleDocument.cpp | 13 +- accessible/xul/XULTreeAccessible.cpp | 16 +- accessible/xul/XULTreeGridAccessible.cpp | 3 +- build/gen_mach_buildprops.py | 124 ------- build/moz-automation.mk | 70 ++-- build/mozconfig.automation | 1 + build/upload.py | 145 ++++++-- caps/nsPrincipal.cpp | 18 +- config/Makefile.in | 4 +- dom/bindings/BindingUtils.cpp | 49 +++ dom/bindings/BindingUtils.h | 10 - dom/bindings/Codegen.py | 97 ++++-- dom/bindings/DOMJSClass.h | 40 +++ dom/fetch/Fetch.cpp | 20 +- dom/fetch/FetchDriver.cpp | 6 +- dom/fetch/Headers.h | 13 + dom/fetch/InternalHeaders.cpp | 9 +- dom/fetch/InternalHeaders.h | 15 + dom/fetch/Request.cpp | 19 + dom/fetch/Request.h | 2 + dom/fetch/Response.h | 2 +- dom/indexedDB/IDBFactory.cpp | 1 + .../mochitest/fetch/fetch_test_framework.js | 3 +- dom/tests/mochitest/fetch/mochitest.ini | 1 + dom/tests/mochitest/fetch/sw_reroute.js | 3 +- .../mochitest/fetch/test_headers_common.js | 73 +++- .../mochitest/fetch/test_request_cache.html | 19 + dom/webidl/EventTarget.webidl | 2 +- dom/webidl/Headers.webidl | 1 + dom/webidl/Request.webidl | 1 + dom/workers/RuntimeService.cpp | 327 ++++++------------ dom/workers/RuntimeService.h | 14 +- dom/workers/WorkerPrefs.h | 48 +++ dom/workers/WorkerPrivate.h | 107 +----- dom/workers/WorkerScope.cpp | 2 + dom/workers/Workers.h | 19 +- dom/workers/moz.build | 1 + js/public/Class.h | 2 +- js/src/builtin/ModuleObject.cpp | 86 +++-- js/src/builtin/ModuleObject.h | 4 +- js/src/jsprototypes.h | 3 - js/src/shell/js.cpp | 3 + js/src/vm/GlobalObject.h | 20 ++ modules/libpref/init/all.js | 3 + testing/docker/desktop-build/bin/build.sh | 12 + .../desktop-build/bin/checkout-sources.sh | 54 +++ .../mozharness/mozilla/building/buildbase.py | 12 +- .../scripts/builder/build-linux.sh | 153 ++++++++ .../cache-storage/serviceworker/__dir__.ini | 1 + .../serviceworker/cache-add.https.html.ini | 3 - .../serviceworker/cache-delete.https.html.ini | 3 - .../serviceworker/cache-match.https.html.ini | 6 - .../serviceworker/cache-put.https.html.ini | 6 - .../cache-storage-keys.https.html.ini | 3 - .../cache-storage-match.https.html.ini | 3 - .../cache-storage.https.html.ini | 3 - .../window/cache-match.https.html.ini | 5 - .../window/cache-put.https.html.ini | 6 - .../window/cache-storage-match.https.html.ini | 3 - .../cache-storage/worker/__dir__.ini | 1 + .../worker/cache-add.https.html.ini | 3 - .../worker/cache-delete.https.html.ini | 3 - .../worker/cache-match.https.html.ini | 5 - .../worker/cache-put.https.html.ini | 6 - .../worker/cache-storage-keys.https.html.ini | 3 - .../worker/cache-storage-match.https.html.ini | 3 - .../worker/cache-storage.https.html.ini | 3 - toolkit/mozapps/installer/packager.mk | 2 + widget/cocoa/nsMenuBarX.mm | 13 +- widget/cocoa/nsNativeThemeCocoa.mm | 10 +- 71 files changed, 1003 insertions(+), 781 deletions(-) delete mode 100644 build/gen_mach_buildprops.py create mode 100644 dom/tests/mochitest/fetch/test_request_cache.html create mode 100644 dom/workers/WorkerPrefs.h create mode 100644 testing/docker/desktop-build/bin/build.sh create mode 100644 testing/docker/desktop-build/bin/checkout-sources.sh create mode 100644 testing/taskcluster/scripts/builder/build-linux.sh create mode 100644 testing/web-platform/meta/service-workers/cache-storage/serviceworker/__dir__.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-add.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-delete.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-match.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-put.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage-match.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/window/cache-match.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/window/cache-put.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/window/cache-storage-match.https.html.ini create mode 100644 testing/web-platform/meta/service-workers/cache-storage/worker/__dir__.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/worker/cache-add.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/worker/cache-delete.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/worker/cache-match.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/worker/cache-put.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage-keys.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage-match.https.html.ini delete mode 100644 testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage.https.html.ini diff --git a/accessible/base/nsAccCache.h b/accessible/base/nsAccCache.h index acfedb8e63..4e97dbf2c4 100644 --- a/accessible/base/nsAccCache.h +++ b/accessible/base/nsAccCache.h @@ -12,40 +12,34 @@ // Accessible cache utils //////////////////////////////////////////////////////////////////////////////// -/** - * Shutdown and removes the accessible from cache. - */ template -static PLDHashOperator -ClearCacheEntry(const void* aKey, RefPtr& aAccessible, void* aUserArg) +void +UnbindCacheEntriesFromDocument( + nsRefPtrHashtable, T>& aCache) { - NS_ASSERTION(aAccessible, "Calling ClearCacheEntry with a nullptr pointer!"); - if (aAccessible && !aAccessible->IsDefunct()) - aAccessible->Shutdown(); - - return PL_DHASH_REMOVE; -} - -template -static PLDHashOperator -UnbindCacheEntryFromDocument(const void* aKey, RefPtr& aAccessible, - void* aUserArg) -{ - MOZ_ASSERT(aAccessible && !aAccessible->IsDefunct()); - aAccessible->Document()->UnbindFromDocument(aAccessible); - - return PL_DHASH_REMOVE; + for (auto iter = aCache.Iter(); !iter.Done(); iter.Next()) { + T* accessible = iter.Data(); + MOZ_ASSERT(accessible && !accessible->IsDefunct()); + accessible->Document()->UnbindFromDocument(accessible); + iter.Remove(); + } } /** * Clear the cache and shutdown the accessibles. */ - template static void ClearCache(nsRefPtrHashtable, T>& aCache) { - aCache.Enumerate(ClearCacheEntry, nullptr); + for (auto iter = aCache.Iter(); !iter.Done(); iter.Next()) { + T* accessible = iter.Data(); + MOZ_ASSERT(accessible); + if (accessible && !accessible->IsDefunct()) { + accessible->Shutdown(); + } + iter.Remove(); + } } #endif diff --git a/accessible/xpcom/xpcAccessibleDocument.cpp b/accessible/xpcom/xpcAccessibleDocument.cpp index 412a68a393..de3b7ebcfe 100644 --- a/accessible/xpcom/xpcAccessibleDocument.cpp +++ b/accessible/xpcom/xpcAccessibleDocument.cpp @@ -195,17 +195,12 @@ xpcAccessibleDocument::GetAccessible(Accessible* aAccessible) return xpcAcc; } -static PLDHashOperator -ShutdownAndRemove(const Accessible* aKey, RefPtr& aValue, - void* aUnused) -{ - aValue->Shutdown(); - return PL_DHASH_REMOVE; -} - void xpcAccessibleDocument::Shutdown() { - mCache.Enumerate(ShutdownAndRemove, nullptr); + for (auto iter = mCache.Iter(); !iter.Done(); iter.Next()) { + iter.Data()->Shutdown(); + iter.Remove(); + } xpcAccessibleGeneric::Shutdown(); } diff --git a/accessible/xul/XULTreeAccessible.cpp b/accessible/xul/XULTreeAccessible.cpp index 4c99ccf461..0295099522 100644 --- a/accessible/xul/XULTreeAccessible.cpp +++ b/accessible/xul/XULTreeAccessible.cpp @@ -145,8 +145,9 @@ XULTreeAccessible::Value(nsString& aValue) void XULTreeAccessible::Shutdown() { - if (mDoc && !mDoc->IsDefunct()) - mAccessibleCache.Enumerate(UnbindCacheEntryFromDocument, nullptr); + if (mDoc && !mDoc->IsDefunct()) { + UnbindCacheEntriesFromDocument(mAccessibleCache); + } mTree = nullptr; mTreeView = nullptr; @@ -550,8 +551,7 @@ XULTreeAccessible::InvalidateCache(int32_t aRow, int32_t aCount) return; if (!mTreeView) { - mAccessibleCache.Enumerate(UnbindCacheEntryFromDocument, - nullptr); + UnbindCacheEntriesFromDocument(mAccessibleCache); return; } @@ -609,8 +609,7 @@ XULTreeAccessible::TreeViewInvalidated(int32_t aStartRow, int32_t aEndRow, return; if (!mTreeView) { - mAccessibleCache.Enumerate(UnbindCacheEntryFromDocument, - nullptr); + UnbindCacheEntriesFromDocument(mAccessibleCache); return; } @@ -669,8 +668,7 @@ XULTreeAccessible::TreeViewChanged(nsITreeView* aView) Document()->FireDelayedEvent(reorderEvent); // Clear cache. - mAccessibleCache.Enumerate(UnbindCacheEntryFromDocument, - nullptr); + UnbindCacheEntriesFromDocument(mAccessibleCache); mTreeView = aView; } @@ -687,7 +685,7 @@ XULTreeAccessible::CreateTreeItemAccessible(int32_t aRow) const return accessible.forget(); } - + //////////////////////////////////////////////////////////////////////////////// // XULTreeItemAccessibleBase //////////////////////////////////////////////////////////////////////////////// diff --git a/accessible/xul/XULTreeGridAccessible.cpp b/accessible/xul/XULTreeGridAccessible.cpp index 03ee2642d6..112397c432 100644 --- a/accessible/xul/XULTreeGridAccessible.cpp +++ b/accessible/xul/XULTreeGridAccessible.cpp @@ -277,8 +277,7 @@ void XULTreeGridRowAccessible::Shutdown() { if (mDoc && !mDoc->IsDefunct()) { - mAccessibleCache.Enumerate(UnbindCacheEntryFromDocument, - nullptr); + UnbindCacheEntriesFromDocument(mAccessibleCache); } XULTreeItemAccessibleBase::Shutdown(); diff --git a/build/gen_mach_buildprops.py b/build/gen_mach_buildprops.py deleted file mode 100644 index 0055aa2573..0000000000 --- a/build/gen_mach_buildprops.py +++ /dev/null @@ -1,124 +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/. - -import sys -import os -import hashlib -import json -import re -import errno -from argparse import ArgumentParser - -def getFileHashAndSize(filename): - sha512Hash = 'UNKNOWN' - size = 'UNKNOWN' - - try: - # open in binary mode to make sure we get consistent results - # across all platforms - f = open(filename, "rb") - shaObj = hashlib.sha512(f.read()) - sha512Hash = shaObj.hexdigest() - - size = os.path.getsize(filename) - except: - pass - - return (sha512Hash, size) - -def getMarProperties(filename, partial=False): - if not os.path.exists(filename): - return {} - (mar_hash, mar_size) = getFileHashAndSize(filename) - martype = 'partial' if partial else 'complete' - return { - '%sMarFilename' % martype: os.path.basename(filename), - '%sMarSize' % martype: mar_size, - '%sMarHash' % martype: mar_hash, - } - -def getUrlProperties(filename, package): - # let's create a switch case using name-spaces/dict - # rather than a long if/else with duplicate code - property_conditions = [ - # key: property name, value: condition - ('testsUrl', lambda m: m.endswith(('tests.tar.bz2', 'tests.zip'))), - ('unsignedApkUrl', lambda m: m.endswith('apk') and - 'unsigned-unaligned' in m), - ('robocopApkUrl', lambda m: m.endswith('apk') and 'robocop' in m), - ('jsshellUrl', lambda m: 'jsshell-' in m and m.endswith('.zip')), - ('completeMarUrl', lambda m: m.endswith('.complete.mar')), - ('partialMarUrl', lambda m: m.endswith('.mar') and '.partial.' in m), - ('codeCoverageURL', lambda m: m.endswith('code-coverage-gcno.zip')), - ('sdkUrl', lambda m: m.endswith(('sdk.tar.bz2', 'sdk.zip'))), - ('testPackagesUrl', lambda m: m.endswith('test_packages.json')), - ('packageUrl', lambda m: m.endswith(package)), - ] - url_re = re.compile(r'''^(https?://.*?\.(?:tar\.bz2|dmg|zip|apk|rpm|mar|tar\.gz|json))$''') - properties = {} - - try: - with open(filename) as f: - for line in f: - m = url_re.match(line) - if m: - m = m.group(1) - for prop, condition in property_conditions: - if condition(m): - properties.update({prop: m}) - break - except IOError as e: - if e.errno != errno.ENOENT: - raise - properties = {prop: 'UNKNOWN' for prop, condition in property_conditions} - return properties - -def getPartialInfo(props): - return [{ - "from_buildid": props.get("previous_buildid"), - "size": props.get("partialMarSize"), - "hash": props.get("partialMarHash"), - "url": props.get("partialMarUrl"), - }] - -if __name__ == '__main__': - parser = ArgumentParser(description='Generate mach_build_properties.json for automation builds.') - parser.add_argument("--complete-mar-file", required=True, - action="store", dest="complete_mar_file", - help="Path to the complete MAR file, relative to the objdir.") - parser.add_argument("--partial-mar-file", required=False, - action="store", dest="partial_mar_file", - help="Path to the partial MAR file, relative to the objdir.") - parser.add_argument("--upload-output", required=True, - action="store", dest="upload_output", - help="Path to the text output of 'make upload'") - parser.add_argument("--upload-files", required=True, nargs="+", - action="store", dest="upload_files", - help="List of files to be uploaded.") - parser.add_argument("--package", required=True, - action="store", dest="package", - help="Filename of the build package") - args = parser.parse_args() - - json_data = getMarProperties(args.complete_mar_file) - json_data.update(getUrlProperties(args.upload_output, args.package)) - if args.partial_mar_file: - json_data.update(getMarProperties(args.partial_mar_file, partial=True)) - - # Pull the previous buildid from the partial mar filename. - res = re.match(r'.*\.([0-9]+)-[0-9]+.mar', args.partial_mar_file) - if res: - json_data['previous_buildid'] = res.group(1) - - # Set partialInfo to be a collection of the partial mar properties - # useful for balrog. - json_data['partialInfo'] = getPartialInfo(json_data) - - json_data['uploadFiles'] = args.upload_files - json_data['packageFilename'] = args.package - - with open('mach_build_properties.json', 'w') as outfile: - json.dump(json_data, outfile, indent=4) diff --git a/build/moz-automation.mk b/build/moz-automation.mk index 8c953198c7..fee5194bc7 100644 --- a/build/moz-automation.mk +++ b/build/moz-automation.mk @@ -17,46 +17,44 @@ include $(topsrcdir)/toolkit/mozapps/installer/upload-files.mk # Clear out DIST_FILES if it was set by upload-files.mk (for Android builds) DIST_FILES = -# Log file from the 'make upload' step. We need this to parse out the URLs of -# the uploaded files. -AUTOMATION_UPLOAD_OUTPUT = $(DIST)/automation-upload.txt - # Helper variables to convert from MOZ_AUTOMATION_* variables to the # corresponding the make target -tier_BUILD_SYMBOLS = buildsymbols -tier_L10N_CHECK = l10n-check -tier_PRETTY_L10N_CHECK = pretty-l10n-check -tier_INSTALLER = installer -tier_PRETTY_INSTALLER = pretty-installer -tier_PACKAGE = package -tier_PRETTY_PACKAGE = pretty-package -tier_PACKAGE_TESTS = package-tests -tier_PRETTY_PACKAGE_TESTS = pretty-package-tests -tier_UPDATE_PACKAGING = update-packaging -tier_PRETTY_UPDATE_PACKAGING = pretty-update-packaging -tier_UPLOAD_SYMBOLS = uploadsymbols -tier_UPLOAD = upload +tier_MOZ_AUTOMATION_BUILD_SYMBOLS = buildsymbols +tier_MOZ_AUTOMATION_L10N_CHECK = l10n-check +tier_MOZ_AUTOMATION_PRETTY_L10N_CHECK = pretty-l10n-check +tier_MOZ_AUTOMATION_INSTALLER = installer +tier_MOZ_AUTOMATION_PRETTY_INSTALLER = pretty-installer +tier_MOZ_AUTOMATION_PACKAGE = package +tier_MOZ_AUTOMATION_PRETTY_PACKAGE = pretty-package +tier_MOZ_AUTOMATION_PACKAGE_TESTS = package-tests +tier_MOZ_AUTOMATION_PRETTY_PACKAGE_TESTS = pretty-package-tests +tier_MOZ_AUTOMATION_UPDATE_PACKAGING = update-packaging +tier_MOZ_AUTOMATION_PRETTY_UPDATE_PACKAGING = pretty-update-packaging +tier_MOZ_AUTOMATION_UPLOAD_SYMBOLS = uploadsymbols +tier_MOZ_AUTOMATION_UPLOAD = upload +tier_MOZ_AUTOMATION_SDK = sdk # 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 # here in the order that they will be executed (since mach doesn't know of the # dependencies between them). moz_automation_symbols = \ - PACKAGE_TESTS \ - PRETTY_PACKAGE_TESTS \ - BUILD_SYMBOLS \ - UPLOAD_SYMBOLS \ - PACKAGE \ - PRETTY_PACKAGE \ - INSTALLER \ - PRETTY_INSTALLER \ - UPDATE_PACKAGING \ - PRETTY_UPDATE_PACKAGING \ - L10N_CHECK \ - PRETTY_L10N_CHECK \ - UPLOAD \ + MOZ_AUTOMATION_PACKAGE_TESTS \ + MOZ_AUTOMATION_PRETTY_PACKAGE_TESTS \ + MOZ_AUTOMATION_BUILD_SYMBOLS \ + MOZ_AUTOMATION_UPLOAD_SYMBOLS \ + MOZ_AUTOMATION_PACKAGE \ + MOZ_AUTOMATION_PRETTY_PACKAGE \ + MOZ_AUTOMATION_INSTALLER \ + MOZ_AUTOMATION_PRETTY_INSTALLER \ + MOZ_AUTOMATION_UPDATE_PACKAGING \ + MOZ_AUTOMATION_PRETTY_UPDATE_PACKAGING \ + MOZ_AUTOMATION_L10N_CHECK \ + MOZ_AUTOMATION_PRETTY_L10N_CHECK \ + MOZ_AUTOMATION_UPLOAD \ + MOZ_AUTOMATION_SDK \ $(NULL) -MOZ_AUTOMATION_TIERS := $(foreach sym,$(moz_automation_symbols),$(if $(filter 1,$(MOZ_AUTOMATION_$(sym))),$(tier_$(sym)))) +MOZ_AUTOMATION_TIERS := $(foreach sym,$(moz_automation_symbols),$(if $(filter 1,$($(sym))),$(tier_$(sym)))) # Dependencies between automation build steps automation/uploadsymbols: automation/buildsymbols @@ -76,15 +74,17 @@ automation/upload: automation/package automation/upload: automation/package-tests automation/upload: automation/buildsymbols automation/upload: automation/update-packaging +automation/upload: automation/sdk # automation/{pretty-}package should depend on build (which is implicit due to # the way client.mk invokes automation/build), but buildsymbols changes the # binaries/libs, and that's what we package/test. automation/pretty-package: automation/buildsymbols -# The installer and packager both run stage-package, and may conflict +# The installer, sdk and packager all run stage-package, and may conflict # with each other. automation/installer: automation/package +automation/sdk: automation/installer automation/package # The 'pretty' versions of targets run before the regular ones to avoid # conflicts in writing to the same files. @@ -95,11 +95,7 @@ automation/l10n-check: automation/pretty-l10n-check automation/update-packaging: automation/pretty-update-packaging automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS)) - $(PYTHON) $(topsrcdir)/build/gen_mach_buildprops.py --complete-mar-file $(DIST)/$(COMPLETE_MAR) $(addprefix --partial-mar-file ,$(wildcard $(DIST)/$(PARTIAL_MAR))) --upload-output $(AUTOMATION_UPLOAD_OUTPUT) --upload-files $(abspath $(UPLOAD_FILES)) --package $(PACKAGE) - -# We need the log from make upload to grep it for urls in order to set -# properties. -AUTOMATION_EXTRA_CMDLINE-upload = 2>&1 | tee $(AUTOMATION_UPLOAD_OUTPUT) + @echo Automation steps completed. # Note: We have to force -j1 here, at least until bug 1036563 is fixed. AUTOMATION_EXTRA_CMDLINE-l10n-check = -j1 diff --git a/build/mozconfig.automation b/build/mozconfig.automation index b65f0fa40d..057a4a0b51 100644 --- a/build/mozconfig.automation +++ b/build/mozconfig.automation @@ -17,6 +17,7 @@ mk_add_options "export MOZ_AUTOMATION_INSTALLER=${MOZ_AUTOMATION_INSTALLER-0}" mk_add_options "export MOZ_AUTOMATION_UPDATE_PACKAGING=${MOZ_AUTOMATION_UPDATE_PACKAGING-0}" mk_add_options "export MOZ_AUTOMATION_UPLOAD=${MOZ_AUTOMATION_UPLOAD-1}" mk_add_options "export MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-0}" +mk_add_options "export MOZ_AUTOMATION_SDK=${MOZ_AUTOMATION_SDK-0}" # If we are also building with MOZ_PKG_PRETTYNAMES, set the corresponding # stages. diff --git a/build/upload.py b/build/upload.py index 6b1112eed5..2c70371bae 100644 --- a/build/upload.py +++ b/build/upload.py @@ -8,7 +8,12 @@ # to be set: # UPLOAD_HOST : host to upload files to # UPLOAD_USER : username on that host +# and one of the following: # UPLOAD_PATH : path on that host to put the files in +# UPLOAD_TO_TEMP : upload files to a new temporary directory +# +# If UPLOAD_HOST and UPLOAD_USER are not set, this script will simply write out +# the properties file. # # And will use the following optional environment variables if set: # UPLOAD_SSH_KEY : path to a ssh private key to use @@ -23,18 +28,14 @@ # to the base path. import sys, os +import re +import json +import errno +import hashlib from optparse import OptionParser -from subprocess import check_call, check_output +from subprocess import check_call, check_output, STDOUT import redo -def RequireEnvironmentVariable(v): - """Return the value of the environment variable named v, or print - an error and exit if it's unset (or empty).""" - if not v in os.environ or os.environ[v] == "": - print "Error: required environment variable %s not set" % v - sys.exit(1) - return os.environ[v] - def OptionalEnvironmentVariable(v): """Return the value of the environment variable named v, or None if it's unset (or empty).""" @@ -61,7 +62,9 @@ def WindowsPathToMsysPath(path): """Translate a Windows pathname to an MSYS pathname. Necessary because we call out to ssh/scp, which are MSYS binaries and expect MSYS paths.""" - if sys.platform != 'win32': + # If we're not on Windows, or if we already have an MSYS path (starting + # with '/' instead of 'c:' or something), then just return. + if sys.platform != 'win32' or path.startswith('/'): return path (drive, path) = os.path.splitdrive(os.path.abspath(path)) return "/" + drive[0] + path.replace('\\','/') @@ -85,7 +88,7 @@ def DoSSHCommand(command, user, host, port=None, ssh_key=None): cmdline.extend(["%s@%s" % (user, host), command]) with redo.retrying(check_output, sleeptime=10) as f: - output = f(cmdline).strip() + output = f(cmdline, stderr=STDOUT).strip() return output raise Exception("Command %s returned non-zero exit code" % cmdline) @@ -115,7 +118,71 @@ def GetRemotePath(path, local_file, base_path): dir = dir[len(base_path)+1:].replace('\\','/') return path + dir -def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, base_path=None, upload_to_temp_dir=False, post_upload_command=None): +def GetFileHashAndSize(filename): + sha512Hash = 'UNKNOWN' + size = 'UNKNOWN' + + try: + # open in binary mode to make sure we get consistent results + # across all platforms + with open(filename, "rb") as f: + shaObj = hashlib.sha512(f.read()) + sha512Hash = shaObj.hexdigest() + + size = os.path.getsize(filename) + except: + raise Exception("Unable to get filesize/hash from file: %s" % filename) + + return (sha512Hash, size) + +def GetMarProperties(filename): + if not os.path.exists(filename): + return {} + (mar_hash, mar_size) = GetFileHashAndSize(filename) + return { + 'completeMarFilename': os.path.basename(filename), + 'completeMarSize': mar_size, + 'completeMarHash': mar_hash, + } + +def GetUrlProperties(output, package): + # let's create a switch case using name-spaces/dict + # rather than a long if/else with duplicate code + property_conditions = [ + # key: property name, value: condition + ('symbolsUrl', lambda m: m.endswith('crashreporter-symbols.zip') or + m.endswith('crashreporter-symbols-full.zip')), + ('testsUrl', lambda m: m.endswith(('tests.tar.bz2', 'tests.zip'))), + ('unsignedApkUrl', lambda m: m.endswith('apk') and + 'unsigned-unaligned' in m), + ('robocopApkUrl', lambda m: m.endswith('apk') and 'robocop' in m), + ('jsshellUrl', lambda m: 'jsshell-' in m and m.endswith('.zip')), + ('completeMarUrl', lambda m: m.endswith('.complete.mar')), + ('partialMarUrl', lambda m: m.endswith('.mar') and '.partial.' in m), + ('codeCoverageURL', lambda m: m.endswith('code-coverage-gcno.zip')), + ('sdkUrl', lambda m: m.endswith(('sdk.tar.bz2', 'sdk.zip'))), + ('testPackagesUrl', lambda m: m.endswith('test_packages.json')), + ('packageUrl', lambda m: m.endswith(package)), + ] + url_re = re.compile(r'''^(https?://.*?\.(?:tar\.bz2|dmg|zip|apk|rpm|mar|tar\.gz|json))$''') + properties = {} + + try: + for line in output.splitlines(): + m = url_re.match(line.strip()) + if m: + m = m.group(1) + for prop, condition in property_conditions: + if condition(m): + properties.update({prop: m}) + break + except IOError as e: + if e.errno != errno.ENOENT: + raise + properties = {prop: 'UNKNOWN' for prop, condition in property_conditions} + return properties + +def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, base_path=None, upload_to_temp_dir=False, post_upload_command=None, package=None): """Upload each file in the list files to user@host:path. Optionally pass port and ssh_key to the ssh commands. If base_path is not None, upload files including their path relative to base_path. If upload_to_temp_dir is @@ -126,6 +193,13 @@ def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, after uploading all files, passing it the upload path, and the full paths to all files uploaded. If verbose is True, print status updates while working.""" + if not host or not user: + return {} + if (not path and not upload_to_temp_dir) or (path and upload_to_temp_dir): + print "One (and only one of UPLOAD_PATH or UPLOAD_TO_TEMP must be " + \ + "defined." + sys.exit(1) + if upload_to_temp_dir: path = DoSSHCommand("mktemp -d", user, host, port=port, ssh_key=ssh_key) if not path.endswith("/"): @@ -133,6 +207,7 @@ def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, if base_path is not None: base_path = os.path.abspath(base_path) remote_files = [] + properties = {} try: for file in files: file = os.path.abspath(file) @@ -149,17 +224,31 @@ def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, if verbose: print "Running post-upload command: " + post_upload_command file_list = '"' + '" "'.join(remote_files) + '"' - DoSSHCommand('%s "%s" %s' % (post_upload_command, path, file_list), user, host, port=port, ssh_key=ssh_key) + output = DoSSHCommand('%s "%s" %s' % (post_upload_command, path, file_list), user, host, port=port, ssh_key=ssh_key) + # We print since mozharness may parse URLs from the output stream. + print output + properties = GetUrlProperties(output, package) finally: if upload_to_temp_dir: DoSSHCommand("rm -rf %s" % path, user, host, port=port, ssh_key=ssh_key) if verbose: print "Upload complete" + return properties + +def WriteProperties(files, properties_file, url_properties, package): + properties = url_properties + for file in files: + if file.endswith('.complete.mar'): + properties.update(GetMarProperties(file)) + with open(properties_file, 'w') as outfile: + properties['packageFilename'] = package + properties['uploadFiles'] = [os.path.abspath(f) for f in files] + json.dump(properties, outfile, indent=4) if __name__ == '__main__': - host = RequireEnvironmentVariable('UPLOAD_HOST') - user = RequireEnvironmentVariable('UPLOAD_USER') + host = OptionalEnvironmentVariable('UPLOAD_HOST') + user = OptionalEnvironmentVariable('UPLOAD_USER') path = OptionalEnvironmentVariable('UPLOAD_PATH') upload_to_temp_dir = OptionalEnvironmentVariable('UPLOAD_TO_TEMP') port = OptionalEnvironmentVariable('UPLOAD_PORT') @@ -167,10 +256,7 @@ if __name__ == '__main__': port = int(port) key = OptionalEnvironmentVariable('UPLOAD_SSH_KEY') post_upload_command = OptionalEnvironmentVariable('POST_UPLOAD_CMD') - if (not path and not upload_to_temp_dir) or (path and upload_to_temp_dir): - print "One (and only one of UPLOAD_PATH or UPLOAD_TO_TEMP must be " + \ - "defined." - sys.exit(1) + if sys.platform == 'win32': if path is not None: path = FixupMsysPath(path) @@ -179,17 +265,28 @@ if __name__ == '__main__': parser = OptionParser(usage="usage: %prog [options] ") parser.add_option("-b", "--base-path", - action="store", dest="base_path", + action="store", help="Preserve file paths relative to this path when uploading. If unset, all files will be uploaded directly to UPLOAD_PATH.") + parser.add_option("--properties-file", + action="store", + help="Path to the properties file to store the upload properties.") + parser.add_option("--package", + action="store", + help="Name of the main package.") (options, args) = parser.parse_args() if len(args) < 1: print "You must specify at least one file to upload" sys.exit(1) + if not options.properties_file: + print "You must specify a --properties-file" + sys.exit(1) try: - UploadFiles(user, host, path, args, base_path=options.base_path, - port=port, ssh_key=key, upload_to_temp_dir=upload_to_temp_dir, - post_upload_command=post_upload_command, - verbose=True) + url_properties = UploadFiles(user, host, path, args, base_path=options.base_path, + port=port, ssh_key=key, upload_to_temp_dir=upload_to_temp_dir, + post_upload_command=post_upload_command, + package=options.package, + verbose=True) + WriteProperties(args, options.properties_file, url_properties, options.package) except IOError, (strerror): print strerror sys.exit(1) diff --git a/caps/nsPrincipal.cpp b/caps/nsPrincipal.cpp index cfa221cd32..80e2c1ad57 100644 --- a/caps/nsPrincipal.cpp +++ b/caps/nsPrincipal.cpp @@ -494,17 +494,20 @@ IsOnFullDomainWhitelist(nsIURI* aURI) NS_LITERAL_CSTRING("m.video.baidu.com"), NS_LITERAL_CSTRING("m.video.baidu.com"), NS_LITERAL_CSTRING("imgcache.gtimg.cn"), // for m.v.qq.com + NS_LITERAL_CSTRING("s.tabelog.jp"), + NS_LITERAL_CSTRING("s.yimg.jp"), // for s.tabelog.jp NS_LITERAL_CSTRING("i.yimg.jp"), // for *.yahoo.co.jp NS_LITERAL_CSTRING("ai.yimg.jp"), // for *.yahoo.co.jp + NS_LITERAL_CSTRING("m.finance.yahoo.co.jp"), NS_LITERAL_CSTRING("daily.c.yimg.jp"), // for sp.daily.co.jp NS_LITERAL_CSTRING("stat100.ameba.jp"), // for ameblo.jp NS_LITERAL_CSTRING("user.ameba.jp"), // for ameblo.jp NS_LITERAL_CSTRING("www.goo.ne.jp"), - NS_LITERAL_CSTRING("s.tabelog.jp"), NS_LITERAL_CSTRING("x.gnst.jp"), // for mobile.gnavi.co.jp NS_LITERAL_CSTRING("c.x.gnst.jp"), // for mobile.gnavi.co.jp NS_LITERAL_CSTRING("www.smbc-card.com"), NS_LITERAL_CSTRING("static.card.jp.rakuten-static.com"), // for rakuten-card.co.jp + NS_LITERAL_CSTRING("img.travel.rakuten.co.jp"), // for travel.rakuten.co.jp NS_LITERAL_CSTRING("img.mixi.net"), // for mixi.jp NS_LITERAL_CSTRING("girlschannel.net"), NS_LITERAL_CSTRING("www.fancl.co.jp"), @@ -520,6 +523,16 @@ IsOnFullDomainWhitelist(nsIURI* aURI) NS_LITERAL_CSTRING("mw.nikkei.com"), NS_LITERAL_CSTRING("www.nhk.or.jp"), NS_LITERAL_CSTRING("www.tokyo-sports.co.jp"), + NS_LITERAL_CSTRING("www.bellemaison.jp"), + NS_LITERAL_CSTRING("www.kuronekoyamato.co.jp"), + NS_LITERAL_CSTRING("formassist.jp"), // for orico.jp + NS_LITERAL_CSTRING("sp.m.reuters.co.jp"), + NS_LITERAL_CSTRING("www.atre.co.jp"), + NS_LITERAL_CSTRING("www.jtb.co.jp"), + NS_LITERAL_CSTRING("www.sharp.co.jp"), + NS_LITERAL_CSTRING("www.biccamera.com"), + NS_LITERAL_CSTRING("weathernews.jp"), + NS_LITERAL_CSTRING("cache.ymail.jp"), // for www.yamada-denkiweb.com }; static const size_t sNumFullDomainsOnWhitelist = MOZ_ARRAY_LENGTH(sFullDomainsOnWhitelist); @@ -545,8 +558,11 @@ IsOnBaseDomainWhitelist(nsIURI* aURI) // 0th entry only active when testing: NS_LITERAL_CSTRING("test2.example.org"), NS_LITERAL_CSTRING("tbcdn.cn"), // for m.taobao.com + NS_LITERAL_CSTRING("alicdn.com"), // for m.taobao.com NS_LITERAL_CSTRING("dpfile.com"), // for m.dianping.com NS_LITERAL_CSTRING("hao123img.com"), // for hao123.com + NS_LITERAL_CSTRING("tabelog.k-img.com"), // for s.tabelog.com + NS_LITERAL_CSTRING("tsite.jp"), // for *.tsite.jp }; static const size_t sNumBaseDomainsOnWhitelist = MOZ_ARRAY_LENGTH(sBaseDomainsOnWhitelist); diff --git a/config/Makefile.in b/config/Makefile.in index 596eab6035..4f5d1430c9 100644 --- a/config/Makefile.in +++ b/config/Makefile.in @@ -45,7 +45,9 @@ ifndef JS_STANDALONE ifndef MOZ_PROFILE_USE # Generate a new buildid every time we "export" in config... that's only # supposed to be once per-build! -export:: +export:: buildid + +buildid: FORCE ifdef MOZ_BUILD_DATE printf '%s' $(MOZ_BUILD_DATE) > buildid else diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index e471e7adfd..da116c2007 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -2540,6 +2540,55 @@ CheckAllPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissio return true; } +bool +IsNonExposedGlobal(JSContext* aCx, JSObject* aGlobal, + uint32_t aNonExposedGlobals) +{ + MOZ_ASSERT(aNonExposedGlobals, "Why did we get called?"); + MOZ_ASSERT((aNonExposedGlobals & + ~(GlobalNames::Window | + GlobalNames::BackstagePass | + GlobalNames::DedicatedWorkerGlobalScope | + GlobalNames::SharedWorkerGlobalScope | + GlobalNames::ServiceWorkerGlobalScope | + GlobalNames::WorkerDebuggerGlobalScope)) == 0, + "Unknown non-exposed global type"); + + const char* name = js::GetObjectClass(aGlobal)->name; + + if ((aNonExposedGlobals & GlobalNames::Window) && + !strcmp(name, "Window")) { + return true; + } + + if ((aNonExposedGlobals & GlobalNames::BackstagePass) && + !strcmp(name, "BackstagePass")) { + return true; + } + + if ((aNonExposedGlobals & GlobalNames::DedicatedWorkerGlobalScope) && + !strcmp(name, "DedicatedWorkerGlobalScope")) { + return true; + } + + if ((aNonExposedGlobals & GlobalNames::SharedWorkerGlobalScope) && + !strcmp(name, "SharedWorkerGlobalScope")) { + return true; + } + + if ((aNonExposedGlobals & GlobalNames::ServiceWorkerGlobalScope) && + !strcmp(name, "ServiceWorkerGlobalScope")) { + return true; + } + + if ((aNonExposedGlobals & GlobalNames::WorkerDebuggerGlobalScope) && + !strcmp(name, "WorkerDebuggerGlobalScopex")) { + return true; + } + + return false; +} + void HandlePrerenderingViolation(nsPIDOMWindow* aWindow) { diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index 62bb78d154..77b0197352 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -3163,16 +3163,6 @@ AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitinfo, JS::Handle aValue); #endif -// Returns true if aObj's global has any of the permissions named in aPermissions -// set to nsIPermissionManager::ALLOW_ACTION. aPermissions must be null-terminated. -bool -CheckAnyPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]); - -// Returns true if aObj's global has all of the permissions named in aPermissions -// set to nsIPermissionManager::ALLOW_ACTION. aPermissions must be null-terminated. -bool -CheckAllPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]); - // This function is called by the bindings layer for methods/getters/setters // that are not safe to be called in prerendering mode. It checks to make sure // that the |this| object is not running in a global that is in prerendering diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 256f3222d8..ccf7ecf3ea 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -1906,16 +1906,26 @@ def getAvailableInTestFunc(obj): class MemberCondition: """ An object representing the condition for a member to actually be - exposed. Any of pref, func, and available can be None. If not - None, they should be strings that have the pref name (for "pref") - or function name (for "func" and "available"). + exposed. Any of the arguments can be None. If not + None, they should have the following types: + + pref: The name of the preference. + func: The name of the function. + available: A string indicating where we should be available. + checkAnyPermissions: An integer index for the anypermissions_* to use. + checkAllPermissions: An integer index for the allpermissions_* to use. + nonExposedGlobals: A set of names of globals. Can be empty, in which case + it's treated the same way as None. """ - def __init__(self, pref, func, available=None, checkAnyPermissions=None, checkAllPermissions=None): + def __init__(self, pref=None, func=None, available=None, + checkAnyPermissions=None, checkAllPermissions=None, + nonExposedGlobals=None): assert pref is None or isinstance(pref, str) assert func is None or isinstance(func, str) assert available is None or isinstance(available, str) assert checkAnyPermissions is None or isinstance(checkAnyPermissions, int) assert checkAllPermissions is None or isinstance(checkAllPermissions, int) + assert nonExposedGlobals is None or isinstance(nonExposedGlobals, set) self.pref = pref def toFuncPtr(val): @@ -1933,11 +1943,20 @@ class MemberCondition: else: self.checkAllPermissions = "allpermissions_%i" % checkAllPermissions + if nonExposedGlobals: + # Nonempty set + self.nonExposedGlobals = " | ".join( + map(lambda g: "GlobalNames::%s" % g, + sorted(nonExposedGlobals))) + else: + self.nonExposedGlobals = "0" + def __eq__(self, other): return (self.pref == other.pref and self.func == other.func and self.available == other.available and self.checkAnyPermissions == other.checkAnyPermissions and - self.checkAllPermissions == other.checkAllPermissions) + self.checkAllPermissions == other.checkAllPermissions and + self.nonExposedGlobals == other.nonExposedGlobals) def __ne__(self, other): return not self.__eq__(other) @@ -2000,13 +2019,34 @@ class PropertyDefiner: @staticmethod def getControllingCondition(interfaceMember, descriptor): - return MemberCondition(PropertyDefiner.getStringAttr(interfaceMember, - "Pref"), - PropertyDefiner.getStringAttr(interfaceMember, - "Func"), - getAvailableInTestFunc(interfaceMember), - descriptor.checkAnyPermissionsIndicesForMembers.get(interfaceMember.identifier.name), - descriptor.checkAllPermissionsIndicesForMembers.get(interfaceMember.identifier.name)) + # We do a slightly complicated thing for exposure sets to deal nicely + # with the situation of an [Exposed=Window] thing on an interface + # exposed in workers that has a worker-specific descriptor. In that + # situation, we already skip generation of the member entirely in the + # worker binding, and shouldn't need to check for the various worker + # scopes in the non-worker binding. + interface = descriptor.interface + nonExposureSet = interface.exposureSet - interfaceMember.exposureSet + # Skip getting the descriptor if we're just exposed everywhere or not + # looking at the non-worker descriptor. + if len(nonExposureSet) and not descriptor.workers: + workerProvider = descriptor.config.getDescriptorProvider(True) + workerDesc = workerProvider.getDescriptor(interface.identifier.name) + if workerDesc.workers: + # Just drop all the worker interface names from the + # nonExposureSet, since we know we'll have a mainthread global + # of some sort. + nonExposureSet.difference_update(interface.getWorkerExposureSet()) + + return MemberCondition( + PropertyDefiner.getStringAttr(interfaceMember, + "Pref"), + PropertyDefiner.getStringAttr(interfaceMember, + "Func"), + getAvailableInTestFunc(interfaceMember), + descriptor.checkAnyPermissionsIndicesForMembers.get(interfaceMember.identifier.name), + descriptor.checkAllPermissionsIndicesForMembers.get(interfaceMember.identifier.name), + nonExposureSet) def generatePrefableArray(self, array, name, specFormatter, specTerminator, specType, getCondition, getDataTuple, doIdArrays): @@ -2044,7 +2084,7 @@ class PropertyDefiner: specs = [] prefableSpecs = [] - prefableTemplate = ' { true, %s, %s, %s, %s, &%s[%d] }' + prefableTemplate = ' { true, %s, %s, %s, %s, %s, &%s[%d] }' prefCacheTemplate = '&%s[%d].enabled' def switchToCondition(props, condition): @@ -2056,7 +2096,8 @@ class PropertyDefiner: prefCacheTemplate % (name, len(prefableSpecs)))) # Set up pointers to the new sets of specs inside prefableSpecs prefableSpecs.append(prefableTemplate % - (condition.func, + (condition.nonExposedGlobals, + condition.func, condition.available, condition.checkAnyPermissions, condition.checkAllPermissions, @@ -2075,7 +2116,7 @@ class PropertyDefiner: # And the actual spec specs.append(specFormatter(getDataTuple(member))) specs.append(specTerminator) - prefableSpecs.append(" { false, nullptr }") + prefableSpecs.append(" { false, 0, nullptr, nullptr, nullptr, nullptr, nullptr }") specType = "const " + specType arrays = fill( @@ -2198,7 +2239,7 @@ class MethodDefiner(PropertyDefiner): "methodInfo": False, "length": 1, "flags": "0", - "condition": MemberCondition(None, condition) + "condition": MemberCondition(func=condition) }) continue @@ -2252,23 +2293,7 @@ class MethodDefiner(PropertyDefiner): "selfHostedName": "ArrayValues", "length": 0, "flags": "JSPROP_ENUMERATE", - "condition": MemberCondition(None, None) - }) - - # Output an @@iterator for generated iterator interfaces. This should - # not be necessary, but - # https://bugzilla.mozilla.org/show_bug.cgi?id=1091945 means that - # %IteratorPrototype%[@@iterator] is a broken puppy. - if (not static and - not unforgeable and - descriptor.interface.isIteratorInterface()): - self.regular.append({ - "name": "@@iterator", - "methodInfo": False, - "selfHostedName": "IteratorIdentity", - "length": 0, - "flags": "0", - "condition": MemberCondition(None, None) + "condition": MemberCondition() }) # Generate the maplike/setlike iterator, if one wasn't already @@ -2341,7 +2366,7 @@ class MethodDefiner(PropertyDefiner): "length": 0, "flags": "JSPROP_ENUMERATE", # readonly/permanent added # automatically. - "condition": MemberCondition(None, None) + "condition": MemberCondition() }) if descriptor.interface.isJSImplemented(): @@ -2353,7 +2378,7 @@ class MethodDefiner(PropertyDefiner): "methodInfo": False, "length": 2, "flags": "0", - "condition": MemberCondition(None, None) + "condition": MemberCondition() }) else: for m in clearableCachedAttrs(descriptor): @@ -2364,7 +2389,7 @@ class MethodDefiner(PropertyDefiner): "methodInfo": False, "length": "0", "flags": "0", - "condition": MemberCondition(None, None) + "condition": MemberCondition() }) self.unforgeable = unforgeable diff --git a/dom/bindings/DOMJSClass.h b/dom/bindings/DOMJSClass.h index b27f02166a..8360e45078 100644 --- a/dom/bindings/DOMJSClass.h +++ b/dom/bindings/DOMJSClass.h @@ -39,12 +39,24 @@ typedef bool JS::Handle obj, JS::AutoIdVector& props); +// Returns true if aObj's global has any of the permissions named in +// aPermissions set to nsIPermissionManager::ALLOW_ACTION. aPermissions must be +// null-terminated. bool CheckAnyPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]); +// Returns true if aObj's global has all of the permissions named in +// aPermissions set to nsIPermissionManager::ALLOW_ACTION. aPermissions must be +// null-terminated. bool CheckAllPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]); +// Returns true if the given global is of a type whose bit is set in +// aNonExposedGlobals. +bool +IsNonExposedGlobal(JSContext* aCx, JSObject* aGlobal, + uint32_t aNonExposedGlobals); + struct ConstantSpec { const char* name; @@ -53,9 +65,35 @@ struct ConstantSpec typedef bool (*PropertyEnabled)(JSContext* cx, JSObject* global); +namespace GlobalNames { +// The names of our possible globals. These are the names of the actual +// interfaces, not of the global names used to refer to them in IDL [Exposed] +// annotations. +static const uint32_t Window = 1u << 0; +static const uint32_t BackstagePass = 1u << 1; +static const uint32_t DedicatedWorkerGlobalScope = 1u << 2; +static const uint32_t SharedWorkerGlobalScope = 1u << 3; +static const uint32_t ServiceWorkerGlobalScope = 1u << 4; +static const uint32_t WorkerDebuggerGlobalScope = 1u << 5; +} // namespace GlobalNames + template struct Prefable { inline bool isEnabled(JSContext* cx, JS::Handle obj) const { + // Reading "enabled" on a worker thread is technically undefined behavior, + // because it's written only on main threads, with no barriers of any sort. + // So we want to avoid doing that. But we don't particularly want to make + // expensive NS_IsMainThread calls here. + // + // The good news is that "enabled" is only written for things that have a + // Pref annotation, and such things can never be exposed on non-Window + // globals; our IDL parser enforces that. So as long as we check our + // exposure set before checking "enabled" we will be ok. + if (nonExposedGlobals && + IsNonExposedGlobal(cx, js::GetGlobalForObjectCrossCompartment(obj), + nonExposedGlobals)) { + return false; + } if (!enabled) { return false; } @@ -85,6 +123,8 @@ struct Prefable { // A boolean indicating whether this set of specs is enabled bool enabled; + // Bitmask of global names that we should not be exposed in. + uint32_t nonExposedGlobals; // A function pointer to a function that can say the property is disabled // even if "enabled" is set to true. If the pointer is null the value of // "enabled" is used as-is unless availableFunc overrides. diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp index 59060b6242..9133dc86d4 100644 --- a/dom/fetch/Fetch.cpp +++ b/dom/fetch/Fetch.cpp @@ -136,11 +136,6 @@ public: nsCOMPtr loadGroup = proxy->GetWorkerPrivate()->GetLoadGroup(); MOZ_ASSERT(loadGroup); RefPtr fetch = new FetchDriver(mRequest, principal, loadGroup); - nsIDocument* doc = proxy->GetWorkerPrivate()->GetDocument(); - if (doc) { - fetch->SetDocument(doc); - } - nsresult rv = fetch->Fetch(mResolver); // Right now we only support async fetch, which should never directly fail. if (NS_WARN_IF(NS_FAILED(rv))) { @@ -662,17 +657,15 @@ public: uint8_t* nonconstResult = const_cast(aResult); if (mFetchBody->mWorkerPrivate) { - // This way if the runnable dispatch fails, the body is still released. - AutoFailConsumeBody autoFail(mFetchBody); RefPtr> r = new ContinueConsumeBodyRunnable(mFetchBody, aStatus, aResultLength, nonconstResult); AutoSafeJSContext cx; - if (r->Dispatch(cx)) { - autoFail.DontFail(); - } else { + if (!r->Dispatch(cx)) { + // XXXcatalinb: The worker is shutting down, the pump will be canceled + // by FetchBodyFeature::Notify. NS_WARNING("Could not dispatch ConsumeBodyRunnable"); // Return failure so that aResult is freed. return NS_ERROR_FAILURE; @@ -742,10 +735,12 @@ class FetchBodyFeature final : public workers::WorkerFeature // This is addrefed before the feature is created, and is released in ContinueConsumeBody() // so we can hold a rawptr. FetchBody* mBody; + bool mWasNotified; public: explicit FetchBodyFeature(FetchBody* aBody) : mBody(aBody) + , mWasNotified(false) { } ~FetchBodyFeature() @@ -754,7 +749,10 @@ public: bool Notify(JSContext* aCx, workers::Status aStatus) override { MOZ_ASSERT(aStatus > workers::Running); - mBody->ContinueConsumeBody(NS_BINDING_ABORTED, 0, nullptr); + if (!mWasNotified) { + mWasNotified = true; + mBody->ContinueConsumeBody(NS_BINDING_ABORTED, 0, nullptr); + } return true; } }; diff --git a/dom/fetch/FetchDriver.cpp b/dom/fetch/FetchDriver.cpp index cb54d37d16..6c1fa9e8a7 100644 --- a/dom/fetch/FetchDriver.cpp +++ b/dom/fetch/FetchDriver.cpp @@ -245,10 +245,8 @@ FetchDriver::HttpFetch() MOZ_ASSERT(mLoadGroup); nsCOMPtr chan; - // For dedicated workers mDocument refers to the parent document of the - // worker (why do we do that?). In that case we don't want to use the - // document here since that is not the correct principal. - if (mDocument && mDocument->NodePrincipal() == mPrincipal) { + if (mDocument) { + MOZ_ASSERT(mDocument->NodePrincipal() == mPrincipal); rv = NS_NewChannel(getter_AddRefs(chan), uri, mDocument, diff --git a/dom/fetch/Headers.h b/dom/fetch/Headers.h index a3810baa42..d52a25c222 100644 --- a/dom/fetch/Headers.h +++ b/dom/fetch/Headers.h @@ -102,6 +102,19 @@ public: mInternalHeaders->Set(aName, aValue, aRv); } + uint32_t GetIterableLength() const + { + return mInternalHeaders->GetIterableLength(); + } + const nsString GetKeyAtIndex(unsigned aIndex) const + { + return mInternalHeaders->GetKeyAtIndex(aIndex); + } + const nsString GetValueAtIndex(unsigned aIndex) const + { + return mInternalHeaders->GetValueAtIndex(aIndex); + } + // ChromeOnly HeadersGuardEnum Guard() const { diff --git a/dom/fetch/InternalHeaders.cpp b/dom/fetch/InternalHeaders.cpp index b2941c4038..fccc9fc18f 100644 --- a/dom/fetch/InternalHeaders.cpp +++ b/dom/fetch/InternalHeaders.cpp @@ -151,13 +151,8 @@ InternalHeaders::Clear() void InternalHeaders::SetGuard(HeadersGuardEnum aGuard, ErrorResult& aRv) { - // Rather than re-validate all current headers, just require code to set - // this prior to populating the InternalHeaders object. Allow setting immutable - // late, though, as that is pretty much required to have a useful, immutable - // headers object. - if (aGuard != HeadersGuardEnum::Immutable && mList.Length() > 0) { - aRv.Throw(NS_ERROR_FAILURE); - } + // The guard is only checked during ::Set() and ::Append() in the spec. It + // does not require revalidating headers already set. mGuard = aGuard; } diff --git a/dom/fetch/InternalHeaders.h b/dom/fetch/InternalHeaders.h index 3379aafeb0..54639cb9aa 100644 --- a/dom/fetch/InternalHeaders.h +++ b/dom/fetch/InternalHeaders.h @@ -73,6 +73,21 @@ public: bool Has(const nsACString& aName, ErrorResult& aRv) const; void Set(const nsACString& aName, const nsACString& aValue, ErrorResult& aRv); + uint32_t GetIterableLength() const + { + return mList.Length(); + } + const NS_ConvertASCIItoUTF16 GetKeyAtIndex(unsigned aIndex) const + { + MOZ_ASSERT(aIndex < mList.Length()); + return NS_ConvertASCIItoUTF16(mList[aIndex].mName); + } + const NS_ConvertASCIItoUTF16 GetValueAtIndex(unsigned aIndex) const + { + MOZ_ASSERT(aIndex < mList.Length()); + return NS_ConvertASCIItoUTF16(mList[aIndex].mValue); + } + void Clear(); HeadersGuardEnum Guard() const { return mGuard; } diff --git a/dom/fetch/Request.cpp b/dom/fetch/Request.cpp index 922d886abf..36eea47eae 100644 --- a/dom/fetch/Request.cpp +++ b/dom/fetch/Request.cpp @@ -64,6 +64,25 @@ Request::RequestContextEnabled(JSContext* aCx, JSObject* aObj) return workerPrivate->RequestContextEnabled(); } +// static +bool +Request::RequestCacheEnabled(JSContext* aCx, JSObject* aObj) +{ + if (NS_IsMainThread()) { + return Preferences::GetBool("dom.requestcache.enabled", false); + } + + using namespace workers; + + // Otherwise, check the pref via the WorkerPrivate + WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx); + if (!workerPrivate) { + return false; + } + + return workerPrivate->RequestCacheEnabled(); +} + already_AddRefed Request::GetInternalRequest() { diff --git a/dom/fetch/Request.h b/dom/fetch/Request.h index b3a5fa279e..5679a065a4 100644 --- a/dom/fetch/Request.h +++ b/dom/fetch/Request.h @@ -36,6 +36,8 @@ public: static bool RequestContextEnabled(JSContext* aCx, JSObject* aObj); + static bool + RequestCacheEnabled(JSContext* aCx, JSObject* aObj); JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override diff --git a/dom/fetch/Response.h b/dom/fetch/Response.h index 88e647eaac..54540f1ee8 100644 --- a/dom/fetch/Response.h +++ b/dom/fetch/Response.h @@ -19,7 +19,7 @@ namespace mozilla { namespace ipc { class PrincipalInfo; -} +} // namespace ipc namespace dom { diff --git a/dom/indexedDB/IDBFactory.cpp b/dom/indexedDB/IDBFactory.cpp index 9507133ca8..85e3140693 100644 --- a/dom/indexedDB/IDBFactory.cpp +++ b/dom/indexedDB/IDBFactory.cpp @@ -319,6 +319,7 @@ IDBFactory::CreateForJSInternal(JSContext* aCx, if (aPrincipalInfo->type() != PrincipalInfo::TContentPrincipalInfo && aPrincipalInfo->type() != PrincipalInfo::TSystemPrincipalInfo) { NS_WARNING("IndexedDB not allowed for this principal!"); + aPrincipalInfo = nullptr; *aFactory = nullptr; return NS_OK; } diff --git a/dom/tests/mochitest/fetch/fetch_test_framework.js b/dom/tests/mochitest/fetch/fetch_test_framework.js index 06a29cbd81..5e29b01959 100644 --- a/dom/tests/mochitest/fetch/fetch_test_framework.js +++ b/dom/tests/mochitest/fetch/fetch_test_framework.js @@ -7,7 +7,8 @@ function testScript(script) { function setupPrefs() { return new Promise(function(resolve, reject) { SpecialPowers.pushPrefEnv({ - "set": [["dom.requestcontext.enabled", true], + "set": [["dom.requestcache.enabled", true], + ["dom.requestcontext.enabled", true], ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.testing.enabled", true], ["dom.serviceWorkers.exemptFromPerDomainMax", true]] diff --git a/dom/tests/mochitest/fetch/mochitest.ini b/dom/tests/mochitest/fetch/mochitest.ini index a126ab6822..1282d7ff83 100644 --- a/dom/tests/mochitest/fetch/mochitest.ini +++ b/dom/tests/mochitest/fetch/mochitest.ini @@ -36,6 +36,7 @@ skip-if = e10s || buildapp == 'b2g' # Bug 1173163 for e10s, bug 1137683 for b2g [test_formdataparsing_sw_reroute.html] skip-if = buildapp == 'b2g' # Bug 1137683 [test_request.html] +[test_request_cache.html] [test_request_context.html] [test_request_sw_reroute.html] skip-if = buildapp == 'b2g' # Bug 1137683 diff --git a/dom/tests/mochitest/fetch/sw_reroute.js b/dom/tests/mochitest/fetch/sw_reroute.js index 07f623cc0b..0525258c6c 100644 --- a/dom/tests/mochitest/fetch/sw_reroute.js +++ b/dom/tests/mochitest/fetch/sw_reroute.js @@ -10,7 +10,8 @@ function testScript(script) { } SpecialPowers.pushPrefEnv({ - "set": [["dom.serviceWorkers.enabled", true], + "set": [["dom.requestcache.enabled", true], + ["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.interception.opaque.enabled", true], ["dom.serviceWorkers.testing.enabled", true], ["dom.serviceWorkers.exemptFromPerDomainMax", true]] diff --git a/dom/tests/mochitest/fetch/test_headers_common.js b/dom/tests/mochitest/fetch/test_headers_common.js index fca547bfca..b82e5e2244 100644 --- a/dom/tests/mochitest/fetch/test_headers_common.js +++ b/dom/tests/mochitest/fetch/test_headers_common.js @@ -13,16 +13,27 @@ function shouldThrow(func, expected, msg) { } } +function recursiveArrayCompare(actual, expected) { + is(Array.isArray(actual), Array.isArray(expected), "Both should either be arrays, or not"); + if (Array.isArray(actual) && Array.isArray(expected)) { + var diff = actual.length !== expected.length; + + for (var i = 0, n = actual.length; !diff && i < n; ++i) { + diff = recursiveArrayCompare(actual[i], expected[i]); + } + + return diff; + } else { + return actual !== expected; + } +} + function arrayEquals(actual, expected, msg) { if (actual === expected) { return; } - var diff = actual.length !== expected.length; - - for (var i = 0, n = actual.length; !diff && i < n; ++i) { - diff = actual[i] !== expected[i]; - } + var diff = recursiveArrayCompare(actual, expected); ok(!diff, msg); if (diff) { @@ -169,8 +180,60 @@ function TestFilledHeaders() { }, TypeError, "Fill with non-tuple sequence should throw TypeError."); } +function iterate(iter) { + var result = []; + for (var val = iter.next(); !val.done;) { + result.push(val.value); + val = iter.next(); + } + return result; +} + +function iterateForOf(iter) { + var result = []; + for (var value of iter) { + result.push(value); + } + return result; +} + +function byteInflate(str) { + var encoder = new TextEncoder("utf-8"); + var encoded = encoder.encode(str); + var result = ""; + for (var i = 0; i < encoded.length; ++i) { + result += String.fromCharCode(encoded[i]); + } + return result +} + +function TestHeadersIterator() { + var ehsanInflated = byteInflate("احسان"); + var headers = new Headers(); + headers.set("foo0", "bar0"); + headers.append("foo", "bar"); + headers.append("foo", ehsanInflated); + headers.append("Foo2", "bar2"); + headers.set("Foo2", "baz2"); + headers.set("foo3", "bar3"); + headers.delete("foo0"); + headers.delete("foo3"); + + var key_iter = headers.keys(); + var value_iter = headers.values(); + var entries_iter = headers.entries(); + + arrayEquals(iterate(key_iter), ["foo", "foo", "foo2"], "Correct key iterator"); + arrayEquals(iterate(value_iter), ["bar", ehsanInflated, "baz2"], "Correct value iterator"); + arrayEquals(iterate(entries_iter), [["foo", "bar"], ["foo", ehsanInflated], ["foo2", "baz2"]], "Correct entries iterator"); + + arrayEquals(iterateForOf(headers), [["foo", "bar"], ["foo", ehsanInflated], ["foo2", "baz2"]], "Correct entries iterator"); + arrayEquals(iterateForOf(new Headers(headers)), [["foo", "bar"], ["foo", ehsanInflated], ["foo2", "baz2"]], "Correct entries iterator"); +} + function runTest() { TestEmptyHeaders(); TestFilledHeaders(); + TestHeadersIterator(); return Promise.resolve(); } diff --git a/dom/tests/mochitest/fetch/test_request_cache.html b/dom/tests/mochitest/fetch/test_request_cache.html new file mode 100644 index 0000000000..3f48a690cb --- /dev/null +++ b/dom/tests/mochitest/fetch/test_request_cache.html @@ -0,0 +1,19 @@ + + + + + Make sure that Request.cache is not exposed by default + + + + + + + + diff --git a/dom/webidl/EventTarget.webidl b/dom/webidl/EventTarget.webidl index 6742fce2f0..be23ed1d4a 100644 --- a/dom/webidl/EventTarget.webidl +++ b/dom/webidl/EventTarget.webidl @@ -49,6 +49,6 @@ partial interface EventTarget { // chrome easier. This returns the window which can be used to create // events to fire at this EventTarget, or null if there isn't one. partial interface EventTarget { - [ChromeOnly, Exposed=Window, BinaryName="ownerGlobalForBindings"] + [ChromeOnly, Exposed=(Window,System), BinaryName="ownerGlobalForBindings"] readonly attribute WindowProxy? ownerGlobal; }; diff --git a/dom/webidl/Headers.webidl b/dom/webidl/Headers.webidl index f27a1ec054..38b0a3a204 100644 --- a/dom/webidl/Headers.webidl +++ b/dom/webidl/Headers.webidl @@ -27,6 +27,7 @@ interface Headers { [Throws] sequence getAll(ByteString name); [Throws] boolean has(ByteString name); [Throws] void set(ByteString name, ByteString value); + iterable; // Used to test different guard states from mochitest. // Note: Must be set prior to populating headers or will throw. diff --git a/dom/webidl/Request.webidl b/dom/webidl/Request.webidl index e0c51b3f14..1ab355f3ac 100644 --- a/dom/webidl/Request.webidl +++ b/dom/webidl/Request.webidl @@ -22,6 +22,7 @@ interface Request { readonly attribute DOMString referrer; readonly attribute RequestMode mode; readonly attribute RequestCredentials credentials; + [Func="mozilla::dom::Request::RequestCacheEnabled"] readonly attribute RequestCache cache; readonly attribute RequestRedirect redirect; diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 059da67e9a..982e5cfbc8 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -122,10 +122,6 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 1, #define CC_REQUEST_OBSERVER_TOPIC "child-cc-request" #define MEMORY_PRESSURE_OBSERVER_TOPIC "memory-pressure" -#define PREF_GENERAL_APPNAME_OVERRIDE "general.appname.override" -#define PREF_GENERAL_APPVERSION_OVERRIDE "general.appversion.override" -#define PREF_GENERAL_PLATFORM_OVERRIDE "general.platform.override" - #define BROADCAST_ALL_WORKERS(_func, ...) \ PR_BEGIN_MACRO \ AssertIsOnMainThread(); \ @@ -152,27 +148,6 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 1, #define PREF_MEM_OPTIONS_PREFIX "mem." #define PREF_GCZEAL "gcZeal" -#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP)) -#define DUMP_CONTROLLED_BY_PREF 1 -#define PREF_DOM_WINDOW_DUMP_ENABLED "browser.dom.window.dump.enabled" -#endif - -#define PREF_DOM_CACHES_ENABLED "dom.caches.enabled" -#define PREF_DOM_CACHES_TESTING_ENABLED "dom.caches.testing.enabled" -#define PREF_WORKERS_PERFORMANCE_LOGGING_ENABLED "dom.performance.enable_user_timing_logging" -#define PREF_DOM_WORKERNOTIFICATION_ENABLED "dom.webnotifications.enabled" -#define PREF_DOM_SERVICEWORKERNOTIFICATION_ENABLED "dom.webnotifications.serviceworker.enabled" -#define PREF_WORKERS_LATEST_JS_VERSION "dom.workers.latestJSVersion" -#define PREF_INTL_ACCEPT_LANGUAGES "intl.accept_languages" -#define PREF_SERVICEWORKERS_ENABLED "dom.serviceWorkers.enabled" -#define PREF_SERVICEWORKERS_TESTING_ENABLED "dom.serviceWorkers.testing.enabled" -#define PREF_INTERCEPTION_ENABLED "dom.serviceWorkers.interception.enabled" -#define PREF_INTERCEPTION_OPAQUE_ENABLED "dom.serviceWorkers.interception.opaque.enabled" -#define PREF_OPEN_WINDOW_ENABLED "dom.serviceWorkers.openWindow.enabled" -#define PREF_PUSH_ENABLED "dom.push.enabled" -#define PREF_REQUESTCONTEXT_ENABLED "dom.requestcontext.enabled" -#define PREF_OFFSCREENCANVAS_ENABLED "gfx.offscreencanvas.enabled" - namespace { const uint32_t kNoIndex = uint32_t(-1); @@ -763,9 +738,48 @@ AsmJSCacheOpenEntryForWrite(JS::Handle aGlobal, aSize, aMemory, aHandle); } -struct WorkerThreadRuntimePrivate : public PerThreadAtomCache +class WorkerJSRuntime; + +class WorkerThreadRuntimePrivate : private PerThreadAtomCache { + friend class WorkerJSRuntime; + WorkerPrivate* mWorkerPrivate; + +public: + // This can't return null, but we can't lose the "Get" prefix in the name or + // it will be ambiguous with the WorkerPrivate class name. + WorkerPrivate* + GetWorkerPrivate() const + { + MOZ_ASSERT(!NS_IsMainThread()); + MOZ_ASSERT(mWorkerPrivate); + + return mWorkerPrivate; + } + +private: + explicit + WorkerThreadRuntimePrivate(WorkerPrivate* aWorkerPrivate) + : mWorkerPrivate(aWorkerPrivate) + { + MOZ_ASSERT(!NS_IsMainThread()); + + // Zero out the base class members. + memset(this, 0, sizeof(PerThreadAtomCache)); + + MOZ_ASSERT(mWorkerPrivate); + } + + ~WorkerThreadRuntimePrivate() + { + MOZ_ASSERT(!NS_IsMainThread()); + } + + WorkerThreadRuntimePrivate(const WorkerThreadRuntimePrivate&) = delete; + + WorkerThreadRuntimePrivate& + operator=(const WorkerThreadRuntimePrivate&) = delete; }; JSContext* @@ -814,11 +828,6 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime) return nullptr; } - auto rtPrivate = new WorkerThreadRuntimePrivate(); - memset(rtPrivate, 0, sizeof(WorkerThreadRuntimePrivate)); - rtPrivate->mWorkerPrivate = aWorkerPrivate; - JS_SetRuntimePrivate(aRuntime, rtPrivate); - JS_SetErrorReporter(aRuntime, ErrorReporter); JS_SetInterruptCallback(aRuntime, InterruptCallback); @@ -883,16 +892,23 @@ public: WORKER_DEFAULT_NURSERY_SIZE), mWorkerPrivate(aWorkerPrivate) { - js::SetPreserveWrapperCallback(Runtime(), PreserveWrapper); - JS_InitDestroyPrincipalsCallback(Runtime(), DestroyWorkerPrincipals); - JS_SetWrapObjectCallbacks(Runtime(), &WrapObjectCallbacks); + JSRuntime* rt = Runtime(); + MOZ_ASSERT(rt); + + JS_SetRuntimePrivate(rt, new WorkerThreadRuntimePrivate(aWorkerPrivate)); + + js::SetPreserveWrapperCallback(rt, PreserveWrapper); + JS_InitDestroyPrincipalsCallback(rt, DestroyWorkerPrincipals); + JS_SetWrapObjectCallbacks(rt, &WrapObjectCallbacks); } ~WorkerJSRuntime() { - auto rtPrivate = static_cast(JS_GetRuntimePrivate(Runtime())); - delete rtPrivate; - JS_SetRuntimePrivate(Runtime(), nullptr); + JSRuntime* rt = Runtime(); + MOZ_ASSERT(rt); + + delete static_cast(JS_GetRuntimePrivate(rt)); + JS_SetRuntimePrivate(rt, nullptr); // The worker global should be unrooted and the shutdown cycle collection // should break all remaining cycles. The superclass destructor will run @@ -1141,7 +1157,7 @@ AppNameOverrideChanged(const char* /* aPrefName */, void* /* aClosure */) AssertIsOnMainThread(); const nsAdoptingString& override = - mozilla::Preferences::GetString(PREF_GENERAL_APPNAME_OVERRIDE); + mozilla::Preferences::GetString("general.appname.override"); RuntimeService* runtime = RuntimeService::GetService(); if (runtime) { @@ -1155,7 +1171,7 @@ AppVersionOverrideChanged(const char* /* aPrefName */, void* /* aClosure */) AssertIsOnMainThread(); const nsAdoptingString& override = - mozilla::Preferences::GetString(PREF_GENERAL_APPVERSION_OVERRIDE); + mozilla::Preferences::GetString("general.appversion.override"); RuntimeService* runtime = RuntimeService::GetService(); if (runtime) { @@ -1169,7 +1185,7 @@ PlatformOverrideChanged(const char* /* aPrefName */, void* /* aClosure */) AssertIsOnMainThread(); const nsAdoptingString& override = - mozilla::Preferences::GetString(PREF_GENERAL_PLATFORM_OVERRIDE); + mozilla::Preferences::GetString("general.platform.override"); RuntimeService* runtime = RuntimeService::GetService(); if (runtime) { @@ -1303,7 +1319,8 @@ GetWorkerPrivateFromContext(JSContext* aCx) void* rtPrivate = JS_GetRuntimePrivate(rt); MOZ_ASSERT(rtPrivate); - return static_cast(rtPrivate)->mWorkerPrivate; + return + static_cast(rtPrivate)->GetWorkerPrivate(); } WorkerPrivate* @@ -1322,7 +1339,8 @@ GetCurrentThreadWorkerPrivate() void* rtPrivate = JS_GetRuntimePrivate(rt); MOZ_ASSERT(rtPrivate); - return static_cast(rtPrivate)->mWorkerPrivate; + return + static_cast(rtPrivate)->GetWorkerPrivate(); } bool @@ -1645,7 +1663,7 @@ RuntimeService::UnregisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate) } } - if (!domainInfo->ActiveWorkerCount()) { + if (domainInfo->HasNoWorkers()) { MOZ_ASSERT(domainInfo->mQueuedWorkers.IsEmpty()); mDomainMap.Remove(domain); } @@ -1841,11 +1859,6 @@ RuntimeService::Init() WORKER_DEFAULT_ALLOCATION_THRESHOLD); } -// If dump is not controlled by pref, it's set to true. -#ifndef DUMP_CONTROLLED_BY_PREF - sDefaultPreferences[WORKERPREF_DUMP] = true; -#endif - mIdleThreadTimer = do_CreateInstance(NS_TIMER_CONTRACTID); NS_ENSURE_STATE(mIdleThreadTimer); @@ -1894,95 +1907,29 @@ RuntimeService::Init() LoadGCZealOptions, PREF_JS_OPTIONS_PREFIX PREF_GCZEAL, nullptr)) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - LoadGCZealOptions, - PREF_WORKERS_OPTIONS_PREFIX PREF_GCZEAL, - nullptr)) || #endif -#if DUMP_CONTROLLED_BY_PREF - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_DOM_WINDOW_DUMP_ENABLED, - reinterpret_cast(WORKERPREF_DUMP))) || -#endif - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_DOM_CACHES_ENABLED, - reinterpret_cast(WORKERPREF_DOM_CACHES))) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_DOM_WORKERNOTIFICATION_ENABLED, - reinterpret_cast(WORKERPREF_DOM_WORKERNOTIFICATION))) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_DOM_SERVICEWORKERNOTIFICATION_ENABLED, - reinterpret_cast(WORKERPREF_DOM_SERVICEWORKERNOTIFICATION))) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_SERVICEWORKERS_ENABLED, - reinterpret_cast(WORKERPREF_SERVICEWORKERS))) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_INTERCEPTION_ENABLED, - reinterpret_cast(WORKERPREF_INTERCEPTION_ENABLED))) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_OPEN_WINDOW_ENABLED, - reinterpret_cast(WORKERPREF_OPEN_WINDOW_ENABLED))) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_INTERCEPTION_OPAQUE_ENABLED, - reinterpret_cast(WORKERPREF_INTERCEPTION_OPAQUE_ENABLED))) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_DOM_CACHES_TESTING_ENABLED, - reinterpret_cast(WORKERPREF_DOM_CACHES_TESTING))) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_WORKERS_PERFORMANCE_LOGGING_ENABLED, - reinterpret_cast(WORKERPREF_PERFORMANCE_LOGGING_ENABLED))) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_SERVICEWORKERS_TESTING_ENABLED, - reinterpret_cast(WORKERPREF_SERVICEWORKERS_TESTING))) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_PUSH_ENABLED, - reinterpret_cast(WORKERPREF_PUSH))) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_REQUESTCONTEXT_ENABLED, - reinterpret_cast(WORKERPREF_REQUESTCONTEXT))) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - WorkerPrefChanged, - PREF_OFFSCREENCANVAS_ENABLED, - reinterpret_cast(WORKERPREF_OFFSCREENCANVAS))) || - NS_FAILED(Preferences::RegisterCallback(LoadRuntimeOptions, - PREF_JS_OPTIONS_PREFIX, - nullptr)) || + +#define WORKER_SIMPLE_PREF(name, getter, NAME) \ + NS_FAILED(Preferences::RegisterCallbackAndCall( \ + WorkerPrefChanged, \ + name, \ + reinterpret_cast(WORKERPREF_##NAME))) || +#define WORKER_PREF(name, callback) \ + NS_FAILED(Preferences::RegisterCallbackAndCall( \ + callback, \ + name, \ + nullptr)) || +#include "WorkerPrefs.h" +#undef WORKER_SIMPLE_PREF +#undef WORKER_PREF + NS_FAILED(Preferences::RegisterCallbackAndCall( LoadRuntimeOptions, PREF_WORKERS_OPTIONS_PREFIX, nullptr)) || - NS_FAILED(Preferences::RegisterCallbackAndCall(PrefLanguagesChanged, - PREF_INTL_ACCEPT_LANGUAGES, - nullptr)) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - AppNameOverrideChanged, - PREF_GENERAL_APPNAME_OVERRIDE, - nullptr)) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - AppVersionOverrideChanged, - PREF_GENERAL_APPVERSION_OVERRIDE, - nullptr)) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - PlatformOverrideChanged, - PREF_GENERAL_PLATFORM_OVERRIDE, - nullptr)) || - NS_FAILED(Preferences::RegisterCallbackAndCall( - JSVersionChanged, - PREF_WORKERS_LATEST_JS_VERSION, - nullptr))) { + NS_FAILED(Preferences::RegisterCallback(LoadRuntimeOptions, + PREF_JS_OPTIONS_PREFIX, + nullptr))) { NS_WARNING("Failed to register pref callbacks!"); } @@ -2132,93 +2079,32 @@ RuntimeService::Cleanup() NS_ASSERTION(!mWindowMap.Count(), "All windows should have been released!"); if (mObserved) { - if (NS_FAILED(Preferences::UnregisterCallback(JSVersionChanged, - PREF_WORKERS_LATEST_JS_VERSION, - nullptr)) || - NS_FAILED(Preferences::UnregisterCallback(AppNameOverrideChanged, - PREF_GENERAL_APPNAME_OVERRIDE, - nullptr)) || - NS_FAILED(Preferences::UnregisterCallback( - AppVersionOverrideChanged, - PREF_GENERAL_APPVERSION_OVERRIDE, - nullptr)) || - NS_FAILED(Preferences::UnregisterCallback( - PlatformOverrideChanged, - PREF_GENERAL_PLATFORM_OVERRIDE, - nullptr)) || - NS_FAILED(Preferences::UnregisterCallback(LoadRuntimeOptions, + if (NS_FAILED(Preferences::UnregisterCallback(LoadRuntimeOptions, PREF_JS_OPTIONS_PREFIX, nullptr)) || NS_FAILED(Preferences::UnregisterCallback(LoadRuntimeOptions, PREF_WORKERS_OPTIONS_PREFIX, nullptr)) || - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_SERVICEWORKERS_TESTING_ENABLED, - reinterpret_cast(WORKERPREF_SERVICEWORKERS_TESTING))) || - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_DOM_CACHES_TESTING_ENABLED, - reinterpret_cast(WORKERPREF_DOM_CACHES_TESTING))) || - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_WORKERS_PERFORMANCE_LOGGING_ENABLED, - reinterpret_cast(WORKERPREF_PERFORMANCE_LOGGING_ENABLED))) || - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_INTERCEPTION_OPAQUE_ENABLED, - reinterpret_cast(WORKERPREF_INTERCEPTION_OPAQUE_ENABLED))) || - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_INTERCEPTION_ENABLED, - reinterpret_cast(WORKERPREF_INTERCEPTION_ENABLED))) || - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_OPEN_WINDOW_ENABLED, - reinterpret_cast(WORKERPREF_OPEN_WINDOW_ENABLED))) || - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_SERVICEWORKERS_ENABLED, - reinterpret_cast(WORKERPREF_SERVICEWORKERS))) || - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_DOM_CACHES_ENABLED, - reinterpret_cast(WORKERPREF_DOM_CACHES))) || - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_DOM_WORKERNOTIFICATION_ENABLED, - reinterpret_cast(WORKERPREF_DOM_WORKERNOTIFICATION))) || - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_DOM_SERVICEWORKERNOTIFICATION_ENABLED, - reinterpret_cast(WORKERPREF_DOM_SERVICEWORKERNOTIFICATION))) || - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_PUSH_ENABLED, - reinterpret_cast(WORKERPREF_PUSH))) || - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_REQUESTCONTEXT_ENABLED, - reinterpret_cast(WORKERPREF_REQUESTCONTEXT))) || - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_OFFSCREENCANVAS_ENABLED, - reinterpret_cast(WORKERPREF_OFFSCREENCANVAS))) || -#if DUMP_CONTROLLED_BY_PREF - NS_FAILED(Preferences::UnregisterCallback( - WorkerPrefChanged, - PREF_DOM_WINDOW_DUMP_ENABLED, - reinterpret_cast(WORKERPREF_DUMP))) || -#endif + +#define WORKER_SIMPLE_PREF(name, getter, NAME) \ + NS_FAILED(Preferences::UnregisterCallback( \ + WorkerPrefChanged, \ + name, \ + reinterpret_cast(WORKERPREF_##NAME))) || +#define WORKER_PREF(name, callback) \ + NS_FAILED(Preferences::UnregisterCallback( \ + callback, \ + name, \ + nullptr)) || +#include "WorkerPrefs.h" +#undef WORKER_SIMPLE_PREF +#undef WORKER_PREF + #ifdef JS_GC_ZEAL NS_FAILED(Preferences::UnregisterCallback( LoadGCZealOptions, PREF_JS_OPTIONS_PREFIX PREF_GCZEAL, nullptr)) || - NS_FAILED(Preferences::UnregisterCallback( - LoadGCZealOptions, - PREF_WORKERS_OPTIONS_PREFIX PREF_GCZEAL, - nullptr)) || #endif NS_FAILED(Preferences::UnregisterCallback( LoadJSGCMemoryOptions, @@ -2710,22 +2596,11 @@ RuntimeService::WorkerPrefChanged(const char* aPrefName, void* aClosure) static_cast(reinterpret_cast(aClosure)); switch (key) { - case WORKERPREF_DOM_CACHES: - case WORKERPREF_DOM_CACHES_TESTING: - case WORKERPREF_DOM_WORKERNOTIFICATION: - case WORKERPREF_DOM_SERVICEWORKERNOTIFICATION: - case WORKERPREF_PERFORMANCE_LOGGING_ENABLED: -#ifdef DUMP_CONTROLLED_BY_PREF - case WORKERPREF_DUMP: -#endif - case WORKERPREF_INTERCEPTION_ENABLED: - case WORKERPREF_INTERCEPTION_OPAQUE_ENABLED: - case WORKERPREF_OPEN_WINDOW_ENABLED: - case WORKERPREF_SERVICEWORKERS: - case WORKERPREF_SERVICEWORKERS_TESTING: - case WORKERPREF_PUSH: - case WORKERPREF_REQUESTCONTEXT: - case WORKERPREF_OFFSCREENCANVAS: +#define WORKER_SIMPLE_PREF(name, getter, NAME) case WORKERPREF_##NAME: +#define WORKER_PREF(name, callback) +#include "WorkerPrefs.h" +#undef WORKER_SIMPLE_PREF +#undef WORKER_PREF sDefaultPreferences[key] = Preferences::GetBool(aPrefName, false); break; @@ -2745,7 +2620,7 @@ RuntimeService::JSVersionChanged(const char* /* aPrefName */, void* /* aClosure { AssertIsOnMainThread(); - bool useLatest = Preferences::GetBool(PREF_WORKERS_LATEST_JS_VERSION, false); + bool useLatest = Preferences::GetBool("dom.workers.latestJSVersion", false); JS::CompartmentOptions& options = sDefaultJSSettings.content.compartmentOptions; options.setVersion(useLatest ? JSVERSION_LATEST : JSVERSION_DEFAULT); } diff --git a/dom/workers/RuntimeService.h b/dom/workers/RuntimeService.h index cc3593b240..b5a185f16c 100644 --- a/dom/workers/RuntimeService.h +++ b/dom/workers/RuntimeService.h @@ -56,9 +56,21 @@ class RuntimeService final : public nsIObserver ActiveWorkerCount() const { return mActiveWorkers.Length() + - mActiveServiceWorkers.Length() + mChildWorkerCount; } + + uint32_t + ActiveServiceWorkerCount() const + { + return mActiveServiceWorkers.Length(); + } + + bool + HasNoWorkers() const + { + return ActiveWorkerCount() == 0 && + ActiveServiceWorkerCount() == 0; + } }; struct IdleThreadInfo; diff --git a/dom/workers/WorkerPrefs.h b/dom/workers/WorkerPrefs.h new file mode 100644 index 0000000000..358da36349 --- /dev/null +++ b/dom/workers/WorkerPrefs.h @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// This is the list of the preferences that are exposed to workers. +// The format is as follows: +// +// WORKER_SIMPLE_PREF("foo.bar", FooBar, FOO_BAR, UpdaterFunction) +// +// * First argument is the name of the pref. +// * The name of the getter function. This defines a FindName() +// function that returns the value of the pref on WorkerPrivate. +// * The macro version of the name. This defines a WORKERPREF_FOO_BAR +// macro in Workers.h. +// * The name of the function that updates the new value of a pref. +// +// WORKER_PREF("foo.bar", UpdaterFunction) +// +// * First argument is the name of the pref. +// * The name of the function that updates the new value of a pref. + +#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP)) +WORKER_SIMPLE_PREF("browser.dom.window.dump.enabled", DumpEnabled, DUMP) +#endif +WORKER_SIMPLE_PREF("dom.caches.enabled", DOMCachesEnabled, DOM_CACHES) +WORKER_SIMPLE_PREF("dom.caches.testing.enabled", DOMCachesTestingEnabled, DOM_CACHES_TESTING) +WORKER_SIMPLE_PREF("dom.performance.enable_user_timing_logging", PerformanceLoggingEnabled, PERFORMANCE_LOGGING_ENABLED) +WORKER_SIMPLE_PREF("dom.webnotifications.enabled", DOMWorkerNotificationEnabled, DOM_WORKERNOTIFICATION) +WORKER_SIMPLE_PREF("dom.webnotifications.serviceworker.enabled", DOMServiceWorkerNotificationEnabled, DOM_SERVICEWORKERNOTIFICATION) +WORKER_SIMPLE_PREF("dom.serviceWorkers.enabled", ServiceWorkersEnabled, SERVICEWORKERS_ENABLED) +WORKER_SIMPLE_PREF("dom.serviceWorkers.testing.enabled", ServiceWorkersTestingEnabled, SERVICEWORKERS_TESTING_ENABLED) +WORKER_SIMPLE_PREF("dom.serviceWorkers.interception.enabled", InterceptionEnabled, INTERCEPTION_ENABLED) +WORKER_SIMPLE_PREF("dom.serviceWorkers.interception.opaque.enabled", OpaqueInterceptionEnabled, INTERCEPTION_OPAQUE_ENABLED) +WORKER_SIMPLE_PREF("dom.serviceWorkers.openWindow.enabled", OpenWindowEnabled, OPEN_WINDOW_ENABLED) +WORKER_SIMPLE_PREF("dom.push.enabled", PushEnabled, PUSH_ENABLED) +WORKER_SIMPLE_PREF("dom.requestcache.enabled", RequestCacheEnabled, REQUESTCACHE_ENABLED) +WORKER_SIMPLE_PREF("dom.requestcontext.enabled", RequestContextEnabled, REQUESTCONTEXT_ENABLED) +WORKER_SIMPLE_PREF("gfx.offscreencanvas.enabled", OffscreenCanvasEnabled, OFFSCREENCANVAS_ENABLED) +WORKER_PREF("dom.workers.latestJSVersion", JSVersionChanged) +WORKER_PREF("intl.accept_languages", PrefLanguagesChanged) +WORKER_PREF("general.appname.override", AppNameOverrideChanged) +WORKER_PREF("general.appversion.override", AppVersionOverrideChanged) +WORKER_PREF("general.platform.override", PlatformOverrideChanged) +#ifdef JS_GC_ZEAL +WORKER_PREF("dom.workers.options.gcZeal", LoadGCZealOptions) +#endif diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index 5e24a047c6..d315eb8eee 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -1230,104 +1230,17 @@ public: bool RegisterBindings(JSContext* aCx, JS::Handle aGlobal); - bool - DumpEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_DUMP]; - } - - bool - DOMCachesEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_DOM_CACHES]; - } - - bool - ServiceWorkersEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_SERVICEWORKERS]; - } - - // Determine if the SW testing browser-wide pref is set - bool - ServiceWorkersTestingEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_SERVICEWORKERS_TESTING]; - } - - bool - InterceptionEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_INTERCEPTION_ENABLED]; - } - - bool - OpenWindowEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_OPEN_WINDOW_ENABLED]; - } - - bool - OpaqueInterceptionEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_INTERCEPTION_OPAQUE_ENABLED]; - } - - bool - DOMWorkerNotificationEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_DOM_WORKERNOTIFICATION]; - } - - bool - DOMServiceWorkerNotificationEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_DOM_SERVICEWORKERNOTIFICATION]; - } - - bool - DOMCachesTestingEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_DOM_CACHES_TESTING]; - } - - bool - PerformanceLoggingEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_PERFORMANCE_LOGGING_ENABLED]; - } - - bool - PushEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_PUSH]; - } - - bool - RequestContextEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_REQUESTCONTEXT]; - } - - bool - OffscreenCanvasEnabled() const - { - AssertIsOnWorkerThread(); - return mPreferences[WORKERPREF_OFFSCREENCANVAS]; +#define WORKER_SIMPLE_PREF(name, getter, NAME) \ + bool \ + getter() const \ + { \ + AssertIsOnWorkerThread(); \ + return mPreferences[WORKERPREF_##NAME]; \ } +#define WORKER_PREF(name, callback) +#include "WorkerPrefs.h" +#undef WORKER_SIMPLE_PREF +#undef WORKER_PREF bool OnLine() const diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp index 52cafd1810..41e572551a 100644 --- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -318,9 +318,11 @@ WorkerGlobalScope::Dump(const Optional& aString) const return; } +#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP)) if (!mWorkerPrivate->DumpEnabled()) { return; } +#endif NS_ConvertUTF16toUTF8 str(aString.Value()); diff --git a/dom/workers/Workers.h b/dom/workers/Workers.h index 231bfc0873..d27129059d 100644 --- a/dom/workers/Workers.h +++ b/dom/workers/Workers.h @@ -197,20 +197,11 @@ struct JSSettings enum WorkerPreference { - WORKERPREF_DUMP = 0, // browser.dom.window.dump.enabled - WORKERPREF_DOM_CACHES, // dom.caches.enabled - WORKERPREF_SERVICEWORKERS, // dom.serviceWorkers.enabled - WORKERPREF_INTERCEPTION_ENABLED, // dom.serviceWorkers.interception.enabled - WORKERPREF_OPEN_WINDOW_ENABLED, // dom.serviceWorkers.openWindow.enabled - WORKERPREF_DOM_WORKERNOTIFICATION, // dom.webnotifications.workers.enabled - WORKERPREF_DOM_SERVICEWORKERNOTIFICATION, // dom.webnotifications.serviceworker.enabled - WORKERPREF_DOM_CACHES_TESTING, // dom.caches.testing.enabled - WORKERPREF_SERVICEWORKERS_TESTING, // dom.serviceWorkers.testing.enabled - WORKERPREF_INTERCEPTION_OPAQUE_ENABLED, // dom.serviceWorkers.interception.opaque.enabled - WORKERPREF_PERFORMANCE_LOGGING_ENABLED, // dom.performance.enable_user_timing_logging - WORKERPREF_PUSH, // dom.push.enabled - WORKERPREF_REQUESTCONTEXT, // dom.requestcontext.enabled - WORKERPREF_OFFSCREENCANVAS, // gfx.offscreencanvas.enabled +#define WORKER_SIMPLE_PREF(name, getter, NAME) WORKERPREF_ ## NAME, +#define WORKER_PREF(name, callback) +#include "mozilla/dom/WorkerPrefs.h" +#undef WORKER_SIMPLE_PREF +#undef WORKER_PREF WORKERPREF_COUNT }; diff --git a/dom/workers/moz.build b/dom/workers/moz.build index 6d48ea8646..f33cb1714f 100644 --- a/dom/workers/moz.build +++ b/dom/workers/moz.build @@ -12,6 +12,7 @@ EXPORTS.mozilla.dom += [ 'ServiceWorkerMessageEvent.h', 'ServiceWorkerRegistrar.h', 'ServiceWorkerRegistration.h', + 'WorkerPrefs.h', 'WorkerPrivate.h', 'WorkerRunnable.h', 'WorkerScope.h', diff --git a/js/public/Class.h b/js/public/Class.h index cdc02e5a93..47180fd316 100644 --- a/js/public/Class.h +++ b/js/public/Class.h @@ -719,7 +719,7 @@ struct JSClass { // application. #define JSCLASS_GLOBAL_APPLICATION_SLOTS 5 #define JSCLASS_GLOBAL_SLOT_COUNT \ - (JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 3 + 33) + (JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 3 + 36) #define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \ (JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n))) #define JSCLASS_GLOBAL_FLAGS \ diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp index 7813941450..750ea0af77 100644 --- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -72,7 +72,6 @@ ModuleValueGetter(JSContext* cx, unsigned argc, Value* vp) ImportEntryObject::class_ = { "ImportEntry", JSCLASS_HAS_RESERVED_SLOTS(ImportEntryObject::SlotCount) | - JSCLASS_HAS_CACHED_PROTO(JSProto_ImportEntry) | JSCLASS_IS_ANONYMOUS }; @@ -90,8 +89,8 @@ ImportEntryObject::isInstance(HandleValue value) return value.isObject() && value.toObject().is(); } -/* static */ JSObject* -ImportEntryObject::initClass(JSContext* cx, HandleObject obj) +/* static */ bool +GlobalObject::initImportEntryProto(JSContext* cx, Handle global) { static const JSPropertySpec protoAccessors[] = { JS_PSG("moduleRequest", ImportEntryObject_moduleRequestGetter, 0), @@ -100,22 +99,15 @@ ImportEntryObject::initClass(JSContext* cx, HandleObject obj) JS_PS_END }; - Rooted global(cx, &obj->as()); RootedObject proto(cx, global->createBlankPrototype(cx)); if (!proto) - return nullptr; + return false; if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, nullptr)) - return nullptr; + return false; - global->setPrototype(JSProto_ImportEntry, ObjectValue(*proto)); - return proto; -} - -JSObject* -js::InitImportEntryClass(JSContext* cx, HandleObject obj) -{ - return ImportEntryObject::initClass(cx, obj); + global->setReservedSlot(IMPORT_ENTRY_PROTO, ObjectValue(*proto)); + return true; } /* static */ ImportEntryObject* @@ -124,9 +116,12 @@ ImportEntryObject::create(JSContext* cx, HandleAtom importName, HandleAtom localName) { - RootedImportEntry self(cx, NewBuiltinClassInstance(cx)); - if (!self) + RootedObject proto(cx, cx->global()->getImportEntryPrototype()); + RootedObject obj(cx, NewObjectWithGivenProto(cx, &class_, proto)); + if (!obj) return nullptr; + + RootedImportEntry self(cx, &obj->as()); self->initReservedSlot(ModuleRequestSlot, StringValue(moduleRequest)); self->initReservedSlot(ImportNameSlot, StringValue(importName)); self->initReservedSlot(LocalNameSlot, StringValue(localName)); @@ -140,7 +135,6 @@ ImportEntryObject::create(JSContext* cx, ExportEntryObject::class_ = { "ExportEntry", JSCLASS_HAS_RESERVED_SLOTS(ExportEntryObject::SlotCount) | - JSCLASS_HAS_CACHED_PROTO(JSProto_ExportEntry) | JSCLASS_IS_ANONYMOUS }; @@ -160,8 +154,8 @@ ExportEntryObject::isInstance(HandleValue value) return value.isObject() && value.toObject().is(); } -/* static */ JSObject* -ExportEntryObject::initClass(JSContext* cx, HandleObject obj) +/* static */ bool +GlobalObject::initExportEntryProto(JSContext* cx, Handle global) { static const JSPropertySpec protoAccessors[] = { JS_PSG("exportName", ExportEntryObject_exportNameGetter, 0), @@ -171,22 +165,15 @@ ExportEntryObject::initClass(JSContext* cx, HandleObject obj) JS_PS_END }; - Rooted global(cx, &obj->as()); RootedObject proto(cx, global->createBlankPrototype(cx)); if (!proto) - return nullptr; + return false; if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, nullptr)) - return nullptr; + return false; - global->setPrototype(JSProto_ExportEntry, ObjectValue(*proto)); - return proto; -} - -JSObject* -js::InitExportEntryClass(JSContext* cx, HandleObject obj) -{ - return ExportEntryObject::initClass(cx, obj); + global->setReservedSlot(EXPORT_ENTRY_PROTO, ObjectValue(*proto)); + return true; } static Value @@ -202,9 +189,12 @@ ExportEntryObject::create(JSContext* cx, HandleAtom maybeImportName, HandleAtom maybeLocalName) { - RootedExportEntry self(cx, NewBuiltinClassInstance(cx)); - if (!self) + RootedObject proto(cx, cx->global()->getExportEntryPrototype()); + RootedObject obj(cx, NewObjectWithGivenProto(cx, &class_, proto)); + if (!obj) return nullptr; + + RootedExportEntry self(cx, &obj->as()); self->initReservedSlot(ExportNameSlot, StringOrNullValue(maybeExportName)); self->initReservedSlot(ModuleRequestSlot, StringOrNullValue(maybeModuleRequest)); self->initReservedSlot(ImportNameSlot, StringOrNullValue(maybeImportName)); @@ -544,7 +534,6 @@ void FunctionDeclaration::trace(JSTracer* trc) ModuleObject::class_ = { "Module", JSCLASS_HAS_RESERVED_SLOTS(ModuleObject::SlotCount) | - JSCLASS_HAS_CACHED_PROTO(JSProto_Module) | JSCLASS_IS_ANONYMOUS, nullptr, /* addProperty */ nullptr, /* delProperty */ @@ -553,7 +542,7 @@ ModuleObject::class_ = { nullptr, /* enumerate */ nullptr, /* resolve */ nullptr, /* mayResolve */ - nullptr, /* finalize */ + ModuleObject::finalize, nullptr, /* call */ nullptr, /* hasInstance */ nullptr, /* construct */ @@ -582,10 +571,12 @@ ModuleObject::isInstance(HandleValue value) /* static */ ModuleObject* ModuleObject::create(ExclusiveContext* cx, HandleObject enclosingStaticScope) { - Rooted self(cx, NewBuiltinClassInstance(cx, TenuredObject)); - if (!self) + RootedObject proto(cx, cx->global()->getModulePrototype()); + RootedObject obj(cx, NewObjectWithGivenProto(cx, &class_, proto)); + if (!obj) return nullptr; + RootedModuleObject self(cx, &obj->as()); self->initReservedSlot(StaticScopeSlot, ObjectOrNullValue(enclosingStaticScope)); Zone* zone = cx->zone(); @@ -855,8 +846,8 @@ DEFINE_GETTER_FUNCTIONS(ModuleObject, localExportEntries, LocalExportEntriesSlot DEFINE_GETTER_FUNCTIONS(ModuleObject, indirectExportEntries, IndirectExportEntriesSlot) DEFINE_GETTER_FUNCTIONS(ModuleObject, starExportEntries, StarExportEntriesSlot) -JSObject* -js::InitModuleClass(JSContext* cx, HandleObject obj) +/* static */ bool +GlobalObject::initModuleProto(JSContext* cx, Handle global) { static const JSPropertySpec protoAccessors[] = { JS_PSG("namespace", ModuleObject_namespace_Getter, 0), @@ -877,17 +868,24 @@ js::InitModuleClass(JSContext* cx, HandleObject obj) JS_FS_END }; - Rooted global(cx, &obj->as()); - RootedObject proto(cx, global->createBlankPrototype(cx)); if (!proto) - return nullptr; + return false; if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, protoFunctions)) - return nullptr; + return false; - global->setPrototype(JSProto_Module, ObjectValue(*proto)); - return proto; + global->setReservedSlot(MODULE_PROTO, ObjectValue(*proto)); + return true; +} + +bool +js::InitModuleClasses(JSContext* cx, HandleObject obj) +{ + Rooted global(cx, &obj->as()); + return GlobalObject::initModuleProto(cx, global) && + GlobalObject::initImportEntryProto(cx, global) && + GlobalObject::initExportEntryProto(cx, global); } #undef DEFINE_GETTER_FUNCTIONS diff --git a/js/src/builtin/ModuleObject.h b/js/src/builtin/ModuleObject.h index 07735e0c55..c5b306daa1 100644 --- a/js/src/builtin/ModuleObject.h +++ b/js/src/builtin/ModuleObject.h @@ -306,9 +306,7 @@ class MOZ_STACK_CLASS ModuleBuilder ArrayObject* createArray(const TraceableVector& vector); }; -JSObject* InitModuleClass(JSContext* cx, HandleObject obj); -JSObject* InitImportEntryClass(JSContext* cx, HandleObject obj); -JSObject* InitExportEntryClass(JSContext* cx, HandleObject obj); +bool InitModuleClasses(JSContext* cx, HandleObject obj); } // namespace js diff --git a/js/src/jsprototypes.h b/js/src/jsprototypes.h index b856d742e1..ec170d511d 100644 --- a/js/src/jsprototypes.h +++ b/js/src/jsprototypes.h @@ -112,9 +112,6 @@ IF_SAB(real,imaginary)(SharedUint8ClampedArray, 51, InitViaClassSpec, real(TypedArray, 52, InitViaClassSpec, &js::TypedArrayObject::sharedTypedArrayPrototypeClass) \ IF_SAB(real,imaginary)(Atomics, 53, InitAtomicsClass, OCLASP(Atomics)) \ real(SavedFrame, 54, InitViaClassSpec, &js::SavedFrame::class_) \ - real(Module, 55, InitModuleClass, OCLASP(Module)) \ - real(ImportEntry, 56, InitImportEntryClass, OCLASP(ImportEntry)) \ - real(ExportEntry, 57, InitExportEntryClass, OCLASP(ExportEntry)) \ #define JS_FOR_EACH_PROTOTYPE(macro) JS_FOR_PROTOTYPES(macro,macro) diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 7a440ef5b9..d6443a1628 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -6077,6 +6077,9 @@ NewGlobalObject(JSContext* cx, JS::CompartmentOptions& options, /* Initialize FakeDOMObject.prototype */ InitDOMObject(domProto); + + if (!js::InitModuleClasses(cx, glob)) + return nullptr; } JS_FireOnNewGlobalObject(cx, glob); diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h index 56fc52af12..2e94ea97f4 100644 --- a/js/src/vm/GlobalObject.h +++ b/js/src/vm/GlobalObject.h @@ -108,6 +108,9 @@ class GlobalObject : public NativeObject COLLATOR_PROTO, NUMBER_FORMAT_PROTO, DATE_TIME_FORMAT_PROTO, + MODULE_PROTO, + IMPORT_ENTRY_PROTO, + EXPORT_ENTRY_PROTO, REGEXP_STATICS, WARNED_ONCE_FLAGS, RUNTIME_CODEGEN_ENABLED, @@ -467,6 +470,18 @@ class GlobalObject : public NativeObject return getOrCreateObject(cx, DATE_TIME_FORMAT_PROTO, initDateTimeFormatProto); } + JSObject* getModulePrototype() { + return &getSlot(MODULE_PROTO).toObject(); + } + + JSObject* getImportEntryPrototype() { + return &getSlot(IMPORT_ENTRY_PROTO).toObject(); + } + + JSObject* getExportEntryPrototype() { + return &getSlot(EXPORT_ENTRY_PROTO).toObject(); + } + static JSFunction* getOrCreateTypedArrayConstructor(JSContext* cx, Handle global) { if (!ensureConstructor(cx, global, JSProto_TypedArray)) @@ -679,6 +694,11 @@ class GlobalObject : public NativeObject static bool initNumberFormatProto(JSContext* cx, Handle global); static bool initDateTimeFormatProto(JSContext* cx, Handle global); + // Implemented in builtin/ModuleObject.cpp + static bool initModuleProto(JSContext* cx, Handle global); + static bool initImportEntryProto(JSContext* cx, Handle global); + static bool initExportEntryProto(JSContext* cx, Handle global); + // Implemented in builtin/TypedObject.cpp static bool initTypedObjectModule(JSContext* cx, Handle global); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 347fd2bee2..4728b148d2 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5418,6 +5418,9 @@ pref("media.useAudioChannelAPI", false); // Turn rewriting of youtube embeds on/off pref("plugins.rewrite_youtube_embeds", true); +// Expose Request.cache. Currently disabled since the implementation is incomplete. +pref("dom.requestcache.enabled", false); + // Expose Request.context. Currently disabled since the spec is in flux. pref("dom.requestcontext.enabled", false); diff --git a/testing/docker/desktop-build/bin/build.sh b/testing/docker/desktop-build/bin/build.sh new file mode 100644 index 0000000000..4151ed2b2a --- /dev/null +++ b/testing/docker/desktop-build/bin/build.sh @@ -0,0 +1,12 @@ +#! /bin/bash -vex + +set -x -e -v + +#### +# The default build works for any fx_desktop_build based mozharness job: +# via linux-build.sh +#### + +. $HOME/bin/checkout-sources.sh + +. $WORKSPACE/build/src/testing/taskcluster/scripts/builder/build-linux.sh diff --git a/testing/docker/desktop-build/bin/checkout-sources.sh b/testing/docker/desktop-build/bin/checkout-sources.sh new file mode 100644 index 0000000000..6cc2acfb75 --- /dev/null +++ b/testing/docker/desktop-build/bin/checkout-sources.sh @@ -0,0 +1,54 @@ +#! /bin/bash -vex + +set -x -e + +# Inputs, with defaults + +# mozharness builds use three repositories: gecko (source), mozharness (build +# scripts) and tools (miscellaneous) for each, specify *_REPOSITORY. If the +# revision is not in the standard repo for the codebase, specify *_BASE_REPO as +# the canonical repo to clone and *_HEAD_REPO as the repo containing the +# desired revision. For Mercurial clones, only *_HEAD_REV is required; for Git +# clones, specify the branch name to fetch as *_HEAD_REF and the desired sha1 +# as *_HEAD_REV. For compatibility, we also accept MOZHARNESS_{REV,REF} + +: GECKO_REPOSITORY ${GECKO_REPOSITORY:=https://hg.mozilla.org/mozilla-central} +: GECKO_BASE_REPOSITORY ${GECKO_BASE_REPOSITORY:=${GECKO_REPOSITORY}} +: GECKO_HEAD_REPOSITORY ${GECKO_HEAD_REPOSITORY:=${GECKO_REPOSITORY}} +: GECKO_HEAD_REV ${GECKO_HEAD_REV:=default} +: GECKO_HEAD_REF ${GECKO_HEAD_REF:=${GECKO_HEAD_REV}} + +: MOZHARNESS_REPOSITORY ${MOZHARNESS_REPOSITORY:=https://hg.mozilla.org/build/mozharness} +: MOZHARNESS_BASE_REPOSITORY ${MOZHARNESS_BASE_REPOSITORY:=${MOZHARNESS_REPOSITORY}} +: MOZHARNESS_HEAD_REPOSITORY ${MOZHARNESS_HEAD_REPOSITORY:=${MOZHARNESS_REPOSITORY}} +: MOZHARNESS_REV ${MOZHARNESS_REV:=production} +: MOZHARNESS_REF ${MOZHARNESS_REF:=${MOZHARNESS_REV}} +: MOZHARNESS_HEAD_REV ${MOZHARNESS_HEAD_REV:=${MOZHARNESS_REV}} +: MOZHARNESS_HEAD_REF ${MOZHARNESS_HEAD_REF:=${MOZHARNESS_REF}} + +: TOOLS_REPOSITORY ${TOOLS_REPOSITORY:=https://hg.mozilla.org/build/tools} +: TOOLS_BASE_REPOSITORY ${TOOLS_BASE_REPOSITORY:=${TOOLS_REPOSITORY}} +: TOOLS_HEAD_REPOSITORY ${TOOLS_HEAD_REPOSITORY:=${TOOLS_REPOSITORY}} +: TOOLS_HEAD_REV ${TOOLS_HEAD_REV:=default} +: TOOLS_HEAD_REF ${TOOLS_HEAD_REF:=${TOOLS_HEAD_REV}} + +: MH_CUSTOM_BUILD_VARIANT_CFG ${MH_CUSTOM_BUILD_VARIANT_CFG} +: MH_BRANCH ${MH_BRANCH:=mozilla-central} +: MH_BUILD_POOL ${MH_BUILD_POOL:=staging} + +: WORKSPACE ${WORKSPACE:=/home/worker/workspace} + +set -v + +# check out mozharness +tc-vcs checkout mozharness $MOZHARNESS_BASE_REPOSITORY $MOZHARNESS_HEAD_REPOSITORY $MOZHARNESS_HEAD_REV $MOZHARNESS_HEAD_REF + +# check out tools where mozharness expects it to be ($PWD/build/tools and $WORKSPACE/build/tools) +tc-vcs checkout $WORKSPACE/build/tools $TOOLS_BASE_REPOSITORY $TOOLS_HEAD_REPOSITORY $TOOLS_HEAD_REV $TOOLS_HEAD_REF +if [ ! -d build ]; then + mkdir -p build + ln -s $WORKSPACE/build/tools build/tools +fi + +# and check out mozilla-central where mozharness will use it as a cache (/builds/hg-shared) +tc-vcs checkout $WORKSPACE/build/src $GECKO_BASE_REPOSITORY $GECKO_HEAD_REPOSITORY $GECKO_HEAD_REV $GECKO_HEAD_REF diff --git a/testing/mozharness/mozharness/mozilla/building/buildbase.py b/testing/mozharness/mozharness/mozilla/building/buildbase.py index 0e7823ba3e..77714692fe 100755 --- a/testing/mozharness/mozharness/mozilla/building/buildbase.py +++ b/testing/mozharness/mozharness/mozilla/building/buildbase.py @@ -1273,15 +1273,15 @@ or run without that action (ie: --no-{action})" def _query_props_set_by_mach(self, console_output=True, error_level=FATAL): mach_properties_path = os.path.join( - self.query_abs_dirs()['abs_obj_dir'], 'mach_build_properties.json' + self.query_abs_dirs()['abs_obj_dir'], 'dist', 'mach_build_properties.json' ) self.info("setting properties set by mach build. Looking in path: %s" % mach_properties_path) if os.path.exists(mach_properties_path): with self.opened(mach_properties_path, error_level=error_level) as (fh, err): build_props = json.load(fh) - if not build_props or err: - self.log("%s exists but there was an error finding any " + if err: + self.log("%s exists but there was an error reading the " "properties. props: `%s` - error: " "`%s`" % (mach_properties_path, build_props or 'None', @@ -1294,9 +1294,7 @@ or run without that action (ie: --no-{action})" if prop != 'UNKNOWN': self.set_buildbot_property(key, prop, write_to_file=True) else: - self.log("Could not determine path for build properties. " - "Does this exist: `%s` ?" % mach_properties_path, - level=error_level) + self.info("No mach_build_properties.json found - not importing properties.") def generate_build_props(self, console_output=True, halt_on_failure=False): """sets props found from mach build and, in addition, buildid, @@ -1607,7 +1605,7 @@ or run without that action (ie: --no-{action})" self._run_tooltool() self._create_mozbuild_dir() mach_props = os.path.join( - self.query_abs_dirs()['abs_obj_dir'], 'mach_build_properties.json' + self.query_abs_dirs()['abs_obj_dir'], 'dist', 'mach_build_properties.json' ) if os.path.exists(mach_props): self.info("Removing previous mach property file: %s" % mach_props) diff --git a/testing/taskcluster/scripts/builder/build-linux.sh b/testing/taskcluster/scripts/builder/build-linux.sh new file mode 100644 index 0000000000..28596a2ef6 --- /dev/null +++ b/testing/taskcluster/scripts/builder/build-linux.sh @@ -0,0 +1,153 @@ +#! /bin/bash -vex + +set -x -e + +#### +# Taskcluster friendly wrapper for performing fx desktop builds via mozharness. +#### + +# Inputs, with defaults + +: MOZHARNESS_SCRIPT ${MOZHARNESS_SCRIPT} +: MOZHARNESS_CONFIG ${MOZHARNESS_CONFIG} + +: TOOLTOOL_CACHE ${TOOLTOOL_CACHE:=/home/worker/tooltool-cache} + +: RELENGAPI_TOKEN ${RELENGAPI_TOKEN+HIDDEN} + +: NEED_XVFB ${NEED_XVFB:=false} + +: MH_CUSTOM_BUILD_VARIANT_CFG ${MH_CUSTOM_BUILD_VARIANT_CFG} +: MH_BRANCH ${MH_BRANCH:=mozilla-central} +: MH_BUILD_POOL ${MH_BUILD_POOL:=staging} + +: WORKSPACE ${WORKSPACE:=/home/worker/workspace} + +# files to be "uploaded" (moved to ~/artifacts) from obj-firefox/dist +: DIST_UPLOADS ${DIST_UPLOADS:=""} +# files which will be be prefixed with target before being sent to artifacts +# e.g. DIST_TARGET_UPLOADS="a.zip" runs mv v2.0.a.zip mv artifacts/target.a.zip +: DIST_TARGET_UPLOADS ${DIST_TARGET_UPLOADS:=""} + +set -v + +# Don't run the upload step; this is passed through mozharness to mach. Once +# the mozharness scripts are not run in Buildbot anymore, this can be moved to +# Mozharness (or the upload step removed from mach entirely) +export MOZ_AUTOMATION_UPLOAD=0 + +export MOZ_CRASHREPORTER_NO_REPORT=1 +export MOZ_OBJDIR=obj-firefox +export MOZ_SYMBOLS_EXTRA_BUILDID=linux64 +export POST_SYMBOL_UPLOAD_CMD=/usr/local/bin/post-symbol-upload.py +export TINDERBOX_OUTPUT=1 + +# Ensure that in tree libraries can be found +export LIBRARY_PATH=$LIBRARY_PATH:$WORKSPACE/src/obj-firefox:$WORKSPACE/src/gcc/lib64 + +# test required parameters are supplied +if [[ -z ${MOZHARNESS_SCRIPT} ]]; then exit 1; fi +if [[ -z ${MOZHARNESS_CONFIG} ]]; then exit 1; fi + +cleanup() { + if [ -n "$xvfb_pid" ]; then + kill $xvfb_pid || true + fi +} +trap cleanup EXIT INT + +# run mozharness in XVfb, if necessary; this is an array to maintain the quoting in the -s argument +if $NEED_XVFB; then + # Some mozharness scripts set DISPLAY=:2 + Xvfb :2 -screen 0 1024x768x24 & + export DISPLAY=:2 + xvfb_pid=$! + # Only error code 255 matters, because it signifies that no + # display could be opened. As long as we can open the display + # tests should work. We'll retry a few times with a sleep before + # failing. + retry_count=0 + max_retries=2 + xvfb_test=0 + until [ $retry_count -gt $max_retries ]; do + xvinfo || xvfb_test=$? + if [ $xvfb_test != 255 ]; then + retry_count=$(($max_retries + 1)) + else + retry_count=$(($retry_count + 1)) + echo "Failed to start Xvfb, retry: $retry_count" + sleep 2 + fi done + if [ $xvfb_test == 255 ]; then exit 255; fi +fi + +# set up mozharness configuration, via command line, env, etc. + +debug_flag="" +if [ 0$DEBUG -ne 0 ]; then + debug_flag='--debug' +fi + +custom_build_variant_cfg_flag="" +if [ -n "${MH_CUSTOM_BUILD_VARIANT_CFG}" ]; then + custom_build_variant_cfg_flag="--custom-build-variant-cfg=${MH_CUSTOM_BUILD_VARIANT_CFG}" +fi + +set +x +# mozharness scripts look for the relengapi token at this location, so put it there, +# if specified +if [ -n "${RELENGAPI_TOKEN}" ]; then + echo 'Storing $RELENGAPI_TOKEN in /builds/relengapi.tok' + echo ${RELENGAPI_TOKEN} > /builds/relengapi.tok + # unset it so that mozharness doesn't "helpfully" log it + unset RELENGAPI_TOKEN +fi +set -x + +# $TOOLTOOL_CACHE bypasses mozharness completely and is read by tooltool_wrapper.sh to set the +# cache. However, only some mozharness scripts use tooltool_wrapper.sh, so this may not be +# entirely effective. +export TOOLTOOL_CACHE + +# support multiple, space delimited, config files +config_cmds="" +for cfg in $MOZHARNESS_CONFIG; do + config_cmds="${config_cmds} --config ${cfg}" +done + +# Mozharness would ordinarily do the checkouts itself, but they are disabled +# here (--no-checkout-sources, --no-clone-tools) as the checkout is performed above. + +./${MOZHARNESS_SCRIPT} ${config_cmds} \ + $debug_flag \ + $custom_build_variant_cfg_flag \ + --disable-mock \ + --no-setup-mock \ + --no-checkout-sources \ + --no-clone-tools \ + --no-clobber \ + --no-update \ + --no-upload-files \ + --no-sendchange \ + --log-level=debug \ + --work-dir=$WORKSPACE/build \ + --no-action=generate-build-stats \ + --branch=${MH_BRANCH} \ + --build-pool=${MH_BUILD_POOL} + +mkdir -p /home/worker/artifacts + +# upload auxiliary files +cd $WORKSPACE/build/src/obj-firefox/dist + +for file in $DIST_UPLOADS +do + mv $file $HOME/artifacts/$file +done + +# Discard version numbers from packaged files, they just make it hard to write +# the right filename in the task payload where artifacts are declared +for file in $DIST_TARGET_UPLOADS +do + mv *.$file $HOME/artifacts/target.$file +done diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/__dir__.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/__dir__.ini new file mode 100644 index 0000000000..e05911f92d --- /dev/null +++ b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/__dir__.ini @@ -0,0 +1 @@ +prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true] diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-add.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-add.https.html.ini deleted file mode 100644 index 2dc41a01c8..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-add.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-add.https.html] - type: testharness - prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true] diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-delete.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-delete.https.html.ini deleted file mode 100644 index 4deb7c8667..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-delete.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-delete.https.html] - type: testharness - prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true] diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-match.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-match.https.html.ini deleted file mode 100644 index 2ca31d4ddd..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-match.https.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[cache-match.https.html] - type: testharness - prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true] - [Cache.match and Cache.matchAll] - expected: FAIL - bug: https://github.com/w3c/web-platform-tests/issues/2098 diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-put.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-put.https.html.ini deleted file mode 100644 index a4be22c2b9..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-put.https.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[cache-put.https.html] - type: testharness - prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true] - [Cache.put with request URLs containing embedded credentials] - expected: FAIL - bug: https://github.com/w3c/web-platform-tests/issues/2098 diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html.ini deleted file mode 100644 index bfd50d10e3..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-storage-keys.https.html] - type: testharness - prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true] diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage-match.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage-match.https.html.ini deleted file mode 100644 index 435b29a8cf..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage-match.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-storage-match.https.html] - type: testharness - prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true] diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage.https.html.ini deleted file mode 100644 index f651f5610b..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-storage.https.html] - type: testharness - prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true] diff --git a/testing/web-platform/meta/service-workers/cache-storage/window/cache-match.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/window/cache-match.https.html.ini deleted file mode 100644 index 860f0963c7..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/window/cache-match.https.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[cache-match.https.html] - type: testharness - prefs: [dom.caches.enabled:true] - expected: ERROR - bug: https://github.com/w3c/web-platform-tests/issues/2098 diff --git a/testing/web-platform/meta/service-workers/cache-storage/window/cache-put.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/window/cache-put.https.html.ini deleted file mode 100644 index 66a4a3c7ec..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/window/cache-put.https.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[cache-put.https.html] - type: testharness - prefs: [dom.caches.enabled:true] - [Cache.put with request URLs containing embedded credentials] - expected: FAIL - bug: https://github.com/w3c/web-platform-tests/issues/2098 diff --git a/testing/web-platform/meta/service-workers/cache-storage/window/cache-storage-match.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/window/cache-storage-match.https.html.ini deleted file mode 100644 index 203cd7bece..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/window/cache-storage-match.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-storage-match.https.html] - type: testharness - prefs: [dom.caches.enabled:true] diff --git a/testing/web-platform/meta/service-workers/cache-storage/worker/__dir__.ini b/testing/web-platform/meta/service-workers/cache-storage/worker/__dir__.ini new file mode 100644 index 0000000000..9f3cfaa25a --- /dev/null +++ b/testing/web-platform/meta/service-workers/cache-storage/worker/__dir__.ini @@ -0,0 +1 @@ +prefs: [dom.caches.enabled:true] diff --git a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-add.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/worker/cache-add.https.html.ini deleted file mode 100644 index f85c725a22..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-add.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-add.https.html] - type: testharness - prefs: [dom.caches.enabled:true] diff --git a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-delete.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/worker/cache-delete.https.html.ini deleted file mode 100644 index 76859c63f0..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-delete.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-delete.https.html] - type: testharness - prefs: [dom.caches.enabled:true] diff --git a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-match.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/worker/cache-match.https.html.ini deleted file mode 100644 index 860f0963c7..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-match.https.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[cache-match.https.html] - type: testharness - prefs: [dom.caches.enabled:true] - expected: ERROR - bug: https://github.com/w3c/web-platform-tests/issues/2098 diff --git a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-put.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/worker/cache-put.https.html.ini deleted file mode 100644 index 66a4a3c7ec..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-put.https.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[cache-put.https.html] - type: testharness - prefs: [dom.caches.enabled:true] - [Cache.put with request URLs containing embedded credentials] - expected: FAIL - bug: https://github.com/w3c/web-platform-tests/issues/2098 diff --git a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage-keys.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage-keys.https.html.ini deleted file mode 100644 index 823b570843..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage-keys.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-storage-keys.https.html] - type: testharness - prefs: [dom.caches.enabled:true] diff --git a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage-match.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage-match.https.html.ini deleted file mode 100644 index 203cd7bece..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage-match.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-storage-match.https.html] - type: testharness - prefs: [dom.caches.enabled:true] diff --git a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage.https.html.ini deleted file mode 100644 index 6ed6d9d1af..0000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-storage.https.html] - type: testharness - prefs: [dom.caches.enabled:true] diff --git a/toolkit/mozapps/installer/packager.mk b/toolkit/mozapps/installer/packager.mk index b0eb97a50a..35f5bcf62c 100644 --- a/toolkit/mozapps/installer/packager.mk +++ b/toolkit/mozapps/installer/packager.mk @@ -194,6 +194,8 @@ checksum: upload: checksum $(PYTHON) $(MOZILLA_DIR)/build/upload.py --base-path $(DIST) \ + --package $(PACKAGE) \ + --properties-file $(DIST)/mach_build_properties.json \ $(UPLOAD_FILES) \ $(CHECKSUM_FILES) diff --git a/widget/cocoa/nsMenuBarX.mm b/widget/cocoa/nsMenuBarX.mm index c92009d063..d5390e8e27 100644 --- a/widget/cocoa/nsMenuBarX.mm +++ b/widget/cocoa/nsMenuBarX.mm @@ -248,7 +248,10 @@ void nsMenuBarX::RemoveMenuAtIndex(uint32_t aIndex) { NS_OBJC_BEGIN_TRY_ABORT_BLOCK; - NS_ASSERTION(aIndex < mMenuArray.Length(), "Attempting submenu removal with bad index!"); + if (mMenuArray.Length() <= aIndex) { + NS_ERROR("Attempting submenu removal with bad index!"); + return; + } // Our native menu and our internal menu object array might be out of sync. // This happens, for example, when a submenu is hidden. Because of this we @@ -570,12 +573,14 @@ NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsMenuX* inMenu, const nsAString NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; nsCOMPtr doc = inMenu->Content()->GetUncomposedDoc(); - if (!doc) + if (!doc) { return nil; + } nsCOMPtr domdoc(do_QueryInterface(doc)); - if (!domdoc) + if (!domdoc) { return nil; + } // Get information from the gecko menu item nsAutoString label; @@ -634,7 +639,7 @@ NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsMenuX* inMenu, const nsAString MenuItemInfo * info = [[MenuItemInfo alloc] initWithMenuGroupOwner:this]; [newMenuItem setRepresentedObject:info]; [info release]; - + return newMenuItem; NS_OBJC_END_TRY_ABORT_BLOCK_NIL; diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index 827031c61f..7aada5c607 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -6,6 +6,7 @@ #include "nsNativeThemeCocoa.h" #include "mozilla/gfx/2D.h" +#include "mozilla/gfx/Helpers.h" #include "nsDeviceContext.h" #include "nsLayoutUtils.h" #include "nsObjCExceptions.h" @@ -2428,19 +2429,14 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, if (nativeWidgetRect.IsEmpty()) return NS_OK; // Don't attempt to draw invisible widgets. - gfxContext* thebesCtx = aContext->ThebesContext(); - if (!thebesCtx) - return NS_ERROR_FAILURE; - - gfxContextMatrixAutoSaveRestore save(thebesCtx); + AutoRestoreTransform autoRestoreTransform(&aDrawTarget); bool hidpi = IsHiDPIContext(aFrame->PresContext()); if (hidpi) { // Use high-resolution drawing. nativeWidgetRect.Scale(0.5f); nativeDirtyRect.Scale(0.5f); - thebesCtx->SetMatrix( - thebesCtx->CurrentMatrix().Scale(2.0f, 2.0f)); + aDrawTarget.SetTransform(aDrawTarget.GetTransform().PreScale(2.0f, 2.0f)); } gfxQuartzNativeDrawing nativeDrawing(aDrawTarget, nativeDirtyRect);