1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3
* ***** BEGIN LICENSE BLOCK *****
4
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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
16
* The Original Code is Mozilla Communicator client code, released
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.
25
* John Bandhauer <jband@netscape.com> (original author)
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.
39
* ***** END LICENSE BLOCK ***** */
41
/* Implements nsIStackFrame. */
43
#include "xpcprivate.h"
45
class XPCJSStackFrame : public nsIStackFrame
51
static nsresult CreateStack(JSContext* cx, JSStackFrame* fp,
52
XPCJSStackFrame** stack);
54
static nsresult CreateStackFrameLocation(
56
const char* aFilename,
57
const char* aFunctionName,
59
nsIStackFrame* aCaller,
60
XPCJSStackFrame** stack);
63
virtual ~XPCJSStackFrame();
65
JSBool IsJSFrame() const
66
{return mLanguage == nsIProgrammingLanguage::JAVASCRIPT;}
69
nsIStackFrame* mCaller;
77
/**********************************************/
82
XPCJSStack::CreateStack(JSContext* cx, nsIStackFrame** stack)
85
return NS_ERROR_FAILURE;
87
return XPCJSStackFrame::CreateStack(cx, cx->fp, (XPCJSStackFrame**) stack);
92
XPCJSStack::CreateStackFrameLocation(PRUint32 aLanguage,
93
const char* aFilename,
94
const char* aFunctionName,
96
nsIStackFrame* aCaller,
97
nsIStackFrame** stack)
99
return XPCJSStackFrame::CreateStackFrameLocation(
105
(XPCJSStackFrame**) stack);
109
/**********************************************/
111
XPCJSStackFrame::XPCJSStackFrame()
116
mLanguage(nsIProgrammingLanguage::UNKNOWN)
120
XPCJSStackFrame::~XPCJSStackFrame()
123
nsMemory::Free(mFilename);
125
nsMemory::Free(mFunname);
126
NS_IF_RELEASE(mCaller);
129
NS_IMPL_THREADSAFE_ISUPPORTS1(XPCJSStackFrame, nsIStackFrame)
132
XPCJSStackFrame::CreateStack(JSContext* cx, JSStackFrame* fp,
133
XPCJSStackFrame** stack)
135
XPCJSStackFrame* self = new XPCJSStackFrame();
136
JSBool failed = JS_FALSE;
143
if(NS_FAILED(CreateStack(cx, fp->down,
144
(XPCJSStackFrame**) &self->mCaller)))
150
if (JS_IsNativeFrame(cx, fp))
151
self->mLanguage = nsIProgrammingLanguage::CPLUSPLUS;
153
self->mLanguage = nsIProgrammingLanguage::JAVASCRIPT;
154
if(self->IsJSFrame())
156
JSScript* script = JS_GetFrameScript(cx, fp);
157
jsbytecode* pc = JS_GetFramePC(cx, fp);
160
const char* filename = JS_GetScriptFilename(cx, script);
163
self->mFilename = (char*)
164
nsMemory::Clone(filename,
165
sizeof(char)*(strlen(filename)+1));
168
self->mLineno = (PRInt32) JS_PCToLineNumber(cx, script, pc);
171
JSFunction* fun = JS_GetFrameFunction(cx, fp);
174
const char* funname = JS_GetFunctionName(fun);
177
self->mFunname = (char*)
178
nsMemory::Clone(funname,
179
sizeof(char)*(strlen(funname)+1));
185
self->mLanguage = nsIProgrammingLanguage::CPLUSPLUS;
194
return self ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
199
XPCJSStackFrame::CreateStackFrameLocation(PRUint32 aLanguage,
200
const char* aFilename,
201
const char* aFunctionName,
203
nsIStackFrame* aCaller,
204
XPCJSStackFrame** stack)
206
JSBool failed = JS_FALSE;
207
XPCJSStackFrame* self = new XPCJSStackFrame();
215
self->mLanguage = aLanguage;
216
self->mLineno = aLineNumber;
219
if(!failed && aFilename)
221
self->mFilename = (char*)
222
nsMemory::Clone(aFilename,
223
sizeof(char)*(strlen(aFilename)+1));
228
if(!failed && aFunctionName)
230
self->mFunname = (char*)
231
nsMemory::Clone(aFunctionName,
232
sizeof(char)*(strlen(aFunctionName)+1));
237
if(!failed && aCaller)
240
self->mCaller = aCaller;
245
NS_RELEASE(self); // sets self to nsnull
249
return self ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
252
/* readonly attribute PRUint32 language; */
253
NS_IMETHODIMP XPCJSStackFrame::GetLanguage(PRUint32 *aLanguage)
255
*aLanguage = mLanguage;
259
/* readonly attribute string languageName; */
260
NS_IMETHODIMP XPCJSStackFrame::GetLanguageName(char * *aLanguageName)
262
static const char js[] = "JavaScript";
263
static const char cpp[] = "C++";
267
*aLanguageName = temp = (char*) nsMemory::Clone(js, sizeof(js));
269
*aLanguageName = temp = (char*) nsMemory::Clone(cpp, sizeof(cpp));
271
return temp ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
274
/* readonly attribute string filename; */
275
NS_IMETHODIMP XPCJSStackFrame::GetFilename(char * *aFilename)
277
XPC_STRING_GETTER_BODY(aFilename, mFilename);
280
/* readonly attribute string name; */
281
NS_IMETHODIMP XPCJSStackFrame::GetName(char * *aFunction)
283
XPC_STRING_GETTER_BODY(aFunction, mFunname);
286
/* readonly attribute PRInt32 lineNumber; */
287
NS_IMETHODIMP XPCJSStackFrame::GetLineNumber(PRInt32 *aLineNumber)
290
return NS_ERROR_NULL_POINTER;
292
*aLineNumber = mLineno;
296
/* readonly attribute string sourceLine; */
297
NS_IMETHODIMP XPCJSStackFrame::GetSourceLine(char * *aSourceLine)
300
return NS_ERROR_NULL_POINTER;
301
*aSourceLine = nsnull;
305
/* readonly attribute nsIStackFrame caller; */
306
NS_IMETHODIMP XPCJSStackFrame::GetCaller(nsIStackFrame * *aCaller)
309
return NS_ERROR_NULL_POINTER;
317
/* string toString (); */
318
NS_IMETHODIMP XPCJSStackFrame::ToString(char **_retval)
321
return NS_ERROR_NULL_POINTER;
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 */;
331
char* buf = (char*) nsMemory::Alloc(len);
333
return NS_ERROR_OUT_OF_MEMORY;
335
JS_snprintf(buf, len, format, frametype, filename, funname, mLineno);