1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : *
3 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is mozilla.org code.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Netscape Communications Corporation.
20 : * Portions created by the Initial Developer are Copyright (C) 1998
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Robert Ginda, <rginda@netscape.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifndef JSDSERVICE_H___
41 : #define JSDSERVICE_H___
42 :
43 : #include "jsdIDebuggerService.h"
44 : #include "jsdebug.h"
45 : #include "nsString.h"
46 : #include "nsCOMPtr.h"
47 : #include "nspr.h"
48 :
49 : // #if defined(DEBUG_rginda_l)
50 : // # define DEBUG_verbose
51 : // #endif
52 :
53 : struct LiveEphemeral {
54 : /* link in a chain of live values list */
55 : PRCList links;
56 : jsdIEphemeral *value;
57 : void *key;
58 : };
59 :
60 : struct PCMapEntry {
61 : PRUint32 pc, line;
62 : };
63 :
64 : /*******************************************************************************
65 : * reflected jsd data structures
66 : *******************************************************************************/
67 :
68 : class jsdObject : public jsdIObject
69 : {
70 : public:
71 : NS_DECL_ISUPPORTS
72 : NS_DECL_JSDIOBJECT
73 :
74 : /* you'll normally use use FromPtr() instead of directly constructing one */
75 0 : jsdObject (JSDContext *aCx, JSDObject *aObject) :
76 0 : mCx(aCx), mObject(aObject)
77 : {
78 0 : }
79 :
80 0 : static jsdIObject *FromPtr (JSDContext *aCx,
81 : JSDObject *aObject)
82 : {
83 0 : if (!aObject)
84 0 : return nsnull;
85 :
86 0 : jsdIObject *rv = new jsdObject (aCx, aObject);
87 0 : NS_IF_ADDREF(rv);
88 0 : return rv;
89 : }
90 :
91 : private:
92 : jsdObject(); /* no implementation */
93 : jsdObject(const jsdObject&); /* no implementation */
94 :
95 : JSDContext *mCx;
96 : JSDObject *mObject;
97 : };
98 :
99 :
100 : class jsdProperty : public jsdIProperty
101 : {
102 : public:
103 : NS_DECL_ISUPPORTS
104 : NS_DECL_JSDIPROPERTY
105 : NS_DECL_JSDIEPHEMERAL
106 :
107 : jsdProperty (JSDContext *aCx, JSDProperty *aProperty);
108 : virtual ~jsdProperty ();
109 :
110 0 : static jsdIProperty *FromPtr (JSDContext *aCx,
111 : JSDProperty *aProperty)
112 : {
113 0 : if (!aProperty)
114 0 : return nsnull;
115 :
116 0 : jsdIProperty *rv = new jsdProperty (aCx, aProperty);
117 0 : NS_IF_ADDREF(rv);
118 0 : return rv;
119 : }
120 :
121 : static void InvalidateAll();
122 :
123 : private:
124 : jsdProperty(); /* no implementation */
125 : jsdProperty(const jsdProperty&); /* no implementation */
126 :
127 : bool mValid;
128 : LiveEphemeral mLiveListEntry;
129 : JSDContext *mCx;
130 : JSDProperty *mProperty;
131 : };
132 :
133 : class jsdScript : public jsdIScript
134 : {
135 : public:
136 : NS_DECL_ISUPPORTS
137 : NS_DECL_JSDISCRIPT
138 : NS_DECL_JSDIEPHEMERAL
139 :
140 : /* you'll normally use use FromPtr() instead of directly constructing one */
141 : jsdScript (JSDContext *aCx, JSDScript *aScript);
142 : virtual ~jsdScript();
143 :
144 6 : static jsdIScript *FromPtr (JSDContext *aCx, JSDScript *aScript)
145 : {
146 6 : if (!aScript)
147 0 : return nsnull;
148 :
149 6 : void *data = JSD_GetScriptPrivate (aScript);
150 : jsdIScript *rv;
151 :
152 6 : if (data) {
153 0 : rv = static_cast<jsdIScript *>(data);
154 : } else {
155 6 : rv = new jsdScript (aCx, aScript);
156 6 : NS_IF_ADDREF(rv); /* addref for the SetScriptPrivate, released in
157 : * Invalidate() */
158 6 : JSD_SetScriptPrivate (aScript, static_cast<void *>(rv));
159 : }
160 :
161 6 : NS_IF_ADDREF(rv); /* addref for return value */
162 6 : return rv;
163 : }
164 :
165 : static void InvalidateAll();
166 :
167 : private:
168 : static PRUint32 LastTag;
169 :
170 : jsdScript(); /* no implementation */
171 : jsdScript (const jsdScript&); /* no implementation */
172 : PCMapEntry* CreatePPLineMap();
173 : PRUint32 PPPcToLine(PRUint32 aPC);
174 : PRUint32 PPLineToPc(PRUint32 aLine);
175 :
176 : bool mValid;
177 : PRUint32 mTag;
178 : JSDContext *mCx;
179 : JSDScript *mScript;
180 : nsCString *mFileName;
181 : nsCString *mFunctionName;
182 : PRUint32 mBaseLineNumber, mLineExtent;
183 : PCMapEntry *mPPLineMap;
184 : PRUint32 mPCMapSize;
185 : uintptr_t mFirstPC;
186 : };
187 :
188 : PRUint32 jsdScript::LastTag = 0;
189 :
190 : class jsdContext : public jsdIContext
191 : {
192 : public:
193 : NS_DECL_ISUPPORTS
194 : NS_DECL_JSDICONTEXT
195 : NS_DECL_JSDIEPHEMERAL
196 :
197 : jsdContext (JSDContext *aJSDCx, JSContext *aJSCx, nsISupports *aISCx);
198 : virtual ~jsdContext();
199 :
200 : static void InvalidateAll();
201 : static jsdIContext *FromPtr (JSDContext *aJSDCx, JSContext *aJSCx);
202 : private:
203 : static PRUint32 LastTag;
204 :
205 : jsdContext (); /* no implementation */
206 : jsdContext (const jsdContext&); /* no implementation */
207 :
208 : bool mValid;
209 : LiveEphemeral mLiveListEntry;
210 : PRUint32 mTag;
211 : JSDContext *mJSDCx;
212 : JSContext *mJSCx;
213 : nsCOMPtr<nsISupports> mISCx;
214 : };
215 :
216 : PRUint32 jsdContext::LastTag = 0;
217 :
218 : class jsdStackFrame : public jsdIStackFrame
219 : {
220 : public:
221 : NS_DECL_ISUPPORTS
222 : NS_DECL_JSDISTACKFRAME
223 : NS_DECL_JSDIEPHEMERAL
224 :
225 : /* you'll normally use use FromPtr() instead of directly constructing one */
226 : jsdStackFrame (JSDContext *aCx, JSDThreadState *aThreadState,
227 : JSDStackFrameInfo *aStackFrameInfo);
228 : virtual ~jsdStackFrame();
229 :
230 : static void InvalidateAll();
231 : static jsdIStackFrame* FromPtr (JSDContext *aCx,
232 : JSDThreadState *aThreadState,
233 : JSDStackFrameInfo *aStackFrameInfo);
234 :
235 : private:
236 : jsdStackFrame(); /* no implementation */
237 : jsdStackFrame(const jsdStackFrame&); /* no implementation */
238 :
239 : bool mValid;
240 : LiveEphemeral mLiveListEntry;
241 : JSDContext *mCx;
242 : JSDThreadState *mThreadState;
243 : JSDStackFrameInfo *mStackFrameInfo;
244 : };
245 :
246 : class jsdValue : public jsdIValue
247 : {
248 : public:
249 : NS_DECL_ISUPPORTS
250 : NS_DECL_JSDIVALUE
251 : NS_DECL_JSDIEPHEMERAL
252 :
253 : /* you'll normally use use FromPtr() instead of directly constructing one */
254 : jsdValue (JSDContext *aCx, JSDValue *aValue);
255 : virtual ~jsdValue();
256 :
257 : static jsdIValue *FromPtr (JSDContext *aCx, JSDValue *aValue);
258 : static void InvalidateAll();
259 :
260 : private:
261 : jsdValue(); /* no implementation */
262 : jsdValue (const jsdScript&); /* no implementation */
263 :
264 : bool mValid;
265 : LiveEphemeral mLiveListEntry;
266 : JSDContext *mCx;
267 : JSDValue *mValue;
268 : };
269 :
270 : /******************************************************************************
271 : * debugger service
272 : ******************************************************************************/
273 :
274 : class jsdService : public jsdIDebuggerService
275 : {
276 : public:
277 : NS_DECL_ISUPPORTS
278 : NS_DECL_JSDIDEBUGGERSERVICE
279 :
280 280 : jsdService() : mOn(false), mPauseLevel(0),
281 : mNestedLoopLevel(0), mCx(0), mRuntime(0), mErrorHook(0),
282 : mBreakpointHook(0), mDebugHook(0), mDebuggerHook(0),
283 : mInterruptHook(0), mScriptHook(0), mThrowHook(0),
284 280 : mTopLevelHook(0), mFunctionHook(0)
285 : {
286 280 : }
287 :
288 : virtual ~jsdService();
289 :
290 : static jsdService *GetService ();
291 :
292 0 : bool CheckInterruptHook() { return !!mInterruptHook; }
293 :
294 : nsresult DoPause(PRUint32 *_rval, bool internalCall);
295 : nsresult DoUnPause(PRUint32 *_rval, bool internalCall);
296 :
297 : private:
298 : bool mOn;
299 : PRUint32 mPauseLevel;
300 : PRUint32 mNestedLoopLevel;
301 : JSDContext *mCx;
302 : JSRuntime *mRuntime;
303 :
304 : nsCOMPtr<jsdIErrorHook> mErrorHook;
305 : nsCOMPtr<jsdIExecutionHook> mBreakpointHook;
306 : nsCOMPtr<jsdIExecutionHook> mDebugHook;
307 : nsCOMPtr<jsdIExecutionHook> mDebuggerHook;
308 : nsCOMPtr<jsdIExecutionHook> mInterruptHook;
309 : nsCOMPtr<jsdIScriptHook> mScriptHook;
310 : nsCOMPtr<jsdIExecutionHook> mThrowHook;
311 : nsCOMPtr<jsdICallHook> mTopLevelHook;
312 : nsCOMPtr<jsdICallHook> mFunctionHook;
313 : nsCOMPtr<jsdIActivationCallback> mActivationCallback;
314 : };
315 :
316 : #endif /* JSDSERVICE_H___ */
317 :
318 :
319 : /* graveyard */
320 :
321 : #if 0
322 :
323 : class jsdContext : public jsdIContext
324 : {
325 : public:
326 : NS_DECL_ISUPPORTS
327 : NS_DECL_JSDICONTEXT
328 :
329 : /* you'll normally use use FromPtr() instead of directly constructing one */
330 : jsdContext (JSDContext *aCx) : mCx(aCx)
331 : {
332 : printf ("++++++ jsdContext\n");
333 : }
334 :
335 : static jsdIContext *FromPtr (JSDContext *aCx)
336 : {
337 : if (!aCx)
338 : return nsnull;
339 :
340 : void *data = JSD_GetContextPrivate (aCx);
341 : jsdIContext *rv;
342 :
343 : if (data) {
344 : rv = static_cast<jsdIContext *>(data);
345 : } else {
346 : rv = new jsdContext (aCx);
347 : NS_IF_ADDREF(rv); // addref for the SetContextPrivate
348 : JSD_SetContextPrivate (aCx, static_cast<void *>(rv));
349 : }
350 :
351 : NS_IF_ADDREF(rv); // addref for the return value
352 : return rv;
353 : }
354 :
355 : virtual ~jsdContext() { printf ("------ ~jsdContext\n"); }
356 : private:
357 : jsdContext(); /* no implementation */
358 : jsdContext(const jsdContext&); /* no implementation */
359 :
360 : JSDContext *mCx;
361 : };
362 :
363 : class jsdThreadState : public jsdIThreadState
364 : {
365 : public:
366 : NS_DECL_ISUPPORTS
367 : NS_DECL_JSDITHREADSTATE
368 :
369 : /* you'll normally use use FromPtr() instead of directly constructing one */
370 : jsdThreadState (JSDContext *aCx, JSDThreadState *aThreadState) :
371 : mCx(aCx), mThreadState(aThreadState)
372 : {
373 : }
374 :
375 : /* XXX These things are only valid for a short period of time, they reflect
376 : * state in the js engine that will go away after stepping past wherever
377 : * we were stopped at when this was created. We could keep a list of every
378 : * instance of this we've created, and "invalidate" them before we let the
379 : * engine continue. The next time we need a threadstate, we can search the
380 : * list to find an invalidated one, and just reuse it.
381 : */
382 : static jsdIThreadState *FromPtr (JSDContext *aCx,
383 : JSDThreadState *aThreadState)
384 : {
385 : if (!aThreadState)
386 : return nsnull;
387 :
388 : jsdIThreadState *rv = new jsdThreadState (aCx, aThreadState);
389 : NS_IF_ADDREF(rv);
390 : return rv;
391 : }
392 :
393 : private:
394 : jsdThreadState(); /* no implementation */
395 : jsdThreadState(const jsdThreadState&); /* no implementation */
396 :
397 : JSDContext *mCx;
398 : JSDThreadState *mThreadState;
399 : };
400 :
401 : #endif
|