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
4 : *
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/
9 : *
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.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
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.
21 : *
22 : * Contributor(s):
23 : *
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.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : /*
39 : * JavaScript Debugging support - Object support
40 : */
41 :
42 : #include "jsd.h"
43 :
44 : /*
45 : * #define JSD_TRACE 1
46 : */
47 :
48 : #ifdef JSD_TRACE
49 : #define TRACEOBJ(jsdc, jsdobj, which) _traceObj(jsdc, jsdobj, which)
50 :
51 : static char *
52 : _describeObj(JSDContext* jsdc, JSDObject *jsdobj)
53 : {
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));
62 : }
63 :
64 : static void
65 : _traceObj(JSDContext* jsdc, JSDObject* jsdobj, int which)
66 : {
67 : char* description;
68 :
69 : if( !jsdobj )
70 : return;
71 :
72 : description = _describeObj(jsdc, jsdobj);
73 :
74 : printf("%s : %s\n",
75 : which == 0 ? "new " :
76 : which == 1 ? "final" :
77 : "ctor ",
78 : description);
79 : if(description)
80 : free(description);
81 : }
82 : #else
83 : #define TRACEOBJ(jsdc, jsdobj, which) ((void)0)
84 : #endif /* JSD_TRACE */
85 :
86 : #ifdef DEBUG
87 0 : void JSD_ASSERT_VALID_OBJECT(JSDObject* jsdobj)
88 : {
89 0 : JS_ASSERT(jsdobj);
90 0 : JS_ASSERT(!JS_CLIST_IS_EMPTY(&jsdobj->links));
91 0 : JS_ASSERT(jsdobj->obj);
92 0 : }
93 : #endif
94 :
95 :
96 : static void
97 0 : _destroyJSDObject(JSDContext* jsdc, JSDObject* jsdobj)
98 : {
99 0 : JS_ASSERT(JSD_OBJECTS_LOCKED(jsdc));
100 :
101 0 : JS_REMOVE_LINK(&jsdobj->links);
102 0 : JS_HashTableRemove(jsdc->objectsTable, jsdobj->obj);
103 :
104 0 : if(jsdobj->newURL)
105 0 : jsd_DropAtom(jsdc, jsdobj->newURL);
106 0 : if(jsdobj->ctorURL)
107 0 : jsd_DropAtom(jsdc, jsdobj->ctorURL);
108 0 : if(jsdobj->ctorName)
109 0 : jsd_DropAtom(jsdc, jsdobj->ctorName);
110 0 : free(jsdobj);
111 0 : }
112 :
113 : static JSDObject*
114 0 : _createJSDObject(JSDContext* jsdc, JSContext *cx, JSObject *obj)
115 : {
116 : JSDObject* jsdobj;
117 : JSStackFrame* fp;
118 0 : JSStackFrame* iter = NULL;
119 : const char* newURL;
120 : jsbytecode* pc;
121 :
122 0 : JS_ASSERT(JSD_OBJECTS_LOCKED(jsdc));
123 :
124 0 : jsdobj = (JSDObject*) calloc(1, sizeof(JSDObject));
125 0 : if (jsdobj)
126 : {
127 0 : JS_INIT_CLIST(&jsdobj->links);
128 0 : JS_APPEND_LINK(&jsdobj->links, &jsdc->objectsList);
129 0 : jsdobj->obj = obj;
130 0 : JS_HashTableAdd(jsdc->objectsTable, obj, jsdobj);
131 : }
132 0 : return jsdobj;
133 : }
134 :
135 : void
136 0 : jsd_Constructing(JSDContext* jsdc, JSContext *cx, JSObject *obj,
137 : JSStackFrame *fp)
138 : {
139 : JSDObject* jsdobj;
140 : JSScript* script;
141 : JSDScript* jsdscript;
142 : const char* ctorURL;
143 : JSString* ctorNameStr;
144 : const char* ctorName;
145 :
146 0 : JSD_LOCK_OBJECTS(jsdc);
147 0 : jsdobj = jsd_GetJSDObjectForJSObject(jsdc, obj);
148 0 : if( jsdobj && !jsdobj->ctorURL && JS_IsScriptFrame(cx, fp) )
149 : {
150 0 : script = JS_GetFrameScript(cx, fp);
151 0 : if( script )
152 : {
153 0 : ctorURL = JS_GetScriptFilename(cx, script);
154 0 : if( ctorURL )
155 0 : jsdobj->ctorURL = jsd_AddAtom(jsdc, ctorURL);
156 :
157 0 : JSD_LOCK_SCRIPTS(jsdc);
158 0 : jsdscript = jsd_FindOrCreateJSDScript(jsdc, cx, script, fp);
159 0 : JSD_UNLOCK_SCRIPTS(jsdc);
160 0 : if( jsdscript && (ctorNameStr = jsd_GetScriptFunctionId(jsdc, jsdscript)) ) {
161 0 : if( (ctorName = JS_EncodeString(cx, ctorNameStr)) ) {
162 0 : jsdobj->ctorName = jsd_AddAtom(jsdc, ctorName);
163 0 : JS_free(cx, (void *) ctorName);
164 : }
165 : }
166 0 : jsdobj->ctorLineno = JS_GetScriptBaseLineNumber(cx, script);
167 : }
168 : }
169 : TRACEOBJ(jsdc, jsdobj, 3);
170 0 : JSD_UNLOCK_OBJECTS(jsdc);
171 0 : }
172 :
173 : static JSHashNumber
174 0 : _hash_root(const void *key)
175 : {
176 0 : return ((JSHashNumber)(ptrdiff_t) key) >> 2; /* help lame MSVC1.5 on Win16 */
177 : }
178 :
179 : JSBool
180 280 : jsd_InitObjectManager(JSDContext* jsdc)
181 : {
182 280 : JS_INIT_CLIST(&jsdc->objectsList);
183 280 : jsdc->objectsTable = JS_NewHashTable(256, _hash_root,
184 : JS_CompareValues, JS_CompareValues,
185 : NULL, NULL);
186 280 : return !!jsdc->objectsTable;
187 : }
188 :
189 : void
190 280 : jsd_DestroyObjectManager(JSDContext* jsdc)
191 : {
192 280 : jsd_DestroyObjects(jsdc);
193 280 : JSD_LOCK_OBJECTS(jsdc);
194 280 : JS_HashTableDestroy(jsdc->objectsTable);
195 280 : JSD_UNLOCK_OBJECTS(jsdc);
196 280 : }
197 :
198 : void
199 280 : jsd_DestroyObjects(JSDContext* jsdc)
200 : {
201 280 : JSD_LOCK_OBJECTS(jsdc);
202 560 : while( !JS_CLIST_IS_EMPTY(&jsdc->objectsList) )
203 0 : _destroyJSDObject(jsdc, (JSDObject*)JS_NEXT_LINK(&jsdc->objectsList));
204 280 : JSD_UNLOCK_OBJECTS(jsdc);
205 280 : }
206 :
207 : JSDObject*
208 0 : jsd_IterateObjects(JSDContext* jsdc, JSDObject** iterp)
209 : {
210 0 : JSDObject *jsdobj = *iterp;
211 :
212 0 : JS_ASSERT(JSD_OBJECTS_LOCKED(jsdc));
213 :
214 0 : if( !jsdobj )
215 0 : jsdobj = (JSDObject *)jsdc->objectsList.next;
216 0 : if( jsdobj == (JSDObject *)&jsdc->objectsList )
217 0 : return NULL;
218 0 : *iterp = (JSDObject*) jsdobj->links.next;
219 0 : return jsdobj;
220 : }
221 :
222 : JSObject*
223 0 : jsd_GetWrappedObject(JSDContext* jsdc, JSDObject* jsdobj)
224 : {
225 0 : return jsdobj->obj;
226 : }
227 :
228 : const char*
229 0 : jsd_GetObjectNewURL(JSDContext* jsdc, JSDObject* jsdobj)
230 : {
231 0 : if( jsdobj->newURL )
232 0 : return JSD_ATOM_TO_STRING(jsdobj->newURL);
233 0 : return NULL;
234 : }
235 :
236 : unsigned
237 0 : jsd_GetObjectNewLineNumber(JSDContext* jsdc, JSDObject* jsdobj)
238 : {
239 0 : return jsdobj->newLineno;
240 : }
241 :
242 : const char*
243 0 : jsd_GetObjectConstructorURL(JSDContext* jsdc, JSDObject* jsdobj)
244 : {
245 0 : if( jsdobj->ctorURL )
246 0 : return JSD_ATOM_TO_STRING(jsdobj->ctorURL);
247 0 : return NULL;
248 : }
249 :
250 : unsigned
251 0 : jsd_GetObjectConstructorLineNumber(JSDContext* jsdc, JSDObject* jsdobj)
252 : {
253 0 : return jsdobj->ctorLineno;
254 : }
255 :
256 : const char*
257 0 : jsd_GetObjectConstructorName(JSDContext* jsdc, JSDObject* jsdobj)
258 : {
259 0 : if( jsdobj->ctorName )
260 0 : return JSD_ATOM_TO_STRING(jsdobj->ctorName);
261 0 : return NULL;
262 : }
263 :
264 : JSDObject*
265 0 : jsd_GetJSDObjectForJSObject(JSDContext* jsdc, JSObject* jsobj)
266 : {
267 : JSDObject* jsdobj;
268 :
269 0 : JSD_LOCK_OBJECTS(jsdc);
270 0 : jsdobj = (JSDObject*) JS_HashTableLookup(jsdc->objectsTable, jsobj);
271 0 : JSD_UNLOCK_OBJECTS(jsdc);
272 0 : return jsdobj;
273 : }
274 :
275 : JSDObject*
276 0 : jsd_GetObjectForValue(JSDContext* jsdc, JSDValue* jsdval)
277 : {
278 0 : return jsd_GetJSDObjectForJSObject(jsdc, JSVAL_TO_OBJECT(jsdval->val));
279 : }
280 :
281 : JSDValue*
282 0 : jsd_GetValueForObject(JSDContext* jsdc, JSDObject* jsdobj)
283 : {
284 0 : return jsd_NewValue(jsdc, OBJECT_TO_JSVAL(jsdobj->obj));
285 : }
286 :
287 :
|