Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
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 #ifndef JSDSERVICE_H___
8 #define JSDSERVICE_H___
10 #include "jsdIDebuggerService.h"
11 #include "jsdebug.h"
12 #include "nsString.h"
13 #include "nsCOMPtr.h"
14 #include "nspr.h"
15 #include "nsCycleCollectionParticipant.h"
16 #include "mozilla/Attributes.h"
18 // #if defined(DEBUG_rginda_l)
19 // # define DEBUG_verbose
20 // #endif
22 struct LiveEphemeral {
23 /* link in a chain of live values list */
24 PRCList links;
25 jsdIEphemeral *value;
26 void *key;
27 };
29 struct PCMapEntry {
30 uint32_t pc, line;
31 };
33 /*******************************************************************************
34 * reflected jsd data structures
35 *******************************************************************************/
37 class jsdObject MOZ_FINAL : public jsdIObject
38 {
39 public:
40 NS_DECL_THREADSAFE_ISUPPORTS
41 NS_DECL_JSDIOBJECT
43 /* you'll normally use use FromPtr() instead of directly constructing one */
44 jsdObject (JSDContext *aCx, JSDObject *aObject) :
45 mCx(aCx), mObject(aObject)
46 {
47 }
49 static jsdIObject *FromPtr (JSDContext *aCx,
50 JSDObject *aObject)
51 {
52 if (!aObject)
53 return nullptr;
55 jsdIObject *rv = new jsdObject (aCx, aObject);
56 NS_IF_ADDREF(rv);
57 return rv;
58 }
60 private:
61 jsdObject(); /* no implementation */
62 jsdObject(const jsdObject&); /* no implementation */
64 JSDContext *mCx;
65 JSDObject *mObject;
66 };
69 class jsdProperty : public jsdIProperty
70 {
71 public:
72 NS_DECL_THREADSAFE_ISUPPORTS
73 NS_DECL_JSDIPROPERTY
74 NS_DECL_JSDIEPHEMERAL
76 jsdProperty (JSDContext *aCx, JSDProperty *aProperty);
77 virtual ~jsdProperty ();
79 static jsdIProperty *FromPtr (JSDContext *aCx,
80 JSDProperty *aProperty)
81 {
82 if (!aProperty)
83 return nullptr;
85 jsdIProperty *rv = new jsdProperty (aCx, aProperty);
86 NS_IF_ADDREF(rv);
87 return rv;
88 }
90 static void InvalidateAll();
92 private:
93 jsdProperty(); /* no implementation */
94 jsdProperty(const jsdProperty&); /* no implementation */
96 bool mValid;
97 LiveEphemeral mLiveListEntry;
98 JSDContext *mCx;
99 JSDProperty *mProperty;
100 };
102 class jsdScript : public jsdIScript
103 {
104 public:
105 NS_DECL_THREADSAFE_ISUPPORTS
106 NS_DECL_JSDISCRIPT
107 NS_DECL_JSDIEPHEMERAL
109 /* you'll normally use use FromPtr() instead of directly constructing one */
110 jsdScript (JSDContext *aCx, JSDScript *aScript);
111 virtual ~jsdScript();
113 static jsdIScript *FromPtr (JSDContext *aCx, JSDScript *aScript)
114 {
115 if (!aScript)
116 return nullptr;
118 void *data = JSD_GetScriptPrivate (aScript);
119 jsdIScript *rv;
121 if (data) {
122 rv = static_cast<jsdIScript *>(data);
123 } else {
124 rv = new jsdScript (aCx, aScript);
125 NS_IF_ADDREF(rv); /* addref for the SetScriptPrivate, released in
126 * Invalidate() */
127 JSD_SetScriptPrivate (aScript, static_cast<void *>(rv));
128 }
130 NS_IF_ADDREF(rv); /* addref for return value */
131 return rv;
132 }
134 static void InvalidateAll();
136 private:
137 static uint32_t LastTag;
139 jsdScript(); /* no implementation */
140 jsdScript (const jsdScript&); /* no implementation */
141 PCMapEntry* CreatePPLineMap();
142 uint32_t PPPcToLine(uint32_t aPC);
143 uint32_t PPLineToPc(uint32_t aLine);
145 bool mValid;
146 uint32_t mTag;
147 JSDContext *mCx;
148 JSDScript *mScript;
149 nsCString *mFileName;
150 nsCString *mFunctionName;
151 uint32_t mBaseLineNumber, mLineExtent;
152 PCMapEntry *mPPLineMap;
153 uint32_t mPCMapSize;
154 uintptr_t mFirstPC;
155 };
157 uint32_t jsdScript::LastTag = 0;
159 class jsdContext : public jsdIContext
160 {
161 public:
162 NS_DECL_THREADSAFE_ISUPPORTS
163 NS_DECL_JSDICONTEXT
164 NS_DECL_JSDIEPHEMERAL
166 jsdContext (JSDContext *aJSDCx, JSContext *aJSCx, nsISupports *aISCx);
167 virtual ~jsdContext();
169 static void InvalidateAll();
170 static jsdIContext *FromPtr (JSDContext *aJSDCx, JSContext *aJSCx);
171 private:
172 static uint32_t LastTag;
174 jsdContext (); /* no implementation */
175 jsdContext (const jsdContext&); /* no implementation */
177 bool mValid;
178 // The API exposed by JSD here is problematic, because it allows for per-
179 // JSContext script disabling, which no longer exists in the platform.
180 // The only consumer here in practice is Firebug, which makes sure to re-
181 // enable any disabled script before navigation. But if some other consumer
182 // were to disable script, navigate, and try to re-enable it, we'd end up
183 // with an unmatched UnblockScript call, which violates platform invariants.
184 // So we make a half-hearted attempt to detect this by storing the Window ID
185 // of the scope for which we disabled script.
186 uint64_t mScriptDisabledForWindowWithID;
187 bool IsScriptEnabled() { return !mScriptDisabledForWindowWithID; }
188 LiveEphemeral mLiveListEntry;
189 uint32_t mTag;
190 JSDContext *mJSDCx;
191 JSContext *mJSCx;
192 nsCOMPtr<nsISupports> mISCx;
193 };
195 uint32_t jsdContext::LastTag = 0;
197 class jsdStackFrame : public jsdIStackFrame
198 {
199 public:
200 NS_DECL_THREADSAFE_ISUPPORTS
201 NS_DECL_JSDISTACKFRAME
202 NS_DECL_JSDIEPHEMERAL
204 /* you'll normally use use FromPtr() instead of directly constructing one */
205 jsdStackFrame (JSDContext *aCx, JSDThreadState *aThreadState,
206 JSDStackFrameInfo *aStackFrameInfo);
207 virtual ~jsdStackFrame();
209 static void InvalidateAll();
210 static jsdIStackFrame* FromPtr (JSDContext *aCx,
211 JSDThreadState *aThreadState,
212 JSDStackFrameInfo *aStackFrameInfo);
214 private:
215 jsdStackFrame(); /* no implementation */
216 jsdStackFrame(const jsdStackFrame&); /* no implementation */
218 bool mValid;
219 LiveEphemeral mLiveListEntry;
220 JSDContext *mCx;
221 JSDThreadState *mThreadState;
222 JSDStackFrameInfo *mStackFrameInfo;
223 };
225 class jsdValue : public jsdIValue
226 {
227 public:
228 NS_DECL_THREADSAFE_ISUPPORTS
229 NS_DECL_JSDIVALUE
230 NS_DECL_JSDIEPHEMERAL
232 /* you'll normally use use FromPtr() instead of directly constructing one */
233 jsdValue (JSDContext *aCx, JSDValue *aValue);
234 virtual ~jsdValue();
236 static jsdIValue *FromPtr (JSDContext *aCx, JSDValue *aValue);
237 static void InvalidateAll();
239 private:
240 jsdValue(); /* no implementation */
241 jsdValue (const jsdScript&); /* no implementation */
243 bool mValid;
244 LiveEphemeral mLiveListEntry;
245 JSDContext *mCx;
246 JSDValue *mValue;
247 };
249 /******************************************************************************
250 * debugger service
251 ******************************************************************************/
253 class jsdService : public jsdIDebuggerService
254 {
255 public:
256 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
257 NS_DECL_JSDIDEBUGGERSERVICE
259 NS_DECL_CYCLE_COLLECTION_CLASS(jsdService)
261 jsdService() : mOn(false), mPauseLevel(0),
262 mNestedLoopLevel(0), mCx(0), mRuntime(0), mErrorHook(0),
263 mBreakpointHook(0), mDebugHook(0), mDebuggerHook(0),
264 mInterruptHook(0), mScriptHook(0), mThrowHook(0),
265 mTopLevelHook(0), mFunctionHook(0),
266 mWarnedAboutDeprecation(false),
267 mDeprecationAcknowledged(false)
268 {
269 }
271 virtual ~jsdService();
273 static jsdService *GetService ();
275 bool CheckInterruptHook() { return !!mInterruptHook; }
277 nsresult DoPause(uint32_t *_rval, bool internalCall);
278 nsresult DoUnPause(uint32_t *_rval, bool internalCall);
280 private:
281 bool mOn;
282 uint32_t mPauseLevel;
283 uint32_t mNestedLoopLevel;
284 JSDContext *mCx;
285 JSRuntime *mRuntime;
287 nsCOMPtr<jsdIErrorHook> mErrorHook;
288 nsCOMPtr<jsdIExecutionHook> mBreakpointHook;
289 nsCOMPtr<jsdIExecutionHook> mDebugHook;
290 nsCOMPtr<jsdIExecutionHook> mDebuggerHook;
291 nsCOMPtr<jsdIExecutionHook> mInterruptHook;
292 nsCOMPtr<jsdIScriptHook> mScriptHook;
293 nsCOMPtr<jsdIExecutionHook> mThrowHook;
294 nsCOMPtr<jsdICallHook> mTopLevelHook;
295 nsCOMPtr<jsdICallHook> mFunctionHook;
296 nsCOMPtr<jsdIActivationCallback> mActivationCallback;
298 // True if we have ever printed a warning about JSD being deprecated.
299 // We only ever print the warning once.
300 bool mWarnedAboutDeprecation;
302 // True if the next call to asyncOn should not produce a warning,
303 // because the consumer called jsdIDebuggerService::acknowledgeDeprecation.
304 bool mDeprecationAcknowledged;
305 };
307 #endif /* JSDSERVICE_H___ */
310 /* graveyard */
312 #if 0
314 class jsdContext : public jsdIContext
315 {
316 public:
317 NS_DECL_THREADSAFE_ISUPPORTS
318 NS_DECL_JSDICONTEXT
320 /* you'll normally use use FromPtr() instead of directly constructing one */
321 jsdContext (JSDContext *aCx) : mCx(aCx)
322 {
323 printf ("++++++ jsdContext\n");
324 }
326 static jsdIContext *FromPtr (JSDContext *aCx)
327 {
328 if (!aCx)
329 return nullptr;
331 void *data = JSD_GetContextPrivate (aCx);
332 jsdIContext *rv;
334 if (data) {
335 rv = static_cast<jsdIContext *>(data);
336 } else {
337 rv = new jsdContext (aCx);
338 NS_IF_ADDREF(rv); // addref for the SetContextPrivate
339 JSD_SetContextPrivate (aCx, static_cast<void *>(rv));
340 }
342 NS_IF_ADDREF(rv); // addref for the return value
343 return rv;
344 }
346 virtual ~jsdContext() { printf ("------ ~jsdContext\n"); }
347 private:
348 jsdContext(); /* no implementation */
349 jsdContext(const jsdContext&); /* no implementation */
351 JSDContext *mCx;
352 };
354 class jsdThreadState : public jsdIThreadState
355 {
356 public:
357 NS_DECL_THREADSAFE_ISUPPORTS
358 NS_DECL_JSDITHREADSTATE
360 /* you'll normally use use FromPtr() instead of directly constructing one */
361 jsdThreadState (JSDContext *aCx, JSDThreadState *aThreadState) :
362 mCx(aCx), mThreadState(aThreadState)
363 {
364 }
366 /* XXX These things are only valid for a short period of time, they reflect
367 * state in the js engine that will go away after stepping past wherever
368 * we were stopped at when this was created. We could keep a list of every
369 * instance of this we've created, and "invalidate" them before we let the
370 * engine continue. The next time we need a threadstate, we can search the
371 * list to find an invalidated one, and just reuse it.
372 */
373 static jsdIThreadState *FromPtr (JSDContext *aCx,
374 JSDThreadState *aThreadState)
375 {
376 if (!aThreadState)
377 return nullptr;
379 jsdIThreadState *rv = new jsdThreadState (aCx, aThreadState);
380 NS_IF_ADDREF(rv);
381 return rv;
382 }
384 private:
385 jsdThreadState(); /* no implementation */
386 jsdThreadState(const jsdThreadState&); /* no implementation */
388 JSDContext *mCx;
389 JSDThreadState *mThreadState;
390 };
392 #endif