WorkletGlobalScope.cpp (5173B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "WorkletGlobalScope.h" 8 9 #include "js/RealmOptions.h" 10 #include "mozilla/SchedulerGroup.h" 11 #include "mozilla/dom/Console.h" 12 #include "mozilla/dom/WorkletGlobalScopeBinding.h" 13 #include "mozilla/dom/WorkletImpl.h" 14 #include "mozilla/dom/WorkletThread.h" 15 #include "mozilla/dom/worklet/WorkletModuleLoader.h" 16 #include "nsContentUtils.h" 17 #include "nsJSUtils.h" 18 #include "nsRFPService.h" 19 #include "nsThreadUtils.h" 20 21 using JS::loader::ModuleLoaderBase; 22 using mozilla::dom::loader::WorkletModuleLoader; 23 24 namespace mozilla::dom { 25 26 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(WorkletGlobalScope) 27 28 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WorkletGlobalScope) 29 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER 30 NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsole) 31 NS_IMPL_CYCLE_COLLECTION_UNLINK(mModuleLoader) 32 tmp->UnlinkObjectsInGlobal(); 33 NS_IMPL_CYCLE_COLLECTION_UNLINK_END 34 35 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WorkletGlobalScope) 36 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole) 37 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mModuleLoader) 38 tmp->TraverseObjectsInGlobal(cb); 39 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 40 41 NS_IMPL_CYCLE_COLLECTING_ADDREF(WorkletGlobalScope) 42 NS_IMPL_CYCLE_COLLECTING_RELEASE(WorkletGlobalScope) 43 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WorkletGlobalScope) 44 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 45 NS_INTERFACE_MAP_ENTRY(nsIGlobalObject) 46 NS_INTERFACE_MAP_ENTRY(WorkletGlobalScope) 47 NS_INTERFACE_MAP_END 48 49 WorkletGlobalScope::WorkletGlobalScope(WorkletImpl* aImpl) 50 : mImpl(aImpl), mCreationTimeStamp(TimeStamp::Now()) {} 51 52 WorkletGlobalScope::~WorkletGlobalScope() = default; 53 54 JSObject* WorkletGlobalScope::WrapObject(JSContext* aCx, 55 JS::Handle<JSObject*> aGivenProto) { 56 MOZ_CRASH("We should never get here!"); 57 return nullptr; 58 } 59 60 nsISerialEventTarget* WorkletGlobalScope::SerialEventTarget() const { 61 WorkletThread::AssertIsOnWorkletThread(); 62 return NS_GetCurrentThread(); 63 } 64 65 nsresult WorkletGlobalScope::Dispatch( 66 already_AddRefed<nsIRunnable>&& aRunnable) const { 67 WorkletThread::AssertIsOnWorkletThread(); 68 return SerialEventTarget()->Dispatch(std::move(aRunnable)); 69 } 70 71 already_AddRefed<Console> WorkletGlobalScope::GetConsole(JSContext* aCx, 72 ErrorResult& aRv) { 73 if (!mConsole) { 74 MOZ_ASSERT(Impl()); 75 const WorkletLoadInfo& loadInfo = Impl()->LoadInfo(); 76 mConsole = Console::CreateForWorklet(aCx, this, loadInfo.OuterWindowID(), 77 loadInfo.InnerWindowID(), aRv); 78 if (NS_WARN_IF(aRv.Failed())) { 79 return nullptr; 80 } 81 } 82 83 RefPtr<Console> console = mConsole; 84 return console.forget(); 85 } 86 87 void WorkletGlobalScope::InitModuleLoader(WorkletModuleLoader* aModuleLoader) { 88 MOZ_ASSERT(!mModuleLoader); 89 mModuleLoader = aModuleLoader; 90 } 91 92 ModuleLoaderBase* WorkletGlobalScope::GetModuleLoader(JSContext* aCx) { 93 return mModuleLoader; 94 }; 95 96 OriginTrials WorkletGlobalScope::Trials() const { return mImpl->Trials(); } 97 98 Maybe<nsID> WorkletGlobalScope::GetAgentClusterId() const { 99 return mImpl->GetAgentClusterId(); 100 } 101 102 bool WorkletGlobalScope::IsSharedMemoryAllowed() const { 103 return mImpl->IsSharedMemoryAllowed(); 104 } 105 106 bool WorkletGlobalScope::ShouldResistFingerprinting(RFPTarget aTarget) const { 107 return mImpl->ShouldResistFingerprinting(aTarget); 108 } 109 110 void WorkletGlobalScope::Dump(const Optional<nsAString>& aString) const { 111 WorkletThread::AssertIsOnWorkletThread(); 112 113 if (!nsJSUtils::DumpEnabled()) { 114 return; 115 } 116 117 if (!aString.WasPassed()) { 118 return; 119 } 120 121 NS_ConvertUTF16toUTF8 str(aString.Value()); 122 123 MOZ_LOG(nsContentUtils::DOMDumpLog(), mozilla::LogLevel::Debug, 124 ("[Worklet.Dump] %s", str.get())); 125 #ifdef ANDROID 126 __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", str.get()); 127 #endif 128 fputs(str.get(), stdout); 129 fflush(stdout); 130 } 131 132 JS::RealmOptions WorkletGlobalScope::CreateRealmOptions() const { 133 JS::RealmOptions options; 134 135 if (ShouldResistFingerprinting(RFPTarget::JSDateTimeUTC)) { 136 nsCString timeZone = nsRFPService::GetSpoofedJSTimeZone(); 137 options.behaviors().setTimeZoneOverride(timeZone.get()); 138 } 139 options.creationOptions().setAlwaysUseFdlibm( 140 ShouldResistFingerprinting(RFPTarget::JSMathFdlibm)); 141 if (ShouldResistFingerprinting(RFPTarget::JSLocale)) { 142 nsCString locale = nsRFPService::GetSpoofedJSLocale(); 143 options.behaviors().setLocaleOverride(locale.get()); 144 } 145 146 // The SharedArrayBuffer global constructor property should not be present in 147 // a fresh global object when shared memory objects aren't allowed (because 148 // COOP/COEP support isn't enabled, or because COOP/COEP don't act to isolate 149 // this worklet to a separate process). 150 options.creationOptions().setDefineSharedArrayBufferConstructor( 151 IsSharedMemoryAllowed()); 152 153 return options; 154 } 155 156 } // namespace mozilla::dom