Bug 1851372 [wpt PR 41785] - HTML: search setter always uses UTF-8, a=testonly
[gecko.git] / js / loader / LoadedScript.cpp
blobdfdda337b9c09b30436f5c6edfe422b75e5225dd
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/. */
7 #include "LoadedScript.h"
9 #include "mozilla/HoldDropJSObjects.h"
11 #include "jsfriendapi.h"
12 #include "js/Modules.h" // JS::{Get,Set}ModulePrivate
14 namespace JS::loader {
16 //////////////////////////////////////////////////////////////
17 // LoadedScript
18 //////////////////////////////////////////////////////////////
20 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(LoadedScript)
21 NS_INTERFACE_MAP_ENTRY(nsISupports)
22 NS_INTERFACE_MAP_END
24 NS_IMPL_CYCLE_COLLECTION_CLASS(LoadedScript)
26 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(LoadedScript)
27 NS_IMPL_CYCLE_COLLECTION_UNLINK(mFetchOptions)
28 NS_IMPL_CYCLE_COLLECTION_UNLINK(mBaseURL)
29 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
31 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(LoadedScript)
32 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFetchOptions)
33 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
35 NS_IMPL_CYCLE_COLLECTING_ADDREF(LoadedScript)
36 NS_IMPL_CYCLE_COLLECTING_RELEASE(LoadedScript)
38 LoadedScript::LoadedScript(ScriptKind aKind, ScriptFetchOptions* aFetchOptions,
39 nsIURI* aBaseURL)
40 : mKind(aKind), mFetchOptions(aFetchOptions), mBaseURL(aBaseURL) {
41 MOZ_ASSERT(mFetchOptions);
42 MOZ_ASSERT(mBaseURL);
45 LoadedScript::~LoadedScript() { mozilla::DropJSObjects(this); }
47 void LoadedScript::AssociateWithScript(JSScript* aScript) {
48 // Set a JSScript's private value to point to this object. The JS engine will
49 // increment our reference count by calling HostAddRefTopLevelScript(). This
50 // is decremented by HostReleaseTopLevelScript() below when the JSScript dies.
52 MOZ_ASSERT(JS::GetScriptPrivate(aScript).isUndefined());
53 JS::SetScriptPrivate(aScript, JS::PrivateValue(this));
56 inline void CheckModuleScriptPrivate(LoadedScript* script,
57 const JS::Value& aPrivate) {
58 #ifdef DEBUG
59 if (script->IsModuleScript()) {
60 JSObject* module = script->AsModuleScript()->mModuleRecord.unbarrieredGet();
61 MOZ_ASSERT_IF(module, JS::GetModulePrivate(module) == aPrivate);
63 #endif
66 void HostAddRefTopLevelScript(const JS::Value& aPrivate) {
67 // Increment the reference count of a LoadedScript object that is now pointed
68 // to by a JSScript. The reference count is decremented by
69 // HostReleaseTopLevelScript() below.
71 auto script = static_cast<LoadedScript*>(aPrivate.toPrivate());
72 CheckModuleScriptPrivate(script, aPrivate);
73 script->AddRef();
76 void HostReleaseTopLevelScript(const JS::Value& aPrivate) {
77 // Decrement the reference count of a LoadedScript object that was pointed to
78 // by a JSScript. The reference count was originally incremented by
79 // HostAddRefTopLevelScript() above.
81 auto script = static_cast<LoadedScript*>(aPrivate.toPrivate());
82 CheckModuleScriptPrivate(script, aPrivate);
83 script->Release();
86 //////////////////////////////////////////////////////////////
87 // EventScript
88 //////////////////////////////////////////////////////////////
90 EventScript::EventScript(ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL)
91 : LoadedScript(ScriptKind::eEvent, aFetchOptions, aBaseURL) {}
93 //////////////////////////////////////////////////////////////
94 // ClassicScript
95 //////////////////////////////////////////////////////////////
97 ClassicScript::ClassicScript(ScriptFetchOptions* aFetchOptions,
98 nsIURI* aBaseURL)
99 : LoadedScript(ScriptKind::eClassic, aFetchOptions, aBaseURL) {}
101 //////////////////////////////////////////////////////////////
102 // ModuleScript
103 //////////////////////////////////////////////////////////////
105 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(ModuleScript, LoadedScript)
107 NS_IMPL_CYCLE_COLLECTION_CLASS(ModuleScript)
109 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ModuleScript, LoadedScript)
110 tmp->UnlinkModuleRecord();
111 tmp->mParseError.setUndefined();
112 tmp->mErrorToRethrow.setUndefined();
113 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
115 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ModuleScript, LoadedScript)
116 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
118 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ModuleScript, LoadedScript)
119 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mModuleRecord)
120 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mParseError)
121 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mErrorToRethrow)
122 NS_IMPL_CYCLE_COLLECTION_TRACE_END
124 ModuleScript::ModuleScript(ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL)
125 : LoadedScript(ScriptKind::eModule, aFetchOptions, aBaseURL),
126 mDebuggerDataInitialized(false) {
127 MOZ_ASSERT(!ModuleRecord());
128 MOZ_ASSERT(!HasParseError());
129 MOZ_ASSERT(!HasErrorToRethrow());
132 void ModuleScript::Shutdown() {
133 if (mModuleRecord) {
134 JS::ClearModuleEnvironment(mModuleRecord);
137 UnlinkModuleRecord();
140 void ModuleScript::UnlinkModuleRecord() {
141 // Remove the module record's pointer to this object if present and decrement
142 // our reference count. The reference is added by SetModuleRecord() below.
144 // This takes care not to trigger gray unmarking because this takes a lot of
145 // time when we're tearing down the entire page. This is safe because we are
146 // only writing undefined into the module private, so it won't create any
147 // black-gray edges.
148 if (mModuleRecord) {
149 JSObject* module = mModuleRecord.unbarrieredGet();
150 MOZ_ASSERT(JS::GetModulePrivate(module).toPrivate() == this);
151 JS::ClearModulePrivate(module);
152 mModuleRecord = nullptr;
156 ModuleScript::~ModuleScript() {
157 // The object may be destroyed without being unlinked first.
158 UnlinkModuleRecord();
161 void ModuleScript::SetModuleRecord(JS::Handle<JSObject*> aModuleRecord) {
162 MOZ_ASSERT(!mModuleRecord);
163 MOZ_ASSERT_IF(IsModuleScript(), !AsModuleScript()->HasParseError());
164 MOZ_ASSERT_IF(IsModuleScript(), !AsModuleScript()->HasErrorToRethrow());
166 mModuleRecord = aModuleRecord;
168 // Make module's host defined field point to this object. The JS engine will
169 // increment our reference count by calling HostAddRefTopLevelScript(). This
170 // is decremented when the field is cleared in UnlinkModuleRecord() above or
171 // when the module record dies.
172 MOZ_ASSERT(JS::GetModulePrivate(mModuleRecord).isUndefined());
173 JS::SetModulePrivate(mModuleRecord, JS::PrivateValue(this));
175 mozilla::HoldJSObjects(this);
178 void ModuleScript::SetParseError(const JS::Value& aError) {
179 MOZ_ASSERT(!aError.isUndefined());
180 MOZ_ASSERT(!HasParseError());
181 MOZ_ASSERT(!HasErrorToRethrow());
183 UnlinkModuleRecord();
184 mParseError = aError;
185 mozilla::HoldJSObjects(this);
188 void ModuleScript::SetErrorToRethrow(const JS::Value& aError) {
189 MOZ_ASSERT(!aError.isUndefined());
191 // This is only called after SetModuleRecord() or SetParseError() so we don't
192 // need to call HoldJSObjects() here.
193 MOZ_ASSERT(ModuleRecord() || HasParseError());
195 mErrorToRethrow = aError;
198 void ModuleScript::SetDebuggerDataInitialized() {
199 MOZ_ASSERT(ModuleRecord());
200 MOZ_ASSERT(!mDebuggerDataInitialized);
202 mDebuggerDataInitialized = true;
205 } // namespace JS::loader