Bug 1698238 return default dictionary from GetUserMediaRequest#getConstraints() if...
[gecko.git] / dom / base / nsJSUtils.cpp
blobfb8b8d6db80efb508c1febe5b62f339bbfba8d90
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 /**
8 * This is not a generated file. It contains common utility functions
9 * invoked from the JavaScript code generated from IDL interfaces.
10 * The goal of the utility functions is to cut down on the size of
11 * the generated code itself.
14 #include "nsJSUtils.h"
16 #include <utility>
17 #include "MainThreadUtils.h"
18 #include "js/ComparisonOperators.h"
19 #include "js/CompilationAndEvaluation.h"
20 #include "js/CompileOptions.h"
21 #include "js/Date.h"
22 #include "js/GCVector.h"
23 #include "js/HeapAPI.h"
24 #include "js/Modules.h"
25 #include "js/RootingAPI.h"
26 #include "js/SourceText.h"
27 #include "js/TypeDecls.h"
28 #include "jsfriendapi.h"
29 #include "mozilla/CycleCollectedJSContext.h"
30 #include "mozilla/dom/BindingUtils.h"
31 #include "mozilla/dom/Element.h"
32 #include "mozilla/dom/ScriptSettings.h"
33 #include "mozilla/fallible.h"
34 #include "mozilla/ProfilerLabels.h"
35 #include "nsContentUtils.h"
36 #include "nsDebug.h"
37 #include "nsGlobalWindowInner.h"
38 #include "nsINode.h"
39 #include "nsString.h"
40 #include "nsTPromiseFlatString.h"
41 #include "nscore.h"
43 #if !defined(DEBUG) && !defined(MOZ_ENABLE_JS_DUMP)
44 # include "mozilla/StaticPrefs_browser.h"
45 #endif
47 using namespace mozilla;
48 using namespace mozilla::dom;
50 bool nsJSUtils::GetCallingLocation(JSContext* aContext, nsACString& aFilename,
51 uint32_t* aLineno, uint32_t* aColumn) {
52 JS::AutoFilename filename;
53 if (!JS::DescribeScriptedCaller(aContext, &filename, aLineno, aColumn)) {
54 return false;
57 return aFilename.Assign(filename.get(), fallible);
60 bool nsJSUtils::GetCallingLocation(JSContext* aContext, nsAString& aFilename,
61 uint32_t* aLineno, uint32_t* aColumn) {
62 JS::AutoFilename filename;
63 if (!JS::DescribeScriptedCaller(aContext, &filename, aLineno, aColumn)) {
64 return false;
67 return aFilename.Assign(NS_ConvertUTF8toUTF16(filename.get()), fallible);
70 uint64_t nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(JSContext* aContext) {
71 if (!aContext) return 0;
73 nsGlobalWindowInner* win = xpc::CurrentWindowOrNull(aContext);
74 return win ? win->WindowID() : 0;
77 nsresult nsJSUtils::CompileFunction(AutoJSAPI& jsapi,
78 JS::HandleVector<JSObject*> aScopeChain,
79 JS::CompileOptions& aOptions,
80 const nsACString& aName, uint32_t aArgCount,
81 const char** aArgArray,
82 const nsAString& aBody,
83 JSObject** aFunctionObject) {
84 JSContext* cx = jsapi.cx();
85 MOZ_ASSERT(js::GetContextRealm(cx));
86 MOZ_ASSERT_IF(aScopeChain.length() != 0,
87 js::IsObjectInContextCompartment(aScopeChain[0], cx));
89 // Do the junk Gecko is supposed to do before calling into JSAPI.
90 for (size_t i = 0; i < aScopeChain.length(); ++i) {
91 JS::ExposeObjectToActiveJS(aScopeChain[i]);
94 // Compile.
95 const nsPromiseFlatString& flatBody = PromiseFlatString(aBody);
97 JS::SourceText<char16_t> source;
98 if (!source.init(cx, flatBody.get(), flatBody.Length(),
99 JS::SourceOwnership::Borrowed)) {
100 return NS_ERROR_FAILURE;
103 JS::Rooted<JSFunction*> fun(
104 cx, JS::CompileFunction(cx, aScopeChain, aOptions,
105 PromiseFlatCString(aName).get(), aArgCount,
106 aArgArray, source));
107 if (!fun) {
108 return NS_ERROR_FAILURE;
111 *aFunctionObject = JS_GetFunctionObject(fun);
112 return NS_OK;
115 template <typename Unit>
116 static nsresult CompileJSModule(JSContext* aCx, JS::SourceText<Unit>& aSrcBuf,
117 JS::Handle<JSObject*> aEvaluationGlobal,
118 JS::CompileOptions& aCompileOptions,
119 JS::MutableHandle<JSObject*> aModule) {
120 AUTO_PROFILER_LABEL("nsJSUtils::CompileModule", JS);
121 MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
122 MOZ_ASSERT(aSrcBuf.get());
123 MOZ_ASSERT(JS_IsGlobalObject(aEvaluationGlobal));
124 MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx) == aEvaluationGlobal);
125 MOZ_ASSERT(NS_IsMainThread());
126 MOZ_ASSERT(CycleCollectedJSContext::Get() &&
127 CycleCollectedJSContext::Get()->MicroTaskLevel());
129 NS_ENSURE_TRUE(xpc::Scriptability::Get(aEvaluationGlobal).Allowed(), NS_OK);
131 JSObject* module = JS::CompileModule(aCx, aCompileOptions, aSrcBuf);
132 if (!module) {
133 return NS_ERROR_FAILURE;
136 aModule.set(module);
137 return NS_OK;
140 nsresult nsJSUtils::CompileModule(JSContext* aCx,
141 JS::SourceText<char16_t>& aSrcBuf,
142 JS::Handle<JSObject*> aEvaluationGlobal,
143 JS::CompileOptions& aCompileOptions,
144 JS::MutableHandle<JSObject*> aModule) {
145 return CompileJSModule(aCx, aSrcBuf, aEvaluationGlobal, aCompileOptions,
146 aModule);
149 nsresult nsJSUtils::CompileModule(JSContext* aCx,
150 JS::SourceText<Utf8Unit>& aSrcBuf,
151 JS::Handle<JSObject*> aEvaluationGlobal,
152 JS::CompileOptions& aCompileOptions,
153 JS::MutableHandle<JSObject*> aModule) {
154 return CompileJSModule(aCx, aSrcBuf, aEvaluationGlobal, aCompileOptions,
155 aModule);
158 nsresult nsJSUtils::ModuleInstantiate(JSContext* aCx,
159 JS::Handle<JSObject*> aModule) {
160 AUTO_PROFILER_LABEL("nsJSUtils::ModuleInstantiate", JS);
162 MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
163 MOZ_ASSERT(NS_IsMainThread());
164 MOZ_ASSERT(CycleCollectedJSContext::Get() &&
165 CycleCollectedJSContext::Get()->MicroTaskLevel());
167 NS_ENSURE_TRUE(xpc::Scriptability::Get(aModule).Allowed(), NS_OK);
169 if (!JS::ModuleInstantiate(aCx, aModule)) {
170 return NS_ERROR_FAILURE;
173 return NS_OK;
176 nsresult nsJSUtils::ModuleEvaluate(JSContext* aCx,
177 JS::Handle<JSObject*> aModule,
178 JS::MutableHandle<JS::Value> aResult) {
179 AUTO_PROFILER_LABEL("nsJSUtils::ModuleEvaluate", JS);
181 MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
182 MOZ_ASSERT(NS_IsMainThread());
183 MOZ_ASSERT(CycleCollectedJSContext::Get() &&
184 CycleCollectedJSContext::Get()->MicroTaskLevel());
186 NS_ENSURE_TRUE(xpc::Scriptability::Get(aModule).Allowed(), NS_OK);
188 if (!JS::ModuleEvaluate(aCx, aModule, aResult)) {
189 return NS_ERROR_FAILURE;
192 return NS_OK;
195 static bool AddScopeChainItem(JSContext* aCx, nsINode* aNode,
196 JS::MutableHandleVector<JSObject*> aScopeChain) {
197 JS::RootedValue val(aCx);
198 if (!GetOrCreateDOMReflector(aCx, aNode, &val)) {
199 return false;
202 if (!aScopeChain.append(&val.toObject())) {
203 return false;
206 return true;
209 /* static */
210 bool nsJSUtils::GetScopeChainForElement(
211 JSContext* aCx, Element* aElement,
212 JS::MutableHandleVector<JSObject*> aScopeChain) {
213 for (nsINode* cur = aElement; cur; cur = cur->GetScopeChainParent()) {
214 if (!AddScopeChainItem(aCx, cur, aScopeChain)) {
215 return false;
219 return true;
222 /* static */
223 void nsJSUtils::ResetTimeZone() { JS::ResetTimeZone(); }
225 /* static */
226 bool nsJSUtils::DumpEnabled() {
227 #if defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP)
228 return true;
229 #else
230 return StaticPrefs::browser_dom_window_dump_enabled();
231 #endif
235 // nsDOMJSUtils.h
238 template <typename T>
239 bool nsTAutoJSString<T>::init(const JS::Value& v) {
240 // Note: it's okay to use danger::GetJSContext here instead of AutoJSAPI,
241 // because the init() call below is careful not to run script (for instance,
242 // it only calls JS::ToString for non-object values).
243 JSContext* cx = danger::GetJSContext();
244 if (!init(cx, v)) {
245 JS_ClearPendingException(cx);
246 return false;
248 return true;
251 template bool nsTAutoJSString<char16_t>::init(const JS::Value&);
252 template bool nsTAutoJSString<char>::init(const JS::Value&);