From 202b273a2ef2827aaf589874a4496ba94aa2ae76 Mon Sep 17 00:00:00 2001 From: roytam1 Date: Fri, 30 Apr 2021 09:42:27 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1175485 part 1 - Allow inner iterator of ReverseIterator deref to any type, and change IntegerIterator, EnumeratedRange, and nsFrameList::Iterator to return value type instead of a reference. r=roc,waldo (83c53e8e8) - Bug 1175485 part 2 - Add static_assert to MakeRange to ensure it is used with integers. r=waldo (2b6fc759a) - Bug 1175485 part 3 - Remove unused operators, typedefs and IteratorTraits. r=waldo (91bc5407d) - Bug 1175485 part 4 - Add unit test for integer range. r=waldo (ec2b7d4c1) - Bug 1188204 - Fix more constructors in MFBT; r=froydnj (099428523) - Bug 1187985 - Make PersistentRooted use rootKind to find its lists; r=sfink (0c223593a) - Bug 1184191 - Assert in release mode if we reenter the garbage collector r=terrence (3207d3631) - Bug 1188124 - Use rootKind to select the right PersistentRooted list head; r=sfink (47009c787) - Bug 1174849 - Remove "serviceworker" from RequestContext; r=smaug,bkelly (138e480ea) - Bug 1174868 - Avoid storing RequestContext inside InternalRequest; r=nsm,bkelly,smaug (779a05075) - Bug 1147668 - Correctly reflect video and track RequestContext values; r=smaug (90f265d5f) - Bug 1148818 - Re-enable the Cache part of test_request_context.html on Android now that it passes (782fe9777) - Bug 1148935 - Correctly reflect worker and sharedworker RequestContext values; r=smaug (fd40e01d8) --- dom/base/nsScriptLoader.cpp | 4 +- dom/cache/CacheTypes.ipdlh | 2 - dom/cache/DBSchema.cpp | 58 +------ dom/cache/IPCUtils.h | 5 - dom/cache/TypeUtils.cpp | 5 - dom/fetch/InternalRequest.cpp | 71 +++++--- dom/fetch/InternalRequest.h | 30 ++-- dom/fetch/Request.h | 7 - dom/html/HTMLMediaElement.cpp | 8 +- dom/html/HTMLTrackElement.cpp | 4 +- dom/ipc/manifestMessages.js | 2 +- dom/media/MediaResource.cpp | 12 +- dom/webidl/Request.webidl | 7 +- dom/workers/RuntimeService.cpp | 2 +- dom/workers/ScriptLoader.cpp | 17 +- dom/workers/ScriptLoader.h | 2 + dom/workers/ServiceWorkerManager.cpp | 1 + dom/workers/ServiceWorkerScriptCache.cpp | 5 +- dom/workers/WorkerPrivate.cpp | 4 +- dom/workers/WorkerPrivate.h | 26 ++- .../fetch/context/context_test.js | 19 +- .../serviceworkers/fetch/context/index.html | 63 ++++++- .../fetch/context/parentsharedworker.js | 8 + .../fetch/context/parentworker.js | 4 + .../fetch/context/sharedworker.js | 5 + .../serviceworkers/fetch/context/worker.js | 1 + dom/workers/test/serviceworkers/mochitest.ini | 4 + js/public/RootingAPI.h | 10 +- js/src/gc/RootMarking.cpp | 13 +- js/src/jsgc.cpp | 15 +- js/src/jspubtd.h | 49 ++++-- layout/generic/nsFrameList.h | 7 +- mfbt/AlreadyAddRefed.h | 2 +- mfbt/CheckedInt.h | 2 +- mfbt/EnumeratedRange.h | 30 +--- mfbt/IntegerRange.h | 31 +--- mfbt/IteratorTraits.h | 39 ----- mfbt/RangedPtr.h | 2 +- mfbt/ReentrancyGuard.h | 8 +- mfbt/RefPtr.h | 2 +- mfbt/ReverseIterator.h | 30 +--- mfbt/UniquePtr.h | 7 +- mfbt/moz.build | 1 - mfbt/tests/TestIntegerRange.cpp | 163 ++++++++++++++++++ mfbt/tests/moz.build | 1 + testing/cppunittest.ini | 1 + 46 files changed, 472 insertions(+), 317 deletions(-) create mode 100644 dom/workers/test/serviceworkers/fetch/context/parentsharedworker.js create mode 100644 dom/workers/test/serviceworkers/fetch/context/parentworker.js create mode 100644 dom/workers/test/serviceworkers/fetch/context/sharedworker.js create mode 100644 dom/workers/test/serviceworkers/fetch/context/worker.js delete mode 100644 mfbt/IteratorTraits.h create mode 100644 mfbt/tests/TestIntegerRange.cpp diff --git a/dom/base/nsScriptLoader.cpp b/dom/base/nsScriptLoader.cpp index 643ba2fc4b..2a170f5ab8 100644 --- a/dom/base/nsScriptLoader.cpp +++ b/dom/base/nsScriptLoader.cpp @@ -234,7 +234,7 @@ nsScriptLoader::CheckContentPolicy(nsIDocument* aDocument, const nsAString &aType) { int16_t shouldLoad = nsIContentPolicy::ACCEPT; - nsresult rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_SCRIPT, + nsresult rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_INTERNAL_SCRIPT, aURI, aDocument->NodePrincipal(), aContext, @@ -309,7 +309,7 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType, aRequest->mURI, mDocument, nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_SCRIPT, + nsIContentPolicy::TYPE_INTERNAL_SCRIPT, loadGroup, prompter, nsIRequest::LOAD_NORMAL | diff --git a/dom/cache/CacheTypes.ipdlh b/dom/cache/CacheTypes.ipdlh index ddb53ddf29..05cd428232 100644 --- a/dom/cache/CacheTypes.ipdlh +++ b/dom/cache/CacheTypes.ipdlh @@ -13,7 +13,6 @@ using HeadersGuardEnum from "mozilla/dom/cache/IPCUtils.h"; using RequestCredentials from "mozilla/dom/cache/IPCUtils.h"; using RequestMode from "mozilla/dom/cache/IPCUtils.h"; using RequestCache from "mozilla/dom/cache/IPCUtils.h"; -using RequestContext from "mozilla/dom/cache/IPCUtils.h"; using ResponseType from "mozilla/dom/cache/IPCUtils.h"; using mozilla::void_t from "ipc/IPCMessageUtils.h"; using struct nsID from "nsID.h"; @@ -64,7 +63,6 @@ struct CacheRequest RequestCredentials credentials; CacheReadStreamOrVoid body; uint32_t contentPolicyType; - RequestContext context; RequestCache requestCache; }; diff --git a/dom/cache/DBSchema.cpp b/dom/cache/DBSchema.cpp index d46820ac64..f7a02a40c2 100644 --- a/dom/cache/DBSchema.cpp +++ b/dom/cache/DBSchema.cpp @@ -30,11 +30,11 @@ namespace dom { namespace cache { namespace db { -const int32_t kMaxWipeSchemaVersion = 11; +const int32_t kMaxWipeSchemaVersion = 13; namespace { -const int32_t kLatestSchemaVersion = 11; +const int32_t kLatestSchemaVersion = 13; const int32_t kMaxEntriesPerStatement = 255; const uint32_t kPageSize = 4 * 1024; @@ -78,40 +78,6 @@ static_assert(int(RequestCredentials::Omit) == 0 && int(RequestCredentials::Include) == 2 && int(RequestCredentials::EndGuard_) == 3, "RequestCredentials values are as expected"); -static_assert(int(RequestContext::Audio) == 0 && - int(RequestContext::Beacon) == 1 && - int(RequestContext::Cspreport) == 2 && - int(RequestContext::Download) == 3 && - int(RequestContext::Embed) == 4 && - int(RequestContext::Eventsource) == 5 && - int(RequestContext::Favicon) == 6 && - int(RequestContext::Fetch) == 7 && - int(RequestContext::Font) == 8 && - int(RequestContext::Form) == 9 && - int(RequestContext::Frame) == 10 && - int(RequestContext::Hyperlink) == 11 && - int(RequestContext::Iframe) == 12 && - int(RequestContext::Image) == 13 && - int(RequestContext::Imageset) == 14 && - int(RequestContext::Import) == 15 && - int(RequestContext::Internal) == 16 && - int(RequestContext::Location) == 17 && - int(RequestContext::Manifest) == 18 && - int(RequestContext::Object) == 19 && - int(RequestContext::Ping) == 20 && - int(RequestContext::Plugin) == 21 && - int(RequestContext::Prefetch) == 22 && - int(RequestContext::Script) == 23 && - int(RequestContext::Serviceworker) == 24 && - int(RequestContext::Sharedworker) == 25 && - int(RequestContext::Subresource) == 26 && - int(RequestContext::Style) == 27 && - int(RequestContext::Track) == 28 && - int(RequestContext::Video) == 29 && - int(RequestContext::Worker) == 30 && - int(RequestContext::Xmlhttprequest) == 31 && - int(RequestContext::Xslt) == 32, - "RequestContext values are as expected"); static_assert(int(RequestCache::Default) == 0 && int(RequestCache::No_store) == 1 && int(RequestCache::Reload) == 2 && @@ -292,7 +258,6 @@ CreateSchema(mozIStorageConnection* aConn) "request_mode INTEGER NOT NULL, " "request_credentials INTEGER NOT NULL, " "request_contentpolicytype INTEGER NOT NULL, " - "request_context INTEGER NOT NULL, " "request_cache INTEGER NOT NULL, " "request_body_id TEXT NULL, " "response_type INTEGER NOT NULL, " @@ -1520,7 +1485,6 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId, "request_mode, " "request_credentials, " "request_contentpolicytype, " - "request_context, " "request_cache, " "request_body_id, " "response_type, " @@ -1543,7 +1507,6 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId, ":request_mode, " ":request_credentials, " ":request_contentpolicytype, " - ":request_context, " ":request_cache, " ":request_body_id, " ":response_type, " @@ -1593,10 +1556,6 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId, static_cast(aRequest.contentPolicyType())); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_context"), - static_cast(aRequest.context())); - if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_cache"), static_cast(aRequest.requestCache())); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -1880,7 +1839,6 @@ ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId, "request_mode, " "request_credentials, " "request_contentpolicytype, " - "request_context, " "request_cache, " "request_body_id " "FROM entries " @@ -1930,25 +1888,19 @@ ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId, aSavedRequestOut->mValue.contentPolicyType() = static_cast(requestContentPolicyType); - int32_t requestContext; - rv = state->GetInt32(8, &requestContext); - if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - aSavedRequestOut->mValue.context() = - static_cast(requestContext); - int32_t requestCache; - rv = state->GetInt32(9, &requestCache); + rv = state->GetInt32(8, &requestCache); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } aSavedRequestOut->mValue.requestCache() = static_cast(requestCache); bool nullBody = false; - rv = state->GetIsNull(10, &nullBody); + rv = state->GetIsNull(9, &nullBody); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } aSavedRequestOut->mHasBodyId = !nullBody; if (aSavedRequestOut->mHasBodyId) { - rv = ExtractId(state, 10, &aSavedRequestOut->mBodyId); + rv = ExtractId(state, 9, &aSavedRequestOut->mBodyId); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } diff --git a/dom/cache/IPCUtils.h b/dom/cache/IPCUtils.h index 81068ccc1a..cb09ebe6fc 100644 --- a/dom/cache/IPCUtils.h +++ b/dom/cache/IPCUtils.h @@ -39,11 +39,6 @@ namespace IPC { mozilla::dom::RequestCache::Default, mozilla::dom::RequestCache::EndGuard_> {}; template<> - struct ParamTraits : - public ContiguousEnumSerializer {}; - template<> struct ParamTraits : public ContiguousEnumSerializerMode(); aOut.credentials() = aIn->GetCredentialsMode(); aOut.contentPolicyType() = aIn->ContentPolicyType(); - aOut.context() = aIn->Context(); aOut.requestCache() = aIn->GetCacheMode(); if (aBodyAction == IgnoreBody) { @@ -337,10 +336,6 @@ TypeUtils::ToInternalRequest(const CacheRequest& aIn) internalRequest->SetMode(aIn.mode()); internalRequest->SetCredentialsMode(aIn.credentials()); internalRequest->SetContentPolicyType(aIn.contentPolicyType()); - DebugOnly contextAfterSetContentPolicyType = internalRequest->Context(); - internalRequest->SetContext(aIn.context()); - MOZ_ASSERT(contextAfterSetContentPolicyType.value == internalRequest->Context(), - "The RequestContext and nsContentPolicyType values should not get out of sync"); internalRequest->SetCacheMode(aIn.requestCache()); nsRefPtr internalHeaders = diff --git a/dom/fetch/InternalRequest.cpp b/dom/fetch/InternalRequest.cpp index feb246c1c6..448d5d4ff0 100644 --- a/dom/fetch/InternalRequest.cpp +++ b/dom/fetch/InternalRequest.cpp @@ -39,7 +39,6 @@ InternalRequest::GetRequestConstructorCopy(nsIGlobalObject* aGlobal, ErrorResult // The default referrer is already about:client. copy->mContentPolicyType = nsIContentPolicy::TYPE_FETCH; - copy->mContext = RequestContext::Fetch; copy->mMode = mMode; copy->mCredentialsMode = mCredentialsMode; copy->mCacheMode = mCacheMode; @@ -76,7 +75,6 @@ InternalRequest::InternalRequest(const InternalRequest& aOther) , mURL(aOther.mURL) , mHeaders(new InternalHeaders(*aOther.mHeaders)) , mContentPolicyType(aOther.mContentPolicyType) - , mContext(aOther.mContext) , mReferrer(aOther.mReferrer) , mMode(aOther.mMode) , mCredentialsMode(aOther.mCredentialsMode) @@ -104,78 +102,97 @@ void InternalRequest::SetContentPolicyType(nsContentPolicyType aContentPolicyType) { mContentPolicyType = aContentPolicyType; +} + +/* static */ +RequestContext +InternalRequest::MapContentPolicyTypeToRequestContext(nsContentPolicyType aContentPolicyType) +{ + RequestContext context = RequestContext::Internal; switch (aContentPolicyType) { case nsIContentPolicy::TYPE_OTHER: - mContext = RequestContext::Internal; + context = RequestContext::Internal; break; - case nsIContentPolicy::TYPE_SCRIPT: - mContext = RequestContext::Script; + case nsIContentPolicy::TYPE_INTERNAL_SCRIPT: + context = RequestContext::Script; + break; + case nsIContentPolicy::TYPE_INTERNAL_WORKER: + context = RequestContext::Worker; + break; + case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER: + context = RequestContext::Sharedworker; break; case nsIContentPolicy::TYPE_IMAGE: - mContext = RequestContext::Image; + context = RequestContext::Image; break; case nsIContentPolicy::TYPE_STYLESHEET: - mContext = RequestContext::Style; + context = RequestContext::Style; break; case nsIContentPolicy::TYPE_OBJECT: - mContext = RequestContext::Object; + context = RequestContext::Object; break; case nsIContentPolicy::TYPE_DOCUMENT: - mContext = RequestContext::Internal; + context = RequestContext::Internal; break; case nsIContentPolicy::TYPE_SUBDOCUMENT: - mContext = RequestContext::Iframe; + context = RequestContext::Iframe; break; case nsIContentPolicy::TYPE_REFRESH: - mContext = RequestContext::Internal; + context = RequestContext::Internal; break; case nsIContentPolicy::TYPE_XBL: - mContext = RequestContext::Internal; + context = RequestContext::Internal; break; case nsIContentPolicy::TYPE_PING: - mContext = RequestContext::Ping; + context = RequestContext::Ping; break; case nsIContentPolicy::TYPE_XMLHTTPREQUEST: - mContext = RequestContext::Xmlhttprequest; + context = RequestContext::Xmlhttprequest; break; case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST: - mContext = RequestContext::Plugin; + context = RequestContext::Plugin; break; case nsIContentPolicy::TYPE_DTD: - mContext = RequestContext::Internal; + context = RequestContext::Internal; break; case nsIContentPolicy::TYPE_FONT: - mContext = RequestContext::Font; + context = RequestContext::Font; break; - case nsIContentPolicy::TYPE_MEDIA: - mContext = RequestContext::Audio; + case nsIContentPolicy::TYPE_INTERNAL_AUDIO: + context = RequestContext::Audio; + break; + case nsIContentPolicy::TYPE_INTERNAL_VIDEO: + context = RequestContext::Video; + break; + case nsIContentPolicy::TYPE_INTERNAL_TRACK: + context = RequestContext::Track; break; case nsIContentPolicy::TYPE_WEBSOCKET: - mContext = RequestContext::Internal; + context = RequestContext::Internal; break; case nsIContentPolicy::TYPE_CSP_REPORT: - mContext = RequestContext::Cspreport; + context = RequestContext::Cspreport; break; case nsIContentPolicy::TYPE_XSLT: - mContext = RequestContext::Xslt; + context = RequestContext::Xslt; break; case nsIContentPolicy::TYPE_BEACON: - mContext = RequestContext::Beacon; + context = RequestContext::Beacon; break; case nsIContentPolicy::TYPE_FETCH: - mContext = RequestContext::Fetch; + context = RequestContext::Fetch; break; case nsIContentPolicy::TYPE_IMAGESET: - mContext = RequestContext::Imageset; + context = RequestContext::Imageset; break; case nsIContentPolicy::TYPE_WEB_MANIFEST: - mContext = RequestContext::Manifest; + context = RequestContext::Manifest; break; default: MOZ_ASSERT(false, "Unhandled nsContentPolicyType value"); - mContext = RequestContext::Internal; break; } + return context; } } // namespace dom diff --git a/dom/fetch/InternalRequest.h b/dom/fetch/InternalRequest.h index 776a58e079..92b6cc3bab 100644 --- a/dom/fetch/InternalRequest.h +++ b/dom/fetch/InternalRequest.h @@ -26,12 +26,11 @@ namespace dom { /* * The mapping of RequestContext and nsContentPolicyType is currently as the * following. Note that this mapping is not perfect yet (see the TODO comments - * below for examples), so for now we'll have to keep both an mContext and an - * mContentPolicyType, because we cannot have a two way conversion. + * below for examples). * * RequestContext | nsContentPolicyType * ------------------+-------------------- - * audio | TYPE_MEDIA + * audio | TYPE_INTERNAL_AUDIO * beacon | TYPE_BEACON * cspreport | TYPE_CSP_REPORT * download | @@ -54,24 +53,21 @@ namespace dom { * ping | TYPE_PING * plugin | TYPE_OBJECT_SUBREQUEST * prefetch | - * script | TYPE_SCRIPT - * serviceworker | - * sharedworker | + * script | TYPE_INTERNAL_SCRIPT + * sharedworker | TYPE_INTERNAL_SHARED_WORKER * subresource | Not supported by Gecko * style | TYPE_STYLESHEET - * track | TYPE_MEDIA - * video | TYPE_MEDIA - * worker | + * track | TYPE_INTERNAL_TRACK + * video | TYPE_INTERNAL_VIDEO + * worker | TYPE_INTERNAL_WORKER * xmlhttprequest | TYPE_XMLHTTPREQUEST * xslt | TYPE_XSLT * * TODO: Figure out if TYPE_REFRESH maps to anything useful * TODO: Figure out if TYPE_DTD maps to anything useful - * TODO: Split TYPE_MEDIA into TYPE_AUDIO, TYPE_VIDEO and TYPE_TRACK * TODO: Split TYPE_XMLHTTPREQUEST and TYPE_DATAREQUEST for EventSource * TODO: Figure out if TYPE_WEBSOCKET maps to anything useful * TODO: Differentiate between frame and iframe - * TODO: Add content types for different kinds of workers * TODO: Add a content type for prefetch * TODO: Use the content type for manifest when it becomes available * TODO: Add a content type for location @@ -282,13 +278,7 @@ public: RequestContext Context() const { - return mContext; - } - - void - SetContext(RequestContext aContext) - { - mContext = aContext; + return MapContentPolicyTypeToRequestContext(mContentPolicyType); } bool @@ -372,13 +362,15 @@ private: ~InternalRequest(); + static RequestContext + MapContentPolicyTypeToRequestContext(nsContentPolicyType aContentPolicyType); + nsCString mMethod; nsCString mURL; nsRefPtr mHeaders; nsCOMPtr mBodyStream; nsContentPolicyType mContentPolicyType; - RequestContext mContext; // Empty string: no-referrer // "about:client": client (default) diff --git a/dom/fetch/Request.h b/dom/fetch/Request.h index d2bf428c55..280d9ee503 100644 --- a/dom/fetch/Request.h +++ b/dom/fetch/Request.h @@ -79,13 +79,6 @@ public: return mRequest->Context(); } - // [ChromeOnly] - void - SetContext(RequestContext aContext) - { - mRequest->SetContext(aContext); - } - void SetContentPolicyType(nsContentPolicyType aContentPolicyType) { diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 0526c029d6..8afe7639ad 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -1156,8 +1156,12 @@ nsresult HTMLMediaElement::LoadResource() return NS_ERROR_FAILURE; } + MOZ_ASSERT(IsAnyOfHTMLElements(nsGkAtoms::audio, nsGkAtoms::video)); + nsContentPolicyType contentPolicyType = IsHTMLElement(nsGkAtoms::audio) ? + nsIContentPolicy::TYPE_INTERNAL_AUDIO : nsIContentPolicy::TYPE_INTERNAL_VIDEO; + int16_t shouldLoad = nsIContentPolicy::ACCEPT; - nsresult rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_MEDIA, + nsresult rv = NS_CheckContentLoadPolicy(contentPolicyType, mLoadingSrc, NodePrincipal(), static_cast(this), @@ -1241,7 +1245,7 @@ nsresult HTMLMediaElement::LoadResource() mLoadingSrc, static_cast(this), securityFlags, - nsIContentPolicy::TYPE_MEDIA, + contentPolicyType, loadGroup, nullptr, // aCallbacks nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY | diff --git a/dom/html/HTMLTrackElement.cpp b/dom/html/HTMLTrackElement.cpp index b9d24d50c4..1c0276aa2d 100644 --- a/dom/html/HTMLTrackElement.cpp +++ b/dom/html/HTMLTrackElement.cpp @@ -209,7 +209,7 @@ HTMLTrackElement::LoadResource() NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv)); int16_t shouldLoad = nsIContentPolicy::ACCEPT; - rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_MEDIA, + rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_INTERNAL_TRACK, uri, NodePrincipal(), static_cast(this), @@ -236,7 +236,7 @@ HTMLTrackElement::LoadResource() uri, static_cast(this), nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_MEDIA, + nsIContentPolicy::TYPE_INTERNAL_TRACK, loadGroup); NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv)); diff --git a/dom/ipc/manifestMessages.js b/dom/ipc/manifestMessages.js index 1ed9b6dac3..ea8cebf249 100644 --- a/dom/ipc/manifestMessages.js +++ b/dom/ipc/manifestMessages.js @@ -79,7 +79,7 @@ function fetchManifest() { reqInit.credentials = 'include'; } const req = new content.Request(manifestURL, reqInit); - req.setContext('manifest'); + req.setContentPolicyType(Ci.nsIContentPolicy.TYPE_WEB_MANIFEST); const response = yield content.fetch(req); const manifest = yield processResponse(response, content); return manifest; diff --git a/dom/media/MediaResource.cpp b/dom/media/MediaResource.cpp index 906b1abf1f..1894684740 100644 --- a/dom/media/MediaResource.cpp +++ b/dom/media/MediaResource.cpp @@ -908,11 +908,15 @@ ChannelMediaResource::RecreateChannel() securityFlags = nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL; } + MOZ_ASSERT(element->IsAnyOfHTMLElements(nsGkAtoms::audio, nsGkAtoms::video)); + nsContentPolicyType contentPolicyType = element->IsHTMLElement(nsGkAtoms::audio) ? + nsIContentPolicy::TYPE_INTERNAL_AUDIO : nsIContentPolicy::TYPE_INTERNAL_VIDEO; + nsresult rv = NS_NewChannel(getter_AddRefs(mChannel), mURI, element, securityFlags, - nsIContentPolicy::TYPE_MEDIA, + contentPolicyType, loadGroup, nullptr, // aCallbacks loadFlags); @@ -1436,13 +1440,17 @@ already_AddRefed FileMediaResource::CloneData(MediaDecoder* aDeco securityFlags = nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL; } + MOZ_ASSERT(element->IsAnyOfHTMLElements(nsGkAtoms::audio, nsGkAtoms::video)); + nsContentPolicyType contentPolicyType = element->IsHTMLElement(nsGkAtoms::audio) ? + nsIContentPolicy::TYPE_INTERNAL_AUDIO : nsIContentPolicy::TYPE_INTERNAL_VIDEO; + nsCOMPtr channel; nsresult rv = NS_NewChannel(getter_AddRefs(channel), mURI, element, securityFlags, - nsIContentPolicy::TYPE_MEDIA, + contentPolicyType, loadGroup); if (NS_FAILED(rv)) diff --git a/dom/webidl/Request.webidl b/dom/webidl/Request.webidl index df8db1ac56..077e13889e 100644 --- a/dom/webidl/Request.webidl +++ b/dom/webidl/Request.webidl @@ -8,6 +8,7 @@ */ typedef (Request or USVString) RequestInfo; +typedef unsigned long nsContentPolicyType; [Constructor(RequestInfo input, optional RequestInit init), Exposed=(Window,Worker)] @@ -27,7 +28,7 @@ interface Request { // Bug 1124638 - Allow chrome callers to set the context. [ChromeOnly] - void setContext(RequestContext context); + void setContentPolicyType(nsContentPolicyType context); }; Request implements Body; @@ -44,8 +45,8 @@ enum RequestContext { "audio", "beacon", "cspreport", "download", "embed", "eventsource", "favicon", "fetch", "font", "form", "frame", "hyperlink", "iframe", "image", "imageset", "import", "internal", "location", "manifest", "object", "ping", "plugin", "prefetch", "script", - "serviceworker", "sharedworker", "subresource", "style", "track", "video", "worker", - "xmlhttprequest", "xslt" + "sharedworker", "subresource", "style", "track", "video", "worker", "xmlhttprequest", + "xslt" }; // cors-with-forced-preflight is internal to the Fetch spec, but adding it here diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 30ae1bfe6a..8a62ee04bb 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -2328,7 +2328,7 @@ RuntimeService::CreateSharedWorkerInternal(const GlobalObject& aGlobal, nsresult rv = WorkerPrivate::GetLoadInfo(cx, window, nullptr, aScriptURL, false, WorkerPrivate::OverrideLoadGroup, - &loadInfo); + aType, &loadInfo); NS_ENSURE_SUCCESS(rv, rv); return CreateSharedWorkerFromLoadInfo(cx, &loadInfo, aScriptURL, aName, aType, diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp index 63619c7da4..9a078d45a2 100644 --- a/dom/workers/ScriptLoader.cpp +++ b/dom/workers/ScriptLoader.cpp @@ -96,6 +96,7 @@ ChannelFromScriptURL(nsIPrincipal* principal, const nsAString& aScriptURL, bool aIsMainScript, WorkerScriptType aWorkerScriptType, + nsContentPolicyType aContentPolicyType, nsIChannel** aChannel) { AssertIsOnMainThread(); @@ -112,7 +113,7 @@ ChannelFromScriptURL(nsIPrincipal* principal, // If we're part of a document then check the content load policy. if (parentDoc) { int16_t shouldLoad = nsIContentPolicy::ACCEPT; - rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_SCRIPT, uri, + rv = NS_CheckContentLoadPolicy(aContentPolicyType, uri, principal, parentDoc, NS_LITERAL_CSTRING("text/javascript"), nullptr, &shouldLoad, @@ -167,7 +168,7 @@ ChannelFromScriptURL(nsIPrincipal* principal, uri, parentDoc, nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_SCRIPT, + aContentPolicyType, loadGroup, nullptr, // aCallbacks flags, @@ -182,7 +183,7 @@ ChannelFromScriptURL(nsIPrincipal* principal, uri, principal, nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_SCRIPT, + aContentPolicyType, loadGroup, nullptr, // aCallbacks flags, @@ -830,7 +831,9 @@ private: if (!channel) { rv = ChannelFromScriptURL(principal, baseURI, parentDoc, loadGroup, ios, secMan, loadInfo.mURL, IsMainWorkerScript(), - mWorkerScriptType, getter_AddRefs(channel)); + mWorkerScriptType, + mWorkerPrivate->ContentPolicyType(), + getter_AddRefs(channel)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -1572,6 +1575,8 @@ public: scriptloader::ChannelFromScriptURLMainThread(principal, baseURI, parentDoc, loadGroup, mScriptURL, + // Nested workers are always dedicated. + nsIContentPolicy::TYPE_INTERNAL_WORKER, getter_AddRefs(channel)); if (NS_SUCCEEDED(mResult)) { channel.forget(mChannel); @@ -1786,6 +1791,7 @@ ChannelFromScriptURLMainThread(nsIPrincipal* aPrincipal, nsIDocument* aParentDoc, nsILoadGroup* aLoadGroup, const nsAString& aScriptURL, + nsContentPolicyType aContentPolicyType, nsIChannel** aChannel) { AssertIsOnMainThread(); @@ -1796,7 +1802,8 @@ ChannelFromScriptURLMainThread(nsIPrincipal* aPrincipal, NS_ASSERTION(secMan, "This should never be null!"); return ChannelFromScriptURL(aPrincipal, aBaseURI, aParentDoc, aLoadGroup, - ios, secMan, aScriptURL, true, WorkerScript, aChannel); + ios, secMan, aScriptURL, true, WorkerScript, + aContentPolicyType, aChannel); } nsresult diff --git a/dom/workers/ScriptLoader.h b/dom/workers/ScriptLoader.h index cbf1e2ce4d..35b0d253d0 100644 --- a/dom/workers/ScriptLoader.h +++ b/dom/workers/ScriptLoader.h @@ -8,6 +8,7 @@ #define mozilla_dom_workers_scriptloader_h__ #include "Workers.h" +#include "nsIContentPolicyBase.h" class nsIPrincipal; class nsIURI; @@ -37,6 +38,7 @@ ChannelFromScriptURLMainThread(nsIPrincipal* aPrincipal, nsIDocument* aParentDoc, nsILoadGroup* aLoadGroup, const nsAString& aScriptURL, + nsContentPolicyType aContentPolicyType, nsIChannel** aChannel); nsresult diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp index d00d685a28..46c6753d09 100644 --- a/dom/workers/ServiceWorkerManager.cpp +++ b/dom/workers/ServiceWorkerManager.cpp @@ -2581,6 +2581,7 @@ ServiceWorkerManager::CreateServiceWorkerForWindow(nsPIDOMWindow* aWindow, NS_ConvertUTF8toUTF16(aInfo->ScriptSpec()), false, WorkerPrivate::OverrideLoadGroup, + WorkerTypeService, &loadInfo); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; diff --git a/dom/workers/ServiceWorkerScriptCache.cpp b/dom/workers/ServiceWorkerScriptCache.cpp index 897752cc06..86a3565f04 100644 --- a/dom/workers/ServiceWorkerScriptCache.cpp +++ b/dom/workers/ServiceWorkerScriptCache.cpp @@ -91,10 +91,13 @@ public: return rv; } + // Note that because there is no "serviceworker" RequestContext type, we can + // use the external TYPE_SCRIPT content policy types when loading a service + // worker. rv = NS_NewChannel(getter_AddRefs(mChannel), uri, aPrincipal, nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_SCRIPT, // FIXME(nsm): TYPE_SERVICEWORKER + nsIContentPolicy::TYPE_SCRIPT, loadGroup); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 0ae77ab013..f9eca2d76c 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -4799,7 +4799,7 @@ WorkerPrivate::Constructor(JSContext* aCx, nsresult rv = GetLoadInfo(aCx, nullptr, parent, aScriptURL, aIsChromeWorker, InheritLoadGroup, - stackLoadInfo.ptr()); + aWorkerType, stackLoadInfo.ptr()); if (NS_FAILED(rv)) { scriptloader::ReportLoadError(aCx, aScriptURL, rv, !parent); aRv.Throw(rv); @@ -4857,6 +4857,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow, WorkerPrivate* aParent, const nsAString& aScriptURL, bool aIsChromeWorker, LoadGroupBehavior aLoadGroupBehavior, + WorkerType aWorkerType, WorkerLoadInfo* aLoadInfo) { using namespace mozilla::dom::workers::scriptloader; @@ -5099,6 +5100,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow, rv = ChannelFromScriptURLMainThread(loadInfo.mPrincipal, loadInfo.mBaseURI, document, loadInfo.mLoadGroup, aScriptURL, + ContentPolicyType(aWorkerType), getter_AddRefs(loadInfo.mChannel)); NS_ENSURE_SUCCESS(rv, rv); diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index 23410989a4..7e5114fd07 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -9,6 +9,7 @@ #include "Workers.h" +#include "nsIContentPolicy.h" #include "nsIContentSecurityPolicy.h" #include "nsILoadGroup.h" #include "nsIWorkerDebugger.h" @@ -726,6 +727,28 @@ public: return mWorkerType == WorkerTypeService; } + nsContentPolicyType + ContentPolicyType() const + { + return ContentPolicyType(mWorkerType); + } + + static nsContentPolicyType + ContentPolicyType(WorkerType aWorkerType) + { + switch (aWorkerType) { + case WorkerTypeDedicated: + return nsIContentPolicy::TYPE_INTERNAL_WORKER; + case WorkerTypeShared: + return nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER; + case WorkerTypeService: + return nsIContentPolicy::TYPE_SCRIPT; + default: + MOZ_ASSERT_UNREACHABLE("Invalid worker type"); + return nsIContentPolicy::TYPE_INVALID; + } + } + const nsCString& SharedWorkerName() const { @@ -961,7 +984,8 @@ public: static nsresult GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow, WorkerPrivate* aParent, const nsAString& aScriptURL, bool aIsChromeWorker, - LoadGroupBehavior aLoadGroupBehavior, WorkerLoadInfo* aLoadInfo); + LoadGroupBehavior aLoadGroupBehavior, WorkerType aWorkerType, + WorkerLoadInfo* aLoadInfo); static void OverrideLoadInfoLoadGroup(WorkerLoadInfo& aLoadInfo); diff --git a/dom/workers/test/serviceworkers/fetch/context/context_test.js b/dom/workers/test/serviceworkers/fetch/context/context_test.js index 24b0002a96..6270603f5f 100644 --- a/dom/workers/test/serviceworkers/fetch/context/context_test.js +++ b/dom/workers/test/serviceworkers/fetch/context/context_test.js @@ -24,8 +24,7 @@ self.addEventListener("fetch", function(event) { event.respondWith(fetch("realaudio.ogg")); } } else if (event.request.url.indexOf("video.ogg") >= 0) { - // FIXME: Bug 1147668: This should be "video". - if (event.request.context == "audio") { + if (event.request.context == "video") { event.respondWith(fetch("realaudio.ogg")); } } else if (event.request.url.indexOf("beacon.sjs") >= 0) { @@ -71,6 +70,22 @@ self.addEventListener("fetch", function(event) { } } else if (event.request.url.indexOf("xslt") >= 0) { respondToServiceWorker(event, "xslt"); + } else if (event.request.url.indexOf("myworker") >= 0) { + if (event.request.context == "worker") { + event.respondWith(fetch("worker.js")); + } + } else if (event.request.url.indexOf("myparentworker") >= 0) { + if (event.request.context == "worker") { + event.respondWith(fetch("parentworker.js")); + } + } else if (event.request.url.indexOf("mysharedworker") >= 0) { + if (event.request.context == "sharedworker") { + event.respondWith(fetch("sharedworker.js")); + } + } else if (event.request.url.indexOf("myparentsharedworker") >= 0) { + if (event.request.context == "sharedworker") { + event.respondWith(fetch("parentsharedworker.js")); + } } else if (event.request.url.indexOf("cache") >= 0) { var cache; var origContext = event.request.context; diff --git a/dom/workers/test/serviceworkers/fetch/context/index.html b/dom/workers/test/serviceworkers/fetch/context/index.html index b78569317b..72748787d4 100644 --- a/dom/workers/test/serviceworkers/fetch/context/index.html +++ b/dom/workers/test/serviceworkers/fetch/context/index.html @@ -301,8 +301,7 @@ document.documentElement.appendChild(video); navigator.serviceWorker.addEventListener("message", function onMessage(e) { if (e.data.data == "track") { - // FIXME: Bug 1147668: This should be "track". - is(e.data.context, "audio", "Expected the audio context on a request coming from a track"); + is(e.data.context, "track", "Expected the track context on a request coming from a track"); navigator.serviceWorker.removeEventListener("message", onMessage); resolve(); } @@ -338,11 +337,59 @@ }); } + function testWorker() { + return new Promise(function(resolve, reject) { + var worker = new Worker("myworker"); + worker.onmessage = function(e) { + if (e.data == "ack") { + worker.terminate(); + resolve(); + } + }; + worker.onerror = reject; + }); + } + + function testNestedWorker() { + return new Promise(function(resolve, reject) { + var worker = new Worker("myparentworker"); + worker.onmessage = function(e) { + if (e.data == "ack") { + worker.terminate(); + resolve(); + } + }; + worker.onerror = reject; + }); + } + + function testSharedWorker() { + return new Promise(function(resolve, reject) { + var worker = new SharedWorker("mysharedworker"); + worker.port.start(); + worker.port.onmessage = function(e) { + if (e.data == "ack") { + resolve(); + } + }; + worker.onerror = reject; + }); + } + + function testNestedWorkerInSharedWorker() { + return new Promise(function(resolve, reject) { + var worker = new SharedWorker("myparentsharedworker"); + worker.port.start(); + worker.port.onmessage = function(e) { + if (e.data == "ack") { + resolve(); + } + }; + worker.onerror = reject; + }); + } + function testCache() { - if (isAndroid) { - // FIXME: Re-enable this test on Android once bug 1148818 gets fixed. - return Promise.resolve(); - } return new Promise(function(resolve, reject) { // Issue an XHR that will be intercepted by the SW in order to start off // the test with a RequestContext value that is not the default ("fetch"). @@ -384,6 +431,10 @@ testTrack(), testXHR(), testXSLT(), + testWorker(), + testNestedWorker(), + testSharedWorker(), + testNestedWorkerInSharedWorker(), // Also, test to see if the type of the request can be persisted in the database. testCache(), diff --git a/dom/workers/test/serviceworkers/fetch/context/parentsharedworker.js b/dom/workers/test/serviceworkers/fetch/context/parentsharedworker.js new file mode 100644 index 0000000000..eac8d5e717 --- /dev/null +++ b/dom/workers/test/serviceworkers/fetch/context/parentsharedworker.js @@ -0,0 +1,8 @@ +onconnect = function(e) { + e.ports[0].start(); + var worker = new Worker("myworker?shared"); + worker.onmessage = function(e2) { + e.ports[0].postMessage(e2.data); + self.close(); + }; +}; diff --git a/dom/workers/test/serviceworkers/fetch/context/parentworker.js b/dom/workers/test/serviceworkers/fetch/context/parentworker.js new file mode 100644 index 0000000000..839fb6640b --- /dev/null +++ b/dom/workers/test/serviceworkers/fetch/context/parentworker.js @@ -0,0 +1,4 @@ +var worker = new Worker("myworker"); +worker.onmessage = function(e) { + postMessage(e.data); +}; diff --git a/dom/workers/test/serviceworkers/fetch/context/sharedworker.js b/dom/workers/test/serviceworkers/fetch/context/sharedworker.js new file mode 100644 index 0000000000..94dca58399 --- /dev/null +++ b/dom/workers/test/serviceworkers/fetch/context/sharedworker.js @@ -0,0 +1,5 @@ +onconnect = function(e) { + e.ports[0].start(); + e.ports[0].postMessage("ack"); + self.close(); +}; diff --git a/dom/workers/test/serviceworkers/fetch/context/worker.js b/dom/workers/test/serviceworkers/fetch/context/worker.js new file mode 100644 index 0000000000..e26e5bc691 --- /dev/null +++ b/dom/workers/test/serviceworkers/fetch/context/worker.js @@ -0,0 +1 @@ +postMessage("ack"); diff --git a/dom/workers/test/serviceworkers/mochitest.ini b/dom/workers/test/serviceworkers/mochitest.ini index b840b96bf5..74a759d5cd 100644 --- a/dom/workers/test/serviceworkers/mochitest.ini +++ b/dom/workers/test/serviceworkers/mochitest.ini @@ -37,6 +37,10 @@ support-files = fetch/context/beacon.sjs fetch/context/csp-violate.sjs fetch/context/ping.html + fetch/context/worker.js + fetch/context/parentworker.js + fetch/context/sharedworker.js + fetch/context/parentsharedworker.js fetch/context/xml.xml fetch/https/index.html fetch/https/register.html diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index 4f997443d9..5370cf9f63 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -1098,7 +1098,15 @@ class PersistentRooted : public js::PersistentRootedBase, void registerWithRootLists(js::RootLists& roots) { MOZ_ASSERT(!initialized()); - roots.getPersistentRootedList().insertBack(this); + js::ThingRootKind kind = js::RootKind::rootKind(); + roots.heapRoots_[kind].insertBack(reinterpret_cast*>(this)); + // Until marking and destruction support the full set, we assert that + // we don't try to add any unsupported types. + MOZ_ASSERT(kind == js::THING_ROOT_OBJECT || + kind == js::THING_ROOT_SCRIPT || + kind == js::THING_ROOT_STRING || + kind == js::THING_ROOT_ID || + kind == js::THING_ROOT_VALUE); } public: diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index fb1434d3f3..6a3c966af1 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -351,17 +351,16 @@ struct PersistentRootedMarker void js::gc::MarkPersistentRootedChainsInLists(RootLists& roots, JSTracer* trc) { - PersistentRootedMarker::markChain(trc, roots.functionPersistentRooteds, - "PersistentRooted"); - PersistentRootedMarker::markChain(trc, roots.objectPersistentRooteds, + PersistentRootedMarker::markChain(trc, roots.getPersistentRootedList(), "PersistentRooted"); - PersistentRootedMarker::markChain(trc, roots.scriptPersistentRooteds, + PersistentRootedMarker::markChain(trc, roots.getPersistentRootedList(), "PersistentRooted"); - PersistentRootedMarker::markChain(trc, roots.stringPersistentRooteds, + PersistentRootedMarker::markChain(trc, roots.getPersistentRootedList(), "PersistentRooted"); - PersistentRootedMarker::markChain(trc, roots.idPersistentRooteds, + + PersistentRootedMarker::markChain(trc, roots.getPersistentRootedList(), "PersistentRooted"); - PersistentRootedMarker::markChain(trc, roots.valuePersistentRooteds, + PersistentRootedMarker::markChain(trc, roots.getPersistentRootedList(), "PersistentRooted"); } diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 71a652cc40..cb600f6c62 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -1369,12 +1369,11 @@ FinishPersistentRootedChain(mozilla::LinkedList>& list) void js::gc::FinishPersistentRootedChains(RootLists& roots) { - FinishPersistentRootedChain(roots.functionPersistentRooteds); - FinishPersistentRootedChain(roots.idPersistentRooteds); - FinishPersistentRootedChain(roots.objectPersistentRooteds); - FinishPersistentRootedChain(roots.scriptPersistentRooteds); - FinishPersistentRootedChain(roots.stringPersistentRooteds); - FinishPersistentRootedChain(roots.valuePersistentRooteds); + FinishPersistentRootedChain(roots.getPersistentRootedList()); + FinishPersistentRootedChain(roots.getPersistentRootedList()); + FinishPersistentRootedChain(roots.getPersistentRootedList()); + FinishPersistentRootedChain(roots.getPersistentRootedList()); + FinishPersistentRootedChain(roots.getPersistentRootedList()); } void @@ -6108,7 +6107,7 @@ GCRuntime::collect(bool incremental, SliceBudget budget, JS::gcreason::Reason re JS_AbortIfWrongThread(rt); /* If we attempt to invoke the GC while we are running in the GC, assert. */ - MOZ_ALWAYS_TRUE(!rt->isHeapBusy()); + MOZ_RELEASE_ASSERT(!rt->isHeapBusy()); /* The engine never locks across anything that could GC. */ MOZ_ASSERT(!rt->currentThreadHasExclusiveAccess()); @@ -6235,7 +6234,7 @@ GCRuntime::abortGC() { JS_AbortIfWrongThread(rt); - MOZ_ALWAYS_TRUE(!rt->isHeapBusy()); + MOZ_RELEASE_ASSERT(!rt->isHeapBusy()); MOZ_ASSERT(!rt->currentThreadHasExclusiveAccess()); MOZ_ASSERT(!rt->mainThread.suppressGC); diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index 4b60eb057f..f36727c26a 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -349,12 +349,7 @@ class RootLists friend void js::gc::MarkPersistentRootedChainsInLists(RootLists&, JSTracer*); friend void js::gc::FinishPersistentRootedChains(RootLists&); - mozilla::LinkedList functionPersistentRooteds; - mozilla::LinkedList idPersistentRooteds; - mozilla::LinkedList objectPersistentRooteds; - mozilla::LinkedList scriptPersistentRooteds; - mozilla::LinkedList stringPersistentRooteds; - mozilla::LinkedList valuePersistentRooteds; + mozilla::LinkedList> heapRoots_[THING_ROOT_LIMIT]; /* Specializations of this return references to the appropriate list. */ template @@ -362,28 +357,46 @@ class RootLists }; template<> -inline mozilla::LinkedList -&RootLists::getPersistentRootedList() { return functionPersistentRooteds; } +inline mozilla::LinkedList& +RootLists::getPersistentRootedList() { + return reinterpret_cast>&>( + heapRoots_[THING_ROOT_OBJECT]); +} template<> -inline mozilla::LinkedList -&RootLists::getPersistentRootedList() { return idPersistentRooteds; } +inline mozilla::LinkedList& +RootLists::getPersistentRootedList() { + return reinterpret_cast>&>( + heapRoots_[THING_ROOT_OBJECT]); +} template<> -inline mozilla::LinkedList -&RootLists::getPersistentRootedList() { return objectPersistentRooteds; } +inline mozilla::LinkedList& +RootLists::getPersistentRootedList() { + return reinterpret_cast>&>( + heapRoots_[THING_ROOT_ID]); +} template<> -inline mozilla::LinkedList -&RootLists::getPersistentRootedList() { return scriptPersistentRooteds; } +inline mozilla::LinkedList& +RootLists::getPersistentRootedList() { + return reinterpret_cast>&>( + heapRoots_[THING_ROOT_SCRIPT]); +} template<> -inline mozilla::LinkedList -&RootLists::getPersistentRootedList() { return stringPersistentRooteds; } +inline mozilla::LinkedList& +RootLists::getPersistentRootedList() { + return reinterpret_cast>&>( + heapRoots_[THING_ROOT_STRING]); +} template<> -inline mozilla::LinkedList -&RootLists::getPersistentRootedList() { return valuePersistentRooteds; } +inline mozilla::LinkedList& +RootLists::getPersistentRootedList() { + return reinterpret_cast>&>( + heapRoots_[THING_ROOT_VALUE]); +} struct ContextFriendFields { diff --git a/layout/generic/nsFrameList.h b/layout/generic/nsFrameList.h index 596d651e60..7084b677da 100644 --- a/layout/generic/nsFrameList.h +++ b/layout/generic/nsFrameList.h @@ -451,11 +451,6 @@ public: class Iterator { public: - typedef nsIFrame* const ValueType; - // Though we don't support +/- a integer currently, - // iterators have to have a DifferenceType. - typedef ptrdiff_t DifferenceType; - Iterator(const nsFrameList& aList, nsIFrame* aCurrent) : mList(aList) , mCurrent(aCurrent) @@ -466,7 +461,7 @@ public: , mCurrent(aOther.mCurrent) {} - ValueType& operator*() const { return mCurrent; } + nsIFrame* operator*() const { return mCurrent; } // The operators need to know about nsIFrame, hence the // implementations are in nsIFrame.h diff --git a/mfbt/AlreadyAddRefed.h b/mfbt/AlreadyAddRefed.h index 099a3d51fe..faf1f4c3d6 100644 --- a/mfbt/AlreadyAddRefed.h +++ b/mfbt/AlreadyAddRefed.h @@ -96,7 +96,7 @@ struct MOZ_MUST_USE already_AddRefed * Note that nsRefPtr is the XPCOM reference counting smart pointer class. */ template - already_AddRefed(already_AddRefed&& aOther) : mRawPtr(aOther.take()) {} + MOZ_IMPLICIT already_AddRefed(already_AddRefed&& aOther) : mRawPtr(aOther.take()) {} ~already_AddRefed() { MOZ_ASSERT(!mRawPtr); } diff --git a/mfbt/CheckedInt.h b/mfbt/CheckedInt.h index 8e1be4b4b3..02ef8d5b7e 100644 --- a/mfbt/CheckedInt.h +++ b/mfbt/CheckedInt.h @@ -526,7 +526,7 @@ public: * argument is valid. */ template - CheckedInt(U aValue) MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT + MOZ_IMPLICIT CheckedInt(U aValue) MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT : mValue(T(aValue)), mIsValid(detail::IsInRange(aValue)) { diff --git a/mfbt/EnumeratedRange.h b/mfbt/EnumeratedRange.h index b9e514508f..2fd0f881f1 100644 --- a/mfbt/EnumeratedRange.h +++ b/mfbt/EnumeratedRange.h @@ -20,8 +20,8 @@ #ifndef mozilla_EnumeratedRange_h #define mozilla_EnumeratedRange_h -#include "mozilla/IntegerRange.h" #include "mozilla/IntegerTypeTraits.h" +#include "mozilla/ReverseIterator.h" namespace mozilla { @@ -31,20 +31,15 @@ template class EnumeratedIterator { public: - typedef const EnumTypeT ValueType; - typedef typename MakeSigned::Type DifferenceType; - template explicit EnumeratedIterator(EnumType aCurrent) : mCurrent(aCurrent) { } template - EnumeratedIterator(const EnumeratedIterator& aOther) + explicit EnumeratedIterator(const EnumeratedIterator& aOther) : mCurrent(aOther.mCurrent) { } - // Since operator* is required to return a reference, we return - // a reference to our member here. - const EnumTypeT& operator*() const { return mCurrent; } + EnumTypeT operator*() const { return mCurrent; } /* Increment and decrement operators */ @@ -71,25 +66,6 @@ public: return ret; } - EnumeratedIterator operator+(DifferenceType aN) const - { - return EnumeratedIterator(EnumTypeT(IntTypeT(mCurrent) + aN)); - } - EnumeratedIterator operator-(DifferenceType aN) const - { - return EnumeratedIterator(EnumTypeT(IntTypeT(mCurrent) - aN)); - } - EnumeratedIterator& operator+=(DifferenceType aN) - { - mCurrent = EnumTypeT(IntTypeT(mCurrent) + aN); - return *this; - } - EnumeratedIterator& operator-=(DifferenceType aN) - { - mCurrent = EnumTypeT(IntTypeT(mCurrent) - aN); - return *this; - } - /* Comparison operators */ template diff --git a/mfbt/IntegerRange.h b/mfbt/IntegerRange.h index 82c6986d0f..8d5d2e4d66 100644 --- a/mfbt/IntegerRange.h +++ b/mfbt/IntegerRange.h @@ -21,20 +21,15 @@ template class IntegerIterator { public: - typedef const IntTypeT ValueType; - typedef typename MakeSigned::Type DifferenceType; - template explicit IntegerIterator(IntType aCurrent) : mCurrent(aCurrent) { } template - IntegerIterator(const IntegerIterator& aOther) + explicit IntegerIterator(const IntegerIterator& aOther) : mCurrent(aOther.mCurrent) { } - // Since operator* is required to return a reference, we return - // a reference to our member here. - const IntTypeT& operator*() const { return mCurrent; } + IntTypeT operator*() const { return mCurrent; } /* Increment and decrement operators */ @@ -43,25 +38,6 @@ public: IntegerIterator operator++(int) { auto ret = *this; ++mCurrent; return ret; } IntegerIterator operator--(int) { auto ret = *this; --mCurrent; return ret; } - IntegerIterator operator+(DifferenceType aN) const - { - return IntegerIterator(mCurrent + aN); - } - IntegerIterator operator-(DifferenceType aN) const - { - return IntegerIterator(mCurrent - aN); - } - IntegerIterator& operator+=(DifferenceType aN) - { - mCurrent += aN; - return *this; - } - IntegerIterator& operator-=(DifferenceType aN) - { - mCurrent -= aN; - return *this; - } - /* Comparison operators */ template @@ -182,6 +158,7 @@ template detail::IntegerRange MakeRange(IntType aEnd) { + static_assert(IsIntegral::value, "value must be integral"); MOZ_ASSERT(detail::GeqZero::check(aEnd), "Should never have negative value here"); return detail::IntegerRange(aEnd); @@ -191,6 +168,8 @@ template detail::IntegerRange MakeRange(IntType1 aBegin, IntType2 aEnd) { + static_assert(IsIntegral::value && IsIntegral::value, + "values must both be integral"); static_assert(IsSigned::value == IsSigned::value, "signed/unsigned mismatch"); MOZ_ASSERT(aEnd >= aBegin, "End value should be larger than begin value"); diff --git a/mfbt/IteratorTraits.h b/mfbt/IteratorTraits.h deleted file mode 100644 index e7ee622dfa..0000000000 --- a/mfbt/IteratorTraits.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Iterator traits to expose a value type and a difference type */ - -#ifndef mozilla_IteratorTraits_h -#define mozilla_IteratorTraits_h - -#include - -namespace mozilla { - -template -struct IteratorTraits -{ - typedef typename Iterator::ValueType ValueType; - typedef typename Iterator::DifferenceType DifferenceType; -}; - -template -struct IteratorTraits -{ - typedef T ValueType; - typedef ptrdiff_t DifferenceType; -}; - -template -struct IteratorTraits -{ - typedef const T ValueType; - typedef ptrdiff_t DifferenceType; -}; - -} // namespace mozilla - -#endif // mozilla_IteratorTraits_h diff --git a/mfbt/RangedPtr.h b/mfbt/RangedPtr.h index fb40d4d9bd..40710415a9 100644 --- a/mfbt/RangedPtr.h +++ b/mfbt/RangedPtr.h @@ -104,7 +104,7 @@ public: /* Equivalent to RangedPtr(aArr, aArr, N). */ template - RangedPtr(T (&aArr)[N]) + explicit RangedPtr(T (&aArr)[N]) : mPtr(aArr) #ifdef DEBUG , mRangeStart(aArr), mRangeEnd(aArr + N) diff --git a/mfbt/ReentrancyGuard.h b/mfbt/ReentrancyGuard.h index 4093a81840..d5142073c1 100644 --- a/mfbt/ReentrancyGuard.h +++ b/mfbt/ReentrancyGuard.h @@ -26,12 +26,12 @@ class ReentrancyGuard public: template #ifdef DEBUG - ReentrancyGuard(T& aObj - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + explicit ReentrancyGuard(T& aObj + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : mEntered(aObj.mEntered) #else - ReentrancyGuard(T& - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + explicit ReentrancyGuard(T& + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) #endif { MOZ_GUARD_OBJECT_NOTIFIER_INIT; diff --git a/mfbt/RefPtr.h b/mfbt/RefPtr.h index 1387e8be7a..f7f54c8b88 100644 --- a/mfbt/RefPtr.h +++ b/mfbt/RefPtr.h @@ -60,7 +60,7 @@ public: MOZ_IMPLICIT RefPtr(T* aVal) : mPtr(ref(aVal)) {} template - RefPtr(const RefPtr& aOther) : mPtr(ref(aOther.get())) {} + MOZ_IMPLICIT RefPtr(const RefPtr& aOther) : mPtr(ref(aOther.get())) {} ~RefPtr() { unref(mPtr); } diff --git a/mfbt/ReverseIterator.h b/mfbt/ReverseIterator.h index e9b2d9b8a0..49c2e27920 100644 --- a/mfbt/ReverseIterator.h +++ b/mfbt/ReverseIterator.h @@ -12,7 +12,7 @@ #define mozilla_ReverseIterator_h #include "mozilla/Attributes.h" -#include "mozilla/IteratorTraits.h" +#include "mozilla/TypeTraits.h" namespace mozilla { @@ -20,9 +20,6 @@ template class ReverseIterator { public: - typedef typename IteratorTraits::ValueType ValueType; - typedef typename IteratorTraits::DifferenceType DifferenceType; - template explicit ReverseIterator(Iterator aIter) : mCurrent(aIter) { } @@ -31,7 +28,7 @@ public: MOZ_IMPLICIT ReverseIterator(const ReverseIterator& aOther) : mCurrent(aOther.mCurrent) { } - ValueType& operator*() const + decltype(*DeclVal()) operator*() const { IteratorT tmp = mCurrent; return *--tmp; @@ -44,25 +41,6 @@ public: ReverseIterator operator++(int) { auto ret = *this; mCurrent--; return ret; } ReverseIterator operator--(int) { auto ret = *this; mCurrent++; return ret; } - ReverseIterator operator+(DifferenceType aN) const - { - return ReverseIterator(mCurrent - aN); - } - ReverseIterator operator-(DifferenceType aN) const - { - return ReverseIterator(mCurrent + aN); - } - ReverseIterator& operator+=(DifferenceType aN) - { - mCurrent -= aN; - return *this; - } - ReverseIterator& operator-=(DifferenceType aN) - { - mCurrent += aN; - return *this; - } - /* Comparison operators */ template @@ -148,11 +126,11 @@ public: typedef ReverseIterator const_reverse_iterator; template - IteratorRange(Iterator1 aIterBegin, Iterator2 aIterEnd) + MOZ_IMPLICIT IteratorRange(Iterator1 aIterBegin, Iterator2 aIterEnd) : mIterBegin(aIterBegin), mIterEnd(aIterEnd) { } template - IteratorRange(const IteratorRange& aOther) + MOZ_IMPLICIT IteratorRange(const IteratorRange& aOther) : mIterBegin(aOther.mIterBegin), mIterEnd(aOther.mIterEnd) { } iterator begin() const { return mIterBegin; } diff --git a/mfbt/UniquePtr.h b/mfbt/UniquePtr.h index 91c3a17bf7..a290ece951 100644 --- a/mfbt/UniquePtr.h +++ b/mfbt/UniquePtr.h @@ -238,6 +238,7 @@ public: } template + MOZ_IMPLICIT UniquePtr(UniquePtr&& aOther, typename EnableIf::Pointer, Pointer>::value && @@ -478,9 +479,9 @@ public: MOZ_CONSTEXPR DefaultDelete() {} template - DefaultDelete(const DefaultDelete& aOther, - typename EnableIf::value, - int>::Type aDummy = 0) + MOZ_IMPLICIT DefaultDelete(const DefaultDelete& aOther, + typename EnableIf::value, + int>::Type aDummy = 0) {} void operator()(T* aPtr) const diff --git a/mfbt/moz.build b/mfbt/moz.build index 4bf2b5f9d5..51e1ee94f5 100644 --- a/mfbt/moz.build +++ b/mfbt/moz.build @@ -48,7 +48,6 @@ EXPORTS.mozilla = [ 'IntegerPrintfMacros.h', 'IntegerRange.h', 'IntegerTypeTraits.h', - 'IteratorTraits.h', 'JSONWriter.h', 'Likely.h', 'LinkedList.h', diff --git a/mfbt/tests/TestIntegerRange.cpp b/mfbt/tests/TestIntegerRange.cpp new file mode 100644 index 0000000000..c2691a26c0 --- /dev/null +++ b/mfbt/tests/TestIntegerRange.cpp @@ -0,0 +1,163 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/Assertions.h" +#include "mozilla/IntegerRange.h" + +#include + +using mozilla::IsSame; +using mozilla::MakeRange; +using mozilla::Reversed; + +const size_t kMaxNumber = 50; +const size_t kArraySize = 256; + +template +static IntType +GenerateNumber() +{ + return static_cast(rand() % kMaxNumber + 1); +} + +template +static void +TestSingleParamRange(const IntType aN) +{ + IntType array[kArraySize]; + IntType* ptr = array; + for (auto i : MakeRange(aN)) { + static_assert(IsSame::value, + "type of the loop var and the param should be the same"); + *ptr++ = i; + } + + MOZ_RELEASE_ASSERT(ptr - array == static_cast(aN), + "Should iterates N items"); + for (size_t i = 0; i < static_cast(aN); i++) { + MOZ_RELEASE_ASSERT(array[i] == static_cast(i), + "Values should equal to the index"); + } +} + +template +static void +TestSingleParamReverseRange(const IntType aN) +{ + IntType array[kArraySize]; + IntType* ptr = array; + for (auto i : Reversed(MakeRange(aN))) { + static_assert(IsSame::value, + "type of the loop var and the param should be the same"); + *ptr++ = i; + } + + MOZ_RELEASE_ASSERT(ptr - array == static_cast(aN), + "Should iterates N items"); + for (size_t i = 0; i < static_cast(aN); i++) { + MOZ_RELEASE_ASSERT(array[i] == static_cast(aN - i - 1), + "Values should be the reverse of their index"); + } +} + +template +static void +TestSingleParamIntegerRange() +{ + const auto kN = GenerateNumber(); + TestSingleParamRange(0); + TestSingleParamReverseRange(0); + TestSingleParamRange(kN); + TestSingleParamReverseRange(kN); +} + +template +static void +TestDoubleParamRange(const IntType1 aBegin, const IntType2 aEnd) +{ + IntType2 array[kArraySize]; + IntType2* ptr = array; + for (auto i : MakeRange(aBegin, aEnd)) { + static_assert(IsSame::value, "type of the loop var " + "should be same as that of the second param"); + *ptr++ = i; + } + + MOZ_RELEASE_ASSERT(ptr - array == static_cast(aEnd - aBegin), + "Should iterates (aEnd - aBegin) times"); + for (size_t i = 0; i < static_cast(aEnd - aBegin); i++) { + MOZ_RELEASE_ASSERT(array[i] == static_cast(aBegin + i), + "Should iterate integers in [aBegin, aEnd) in order"); + } +} + +template +static void +TestDoubleParamReverseRange(const IntType1 aBegin, const IntType2 aEnd) +{ + IntType2 array[kArraySize]; + IntType2* ptr = array; + for (auto i : Reversed(MakeRange(aBegin, aEnd))) { + static_assert(IsSame::value, "type of the loop var " + "should be same as that of the second param"); + *ptr++ = i; + } + + MOZ_RELEASE_ASSERT(ptr - array == static_cast(aEnd - aBegin), + "Should iterates (aEnd - aBegin) times"); + for (size_t i = 0; i < static_cast(aEnd - aBegin); i++) { + MOZ_RELEASE_ASSERT(array[i] == static_cast(aEnd - i - 1), + "Should iterate integers in [aBegin, aEnd) in reverse order"); + } +} + +template +static void +TestDoubleParamIntegerRange() +{ + const auto kStart = GenerateNumber(); + const auto kEnd = static_cast(kStart + GenerateNumber()); + TestDoubleParamRange(kStart, static_cast(kStart)); + TestDoubleParamReverseRange(kStart, static_cast(kStart)); + TestDoubleParamRange(kStart, kEnd); + TestDoubleParamReverseRange(kStart, kEnd); +} + +int +main() +{ + TestSingleParamIntegerRange(); + TestSingleParamIntegerRange(); + TestSingleParamIntegerRange(); + TestSingleParamIntegerRange(); + + TestSingleParamIntegerRange(); + TestSingleParamIntegerRange(); + TestSingleParamIntegerRange(); + TestSingleParamIntegerRange(); + + TestDoubleParamIntegerRange(); + TestDoubleParamIntegerRange(); + TestDoubleParamIntegerRange(); + TestDoubleParamIntegerRange(); + + TestDoubleParamIntegerRange(); + TestDoubleParamIntegerRange(); + TestDoubleParamIntegerRange(); + TestDoubleParamIntegerRange(); + + TestDoubleParamIntegerRange(); + TestDoubleParamIntegerRange(); + TestDoubleParamIntegerRange(); + TestDoubleParamIntegerRange(); + + TestDoubleParamIntegerRange(); + TestDoubleParamIntegerRange(); + TestDoubleParamIntegerRange(); + TestDoubleParamIntegerRange(); + + return 0; +} diff --git a/mfbt/tests/moz.build b/mfbt/tests/moz.build index ddf5e57ab3..6a8b75a1fb 100644 --- a/mfbt/tests/moz.build +++ b/mfbt/tests/moz.build @@ -20,6 +20,7 @@ CppUnitTests([ 'TestFunction', 'TestInitializerList', 'TestIntegerPrintfMacros', + 'TestIntegerRange', 'TestJSONWriter', 'TestMacroArgs', 'TestMacroForEach', diff --git a/testing/cppunittest.ini b/testing/cppunittest.ini index 4573100414..b599aa21d6 100644 --- a/testing/cppunittest.ini +++ b/testing/cppunittest.ini @@ -42,6 +42,7 @@ run-if = os == 'win' [TestID] [TestInitializerList] [TestIntegerPrintfMacros] +[TestIntegerRange] [TestJSONWriter] [TestJemalloc] [TestLineBreak]