~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/js/src/xpconnect/src/xpcstack.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 8; 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 Communicator client code, released
 
17
 * March 31, 1998.
 
18
 *
 
19
 * The Initial Developer of the Original Code is
 
20
 * Netscape Communications Corporation.
 
21
 * Portions created by the Initial Developer are Copyright (C) 1999
 
22
 * the Initial Developer. All Rights Reserved.
 
23
 *
 
24
 * Contributor(s):
 
25
 *   John Bandhauer <jband@netscape.com> (original author)
 
26
 *
 
27
 * Alternatively, the contents of this file may be used under the terms of
 
28
 * either of the GNU General Public License Version 2 or later (the "GPL"),
 
29
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
30
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
31
 * of those above. If you wish to allow use of your version of this file only
 
32
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
33
 * use your version of this file under the terms of the MPL, indicate your
 
34
 * decision by deleting the provisions above and replace them with the notice
 
35
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
36
 * the provisions above, a recipient may use your version of this file under
 
37
 * the terms of any one of the MPL, the GPL or the LGPL.
 
38
 *
 
39
 * ***** END LICENSE BLOCK ***** */
 
40
 
 
41
/* Implements nsIStackFrame. */
 
42
 
 
43
#include "xpcprivate.h"
 
44
 
 
45
class XPCJSStackFrame : public nsIStackFrame
 
46
{
 
47
public:
 
48
    NS_DECL_ISUPPORTS
 
49
    NS_DECL_NSISTACKFRAME
 
50
 
 
51
    static nsresult CreateStack(JSContext* cx, JSStackFrame* fp,
 
52
                                XPCJSStackFrame** stack);
 
53
 
 
54
    static nsresult CreateStackFrameLocation(
 
55
                                        PRUint32 aLanguage,
 
56
                                        const char* aFilename,
 
57
                                        const char* aFunctionName,
 
58
                                        PRInt32 aLineNumber,
 
59
                                        nsIStackFrame* aCaller,
 
60
                                        XPCJSStackFrame** stack);
 
61
 
 
62
    XPCJSStackFrame();
 
63
    virtual ~XPCJSStackFrame();
 
64
 
 
65
    JSBool IsJSFrame() const
 
66
        {return mLanguage == nsIProgrammingLanguage::JAVASCRIPT;}
 
67
 
 
68
private:
 
69
    nsIStackFrame* mCaller;
 
70
 
 
71
    char* mFilename;
 
72
    char* mFunname;
 
73
    PRInt32 mLineno;
 
74
    PRUint32 mLanguage;
 
75
};
 
76
 
 
77
/**********************************************/
 
78
 
 
79
// static
 
80
 
 
81
nsresult
 
82
XPCJSStack::CreateStack(JSContext* cx, nsIStackFrame** stack)
 
83
{
 
84
    if(!cx || !cx->fp)
 
85
        return NS_ERROR_FAILURE;
 
86
 
 
87
    return XPCJSStackFrame::CreateStack(cx, cx->fp, (XPCJSStackFrame**) stack);
 
88
}
 
89
 
 
90
// static
 
91
nsresult
 
92
XPCJSStack::CreateStackFrameLocation(PRUint32 aLanguage,
 
93
                                     const char* aFilename,
 
94
                                     const char* aFunctionName,
 
95
                                     PRInt32 aLineNumber,
 
96
                                     nsIStackFrame* aCaller,
 
97
                                     nsIStackFrame** stack)
 
98
{
 
99
    return XPCJSStackFrame::CreateStackFrameLocation(
 
100
                                        aLanguage,
 
101
                                        aFilename,
 
102
                                        aFunctionName,
 
103
                                        aLineNumber,
 
104
                                        aCaller,
 
105
                                        (XPCJSStackFrame**) stack);
 
106
}
 
107
 
 
108
 
 
109
/**********************************************/
 
110
 
 
111
XPCJSStackFrame::XPCJSStackFrame()
 
112
    :   mCaller(nsnull),
 
113
        mFilename(nsnull),
 
114
        mFunname(nsnull),
 
115
        mLineno(0),
 
116
        mLanguage(nsIProgrammingLanguage::UNKNOWN)
 
117
{
 
118
}
 
119
 
 
120
XPCJSStackFrame::~XPCJSStackFrame()
 
121
{
 
122
    if(mFilename)
 
123
        nsMemory::Free(mFilename);
 
124
    if(mFunname)
 
125
        nsMemory::Free(mFunname);
 
126
    NS_IF_RELEASE(mCaller);
 
127
}
 
128
 
 
129
NS_IMPL_THREADSAFE_ISUPPORTS1(XPCJSStackFrame, nsIStackFrame)
 
130
 
 
131
nsresult
 
132
XPCJSStackFrame::CreateStack(JSContext* cx, JSStackFrame* fp,
 
133
                             XPCJSStackFrame** stack)
 
134
{
 
135
    XPCJSStackFrame* self = new XPCJSStackFrame();
 
136
    JSBool failed = JS_FALSE;
 
137
    if(self)
 
138
    {
 
139
        NS_ADDREF(self);
 
140
 
 
141
        if(fp->down)
 
142
        {
 
143
            if(NS_FAILED(CreateStack(cx, fp->down,
 
144
                         (XPCJSStackFrame**) &self->mCaller)))
 
145
                failed = JS_TRUE;
 
146
        }
 
147
 
 
148
        if(!failed)
 
149
        {
 
150
            if (JS_IsNativeFrame(cx, fp))
 
151
                self->mLanguage = nsIProgrammingLanguage::CPLUSPLUS;
 
152
            else
 
153
                self->mLanguage = nsIProgrammingLanguage::JAVASCRIPT;
 
154
            if(self->IsJSFrame())
 
155
            {
 
156
                JSScript* script = JS_GetFrameScript(cx, fp);
 
157
                jsbytecode* pc = JS_GetFramePC(cx, fp);
 
158
                if(script && pc)
 
159
                {
 
160
                    const char* filename = JS_GetScriptFilename(cx, script);
 
161
                    if(filename)
 
162
                    {
 
163
                        self->mFilename = (char*)
 
164
                                nsMemory::Clone(filename,
 
165
                                        sizeof(char)*(strlen(filename)+1));
 
166
                    }
 
167
 
 
168
                    self->mLineno = (PRInt32) JS_PCToLineNumber(cx, script, pc);
 
169
 
 
170
 
 
171
                    JSFunction* fun = JS_GetFrameFunction(cx, fp);
 
172
                    if(fun)
 
173
                    {
 
174
                        const char* funname = JS_GetFunctionName(fun);
 
175
                        if(funname)
 
176
                        {
 
177
                        self->mFunname = (char*)
 
178
                                nsMemory::Clone(funname,
 
179
                                        sizeof(char)*(strlen(funname)+1));
 
180
                        }
 
181
                    }
 
182
                }
 
183
                else
 
184
                {
 
185
                    self->mLanguage = nsIProgrammingLanguage::CPLUSPLUS;
 
186
                }
 
187
            }
 
188
        }
 
189
        if(failed)
 
190
            NS_RELEASE(self);
 
191
    }
 
192
 
 
193
    *stack = self;
 
194
    return self ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 
195
}
 
196
 
 
197
// static
 
198
nsresult
 
199
XPCJSStackFrame::CreateStackFrameLocation(PRUint32 aLanguage,
 
200
                                          const char* aFilename,
 
201
                                          const char* aFunctionName,
 
202
                                          PRInt32 aLineNumber,
 
203
                                          nsIStackFrame* aCaller,
 
204
                                          XPCJSStackFrame** stack)
 
205
{
 
206
    JSBool failed = JS_FALSE;
 
207
    XPCJSStackFrame* self = new XPCJSStackFrame();
 
208
    if(self)
 
209
        NS_ADDREF(self);
 
210
    else
 
211
        failed = JS_TRUE;
 
212
 
 
213
    if(!failed)
 
214
    {
 
215
        self->mLanguage = aLanguage;
 
216
        self->mLineno = aLineNumber;
 
217
    }
 
218
 
 
219
    if(!failed && aFilename)
 
220
    {
 
221
        self->mFilename = (char*)
 
222
                nsMemory::Clone(aFilename,
 
223
                        sizeof(char)*(strlen(aFilename)+1));
 
224
        if(!self->mFilename)
 
225
            failed = JS_TRUE;
 
226
    }
 
227
 
 
228
    if(!failed && aFunctionName)
 
229
    {
 
230
        self->mFunname = (char*)
 
231
                nsMemory::Clone(aFunctionName,
 
232
                        sizeof(char)*(strlen(aFunctionName)+1));
 
233
        if(!self->mFunname)
 
234
            failed = JS_TRUE;
 
235
    }
 
236
 
 
237
    if(!failed && aCaller)
 
238
    {
 
239
        NS_ADDREF(aCaller);
 
240
        self->mCaller = aCaller;
 
241
    }
 
242
 
 
243
    if(failed && self)
 
244
    {
 
245
        NS_RELEASE(self);   // sets self to nsnull
 
246
    }
 
247
 
 
248
    *stack = self;
 
249
    return self ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 
250
}
 
251
 
 
252
/* readonly attribute PRUint32 language; */
 
253
NS_IMETHODIMP XPCJSStackFrame::GetLanguage(PRUint32 *aLanguage)
 
254
{
 
255
    *aLanguage = mLanguage;
 
256
    return NS_OK;
 
257
}
 
258
 
 
259
/* readonly attribute string languageName; */
 
260
NS_IMETHODIMP XPCJSStackFrame::GetLanguageName(char * *aLanguageName)
 
261
{
 
262
    static const char js[] = "JavaScript";
 
263
    static const char cpp[] = "C++";
 
264
    char* temp;
 
265
 
 
266
    if(IsJSFrame())
 
267
        *aLanguageName = temp = (char*) nsMemory::Clone(js, sizeof(js));
 
268
    else
 
269
        *aLanguageName = temp = (char*) nsMemory::Clone(cpp, sizeof(cpp));
 
270
 
 
271
    return temp ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 
272
}
 
273
 
 
274
/* readonly attribute string filename; */
 
275
NS_IMETHODIMP XPCJSStackFrame::GetFilename(char * *aFilename)
 
276
{
 
277
    XPC_STRING_GETTER_BODY(aFilename, mFilename);
 
278
}
 
279
 
 
280
/* readonly attribute string name; */
 
281
NS_IMETHODIMP XPCJSStackFrame::GetName(char * *aFunction)
 
282
{
 
283
    XPC_STRING_GETTER_BODY(aFunction, mFunname);
 
284
}
 
285
 
 
286
/* readonly attribute PRInt32 lineNumber; */
 
287
NS_IMETHODIMP XPCJSStackFrame::GetLineNumber(PRInt32 *aLineNumber)
 
288
{
 
289
    if(!aLineNumber)
 
290
        return NS_ERROR_NULL_POINTER;
 
291
 
 
292
    *aLineNumber = mLineno;
 
293
    return NS_OK;
 
294
}
 
295
 
 
296
/* readonly attribute string sourceLine; */
 
297
NS_IMETHODIMP XPCJSStackFrame::GetSourceLine(char * *aSourceLine)
 
298
{
 
299
    if(!aSourceLine)
 
300
        return NS_ERROR_NULL_POINTER;
 
301
    *aSourceLine = nsnull;
 
302
    return NS_OK;
 
303
}
 
304
 
 
305
/* readonly attribute nsIStackFrame caller; */
 
306
NS_IMETHODIMP XPCJSStackFrame::GetCaller(nsIStackFrame * *aCaller)
 
307
{
 
308
    if(!aCaller)
 
309
        return NS_ERROR_NULL_POINTER;
 
310
 
 
311
    if(mCaller)
 
312
        NS_ADDREF(mCaller);
 
313
    *aCaller = mCaller;
 
314
    return NS_OK;
 
315
}
 
316
 
 
317
/* string toString (); */
 
318
NS_IMETHODIMP XPCJSStackFrame::ToString(char **_retval)
 
319
{
 
320
    if(!_retval)
 
321
        return NS_ERROR_NULL_POINTER;
 
322
 
 
323
    const char* frametype = IsJSFrame() ? "JS" : "native";
 
324
    const char* filename = mFilename ? mFilename : "<unknown filename>";
 
325
    const char* funname = mFunname ? mFunname : "<TOP_LEVEL>";
 
326
    static const char format[] = "%s frame :: %s :: %s :: line %d";
 
327
    int len = sizeof(char)*
 
328
                (strlen(frametype) + strlen(filename) + strlen(funname)) +
 
329
              sizeof(format) + 6 /* space for lineno */;
 
330
 
 
331
    char* buf = (char*) nsMemory::Alloc(len);
 
332
    if(!buf)
 
333
        return NS_ERROR_OUT_OF_MEMORY;
 
334
 
 
335
    JS_snprintf(buf, len, format, frametype, filename, funname, mLineno);
 
336
    *_retval = buf;
 
337
    return NS_OK;
 
338
}
 
339