|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef nsJSUtils_h__ |
|
7 #define nsJSUtils_h__ |
|
8 |
|
9 /** |
|
10 * This is not a generated file. It contains common utility functions |
|
11 * invoked from the JavaScript code generated from IDL interfaces. |
|
12 * The goal of the utility functions is to cut down on the size of |
|
13 * the generated code itself. |
|
14 */ |
|
15 |
|
16 #include "mozilla/Assertions.h" |
|
17 |
|
18 #include "jsapi.h" |
|
19 #include "nsString.h" |
|
20 |
|
21 class nsIScriptContext; |
|
22 class nsIScriptGlobalObject; |
|
23 |
|
24 class nsJSUtils |
|
25 { |
|
26 public: |
|
27 static bool GetCallingLocation(JSContext* aContext, const char* *aFilename, |
|
28 uint32_t* aLineno); |
|
29 |
|
30 static nsIScriptGlobalObject *GetStaticScriptGlobal(JSObject* aObj); |
|
31 |
|
32 static nsIScriptContext *GetStaticScriptContext(JSObject* aObj); |
|
33 |
|
34 static nsIScriptGlobalObject *GetDynamicScriptGlobal(JSContext *aContext); |
|
35 |
|
36 static nsIScriptContext *GetDynamicScriptContext(JSContext *aContext); |
|
37 |
|
38 /** |
|
39 * Retrieve the inner window ID based on the given JSContext. |
|
40 * |
|
41 * @param JSContext aContext |
|
42 * The JSContext from which you want to find the inner window ID. |
|
43 * |
|
44 * @returns uint64_t the inner window ID. |
|
45 */ |
|
46 static uint64_t GetCurrentlyRunningCodeInnerWindowID(JSContext *aContext); |
|
47 |
|
48 /** |
|
49 * Report a pending exception on aContext, if any. Note that this |
|
50 * can be called when the context has a JS stack. If that's the |
|
51 * case, the stack will be set aside before reporting the exception. |
|
52 */ |
|
53 static void ReportPendingException(JSContext *aContext); |
|
54 |
|
55 static nsresult CompileFunction(JSContext* aCx, |
|
56 JS::Handle<JSObject*> aTarget, |
|
57 JS::CompileOptions& aOptions, |
|
58 const nsACString& aName, |
|
59 uint32_t aArgCount, |
|
60 const char** aArgArray, |
|
61 const nsAString& aBody, |
|
62 JSObject** aFunctionObject); |
|
63 |
|
64 struct EvaluateOptions { |
|
65 bool coerceToString; |
|
66 bool reportUncaught; |
|
67 bool needResult; |
|
68 |
|
69 explicit EvaluateOptions() : coerceToString(false) |
|
70 , reportUncaught(true) |
|
71 , needResult(true) |
|
72 {} |
|
73 |
|
74 EvaluateOptions& setCoerceToString(bool aCoerce) { |
|
75 coerceToString = aCoerce; |
|
76 return *this; |
|
77 } |
|
78 |
|
79 EvaluateOptions& setReportUncaught(bool aReport) { |
|
80 reportUncaught = aReport; |
|
81 return *this; |
|
82 } |
|
83 |
|
84 EvaluateOptions& setNeedResult(bool aNeedResult) { |
|
85 needResult = aNeedResult; |
|
86 return *this; |
|
87 } |
|
88 }; |
|
89 |
|
90 static nsresult EvaluateString(JSContext* aCx, |
|
91 const nsAString& aScript, |
|
92 JS::Handle<JSObject*> aScopeObject, |
|
93 JS::CompileOptions &aCompileOptions, |
|
94 const EvaluateOptions& aEvaluateOptions, |
|
95 JS::MutableHandle<JS::Value> aRetValue, |
|
96 void **aOffThreadToken = nullptr); |
|
97 |
|
98 static nsresult EvaluateString(JSContext* aCx, |
|
99 JS::SourceBufferHolder& aSrcBuf, |
|
100 JS::Handle<JSObject*> aScopeObject, |
|
101 JS::CompileOptions &aCompileOptions, |
|
102 const EvaluateOptions& aEvaluateOptions, |
|
103 JS::MutableHandle<JS::Value> aRetValue, |
|
104 void **aOffThreadToken = nullptr); |
|
105 |
|
106 |
|
107 static nsresult EvaluateString(JSContext* aCx, |
|
108 const nsAString& aScript, |
|
109 JS::Handle<JSObject*> aScopeObject, |
|
110 JS::CompileOptions &aCompileOptions, |
|
111 void **aOffThreadToken = nullptr); |
|
112 |
|
113 static nsresult EvaluateString(JSContext* aCx, |
|
114 JS::SourceBufferHolder& aSrcBuf, |
|
115 JS::Handle<JSObject*> aScopeObject, |
|
116 JS::CompileOptions &aCompileOptions, |
|
117 void **aOffThreadToken = nullptr); |
|
118 |
|
119 }; |
|
120 |
|
121 class MOZ_STACK_CLASS AutoDontReportUncaught { |
|
122 JSContext* mContext; |
|
123 bool mWasSet; |
|
124 |
|
125 public: |
|
126 AutoDontReportUncaught(JSContext* aContext) : mContext(aContext) { |
|
127 MOZ_ASSERT(aContext); |
|
128 mWasSet = JS::ContextOptionsRef(mContext).dontReportUncaught(); |
|
129 if (!mWasSet) { |
|
130 JS::ContextOptionsRef(mContext).setDontReportUncaught(true); |
|
131 } |
|
132 } |
|
133 ~AutoDontReportUncaught() { |
|
134 if (!mWasSet) { |
|
135 JS::ContextOptionsRef(mContext).setDontReportUncaught(false); |
|
136 } |
|
137 } |
|
138 }; |
|
139 |
|
140 |
|
141 class nsDependentJSString : public nsDependentString |
|
142 { |
|
143 public: |
|
144 /** |
|
145 * In the case of string ids, getting the string's chars is infallible, so |
|
146 * the dependent string can be constructed directly. |
|
147 */ |
|
148 explicit nsDependentJSString(JS::Handle<jsid> id) |
|
149 : nsDependentString(JS_GetInternedStringChars(JSID_TO_STRING(id)), |
|
150 JS_GetStringLength(JSID_TO_STRING(id))) |
|
151 { |
|
152 } |
|
153 |
|
154 /** |
|
155 * Ditto for flat strings. |
|
156 */ |
|
157 explicit nsDependentJSString(JSFlatString* fstr) |
|
158 : nsDependentString(JS_GetFlatStringChars(fstr), |
|
159 JS_GetStringLength(JS_FORGET_STRING_FLATNESS(fstr))) |
|
160 { |
|
161 } |
|
162 |
|
163 /** |
|
164 * For all other strings, the nsDependentJSString object should be default |
|
165 * constructed, which leaves it empty (this->IsEmpty()), and initialized with |
|
166 * one of the init() methods below. |
|
167 */ |
|
168 |
|
169 nsDependentJSString() |
|
170 { |
|
171 } |
|
172 |
|
173 bool init(JSContext* aContext, JSString* str) |
|
174 { |
|
175 size_t length; |
|
176 const jschar* chars = JS_GetStringCharsZAndLength(aContext, str, &length); |
|
177 if (!chars) |
|
178 return false; |
|
179 |
|
180 NS_ASSERTION(IsEmpty(), "init() on initialized string"); |
|
181 nsDependentString* base = this; |
|
182 new(base) nsDependentString(chars, length); |
|
183 return true; |
|
184 } |
|
185 |
|
186 bool init(JSContext* aContext, const JS::Value &v) |
|
187 { |
|
188 return init(aContext, JSVAL_TO_STRING(v)); |
|
189 } |
|
190 |
|
191 void init(JSFlatString* fstr) |
|
192 { |
|
193 MOZ_ASSERT(IsEmpty(), "init() on initialized string"); |
|
194 new(this) nsDependentJSString(fstr); |
|
195 } |
|
196 |
|
197 ~nsDependentJSString() |
|
198 { |
|
199 } |
|
200 }; |
|
201 |
|
202 #endif /* nsJSUtils_h__ */ |