Bug 550784 - [OOPP] Flash deadlocks during script evals that trigger focus related...
[mozilla-central.git] / js / jsd / jsd_obj.c
blobcb88965bb0eede9bbd8d99efb7d0454f3ea51194
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
39 * JavaScript Debugging support - Object support
42 #include "jsd.h"
45 * #define JSD_TRACE 1
48 #ifdef JSD_TRACE
49 #define TRACEOBJ(jsdc, jsdobj, which) _traceObj(jsdc, jsdobj, which)
51 static char *
52 _describeObj(JSDContext* jsdc, JSDObject *jsdobj)
54 return
55 JS_smprintf("%0x new'd in %s at line %d using ctor %s in %s at line %d",
56 (int)jsdobj,
57 JSD_GetObjectNewURL(jsdc, jsdobj),
58 JSD_GetObjectNewLineNumber(jsdc, jsdobj),
59 JSD_GetObjectConstructorName(jsdc, jsdobj),
60 JSD_GetObjectConstructorURL(jsdc, jsdobj),
61 JSD_GetObjectConstructorLineNumber(jsdc, jsdobj));
64 static void
65 _traceObj(JSDContext* jsdc, JSDObject* jsdobj, int which)
67 char* description;
69 if( !jsdobj )
70 return;
72 description = _describeObj(jsdc, jsdobj);
74 printf("%s : %s\n",
75 which == 0 ? "new " :
76 which == 1 ? "final" :
77 "ctor ",
78 description);
79 if(description)
80 free(description);
82 #else
83 #define TRACEOBJ(jsdc, jsdobj, which) ((void)0)
84 #endif /* JSD_TRACE */
86 #ifdef DEBUG
87 void JSD_ASSERT_VALID_OBJECT(JSDObject* jsdobj)
89 JS_ASSERT(jsdobj);
90 JS_ASSERT(!JS_CLIST_IS_EMPTY(&jsdobj->links));
91 JS_ASSERT(jsdobj->obj);
93 #endif
96 static void
97 _destroyJSDObject(JSDContext* jsdc, JSDObject* jsdobj)
99 JS_ASSERT(JSD_OBJECTS_LOCKED(jsdc));
101 JS_REMOVE_LINK(&jsdobj->links);
102 JS_HashTableRemove(jsdc->objectsTable, jsdobj->obj);
104 if(jsdobj->newURL)
105 jsd_DropAtom(jsdc, jsdobj->newURL);
106 if(jsdobj->ctorURL)
107 jsd_DropAtom(jsdc, jsdobj->ctorURL);
108 if(jsdobj->ctorName)
109 jsd_DropAtom(jsdc, jsdobj->ctorName);
110 free(jsdobj);
113 static JSDObject*
114 _createJSDObject(JSDContext* jsdc, JSContext *cx, JSObject *obj)
116 JSDObject* jsdobj;
117 JSStackFrame* fp;
118 JSStackFrame* iter = NULL;
119 const char* newURL;
120 jsbytecode* pc;
122 JS_ASSERT(JSD_OBJECTS_LOCKED(jsdc));
124 jsdobj = (JSDObject*) calloc(1, sizeof(JSDObject));
125 if (jsdobj)
127 JS_INIT_CLIST(&jsdobj->links);
128 JS_APPEND_LINK(&jsdobj->links, &jsdc->objectsList);
129 jsdobj->obj = obj;
130 JS_HashTableAdd(jsdc->objectsTable, obj, jsdobj);
132 if (jsdc->flags & JSD_DISABLE_OBJECT_TRACE)
133 return jsdobj;
135 /* walk the stack to find js frame (if any) causing creation */
136 while (NULL != (fp = JS_FrameIterator(cx, &iter)))
138 if( !JS_IsNativeFrame(cx, fp) )
140 JSScript* script = JS_GetFrameScript(cx, fp);
141 if( !script )
142 continue;
144 newURL = JS_GetScriptFilename(cx, script);
145 if( newURL )
146 jsdobj->newURL = jsd_AddAtom(jsdc, newURL);
148 pc = JS_GetFramePC(cx, fp);
149 if( pc )
150 jsdobj->newLineno = JS_PCToLineNumber(cx, script, pc);
152 break;
156 return jsdobj;
159 void
160 jsd_ObjectHook(JSContext *cx, JSObject *obj, JSBool isNew, void *closure)
162 JSDObject* jsdobj;
163 JSDContext* jsdc = (JSDContext*) closure;
165 if( ! jsdc || ! jsdc->inited )
166 return;
168 JSD_LOCK_OBJECTS(jsdc);
169 if(isNew)
171 jsdobj = _createJSDObject(jsdc, cx, obj);
172 TRACEOBJ(jsdc, jsdobj, 0);
174 else
176 jsdobj = jsd_GetJSDObjectForJSObject(jsdc, obj);
177 if( jsdobj )
179 TRACEOBJ(jsdc, jsdobj, 1);
180 _destroyJSDObject(jsdc, jsdobj);
183 JSD_UNLOCK_OBJECTS(jsdc);
186 void
187 jsd_Constructing(JSDContext* jsdc, JSContext *cx, JSObject *obj,
188 JSStackFrame *fp)
190 JSDObject* jsdobj;
191 JSScript* script;
192 JSDScript* jsdscript;
193 const char* ctorURL;
194 const char* ctorName;
196 JSD_LOCK_OBJECTS(jsdc);
197 jsdobj = jsd_GetJSDObjectForJSObject(jsdc, obj);
198 if( jsdobj && !jsdobj->ctorURL && !JS_IsNativeFrame(cx, fp) )
200 script = JS_GetFrameScript(cx, fp);
201 if( script )
203 ctorURL = JS_GetScriptFilename(cx, script);
204 if( ctorURL )
205 jsdobj->ctorURL = jsd_AddAtom(jsdc, ctorURL);
207 JSD_LOCK_SCRIPTS(jsdc);
208 jsdscript = jsd_FindOrCreateJSDScript(jsdc, cx, script, fp);
209 JSD_UNLOCK_SCRIPTS(jsdc);
210 if( jsdscript )
212 ctorName = jsd_GetScriptFunctionName(jsdc, jsdscript);
213 if( ctorName )
214 jsdobj->ctorName = jsd_AddAtom(jsdc, ctorName);
216 jsdobj->ctorLineno = JS_GetScriptBaseLineNumber(cx, script);
219 TRACEOBJ(jsdc, jsdobj, 3);
220 JSD_UNLOCK_OBJECTS(jsdc);
223 static JSHashNumber
224 _hash_root(const void *key)
226 return ((JSHashNumber) key) >> 2; /* help lame MSVC1.5 on Win16 */
229 JSBool
230 jsd_InitObjectManager(JSDContext* jsdc)
232 JS_INIT_CLIST(&jsdc->objectsList);
233 jsdc->objectsTable = JS_NewHashTable(256, _hash_root,
234 JS_CompareValues, JS_CompareValues,
235 NULL, NULL);
236 return (JSBool) jsdc->objectsTable;
239 void
240 jsd_DestroyObjectManager(JSDContext* jsdc)
242 jsd_DestroyObjects(jsdc);
243 JSD_LOCK_OBJECTS(jsdc);
244 JS_HashTableDestroy(jsdc->objectsTable);
245 JSD_UNLOCK_OBJECTS(jsdc);
248 void
249 jsd_DestroyObjects(JSDContext* jsdc)
251 JSD_LOCK_OBJECTS(jsdc);
252 while( !JS_CLIST_IS_EMPTY(&jsdc->objectsList) )
253 _destroyJSDObject(jsdc, (JSDObject*)JS_NEXT_LINK(&jsdc->objectsList));
254 JSD_UNLOCK_OBJECTS(jsdc);
257 JSDObject*
258 jsd_IterateObjects(JSDContext* jsdc, JSDObject** iterp)
260 JSDObject *jsdobj = *iterp;
262 JS_ASSERT(JSD_OBJECTS_LOCKED(jsdc));
264 if( !jsdobj )
265 jsdobj = (JSDObject *)jsdc->objectsList.next;
266 if( jsdobj == (JSDObject *)&jsdc->objectsList )
267 return NULL;
268 *iterp = (JSDObject*) jsdobj->links.next;
269 return jsdobj;
272 JSObject*
273 jsd_GetWrappedObject(JSDContext* jsdc, JSDObject* jsdobj)
275 return jsdobj->obj;
278 const char*
279 jsd_GetObjectNewURL(JSDContext* jsdc, JSDObject* jsdobj)
281 if( jsdobj->newURL )
282 return JSD_ATOM_TO_STRING(jsdobj->newURL);
283 return NULL;
286 uintN
287 jsd_GetObjectNewLineNumber(JSDContext* jsdc, JSDObject* jsdobj)
289 return jsdobj->newLineno;
292 const char*
293 jsd_GetObjectConstructorURL(JSDContext* jsdc, JSDObject* jsdobj)
295 if( jsdobj->ctorURL )
296 return JSD_ATOM_TO_STRING(jsdobj->ctorURL);
297 return NULL;
300 uintN
301 jsd_GetObjectConstructorLineNumber(JSDContext* jsdc, JSDObject* jsdobj)
303 return jsdobj->ctorLineno;
306 const char*
307 jsd_GetObjectConstructorName(JSDContext* jsdc, JSDObject* jsdobj)
309 if( jsdobj->ctorName )
310 return JSD_ATOM_TO_STRING(jsdobj->ctorName);
311 return NULL;
314 JSDObject*
315 jsd_GetJSDObjectForJSObject(JSDContext* jsdc, JSObject* jsobj)
317 JSDObject* jsdobj;
319 JSD_LOCK_OBJECTS(jsdc);
320 jsdobj = (JSDObject*) JS_HashTableLookup(jsdc->objectsTable, jsobj);
321 JSD_UNLOCK_OBJECTS(jsdc);
322 return jsdobj;
325 JSDObject*
326 jsd_GetObjectForValue(JSDContext* jsdc, JSDValue* jsdval)
328 return jsd_GetJSDObjectForJSObject(jsdc, JSVAL_TO_OBJECT(jsdval->val));
331 JSDValue*
332 jsd_GetValueForObject(JSDContext* jsdc, JSDObject* jsdobj)
334 return jsd_NewValue(jsdc, OBJECT_TO_JSVAL(jsdobj->obj));